diff --git a/.gitignore b/.gitignore index 7e3b942d7a505517053fecaabf79beb5953c4a93..257077ee45bce84a2bef1d91981a06038362e8ce 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ ets2panda/linter*/test_rules/**/results ets2panda/linter*/test_regression/**/results ets2panda/linter*/test_extended_features/**/results ets2panda/linter*/**/package-lock.json +ets2panda/linter*/arkanalyzer/**/lib +ets2panda/linter*/homecheck/**/lib **/compile_commands.json .cache .vscode diff --git a/bundle.json b/bundle.json index aaab390cf32c3c7bcafe70a2734362d6bf47b2c5..142291a602d1816d52b25cde51f9854cbe80013b 100644 --- a/bundle.json +++ b/bundle.json @@ -39,6 +39,12 @@ }, { "name": "//arkcompiler/ets_frontend/es2panda:es2panda" + }, + { + "name": "//arkcompiler/ets_frontend/ets2panda/driver/build_system:ohos_ets_build_system" + }, + { + "name": "//arkcompiler/ets_frontend/ets2panda:libes2panda_public" } ], "test": [ diff --git a/codecheck_ignore.json b/codecheck_ignore.json index c0c4e5df780e28199f151310a79a20576a8c14ed..775d3e87749d84a686e43295bed4f0abf0ba279e 100755 --- a/codecheck_ignore.json +++ b/codecheck_ignore.json @@ -9,6 +9,8 @@ "legacy_bin": "*", "merge_abc": "*", "ets2panda/public/headers_parser": "*", + "ets2panda/linter/arkanalyzer": "*", + "ets2panda/linter/homecheck": "*", "*": ["G.CMT.03", "G.FMT.11", "G.NAM.03", "huge_headerfile", "huge_non_headerfile", "bc-30001"] } diff --git a/es2panda/aot/options.cpp b/es2panda/aot/options.cpp index ccaa1d2a9a50c32b806d4b222f2f60bb9315a0b3..0ae82fe65fdb6c60b9628bb340c07f2ff3dbccb1 100644 --- a/es2panda/aot/options.cpp +++ b/es2panda/aot/options.cpp @@ -446,6 +446,9 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg dstPkgName("dst-package-name", "", "This is for modify pacakge name in input abc"\ " file, and should always be used with srcPkgName. dstPkgName what targeting package name will be"\ " modified to."); + panda::PandArg enableEtsImplements( + "enable-ets-implements", false, + "Allow es2abc to pass static ETS implementation information from source files to bytecode"); // aop transform panda::PandArg transformLib("transform-lib", "", "aop transform lib file path"); @@ -518,6 +521,7 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&srcPkgName); argparser_->Add(&dstPkgName); + argparser_->Add(&enableEtsImplements); argparser_->PushBackTail(&inputFile); argparser_->EnableTail(); @@ -745,6 +749,7 @@ bool Options::Parse(int argc, const char **argv) compilerOptions_.patchFixOptions.coldFix = coldFix; compilerOptions_.enableAnnotations = enableAnnotations.GetValue(); + compilerOptions_.enableEtsImplements = enableEtsImplements.GetValue(); bool transformLibIsEmpty = transformLib.GetValue().empty(); if (!transformLibIsEmpty) { diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 3700382d175bab304de22de637a1d73948a1f196..32b9e3809cb95483aee1f42278fc31916aca99e4 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -768,11 +768,12 @@ void Binder::ResolveReference(const ir::AstNode *parent, ir::AstNode *childNode) if (inSendableClass_ || inSendableFunction_) { scriptFunc->SetInSendable(); } - bool enableSendableClass = program_->TargetApiVersion() >= - util::Helpers::SENDABLE_CLASS_MIN_SUPPORTED_API_VERSION; - util::Helpers::ScanDirectives(const_cast(scriptFunc), Program()->GetLineIndex(), - enableSendableClass, - !util::Helpers::IsDefaultApiVersion(program_->TargetApiVersion(), program_->GetTargetApiSubVersion())); + util::DirectiveScanConfig scanInfos { + Program()->GetLineIndex(), + program_->TargetApiVersion() >= util::Helpers::SENDABLE_CLASS_MIN_SUPPORTED_API_VERSION, + !util::Helpers::IsDefaultApiVersion(program_->TargetApiVersion(), program_->GetTargetApiSubVersion()), + program_->IsEnableEtsImplements()}; + util::Helpers::ScanDirectives(const_cast(scriptFunc), scanInfos); if (scriptFunc->IsConstructor() && util::Helpers::GetClassDefiniton(scriptFunc)->IsSendable()) { scriptFunc->SetInSendable(); diff --git a/es2panda/compiler/core/compileQueue.cpp b/es2panda/compiler/core/compileQueue.cpp index c882b086ddd8f6ba1cd82ef435a3a763ef495d02..5abe07121740f7cff78460432871b6ba7fa1bbd5 100644 --- a/es2panda/compiler/core/compileQueue.cpp +++ b/es2panda/compiler/core/compileQueue.cpp @@ -281,7 +281,7 @@ void CompileAbcClassJob::UpdateDynamicImport(panda::pandasm::Program *prog, const std::map &pkgContextInfo) { for (auto &[name, function] : prog->function_table) { - util::VisitDyanmicImports(function, [this, pkgContextInfo](std::string &ohmurl) { + util::VisitDyanmicImports(function, [this, &prog, pkgContextInfo](std::string &ohmurl) { if (this->options_.compileContextInfo.needModifyRecord) { this->UpdateBundleNameOfOhmurl(ohmurl); } @@ -289,6 +289,7 @@ void CompileAbcClassJob::UpdateDynamicImport(panda::pandasm::Program *prog, if (newOhmurl == ohmurl) { return; } + prog->strings.insert(newOhmurl); this->SetOhmurlBeenChanged(true); ohmurl = newOhmurl; }); diff --git a/es2panda/compiler/core/emitter/emitter.cpp b/es2panda/compiler/core/emitter/emitter.cpp index b1799b3210c89b887c2bb8e12ae7cc6035580208..051e0d84d0fd7a81ac2b1da693f3fa65364a362c 100644 --- a/es2panda/compiler/core/emitter/emitter.cpp +++ b/es2panda/compiler/core/emitter/emitter.cpp @@ -1211,6 +1211,11 @@ void Emitter::GenBufferLiterals(ArenaVectorGetMethod().Mutf8(); break; } + case ir::LiteralTag::ETS_IMPLEMENTS: { + valueLit.tag_ = panda::panda_file::LiteralTag::ETS_IMPLEMENTS; + valueLit.value_ = literal->GetString().Mutf8(); + break; + } case ir::LiteralTag::NULL_VALUE: { valueLit.tag_ = panda::panda_file::LiteralTag::NULLVALUE; valueLit.value_ = static_cast(0); diff --git a/es2panda/es2panda.h b/es2panda/es2panda.h index 1715ae289b0ec17e8b6f709c697698ea0afd6008..31525f01af02c16ce354215070cae5dfe4e924c8 100644 --- a/es2panda/es2panda.h +++ b/es2panda/es2panda.h @@ -124,6 +124,7 @@ struct CompilerOptions { std::string targetApiSubVersion; std::string moduleRecordFieldName; bool enableAnnotations; + bool enableEtsImplements {false}; // Ability to modify package names using bytecode std::string modifiedPkgName {}; }; diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index 83ebbdbbe7c84e71896182e50ab843ee49a29627..274a533e0234619d3939cb07a5ce8a456912cd9e 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -212,6 +212,11 @@ int32_t ClassDefinition::CreateClassPublicBuffer(compiler::PandaGen *pg, util::B util::UString fieldTypeLitId(fieldTypeIdxStr, pg->Allocator()); buf->Add(pg->Allocator()->New(LiteralTag::LITERALARRAY, fieldTypeLitId.View())); } + + if (IsImplementFromEts()) { + buf->Add(pg->Allocator()->New(LiteralTag::ETS_IMPLEMENTS, etsImplementsMessage_)); + } + return pg->AddLiteralBuffer(buf); } diff --git a/es2panda/ir/base/classDefinition.h b/es2panda/ir/base/classDefinition.h index 711d1127e5c3cf17a1e614cc6de38e10c6501df7..ca52a31c34531cfc41432bd391152945fd956ba5 100644 --- a/es2panda/ir/base/classDefinition.h +++ b/es2panda/ir/base/classDefinition.h @@ -231,6 +231,16 @@ public: return isSendable_; } + void SetImplementFromEts() + { + isImplementFromEts_ = true; + } + + bool IsImplementFromEts() const + { + return isImplementFromEts_; + } + void SetClassDecoratorPresent() { isClassDecoratorPresent_ = true; @@ -251,6 +261,16 @@ public: return classExpectedPropertyCount_; } + void SetEtsImplementsMessage(util::StringView message) + { + etsImplementsMessage_ = message; + } + + util::StringView GetEtsImplementsMessage() const + { + return etsImplementsMessage_; + } + void CalculateClassExpectedPropertyCount(); void ProcessClassProperty(const ClassProperty *prop, const std::function& addPropertyName); @@ -309,7 +329,9 @@ private: bool hasPrivateElement_ {false}; bool isSendable_ {false}; bool isClassDecoratorPresent_ {false}; + bool isImplementFromEts_ {false}; size_t classExpectedPropertyCount_ {0}; + util::StringView etsImplementsMessage_ {""}; }; } // namespace panda::es2panda::ir diff --git a/es2panda/ir/expressions/literal.h b/es2panda/ir/expressions/literal.h index b92ea7b48612a3c4745ae456d970764575f999c0..d51f05619d94e375a3a1cab11daa97f05e0197d8 100644 --- a/es2panda/ir/expressions/literal.h +++ b/es2panda/ir/expressions/literal.h @@ -48,6 +48,7 @@ enum class LiteralTag { BUILTINTYPEINDEX = 25, GETTER = 26, SETTER = 27, + ETS_IMPLEMENTS = 28, NULL_VALUE = 255, }; diff --git a/es2panda/ir/expressions/literals/taggedLiteral.h b/es2panda/ir/expressions/literals/taggedLiteral.h index 006b87d98134abdf8c53ce7501b41b07ec2c11ab..2dfe2a321202930d63eeb0a20af06de085104e94 100644 --- a/es2panda/ir/expressions/literals/taggedLiteral.h +++ b/es2panda/ir/expressions/literals/taggedLiteral.h @@ -60,7 +60,7 @@ public: const util::StringView &Method() const { ASSERT(tag_ == LiteralTag::ACCESSOR || tag_ == LiteralTag::METHOD || tag_ == LiteralTag::GENERATOR_METHOD || - tag_ == LiteralTag::ASYNC_GENERATOR_METHOD || tag_== LiteralTag::GETTER || tag_ == LiteralTag::SETTER); + tag_ == LiteralTag::ASYNC_GENERATOR_METHOD || tag_ == LiteralTag::GETTER || tag_ == LiteralTag::SETTER); return str_; } diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index 0784e69c5cb18bc6c5ef5f73f05fe34f28a17a8e..cf578562b764135d0c0878bee238ba18d9df6b22 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -118,6 +118,7 @@ Program ParserImpl::Parse(const SourceFile &sourceFile, const CompilerOptions &o program_.SetTargetApiVersion(options.targetApiVersion); program_.SetTargetApiSubVersion(options.targetApiSubVersion); program_.SetEnableAnnotations(options.enableAnnotations); + program_.SetEnableEtsImplements(options.enableEtsImplements); program_.SetShared(sourceFile.isSharedModule); program_.SetModuleRecordFieldName(options.moduleRecordFieldName); program_.SetSourceLang(sourceFile.sourceLang); diff --git a/es2panda/parser/program/program.cpp b/es2panda/parser/program/program.cpp index a87107bf8877fc4d90e10d37261467d8e5ade942..5151f3845c35b604012dd754b291710a9f0ec940 100644 --- a/es2panda/parser/program/program.cpp +++ b/es2panda/parser/program/program.cpp @@ -48,6 +48,7 @@ Program::Program(Program &&other) targetApiVersion_(other.targetApiVersion_), useDefineSemantic_(other.useDefineSemantic_), isShared_(other.isShared_), + enableEtsImplements_(other.enableEtsImplements_), targetApiSubVersion_(other.targetApiSubVersion_), moduleRecordFieldName_(other.moduleRecordFieldName_), sourceLang_(other.sourceLang_) @@ -78,6 +79,7 @@ Program &Program::operator=(Program &&other) targetApiVersion_ = other.targetApiVersion_; useDefineSemantic_ = other.useDefineSemantic_; isShared_ = other.isShared_; + enableEtsImplements_ = other.enableEtsImplements_; targetApiSubVersion_ = other.targetApiSubVersion_; moduleRecordFieldName_ = other.moduleRecordFieldName_; sourceLang_ = other.sourceLang_; diff --git a/es2panda/parser/program/program.h b/es2panda/parser/program/program.h index 050cf234577ea47e1a7b3d4eda547aebfb332be1..493fff1a021dd357725a7380477f3c0bebe004c8 100644 --- a/es2panda/parser/program/program.h +++ b/es2panda/parser/program/program.h @@ -235,6 +235,16 @@ public: return enableAnnotations_; } + void SetEnableEtsImplements(bool enableEtsImplements) + { + enableEtsImplements_ = enableEtsImplements; + } + + bool IsEnableEtsImplements() const + { + return enableEtsImplements_; + } + void SetSourceLang(const std::string &sourceLang) { if (sourceLang == "ets") { @@ -277,6 +287,7 @@ private: bool useDefineSemantic_ {true}; bool isShared_ {false}; bool enableAnnotations_ {false}; + bool enableEtsImplements_ {false}; std::string targetApiSubVersion_ { util::Helpers::DEFAULT_SUB_API_VERSION }; std::string moduleRecordFieldName_; panda::pandasm::extensions::Language sourceLang_ {panda::pandasm::extensions::DEFAULT_LANGUAGE}; diff --git a/es2panda/scripts/generate_js_bytecode.py b/es2panda/scripts/generate_js_bytecode.py index 712b721fefdb169dbf68798c5ea5a7bab52c9185..c1d364a95b19ce0ea64aca487078847ea96fb253 100755 --- a/es2panda/scripts/generate_js_bytecode.py +++ b/es2panda/scripts/generate_js_bytecode.py @@ -58,6 +58,8 @@ def parse_args(): 'its value will be the path of input file if not specified') parser.add_argument("--enable-annotations", action='store_true', help='whether annotations are enabled or not') + parser.add_argument("--enable-ets-implements", action='store_true', + help='whether ets implements are enabled or not'), arguments = parser.parse_args() return arguments @@ -107,6 +109,9 @@ def gen_abc_info(input_arguments): if input_arguments.enable_annotations: src_index = cmd.index(input_arguments.src_js) cmd.insert(src_index, '--enable-annotations') + if input_arguments.enable_ets_implements: + src_index = cmd.index(input_arguments.src_js) + cmd.insert(src_index, '--enable-ets-implements') # insert d.ts option to cmd later cmd.append("--target-api-sub-version=beta3") diff --git a/es2panda/test/compiler/abc2program/update-version/base.ts b/es2panda/test/compiler/abc2program/update-version/base.ts new file mode 100644 index 0000000000000000000000000000000000000000..62cf898c389bc4eb98b84a5ccb584cdf456ed142 --- /dev/null +++ b/es2panda/test/compiler/abc2program/update-version/base.ts @@ -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. + */ + +import { test } from '@normalized:N&&&package/src/main/test&1.0.0'; + +test(); + +import('@normalized:N&&&package/src/main/other&1.0.0').then(()=>{ +}); diff --git a/es2panda/test/compiler/abc2program/update-version/compileContextInfo.json b/es2panda/test/compiler/abc2program/update-version/compileContextInfo.json new file mode 100644 index 0000000000000000000000000000000000000000..1d3cedb7c447c324583fa471afecdbcf1a0e1538 --- /dev/null +++ b/es2panda/test/compiler/abc2program/update-version/compileContextInfo.json @@ -0,0 +1,12 @@ +{ + "compileEntries": [ + ], + "projectRootPath": "", + "pkgContextInfo": { + "package": { + "packageName": "package", + "version": "2.0.0" + } + }, + "hspPkgNames": [] +} \ No newline at end of file diff --git a/es2panda/test/compiler/abc2program/update-version/expected.txt b/es2panda/test/compiler/abc2program/update-version/expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..da32b0ac805a487a0ffef3710b82e1ac746f30d0 --- /dev/null +++ b/es2panda/test/compiler/abc2program/update-version/expected.txt @@ -0,0 +1,101 @@ + +======> literal array buffer <====== +======> strings <====== + + +======> literal array buffer <====== +======> strings <====== + + +======> literal array buffer <====== +======> strings <====== + +slotNum = 0x0 +.language ECMAScript +.function any original.#*#(any a0, any a1, any a2) { + returnundefined +} + +slotNum = 0x7 +.language ECMAScript +.function any original.func_main_0(any a0, any a1, any a2) { + newlexenv 0x2 + lda a1 + stlexvar 0x0, 0x0 + lda a2 + stlexvar 0x0, 0x1 + ldexternalmodulevar 0x0 + sta v0 + throw.undefinedifholewithname test + lda v0 + callarg0 0x0 + lda.str @normalized:N&&&package/src/main/other&2.0.0 + dynamicimport + sta v0 + ldobjbyname 0x2, then + sta v1 + definefunc 0x4, original.#*#, 0x0 + sta v2 + lda v1 + callthis1 0x5, v0, v2 + returnundefined +} + + +======> literal array buffer <====== +------------------------------------ +slot original_686 +------------------------------------ +slot original_690 +{ + index: 0 + tag: 2 + val: 1 +}, +{ + index: 1 + tag: 5 + val: @normalized:N&&&package/src/main/test&2.0.0 +}, +{ + index: 2 + tag: 2 + val: 1 +}, +{ + index: 3 + tag: 5 + val: test +}, +{ + index: 4 + tag: 5 + val: test +}, +{ + index: 5 + tag: 9 + val: 0 +}, +{ + index: 6 + tag: 2 + val: 0 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 2 + val: 0 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +======> strings <====== +"@normalized:N&&&package/src/main/other&1.0.0"; "@normalized:N&&&package/src/main/other&2.0.0"; "original.#*#"; "test"; "then"; diff --git a/es2panda/test/compiler/interop/etsInterface/etsExtends1-expected.pa.txt b/es2panda/test/compiler/interop/etsInterface/etsExtends1-expected.pa.txt new file mode 100644 index 0000000000000000000000000000000000000000..7fe959e8b5a86e642ae161ea104b22ec9d69551f --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/etsExtends1-expected.pa.txt @@ -0,0 +1,126 @@ +slotNum = 0x0 +.language ECMAScript +.function any .#~A=#A(any a0, any a1, any a2, any a3) { +label_1: +label_0: + lda a2 + return +label_2: +} + +slotNum = 0x3 +.language ECMAScript +.function any .#~A>#foo(any a0, any a1, any a2) { +label_1: +label_0: + tryldglobalbyname 0x0, print + sta v0 + lda.str a + sta v1 + lda v0 + callarg1 0x1, v1 + returnundefined +label_2: +} + +slotNum = 0x3 +.language ECMAScript +.function any .func_main_0(any a0, any a1, any a2) { +label_1: +label_0: + ldhole + sta v0 + defineclasswithbuffer 0x0, .#~A=#A, _2, 0x1, v0 + ldobjbyname 0x1, prototype + returnundefined +label_2: +} + + +======> literal array buffer <====== +------------------------------------ +slot _0 +------------------------------------ +slot _1 +{ + index: 0 + tag: 2 + val: 0 +}, +{ + index: 1 + tag: 2 + val: 0 +}, +{ + index: 2 + tag: 2 + val: 0 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 2 + val: 0 +}, +{ + index: 5 + tag: 2 + val: 0 +}, +------------------------------------ +slot _2 +{ + index: 0 + tag: 0 + val: 5 +}, +{ + index: 1 + tag: 5 + val: foo +}, +{ + index: 2 + tag: 0 + val: 6 +}, +{ + index: 3 + tag: 6 + val: .#~A>#foo +}, +{ + index: 4 + tag: 0 + val: 9 +}, +{ + index: 5 + tag: 9 + val: 0 +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 1 +}, +{ + index: 8 + tag: 0 + val: 28 +}, +{ + index: 9 + tag: 28 + val: L/src/main/ets//I; +}, diff --git a/es2panda/test/compiler/interop/etsInterface/etsExtends1.ts b/es2panda/test/compiler/interop/etsInterface/etsExtends1.ts new file mode 100644 index 0000000000000000000000000000000000000000..e913c45f699562af42b49651ad73c9ed69c7022b --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/etsExtends1.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. + */ + +// I is a static interface +interface I1 extends I { } + +class A implements I1 { + constructor(a: number) { + "implements static:L/src/main/ets//I;" + } + foo() { + print("a"); + } +} diff --git a/es2panda/test/compiler/interop/etsInterface/etsExtends2-expected.pa.txt b/es2panda/test/compiler/interop/etsInterface/etsExtends2-expected.pa.txt new file mode 100644 index 0000000000000000000000000000000000000000..7fe959e8b5a86e642ae161ea104b22ec9d69551f --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/etsExtends2-expected.pa.txt @@ -0,0 +1,126 @@ +slotNum = 0x0 +.language ECMAScript +.function any .#~A=#A(any a0, any a1, any a2, any a3) { +label_1: +label_0: + lda a2 + return +label_2: +} + +slotNum = 0x3 +.language ECMAScript +.function any .#~A>#foo(any a0, any a1, any a2) { +label_1: +label_0: + tryldglobalbyname 0x0, print + sta v0 + lda.str a + sta v1 + lda v0 + callarg1 0x1, v1 + returnundefined +label_2: +} + +slotNum = 0x3 +.language ECMAScript +.function any .func_main_0(any a0, any a1, any a2) { +label_1: +label_0: + ldhole + sta v0 + defineclasswithbuffer 0x0, .#~A=#A, _2, 0x1, v0 + ldobjbyname 0x1, prototype + returnundefined +label_2: +} + + +======> literal array buffer <====== +------------------------------------ +slot _0 +------------------------------------ +slot _1 +{ + index: 0 + tag: 2 + val: 0 +}, +{ + index: 1 + tag: 2 + val: 0 +}, +{ + index: 2 + tag: 2 + val: 0 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 2 + val: 0 +}, +{ + index: 5 + tag: 2 + val: 0 +}, +------------------------------------ +slot _2 +{ + index: 0 + tag: 0 + val: 5 +}, +{ + index: 1 + tag: 5 + val: foo +}, +{ + index: 2 + tag: 0 + val: 6 +}, +{ + index: 3 + tag: 6 + val: .#~A>#foo +}, +{ + index: 4 + tag: 0 + val: 9 +}, +{ + index: 5 + tag: 9 + val: 0 +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 1 +}, +{ + index: 8 + tag: 0 + val: 28 +}, +{ + index: 9 + tag: 28 + val: L/src/main/ets//I; +}, diff --git a/es2panda/test/compiler/interop/etsInterface/etsExtends2.ts b/es2panda/test/compiler/interop/etsInterface/etsExtends2.ts new file mode 100644 index 0000000000000000000000000000000000000000..aa60fbfbeae3090545356a0fab744ad527db1727 --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/etsExtends2.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. + */ + +// I is a static interface +interface I1 extends I { } + +class A implements I1 { + constructor(a: number) { + "implements static:L/src/main/ets//I;" + } + foo() { + print("a"); + } +} \ No newline at end of file diff --git a/es2panda/test/compiler/interop/etsInterface/etsImplements-expected.pa.txt b/es2panda/test/compiler/interop/etsInterface/etsImplements-expected.pa.txt new file mode 100644 index 0000000000000000000000000000000000000000..ea854ca2fcb6c2c1d6e8f597d28f65a51309b3fb --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/etsImplements-expected.pa.txt @@ -0,0 +1,89 @@ +# ==================== +# LITERALS + +_0 + +_1 { 6 [ i32:0, i32:0, i32:0, i32:0, i32:0, i32:0, ]} + +_2 { 10 [ tag_value:5, string:"foo", tag_value:6, method:.#~A>#foo, tag_value:9, method_affiliate:1, tag_value:2, i32:1, tag_value:28, ets_implements:L/src/main/ets//I1;,L/src/main/ets//I2;, ]} + + + +# ==================== +# RECORDS + +.language ECMAScript +.record _ESExpectedPropertyCountAnnotation { +} +.record.source_file + +.language ECMAScript +.record _ESModuleRecord { + u32 /mnt/data/z00887425/ohos1/arkcompiler/ets_frontend/es2panda/test/compiler/interop/etsInterface/etsImplements.ts _1 +} +.record.source_file + +.language ECMAScript +.record _ESScopeNamesRecord { + u32 /mnt/data/z00887425/ohos1/arkcompiler/ets_frontend/es2panda/test/compiler/interop/etsInterface/etsImplements.ts _0 +} +.record.source_file + +.language ECMAScript +.record _ESSlotNumberAnnotation { +} +.record.source_file + + +# ==================== +# METHODS + +.function_kind FunctionKind::NONE + _ESSlotNumberAnnotation + SlotNumber 2 +.language ECMAScript +.function any .#~A=#A(any a0, any a1, any a2, any a3) { + label_1: # line: 18 # column: 0 + label_0: # line: 18 # column: 0 + lda a3 # line: 18 # column: 0 + stobjbyname 0x0, a, a2 # line: 18 # column: 0 + lda a2 # line: 18 # column: 0 + return # line: 18 # column: 0 + label_2: # line: 18 # column: 0 +} + +.function_kind FunctionKind::NONE + _ESSlotNumberAnnotation + SlotNumber 3 +.language ECMAScript +.function any .#~A>#foo(any a0, any a1, any a2, any a3) { + label_1: # line: 20 # column: 0 + label_0: # line: 20 # column: 0 + tryldglobalbyname 0x0, print # line: 20 # column: 0 + callarg1 0x1, a3 # line: 20 # column: 0 + returnundefined # line: 21 # column: 0 + label_2: # line: 21 # column: 0 +} + +.function_kind FunctionKind::FUNCTION + _ESSlotNumberAnnotation + SlotNumber 3 +.language ECMAScript +.function any .func_main_0(any a0, any a1, any a2) { + label_1: # line: 15 # column: 0 + label_0: # line: 15 # column: 0 + ldhole # line: 15 # column: 0 + sta v0 # line: 15 # column: 0 + defineclasswithbuffer 0x0, .#~A=#A, _2, 0x1, v0 # line: 15 # column: 0 + ldobjbyname 0x1, prototype # line: 15 # column: 0 + returnundefined # line: 18446744073709551615 # column: 0 + label_2: # line: 18446744073709551615 # column: 0 +} + +# ==================== +# STRING +.#~A=#A +a +implements static:L/src/main/ets//I1;,L/src/main/ets//I2; +print +prototype diff --git a/es2panda/test/compiler/interop/etsInterface/etsImplements1-expected.pa.txt b/es2panda/test/compiler/interop/etsInterface/etsImplements1-expected.pa.txt new file mode 100644 index 0000000000000000000000000000000000000000..2b0d51f38952ac76dc1fcf392fd2519a80415408 --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/etsImplements1-expected.pa.txt @@ -0,0 +1,124 @@ +slotNum = 0x2 +.language ECMAScript +.function any .#~A=#A(any a0, any a1, any a2, any a3) { +label_1: +label_0: + lda a3 + stobjbyname 0x0, a, a2 + lda a2 + return +label_2: +} + +slotNum = 0x3 +.language ECMAScript +.function any .#~A>#foo(any a0, any a1, any a2, any a3) { +label_1: +label_0: + tryldglobalbyname 0x0, print + callarg1 0x1, a3 + returnundefined +label_2: +} + +slotNum = 0x3 +.language ECMAScript +.function any .func_main_0(any a0, any a1, any a2) { +label_1: +label_0: + ldhole + sta v0 + defineclasswithbuffer 0x0, .#~A=#A, _2, 0x1, v0 + ldobjbyname 0x1, prototype + returnundefined +label_2: +} + + +======> literal array buffer <====== +------------------------------------ +slot _0 +------------------------------------ +slot _1 +{ + index: 0 + tag: 2 + val: 0 +}, +{ + index: 1 + tag: 2 + val: 0 +}, +{ + index: 2 + tag: 2 + val: 0 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 2 + val: 0 +}, +{ + index: 5 + tag: 2 + val: 0 +}, +------------------------------------ +slot _2 +{ + index: 0 + tag: 0 + val: 5 +}, +{ + index: 1 + tag: 5 + val: foo +}, +{ + index: 2 + tag: 0 + val: 6 +}, +{ + index: 3 + tag: 6 + val: .#~A>#foo +}, +{ + index: 4 + tag: 0 + val: 9 +}, +{ + index: 5 + tag: 9 + val: 1 +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 1 +}, +{ + index: 8 + tag: 0 + val: 28 +}, +{ + index: 9 + tag: 28 + val: L/src/main/ets//I; +}, diff --git a/es2panda/test/compiler/interop/etsInterface/etsImplements1.ts b/es2panda/test/compiler/interop/etsInterface/etsImplements1.ts new file mode 100644 index 0000000000000000000000000000000000000000..25b90995f8d11948574cacfd156942299e12b5fe --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/etsImplements1.ts @@ -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. + */ + +// I is a static interface +class A implements I { + constructor(public a: number) { + "implements static:L/src/main/ets//I;" + } + foo(a) { + print(a); + } +} diff --git a/es2panda/test/compiler/interop/etsInterface/etsImplements2-expected.pa.txt b/es2panda/test/compiler/interop/etsInterface/etsImplements2-expected.pa.txt new file mode 100644 index 0000000000000000000000000000000000000000..50aba435c825fc9e440cf3d23b942dce8cd7d213 --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/etsImplements2-expected.pa.txt @@ -0,0 +1,124 @@ +slotNum = 0x2 +.language ECMAScript +.function any .#~A=#A(any a0, any a1, any a2, any a3) { +label_1: +label_0: + lda a3 + stobjbyname 0x0, a, a2 + lda a2 + return +label_2: +} + +slotNum = 0x3 +.language ECMAScript +.function any .#~A>#foo(any a0, any a1, any a2, any a3) { +label_1: +label_0: + tryldglobalbyname 0x0, print + callarg1 0x1, a3 + returnundefined +label_2: +} + +slotNum = 0x3 +.language ECMAScript +.function any .func_main_0(any a0, any a1, any a2) { +label_1: +label_0: + ldhole + sta v0 + defineclasswithbuffer 0x0, .#~A=#A, _2, 0x1, v0 + ldobjbyname 0x1, prototype + returnundefined +label_2: +} + + +======> literal array buffer <====== +------------------------------------ +slot _0 +------------------------------------ +slot _1 +{ + index: 0 + tag: 2 + val: 0 +}, +{ + index: 1 + tag: 2 + val: 0 +}, +{ + index: 2 + tag: 2 + val: 0 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 2 + val: 0 +}, +{ + index: 5 + tag: 2 + val: 0 +}, +------------------------------------ +slot _2 +{ + index: 0 + tag: 0 + val: 5 +}, +{ + index: 1 + tag: 5 + val: foo +}, +{ + index: 2 + tag: 0 + val: 6 +}, +{ + index: 3 + tag: 6 + val: .#~A>#foo +}, +{ + index: 4 + tag: 0 + val: 9 +}, +{ + index: 5 + tag: 9 + val: 1 +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 1 +}, +{ + index: 8 + tag: 0 + val: 28 +}, +{ + index: 9 + tag: 28 + val: L/src/main/ets//I1;,L/src/main/ets//I2; +}, diff --git a/es2panda/test/compiler/interop/etsInterface/etsImplements2.ts b/es2panda/test/compiler/interop/etsInterface/etsImplements2.ts new file mode 100644 index 0000000000000000000000000000000000000000..98122ee597c451371f1537086d6cfd10e85793e6 --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/etsImplements2.ts @@ -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. + */ + +// I1, I2 is a static interface +class A implements I1, I2 { + constructor(public a: number) { + "implements static:L/src/main/ets//I1;,L/src/main/ets//I2;" + } + foo(a) { + print(a); + } +} diff --git a/es2panda/test/compiler/interop/etsInterface/tesExtends3-expected.pa.txt b/es2panda/test/compiler/interop/etsInterface/tesExtends3-expected.pa.txt new file mode 100644 index 0000000000000000000000000000000000000000..d2e4c680c2a22afa35d92267fb2da30fc69d4738 --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/tesExtends3-expected.pa.txt @@ -0,0 +1,169 @@ +slotNum = 0x0 +.language ECMAScript +.function any .#~A=#A(any a0, any a1, any a2) { +label_1: +label_0: + lda a2 + return +label_2: +} + +slotNum = 0x2 +.language ECMAScript +.function any .#~B=#B(any a0, any a1, any a2) { +label_1: +label_0: + ldundefined + sta v0 + mov v1, v0 + supercallthisrange 0x0, 0x0, v1 + sta v0 + lda a2 + throw.ifsupernotcorrectcall 0x1 + lda v0 + throw.ifsupernotcorrectcall 0x0 + lda v0 + return +label_2: +} + +slotNum = 0x2 +.language ECMAScript +.function any .#~C=#C(any a0, any a1, any a2) { +label_1: +label_0: + ldundefined + sta v0 + mov v1, v0 + supercallthisrange 0x0, 0x0, v1 + sta v0 + lda a2 + throw.ifsupernotcorrectcall 0x1 + lda v0 + throw.ifsupernotcorrectcall 0x0 + lda v0 + return +label_2: +} + +slotNum = 0x9 +.language ECMAScript +.function any .func_main_0(any a0, any a1, any a2) { +label_1: +label_0: + ldhole + sta v0 + defineclasswithbuffer 0x0, .#~A=#A, _2, 0x0, v0 + sta v0 + ldobjbyname 0x1, prototype + defineclasswithbuffer 0x3, .#~B=#B, _3, 0x0, v0 + sta v0 + ldobjbyname 0x4, prototype + defineclasswithbuffer 0x6, .#~C=#C, _4, 0x0, v0 + ldobjbyname 0x7, prototype + returnundefined +label_2: +} + + +======> literal array buffer <====== +------------------------------------ +slot _0 +------------------------------------ +slot _1 +{ + index: 0 + tag: 2 + val: 0 +}, +{ + index: 1 + tag: 2 + val: 0 +}, +{ + index: 2 + tag: 2 + val: 0 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 2 + val: 0 +}, +{ + index: 5 + tag: 2 + val: 0 +}, +------------------------------------ +slot _2 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 0 +}, +{ + index: 2 + tag: 0 + val: 28 +}, +{ + index: 3 + tag: 28 + val: L/src/main/ets//I1; +}, +------------------------------------ +slot _3 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 0 +}, +{ + index: 2 + tag: 0 + val: 28 +}, +{ + index: 3 + tag: 28 + val: L/src/main/ets//I1; +}, +------------------------------------ +slot _4 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 0 +}, +{ + index: 2 + tag: 0 + val: 28 +}, +{ + index: 3 + tag: 28 + val: L/src/main/ets//I1;,L/src/main/ets//I2; +}, diff --git a/es2panda/test/compiler/interop/etsInterface/tesExtends3.ts b/es2panda/test/compiler/interop/etsInterface/tesExtends3.ts new file mode 100644 index 0000000000000000000000000000000000000000..343061e2ede22beb815f942db4e7df12fc713e5e --- /dev/null +++ b/es2panda/test/compiler/interop/etsInterface/tesExtends3.ts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// I1 is a static interface +class A implements I1 { + constructor() { + "implements static:L/src/main/ets//I1;" + } +} + +class B extends A { + constructor() { + "implements static:L/src/main/ets//I1;" + super(); + } +} + +// I2 is a static interface +interface I3 extends I2 { } + +class C extends B implements I3 { + constructor() { + "implements static:L/src/main/ets//I1;,L/src/main/ets//I2;" + super(); + } +} diff --git a/es2panda/test/runner.py b/es2panda/test/runner.py index 14bb308dd62fcfd51ee6d953dfa1c9f515c8fdde..f378d108c383ef54f2a3cf610c6d82b24009c76a 100755 --- a/es2panda/test/runner.py +++ b/es2panda/test/runner.py @@ -601,6 +601,10 @@ class CompilerRunner(Runner): test_path = path.join(self.test_root, directory) for project in os.listdir(test_path): self.tests.append(CompilerProtobinTest(path.join(test_path, project), flags)) + elif directory.endswith("abc2program"): + test_path = path.join(self.test_root, directory) + for project in os.listdir(test_path): + self.tests.append(CompilerAbcFileTest(path.join(test_path, project), flags)) else: glob_expression = path.join( self.test_root, directory, "**/*.%s" % (extension)) @@ -716,6 +720,64 @@ class CompilerTest(Test): return self +class CompilerAbcFileTest(Test): + def __init__(self, test_dir, flags): + Test.__init__(self, test_dir, flags) + self.test_dir = test_dir + self.generated_path = os.path.join(self.test_dir, "gen") + if not path.exists(self.generated_path): + os.makedirs(self.generated_path) + self.original_abc_path = os.path.join(self.generated_path, "original.abc") + self.output_path = os.path.join(self.generated_path, "result.abc") + self.original_test = os.path.join(self.test_dir, "base.ts") + self.expected_path = os.path.join(self.test_dir, "expected.txt") + + def remove_test_build(self, runner): + if path.exists(self.generated_path): + shutil.rmtree(self.generated_path) + + def gen_abc(self, runner, test_path, output_path, flags): + es2abc_cmd = runner.cmd_prefix + [runner.es2panda] + es2abc_cmd.extend(['%s%s' % ("--output=", output_path)]) + es2abc_cmd.extend(flags) + es2abc_cmd.append(test_path) + process = run_subprocess_with_beta3(self, es2abc_cmd) + out, err = process.communicate() + if err: + self.passed = False + self.error = err.decode("utf-8", errors="ignore") + self.remove_test_build(runner) + return self + + def run(self, runner): + new_flags = self.flags + # Generate 'abc' from the source file + self.gen_abc(runner, self.original_test, self.original_abc_path, new_flags) + # Generate 'abc' from the abc file + new_flags = self.flags + compile_context_info_path = path.join(self.test_dir, "compileContextInfo.json") + if path.exists(compile_context_info_path): + new_flags.append("%s%s" % ("--compile-context-info=", compile_context_info_path)) + es2abc_cmd = runner.cmd_prefix + [runner.es2panda] + es2abc_cmd.append('%s%s' % ("--output=", self.output_path)) + es2abc_cmd.append(self.original_abc_path) + es2abc_cmd.extend(new_flags) + process = run_subprocess_with_beta3(self, es2abc_cmd) + out, err = process.communicate() + self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore") + try: + with open(self.expected_path, 'r') as fp: + expected = fp.read() + self.passed = expected == self.output and process.returncode in [0, 1] + except Exception: + self.passed = False + if not self.passed: + self.remove_test_build(runner) + return self + self.remove_test_build(runner) + return self + + class CompilerProtobinTest(Test): def __init__(self, test_dir, flags): Test.__init__(self, test_dir, flags) @@ -2730,6 +2792,10 @@ def add_directory_for_compiler(runners, args): compiler_test_infos.append(CompilerTestInfo("compiler/merge_hap/projects", "ts", ["--merge-abc", "--dump-assembly", "--enable-abc-input", "--dump-literal-buffer", "--dump-string", "--abc-class-threads=4"])) + compiler_test_infos.append(CompilerTestInfo("compiler/abc2program", "ts", + ["--merge-abc", "--module", "--dump-assembly", "--enable-abc-input", + "--dump-literal-buffer", "--dump-string", "--source-file=source.ts", + "--module-record-field-name=source"])) if args.enable_arkguard: prepare_for_obfuscation(compiler_test_infos, runner.test_root) diff --git a/es2panda/util/helpers.cpp b/es2panda/util/helpers.cpp index 2c2462cd927d99e9bfebb5a46c45c32c3e1d84d8..8d4d486be4f8b9264dec4c84b074eff9086cb9ea 100644 --- a/es2panda/util/helpers.cpp +++ b/es2panda/util/helpers.cpp @@ -802,8 +802,7 @@ bool Helpers::ReadFileToBuffer(const std::string &file, std::stringstream &ss) return true; } -void Helpers::ScanDirectives(ir::ScriptFunction *func, const lexer::LineIndex &lineIndex, bool enableSendableClass, - bool enableSendableFunc) +void Helpers::ScanDirectives(ir::ScriptFunction *func, const DirectiveScanConfig &scanConfig) { auto *body = func->Body(); if (!body || body->IsExpression()) { @@ -828,34 +827,38 @@ void Helpers::ScanDirectives(ir::ScriptFunction *func, const lexer::LineIndex &l return; } - keepScan = SetFuncFlagsForDirectives(expr->AsStringLiteral(), func, lineIndex, enableSendableClass, - enableSendableFunc); + keepScan = SetFuncFlagsForDirectives(expr->AsStringLiteral(), func, scanConfig); } return; } bool Helpers::SetFuncFlagsForDirectives(const ir::StringLiteral *strLit, ir::ScriptFunction *func, - const lexer::LineIndex &lineIndex, bool enableSendableClass, - bool enableSendableFunc) + const DirectiveScanConfig &scanConfig) { if (strLit->Str().Is(USE_CONCURRENT)) { - util::Concurrent::SetConcurrent(func, strLit, lineIndex); + util::Concurrent::SetConcurrent(func, strLit, scanConfig.lineIndex); return true; } if (strLit->Str().Is(USE_SENDABLE)) { if (func->IsConstructor()) { - if (enableSendableClass) { + if (scanConfig.enableSendableClass) { auto *classDef = const_cast(GetClassDefiniton(func)); classDef->SetSendable(); } - } else if (enableSendableFunc) { + } else if (scanConfig.enableSendableFunc) { func->AddFlag(ir::ScriptFunctionFlags::SENDABLE); } return true; } + if (scanConfig.enableEtsImplements && func->IsConstructor() && strLit->Str().StartsWith(IMPLEMENTS_STATIC)) { + auto *classDef = const_cast(GetClassDefiniton(func)); + classDef->SetImplementFromEts(); + classDef->SetEtsImplementsMessage(strLit->Str().Substr(IMPLEMENTS_STATIC.size(), strLit->Str().Length())); + } + return false; } diff --git a/es2panda/util/helpers.h b/es2panda/util/helpers.h index 6ed116a475fe8af5585639aa98f26c35eaa480ec..e831d3727518480f2b2fdabb8bd3c57c335b558a 100644 --- a/es2panda/util/helpers.h +++ b/es2panda/util/helpers.h @@ -110,6 +110,13 @@ private: using AopTransformFuncDef = int (*)(const char *); +struct DirectiveScanConfig { + const lexer::LineIndex &lineIndex; + bool enableSendableClass; + bool enableSendableFunc; + bool enableEtsImplements; +}; + class Helpers { public: Helpers() = delete; @@ -163,8 +170,7 @@ public: template static T BaseName(T const &path, T const &delims = std::string(panda::os::file::File::GetPathDelim())); static bool ReadFileToBuffer(const std::string &file, std::stringstream &ss); - static void ScanDirectives(ir::ScriptFunction *func, const lexer::LineIndex &lineIndex, bool enableSendableClass, - bool enableSendableFunc); + static void ScanDirectives(ir::ScriptFunction *func, const DirectiveScanConfig &scanConfig); static std::string GetHashString(const std::string &str); static std::wstring Utf8ToUtf16(const std::string &utf8); template @@ -181,6 +187,7 @@ public: static bool IsDefaultApiVersion(int apiVersion, std::string subApiVersion); static bool IsSupportLazyImportVersion(int apiVersion, std::string subApiVersion); static bool IsSupportLazyImportDefaultVersion(int apiVersion); + static bool IsSupportEtsImplementsVersion(int apiVersion); static const uint32_t MAX_DOUBLE_DIGIT = 310; static const uint32_t MAX_DOUBLE_PRECISION_DIGIT = 17; @@ -194,6 +201,7 @@ public: static constexpr std::string_view USE_CONCURRENT = "use concurrent"; static constexpr std::string_view USE_SENDABLE = "use sendable"; static constexpr std::string_view USE_SHARED = "use shared"; + static constexpr std::string_view IMPLEMENTS_STATIC = "implements static:"; static constexpr std::string_view STRING_EMPTY = ""; // Default tag value, or tag of GlobalScope and ModuleScope static constexpr std::string_view CLASS_SCOPE_TAG = "~"; static constexpr std::string_view FUNCTION_TAG = "*"; @@ -226,8 +234,7 @@ public: private: static bool SetFuncFlagsForDirectives(const ir::StringLiteral *strLit, ir::ScriptFunction *func, - const lexer::LineIndex &lineIndex, bool enableSendableClass, - bool enableSendableFunc); + const DirectiveScanConfig &scanConfig); }; template diff --git a/es2panda/util/ustring.h b/es2panda/util/ustring.h index 662039ef737cfeebc759581d15edbdb98e46ccbf..6f6096fd5fd9b101d18174f8500717f2c5bedd5a 100644 --- a/es2panda/util/ustring.h +++ b/es2panda/util/ustring.h @@ -114,6 +114,12 @@ public: return sv_.find(str); } + bool StartsWith(const std::string_view str) const noexcept + { + auto const length = str.size(); + return sv_.size() >= length && sv_.substr(0U, length) == str; + } + static bool IsHighSurrogate(char32_t cp) { return (cp >= Constants::SURROGATE_HIGH_MIN && cp < Constants::SURROGATE_HIGH_MAX); diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index d42f093b50178ced82d2c61f60303d9f0b96ad65..2ef3ae274a71ebe4ad29af07f83652d856c8d81e 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -33,33 +33,33 @@ config("libes2panda_public_config") { libes2panda_sources = [ "ast_verifier/ASTVerifier.cpp", - "ast_verifier/arithmeticOperationValid.cpp", - "ast_verifier/checkAbstractMethod.cpp", - "ast_verifier/checkConstProperties.cpp", - "ast_verifier/checkInfiniteLoop.cpp", - "ast_verifier/checkScopeDeclaration.cpp", - "ast_verifier/checkStructDeclaration.cpp", - "ast_verifier/everyChildHasValidParent.cpp", - "ast_verifier/everyChildInParentRange.cpp", - "ast_verifier/forLoopCorrectlyInitialized.cpp", - "ast_verifier/getterSetterValidation.cpp", "ast_verifier/helpers.cpp", - "ast_verifier/identifierHasVariable.cpp", - "ast_verifier/importExportAccessValid.cpp", - "ast_verifier/modifierAccessValid.cpp", - "ast_verifier/nodeHasParent.cpp", - "ast_verifier/nodeHasSourceRange.cpp", - "ast_verifier/nodeHasType.cpp", - "ast_verifier/referenceTypeAnnotationIsNull.cpp", - "ast_verifier/sequenceExpressionHasLastType.cpp", - "ast_verifier/variableHasEnclosingScope.cpp", - "ast_verifier/variableHasScope.cpp", - "ast_verifier/variableNameIdentifierNameSame.cpp", + "ast_verifier/invariants/arithmeticOperationValid.cpp", + "ast_verifier/invariants/checkAbstractMethod.cpp", + "ast_verifier/invariants/checkConstProperties.cpp", + "ast_verifier/invariants/checkScopeDeclaration.cpp", + "ast_verifier/invariants/checkStructDeclaration.cpp", + "ast_verifier/invariants/everyChildHasValidParent.cpp", + "ast_verifier/invariants/everyChildInParentRange.cpp", + "ast_verifier/invariants/forLoopCorrectlyInitialized.cpp", + "ast_verifier/invariants/getterSetterValidation.cpp", + "ast_verifier/invariants/identifierHasVariable.cpp", + "ast_verifier/invariants/importExportAccessValid.cpp", + "ast_verifier/invariants/modifierAccessValid.cpp", + "ast_verifier/invariants/nodeHasParent.cpp", + "ast_verifier/invariants/nodeHasSourceRange.cpp", + "ast_verifier/invariants/nodeHasType.cpp", + "ast_verifier/invariants/referenceTypeAnnotationIsNull.cpp", + "ast_verifier/invariants/sequenceExpressionHasLastType.cpp", + "ast_verifier/invariants/variableHasEnclosingScope.cpp", + "ast_verifier/invariants/variableHasScope.cpp", + "ast_verifier/invariants/variableNameIdentifierNameSame.cpp", "checker/ASchecker.cpp", "checker/ETSAnalyzer.cpp", "checker/ETSAnalyzerHelpers.cpp", "checker/ETSAnalyzerUnreachable.cpp", "checker/ETSchecker.cpp", + "checker/IsolatedDeclgenChecker.cpp", "checker/JSchecker.cpp", "checker/TSAnalyzer.cpp", "checker/TSAnalyzerUnreachable.cpp", @@ -115,6 +115,7 @@ libes2panda_sources = [ "checker/types/ets/etsObjectType.cpp", "checker/types/ets/etsPartialTypeParameter.cpp", "checker/types/ets/etsReadonlyType.cpp", + "checker/types/ets/etsResizableArrayType.cpp", "checker/types/ets/etsStringType.cpp", "checker/types/ets/etsTupleType.cpp", "checker/types/ets/etsTypeAliasType.cpp", @@ -202,25 +203,30 @@ libes2panda_sources = [ "compiler/function/generatorFunctionBuilder.cpp", "compiler/lowering/checkerPhase.cpp", "compiler/lowering/ets/ambientLowering.cpp", + "compiler/lowering/ets/arrayLiteralLowering.cpp", "compiler/lowering/ets/asyncMethodLowering.cpp", "compiler/lowering/ets/bigintLowering.cpp", "compiler/lowering/ets/boxedTypeLowering.cpp", "compiler/lowering/ets/boxingForLocals.cpp", "compiler/lowering/ets/capturedVariables.cpp", "compiler/lowering/ets/cfgBuilderPhase.cpp", - "compiler/lowering/ets/constStringToCharLowering.cpp", "compiler/lowering/ets/constantExpressionLowering.cpp", + "compiler/lowering/ets/convertPrimitiveCastMethodCall.cpp", "compiler/lowering/ets/declareOverloadLowering.cpp", "compiler/lowering/ets/defaultParametersInConstructorLowering.cpp", "compiler/lowering/ets/defaultParametersLowering.cpp", + "compiler/lowering/ets/dynamicImportLowering.cpp", "compiler/lowering/ets/enumLowering.cpp", "compiler/lowering/ets/enumPostCheckLowering.cpp", "compiler/lowering/ets/expandBrackets.cpp", + "compiler/lowering/ets/exportAnonymousConst.cpp", "compiler/lowering/ets/expressionLambdaLowering.cpp", "compiler/lowering/ets/extensionAccessorLowering.cpp", "compiler/lowering/ets/genericBridgesLowering.cpp", + "compiler/lowering/ets/insertOptionalParametersAnnotation.cpp", "compiler/lowering/ets/interfaceObjectLiteralLowering.cpp", "compiler/lowering/ets/interfacePropertyDeclarations.cpp", + "compiler/lowering/ets/lateInitialization.cpp", "compiler/lowering/ets/lambdaLowering.cpp", "compiler/lowering/ets/localClassLowering.cpp", "compiler/lowering/ets/objectIndexAccess.cpp", @@ -233,6 +239,9 @@ libes2panda_sources = [ "compiler/lowering/ets/partialExportClassGen.cpp", "compiler/lowering/ets/promiseVoid.cpp", "compiler/lowering/ets/recordLowering.cpp", + "compiler/lowering/ets/resizableArrayLowering.cpp", + "compiler/lowering/ets/restArgsLowering.cpp", + "compiler/lowering/ets/restTupleLowering.cpp", "compiler/lowering/ets/setJumpTarget.cpp", "compiler/lowering/ets/spreadLowering.cpp", "compiler/lowering/ets/stringComparison.cpp", @@ -242,7 +251,7 @@ libes2panda_sources = [ "compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp", "compiler/lowering/ets/topLevelStmts/importExportDecls.cpp", "compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp", - "compiler/lowering/ets/tupleLowering.cpp", + "compiler/lowering/ets/typeFromLowering.cpp", "compiler/lowering/ets/unionLowering.cpp", "compiler/lowering/phase.cpp", "compiler/lowering/plugin_phase.cpp", @@ -267,6 +276,7 @@ libes2panda_sources = [ "ir/as/prefixAssertionExpression.cpp", "ir/astDump.cpp", "ir/astNode.cpp", + "ir/astNodeHistory.cpp", "ir/base/catchClause.cpp", "ir/base/classDefinition.cpp", "ir/base/classElement.cpp", @@ -288,12 +298,12 @@ libes2panda_sources = [ "ir/ets/etsClassLiteral.cpp", "ir/ets/etsFunctionType.cpp", "ir/ets/etsKeyofType.cpp", - "ir/ets/etsLaunchExpression.cpp", "ir/ets/etsModule.cpp", "ir/ets/etsNeverType.cpp", "ir/ets/etsNewArrayInstanceExpression.cpp", "ir/ets/etsNewClassInstanceExpression.cpp", "ir/ets/etsNewMultiDimArrayInstanceExpression.cpp", + "ir/ets/etsNonNullishTypeNode.cpp", "ir/ets/etsNullishTypes.cpp", "ir/ets/etsPackageDeclaration.cpp", "ir/ets/etsParameterExpression.cpp", @@ -451,6 +461,7 @@ libes2panda_sources = [ "parser/ETSparserClasses.cpp", "parser/ETSparserEnums.cpp", "parser/ETSparserExpressions.cpp", + "parser/ETSparserJsDocInfo.cpp", "parser/ETSparserNamespaces.cpp", "parser/ETSparserStatements.cpp", "parser/ETSparserTypes.cpp", @@ -467,6 +478,7 @@ libes2panda_sources = [ "parser/program/program.cpp", "parser/statementParser.cpp", "parser/statementTSParser.cpp", + "public/public.cpp", "util/arktsconfig.cpp", "util/bitset.cpp", "util/diagnostic.cpp", @@ -599,8 +611,8 @@ HEADERS_TO_BE_PARSED = [ "checker/types/ts/typeReference.h", "ir/expressions/memberExpression.h", "checker/types/ets/etsExtensionFuncHelperType.h", + "ir/ets/etsNonNullishTypeNode.h", "ir/ets/etsNullishTypes.h", - "ir/ets/etsLaunchExpression.h", "ir/expressions/awaitExpression.h", "ir/ets/etsFunctionType.h", "checker/types/ets/etsArrayType.h", @@ -741,6 +753,7 @@ HEADERS_TO_BE_PARSED = [ "ir/ets/etsParameterExpression.h", "ir/ts/tsTypeQuery.h", "ir/expressions/importExpression.h", + "ir/jsDocAllowed.h", "varbinder/variable.h", "varbinder/scope.h", "varbinder/varbinder.h", @@ -757,7 +770,6 @@ HEADERS_TO_BE_PARSED = [ "parser/program/program.h", "es2panda.h", "ast_verifier/ASTVerifier.h", - "ast_verifier/checkContext.h", "util/importPathManager.h", ] @@ -768,6 +780,7 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/varbinder/variableFlags.yaml", "$LIBGEN_DIR/gen/headers/ir/typed.yaml", "$LIBGEN_DIR/gen/headers/ir/annotationAllowed.yaml", + "$LIBGEN_DIR/gen/headers/ir/jsDocAllowed.yaml", "$LIBGEN_DIR/gen/headers/es2panda.yaml", "$LIBGEN_DIR/gen/headers/ir/statements/labelledStatement.yaml", "$LIBGEN_DIR/gen/headers/checker/types/ts/unknownType.yaml", @@ -901,7 +914,6 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/ir/statements/annotationDeclaration.yaml", "$LIBGEN_DIR/gen/headers/ir/statements/annotationUsage.yaml", "$LIBGEN_DIR/gen/headers/ir/statements/emptyStatement.yaml", - "$LIBGEN_DIR/gen/headers/ir/ets/etsLaunchExpression.yaml", "$LIBGEN_DIR/gen/headers/ir/statements/whileStatement.yaml", "$LIBGEN_DIR/gen/headers/ir/base/scriptFunctionSignature.yaml", "$LIBGEN_DIR/gen/headers/checker/types/ts/numberLiteralType.yaml", @@ -1025,7 +1037,6 @@ ES2PANDA_API_GENERATED = [ "$LIBGEN_DIR/gen/headers/parser/ETSparser.yaml", "$LIBGEN_DIR/gen/headers/parser/program/program.yaml", "$LIBGEN_DIR/gen/headers/ast_verifier/ASTVerifier.yaml", - "$LIBGEN_DIR/gen/headers/ast_verifier/checkContext.yaml", "$LIBGEN_DIR/gen/headers/util/importPathManager.yaml", ] @@ -1074,6 +1085,7 @@ ark_gen("gen") { "${LIB_NAME}_impl.inc.erb", "${LIB_NAME}_include.inc.erb", "${LIB_NAME}_list.inc.erb", + "${LIB_NAME}.idl.erb", ] sources = "public/" destination = "$LIBGEN_DIR/" @@ -1138,6 +1150,7 @@ ohos_source_set("libes2panda_frontend_static") { ":gen_${LIB_NAME}_impl_inc", ":gen_${LIB_NAME}_include_inc", ":gen_${LIB_NAME}_list_inc", + ":gen_${LIB_NAME}_idl", ":gen_es2panda_compiler_signatures_h", ":gen_es2panda_lexer_keywords_h", ":gen_es2panda_lexer_tokenType_h", @@ -1231,6 +1244,7 @@ ark_gen("es2panda_diagnostic_gen") { "util/diagnostic/semantic.yaml", "util/diagnostic/warning.yaml", "util/diagnostic/fatal.yaml", + "util/diagnostic/isolated_declgen.yaml", "declgen_ets2ts/declgen_ets2ts_error.yaml", "declgen_ets2ts/declgen_ets2ts_warning.yaml", "util/diagnostic/arktsconfig_error.yaml", @@ -1246,6 +1260,7 @@ ark_gen("es2panda_diagnostic_gen") { "util/diagnostic/diagnostic.rb", "util/diagnostic/diagnostic.rb", "util/diagnostic/diagnostic.rb", + "util/diagnostic/diagnostic.rb", ] } diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 7dd3f51e8138b52ef9ae943ca1fc499a720b5612..0857184f54be9013c34c14c7e67067b4d2f9163b 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -48,8 +48,29 @@ if(PANDA_WITH_ETS) " \"paths\": {\n" " \"std\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}stdlib${DELIM}std\"],\n" " \"escompat\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}stdlib${DELIM}escompat\"],\n" - " \"api\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api\"],\n" - " \"arkts\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}arkts\"],\n" + " \"@ohos.buffer\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.buffer.ets\"],\n" + " \"@ohos.util.ArrayList\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.ArrayList.ets\"],\n" + " \"@ohos.util.Deque\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.Deque.ets\"],\n" + " \"@ohos.util.HashMap\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.HashMap.ets\"],\n" + " \"@ohos.util.HashSet\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.HashSet.ets\"],\n" + " \"@ohos.util.json\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.json.ets\"],\n" + " \"@ohos.util.LightWeightMap\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.LightWeightMap.ets\"],\n" + " \"@ohos.util.LightWeightSet\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.LightWeightSet.ets\"],\n" + " \"@ohos.util.LinkedList\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.LinkedList.ets\"],\n" + " \"@ohos.util.List\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.List.ets\"],\n" + " \"@ohos.util.PlainArray\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.PlainArray.ets\"],\n" + " \"@ohos.util.Queue\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.Queue.ets\"],\n" + " \"@ohos.util.Stack\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.Stack.ets\"],\n" + " \"@ohos.util.stream\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.stream.ets\"],\n" + " \"@ohos.util\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.ets\"],\n" + " \"@ohos.util.TreeMap\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.TreeMap.ets\"],\n" + " \"@ohos.util.TreeSet\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.util.TreeSet.ets\"],\n" + " \"@ohos.uri\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.uri.ets\"],\n" + " \"@ohos.url\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.url.ets\"],\n" + " \"@ohos.xml\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.xml.ets\"],\n" + " \"@ohos.base\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}api${DELIM}@ohos.base.ets\"],\n" + " \"@arkts.math.Decimal\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}arkts${DELIM}@arkts.math.Decimal.ets\"],\n" + " \"@arkts.collections\": [\"${STATIC_CORE}${DELIM}plugins${DELIM}ets${DELIM}sdk${DELIM}arkts${DELIM}@arkts.collections.ets\"],\n" " \"import_tests\": [\"${CMAKE_CURRENT_SOURCE_DIR}/test/parser/ets/import_tests\"]\n" " },\n" " \"dynamicPaths\": {\n" @@ -124,6 +145,7 @@ panda_gen( ${CMAKE_CURRENT_SOURCE_DIR}/declgen_ets2ts/declgen_ets2ts_error.yaml ${CMAKE_CURRENT_SOURCE_DIR}/declgen_ets2ts/declgen_ets2ts_warning.yaml ${DIAGNOSTIC_DIR}/arktsconfig_error.yaml + ${DIAGNOSTIC_DIR}/isolated_declgen.yaml TARGET_NAME es2panda_diagnostic_gen TEMPLATES diagnostic.h.erb SOURCE ${DIAGNOSTIC_DIR} @@ -136,6 +158,7 @@ panda_gen( ${DIAGNOSTIC_DIR}/diagnostic.rb ${DIAGNOSTIC_DIR}/diagnostic.rb ${DIAGNOSTIC_DIR}/diagnostic.rb + ${DIAGNOSTIC_DIR}/diagnostic.rb ) panda_gen( @@ -166,28 +189,27 @@ panda_gen( set(ES2PANDA_LIB_SRC ast_verifier/ASTVerifier.cpp - ast_verifier/arithmeticOperationValid.cpp - ast_verifier/checkAbstractMethod.cpp - ast_verifier/checkConstProperties.cpp - ast_verifier/checkInfiniteLoop.cpp - ast_verifier/checkScopeDeclaration.cpp - ast_verifier/checkStructDeclaration.cpp - ast_verifier/everyChildHasValidParent.cpp - ast_verifier/everyChildInParentRange.cpp - ast_verifier/getterSetterValidation.cpp ast_verifier/helpers.cpp - ast_verifier/identifierHasVariable.cpp - ast_verifier/importExportAccessValid.cpp - ast_verifier/nodeHasParent.cpp - ast_verifier/nodeHasSourceRange.cpp - ast_verifier/nodeHasType.cpp - ast_verifier/referenceTypeAnnotationIsNull.cpp - ast_verifier/forLoopCorrectlyInitialized.cpp - ast_verifier/modifierAccessValid.cpp - ast_verifier/sequenceExpressionHasLastType.cpp - ast_verifier/variableHasEnclosingScope.cpp - ast_verifier/variableHasScope.cpp - ast_verifier/variableNameIdentifierNameSame.cpp + ast_verifier/invariants/arithmeticOperationValid.cpp + ast_verifier/invariants/checkAbstractMethod.cpp + ast_verifier/invariants/checkConstProperties.cpp + ast_verifier/invariants/checkScopeDeclaration.cpp + ast_verifier/invariants/checkStructDeclaration.cpp + ast_verifier/invariants/everyChildHasValidParent.cpp + ast_verifier/invariants/everyChildInParentRange.cpp + ast_verifier/invariants/getterSetterValidation.cpp + ast_verifier/invariants/identifierHasVariable.cpp + ast_verifier/invariants/importExportAccessValid.cpp + ast_verifier/invariants/nodeHasParent.cpp + ast_verifier/invariants/nodeHasSourceRange.cpp + ast_verifier/invariants/nodeHasType.cpp + ast_verifier/invariants/referenceTypeAnnotationIsNull.cpp + ast_verifier/invariants/forLoopCorrectlyInitialized.cpp + ast_verifier/invariants/modifierAccessValid.cpp + ast_verifier/invariants/sequenceExpressionHasLastType.cpp + ast_verifier/invariants/variableHasEnclosingScope.cpp + ast_verifier/invariants/variableHasScope.cpp + ast_verifier/invariants/variableNameIdentifierNameSame.cpp es2panda.cpp varbinder/ASBinder.cpp varbinder/TSBinder.cpp @@ -254,27 +276,34 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/expressionLambdaLowering.cpp compiler/lowering/ets/extensionAccessorLowering.cpp compiler/lowering/ets/genericBridgesLowering.cpp + compiler/lowering/ets/arrayLiteralLowering.cpp compiler/lowering/ets/boxedTypeLowering.cpp compiler/lowering/ets/boxingForLocals.cpp compiler/lowering/ets/capturedVariables.cpp compiler/lowering/ets/cfgBuilderPhase.cpp compiler/lowering/ets/constantExpressionLowering.cpp + compiler/lowering/ets/convertPrimitiveCastMethodCall.cpp compiler/lowering/ets/declareOverloadLowering.cpp compiler/lowering/ets/defaultParametersInConstructorLowering.cpp compiler/lowering/ets/defaultParametersLowering.cpp + compiler/lowering/ets/dynamicImportLowering.cpp + compiler/lowering/ets/exportAnonymousConst.cpp + compiler/lowering/ets/lateInitialization.cpp compiler/lowering/ets/lambdaLowering.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 compiler/lowering/ets/interfacePropertyDeclarations.cpp compiler/lowering/ets/opAssignment.cpp compiler/lowering/ets/ambientLowering.cpp compiler/lowering/ets/asyncMethodLowering.cpp compiler/lowering/ets/bigintLowering.cpp - compiler/lowering/ets/constStringToCharLowering.cpp compiler/lowering/ets/recordLowering.cpp - compiler/lowering/ets/tupleLowering.cpp + compiler/lowering/ets/resizableArrayLowering.cpp + compiler/lowering/ets/restArgsLowering.cpp compiler/lowering/ets/unionLowering.cpp compiler/lowering/ets/optionalArgumentsLowering.cpp compiler/lowering/ets/optionalLowering.cpp @@ -287,12 +316,14 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/stringComparison.cpp compiler/lowering/ets/stringConstantsLowering.cpp compiler/lowering/ets/stringConstructorLowering.cpp + compiler/lowering/ets/typeFromLowering.cpp compiler/lowering/ets/enumLowering.cpp compiler/lowering/ets/enumPostCheckLowering.cpp compiler/lowering/ets/setJumpTarget.cpp ir/astDump.cpp ir/srcDump.cpp ir/astNode.cpp + ir/astNodeHistory.cpp ir/irnode.cpp ir/typeNode.cpp ir/opaqueTypeNode.cpp @@ -394,13 +425,13 @@ set(ES2PANDA_LIB_SRC ir/ets/etsClassLiteral.cpp ir/ets/etsFunctionType.cpp ir/ets/etsKeyofType.cpp - ir/ets/etsLaunchExpression.cpp ir/ets/etsNewArrayInstanceExpression.cpp ir/ets/etsNewClassInstanceExpression.cpp ir/ets/etsNewMultiDimArrayInstanceExpression.cpp ir/ets/etsPackageDeclaration.cpp ir/ets/etsParameterExpression.cpp ir/ets/etsPrimitiveType.cpp + ir/ets/etsNonNullishTypeNode.cpp ir/ets/etsNullishTypes.cpp ir/ets/etsNeverType.cpp ir/ets/etsModule.cpp @@ -483,6 +514,7 @@ set(ES2PANDA_LIB_SRC parser/ETSparserClasses.cpp parser/ETSparserEnums.cpp parser/ETSparserExpressions.cpp + parser/ETSparserJsDocInfo.cpp parser/ETSparserNamespaces.cpp parser/ETSparserStatements.cpp parser/ETSparserTypes.cpp @@ -494,6 +526,7 @@ set(ES2PANDA_LIB_SRC parser/program/program.cpp parser/statementParser.cpp parser/statementTSParser.cpp + public/public.cpp checker/checker.cpp checker/checkerContext.cpp checker/ETSAnalyzer.cpp @@ -505,6 +538,7 @@ set(ES2PANDA_LIB_SRC checker/TSAnalyzer.cpp checker/TSAnalyzerUnreachable.cpp checker/JSchecker.cpp + checker/IsolatedDeclgenChecker.cpp checker/typeChecker/TypeChecker.cpp checker/ets/aliveAnalyzer.cpp checker/ets/etsWarningAnalyzer.cpp @@ -557,6 +591,7 @@ set(ES2PANDA_LIB_SRC checker/types/ets/etsNonNullishType.cpp checker/types/ets/etsNeverType.cpp checker/types/ets/etsReadonlyType.cpp + checker/types/ets/etsResizableArrayType.cpp checker/types/ets/etsNullishTypes.cpp checker/types/ets/etsObjectType.cpp checker/types/ets/etsStringType.cpp diff --git a/ets2panda/aot/main.cpp b/ets2panda/aot/main.cpp index face618ccbbcf2bd1ccc1d567dfbebd1be7b9f0b..411df8364a29cccacefe03a517ccd368f2658b63 100644 --- a/ets2panda/aot/main.cpp +++ b/ets2panda/aot/main.cpp @@ -30,6 +30,7 @@ #include #include #include + namespace ark::es2panda::aot { using mem::MemConfig; @@ -76,8 +77,31 @@ static int CompileFromSource(es2panda::Compiler &compiler, es2panda::SourceFile }); } -static int CompileFromConfig(es2panda::Compiler &compiler, util::Options *options, - util::DiagnosticEngine &diagnosticEngine) +using StringPairVector = std::vector>; + +static int CompileMultipleFiles(es2panda::Compiler &compiler, std::vector &inputs, util::Options *options, + util::DiagnosticEngine &diagnosticEngine) +{ + std::vector result; + auto overallRes = compiler.CompileM(inputs, *options, diagnosticEngine, result); + for (size_t i = 0; i < result.size(); i++) { + auto *program = result[i]; + if (program == nullptr) { + overallRes |= 1U; + continue; + } + options->SetOutput(std::string(inputs[i].dest)); + overallRes |= (unsigned int)util::GenerateProgram( + program, *options, + [&diagnosticEngine](const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams ¶ms) { + diagnosticEngine.LogDiagnostic(kind, params); + }); + } + return overallRes; +} + +static unsigned int CompileFromConfig(es2panda::Compiler &compiler, util::Options *options, + util::DiagnosticEngine &diagnosticEngine) { auto compilationList = FindProjectSources(options->ArkTSConfig()); if (compilationList.empty()) { @@ -85,30 +109,37 @@ static int CompileFromConfig(es2panda::Compiler &compiler, util::Options *option return 1; } - unsigned overallRes = 0; + std::vector inputs {}; + unsigned int overallRes = 0; for (auto &[src, dst] : compilationList) { std::ifstream inputStream(src); if (inputStream.fail()) { diagnosticEngine.LogDiagnostic(diagnostic::OPEN_FAILED, util::DiagnosticMessageParams {src}); return 1; } - std::stringstream ss; ss << inputStream.rdbuf(); - std::string parserInput = ss.str(); + auto *parserInput = new std::string(ss.str()); inputStream.close(); - es2panda::SourceFile input(src, parserInput, options->IsModule()); - options->SetOutput(dst); - LOG_IF(options->IsListFiles(), INFO, ES2PANDA) - << "> es2panda: compiling from '" << src << "' to '" << dst << "'"; + es2panda::SourceFile input(src, *parserInput, options->IsModule(), std::string_view(dst)); + inputs.push_back(input); + } + if (options->IsPermArena() && (options->GetExtension() == util::gen::extension::ETS)) { + return CompileMultipleFiles(compiler, inputs, options, diagnosticEngine); + } + + for (auto &input : inputs) { + LOG_IF(options->IsListFiles(), INFO, ES2PANDA) + << "> es2panda: compiling from '" << input.filePath << "' to '" << input.dest << "'"; + options->SetOutput(std::string(input.dest)); auto res = CompileFromSource(compiler, input, *options, diagnosticEngine); if (res != 0) { - diagnosticEngine.LogDiagnostic(diagnostic::COMPILE_FAILED, util::DiagnosticMessageParams {src, dst}); + diagnosticEngine.LogDiagnostic(diagnostic::COMPILE_FAILED, + util::DiagnosticMessageParams {input.filePath, input.dest}); overallRes |= static_cast(res); } } - return overallRes; } @@ -168,7 +199,7 @@ static int Run(Span args) auto [buf, size] = options->CStrParserInputContents(); parserInput = std::string_view(buf, size); } - es2panda::SourceFile input(sourceFile, parserInput, options->IsModule()); + es2panda::SourceFile input(sourceFile, parserInput, options->IsModule(), options->GetOutput()); return CompileFromSource(compiler, input, *options.get(), diagnosticEngine); } } // namespace ark::es2panda::aot diff --git a/ets2panda/ast_verifier/ASTVerifier.cpp b/ets2panda/ast_verifier/ASTVerifier.cpp index ced6d67138e67e1846f9c795cf2359821751c276..9854161341dad190e547fec914f090536c2a9f5e 100644 --- a/ets2panda/ast_verifier/ASTVerifier.cpp +++ b/ets2panda/ast_verifier/ASTVerifier.cpp @@ -19,6 +19,16 @@ namespace ark::es2panda::compiler::ast_verifier { using AstToCheck = ArenaMap; +template +auto VerifyNode(Inv *inv, const ir::AstNode *node) +{ + auto [res, action] = (*inv)(node); + if (action == CheckAction::SKIP_SUBTREE) { + LOG_ASTV(DEBUG, Inv::NAME << ": SKIP_SUBTREE"); + } + return CheckResult {res, action}; +} + struct ASTVerifier::SinglePassVerifier { // NOLINTBEGIN(misc-non-private-member-variables-in-classes) ASTVerifier *verifier {nullptr}; @@ -29,28 +39,25 @@ struct ASTVerifier::SinglePassVerifier { { const auto *node = ncnode; auto enabledSave = verifier->enabled_; - LOG_ASTV(DEBUG, "Verify: " << node->DumpJSON()); - - std::apply( - [this, node](auto &...inv) { - InvArray decisions {}; - InvArray actions {}; - ((std::tie(decisions[inv.ID], actions[inv.ID]) = - verifier->NeedCheckInvariant(inv) - ? inv.VerifyNode(node) - : CheckResult {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}), - ...); - // Temporaly disable invariant, the value should be restored after node and its childs are visited: - ((verifier->enabled_[inv.ID] &= (actions[inv.ID] == CheckAction::CONTINUE)), ...); - - for (size_t i = 0; i < VerifierInvariants::COUNT; i++) { - LOG_ASTV(DEBUG, (actions[i] == CheckAction::CONTINUE ? "Enabled " : "Disabled ") - << util::gen::ast_verifier::ToString(VerifierInvariants {i})); - } - - (*astCorrect) &= ((decisions[inv.ID] == CheckDecision::CORRECT) && ...); - }, - verifier->invariants_); + LOG_ASTV(DEBUG, "Verify: " << ir::ToString(node->Type())); + + verifier->Apply([this, node](auto &...inv) { + InvArray decisions {}; + InvArray actions {}; + ((std::tie(decisions[inv.ID], actions[inv.ID]) = + verifier->NeedCheckInvariant(inv) ? VerifyNode(&inv, node) + : CheckResult {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}), + ...); + // Temporaly disable invariant, the value should be restored after node and its childs are visited: + ((verifier->enabled_[inv.ID] &= (actions[inv.ID] == CheckAction::CONTINUE)), ...); + + for (size_t i = 0; i < VerifierInvariants::COUNT; i++) { + LOG_ASTV(DEBUG, (actions[i] == CheckAction::CONTINUE ? "Enabled " : "Disabled ") + << util::gen::ast_verifier::ToString(VerifierInvariants {i})); + } + + (*astCorrect) &= ((decisions[inv.ID] == CheckDecision::CORRECT) && ...); + }); node->Iterate(*this); verifier->enabled_ = enabledSave; @@ -75,14 +82,19 @@ static auto ExtractAst(const parser::Program &program, bool checkFullProgram) void ASTVerifier::Verify(std::string_view phaseName) { + if (context_.diagnosticEngine->IsAnyError()) { + // NOTE(dkofanov): As for now, the policy is that ASTVerifier doesn't interrupt pipeline if there were errors + // reported. Should be revisited. + Suppress(); + } if (suppressed_) { return; } - auto astToCheck = ExtractAst(program_, options_.IsAstVerifierFullProgram()); + auto astToCheck = ExtractAst(program_, Options().IsAstVerifierFullProgram()); for (const auto &p : astToCheck) { const auto sourceName = p.first; const auto *ast = p.second; - std::apply([](auto &&...inv) { ((inv.Init()), ...); }, invariants_); + Apply([](auto &&...inv) { ((inv.Init()), ...); }); LOG_ASTV(INFO, "Begin traversal (" << sourceName << ')'); @@ -93,18 +105,17 @@ void ASTVerifier::Verify(std::string_view phaseName) auto reporter = [this, sourceName](auto &&inv) { if (inv.HasMessages()) { report_.back().second[sourceName][TreatAsError(inv.ID) ? "errors" : "warnings"][inv.ID] = - std::forward(inv).MoveMessages(); + std::forward(inv).MoveMessages(); (TreatAsError(inv.ID) ? hasErrors_ : hasWarnings_) = true; } }; - ES2PANDA_ASSERT(astCorrect == - std::apply([](const auto &...inv) { return ((!inv.HasMessages()) && ...); }, invariants_)); + ES2PANDA_ASSERT(astCorrect == Apply([](const auto &...inv) { return ((!inv.HasMessages()) && ...); })); if (!astCorrect) { if (report_.empty() || report_.back().first != phaseName) { report_.emplace_back(); report_.back().first = phaseName; } - std::apply([&reporter](auto &...inv) { (reporter(std::move(inv)), ...); }, invariants_); + Apply([&reporter](auto &...inv) { (reporter(std::move(inv)), ...); }); } } } @@ -191,22 +202,22 @@ void DumpLog(const ASTVerifier::GroupedMessages &report) void ASTVerifier::DumpMessages() const { std::string errMsg = "ASTVerifier found broken invariants."; - if (options_.IsAstVerifierJson()) { - DumpJson(report_, options_.GetAstVerifierJsonPath()); - errMsg += " Dumped to '" + std::string(options_.GetAstVerifierJsonPath()) + "'."; + if (Options().IsAstVerifierJson()) { + DumpJson(report_, Options().GetAstVerifierJsonPath()); + errMsg += " Dumped to '" + std::string(Options().GetAstVerifierJsonPath()) + "'."; } else { DumpLog(report_); errMsg += " You may want to pass '--ast-verifier:json' option for more verbose output."; } if (hasErrors_) { - LOG(ERROR, ES2PANDA) << errMsg; + LOG(FATAL, ES2PANDA) << errMsg; } else if (hasWarnings_) { LOG(WARNING, ES2PANDA) << errMsg; } } -void CheckContext::AddCheckMessage(const std::string &cause, const ir::AstNode &node) +void InvariantMessages::AddCheckMessage(const std::string &cause, const ir::AstNode &node) { messages_.emplace_back(cause.data(), &node); } diff --git a/ets2panda/ast_verifier/ASTVerifier.h b/ets2panda/ast_verifier/ASTVerifier.h index 1e457f23814299668f78a2be1dc7fce216f9c1f8..9aaa1aecc3e55d08feea243f73b2f6329e0b46f7 100644 --- a/ets2panda/ast_verifier/ASTVerifier.h +++ b/ets2panda/ast_verifier/ASTVerifier.h @@ -22,28 +22,27 @@ #include #include -#include "ast_verifier/checkContext.h" -#include "ast_verifier/sequenceExpressionHasLastType.h" -#include "ast_verifier/checkAbstractMethod.h" -#include "ast_verifier/checkInfiniteLoop.h" -#include "ast_verifier/everyChildHasValidParent.h" -#include "ast_verifier/everyChildInParentRange.h" -#include "ast_verifier/getterSetterValidation.h" -#include "ast_verifier/identifierHasVariable.h" -#include "ast_verifier/nodeHasParent.h" -#include "ast_verifier/nodeHasSourceRange.h" -#include "ast_verifier/nodeHasType.h" -#include "ast_verifier/referenceTypeAnnotationIsNull.h" -#include "ast_verifier/variableHasScope.h" -#include "ast_verifier/variableHasEnclosingScope.h" -#include "ast_verifier/forLoopCorrectlyInitialized.h" -#include "ast_verifier/modifierAccessValid.h" -#include "ast_verifier/importExportAccessValid.h" -#include "ast_verifier/arithmeticOperationValid.h" -#include "ast_verifier/variableNameIdentifierNameSame.h" -#include "ast_verifier/checkScopeDeclaration.h" -#include "ast_verifier/checkStructDeclaration.h" -#include "ast_verifier/checkConstProperties.h" +#include "ast_verifier/invariantBase.h" +#include "ast_verifier/invariants/sequenceExpressionHasLastType.h" +#include "ast_verifier/invariants/checkAbstractMethod.h" +#include "ast_verifier/invariants/everyChildHasValidParent.h" +#include "ast_verifier/invariants/everyChildInParentRange.h" +#include "ast_verifier/invariants/getterSetterValidation.h" +#include "ast_verifier/invariants/identifierHasVariable.h" +#include "ast_verifier/invariants/nodeHasParent.h" +#include "ast_verifier/invariants/nodeHasSourceRange.h" +#include "ast_verifier/invariants/nodeHasType.h" +#include "ast_verifier/invariants/referenceTypeAnnotationIsNull.h" +#include "ast_verifier/invariants/variableHasScope.h" +#include "ast_verifier/invariants/variableHasEnclosingScope.h" +#include "ast_verifier/invariants/forLoopCorrectlyInitialized.h" +#include "ast_verifier/invariants/modifierAccessValid.h" +#include "ast_verifier/invariants/importExportAccessValid.h" +#include "ast_verifier/invariants/arithmeticOperationValid.h" +#include "ast_verifier/invariants/variableNameIdentifierNameSame.h" +#include "ast_verifier/invariants/checkScopeDeclaration.h" +#include "ast_verifier/invariants/checkStructDeclaration.h" +#include "ast_verifier/invariants/checkConstProperties.h" #include "ir/astNode.h" #include "ir/statements/blockStatement.h" @@ -66,47 +65,14 @@ namespace ark::es2panda::compiler::ast_verifier { -template -class InvariantsRegistryImpl { -public: - using Invariants = std::tuple; - template - using InvariantClass = std::tuple_element_t; - template - using InvArray = std::array; - -private: - template - static constexpr bool CheckRegistry(std::integer_sequence /*unused*/) - { - return ((CheckRegistry()) && ...); - } - - template - static constexpr bool CheckRegistry() - { - static_assert(ORDER_IN_PARAMETER_LIST == DEFINED_ENUM, - "Invariant's `ID` must be equal to" - "index of the invariant in `InvariantsRegistryImpl` parameter-list"); - return true; - } - -protected: - Invariants invariants_ {}; - - static_assert(sizeof...(Invs) == VerifierInvariants::COUNT, - "Parameter-list is inconsistent with invaraints' declararation in 'options.yaml'"); - static_assert(CheckRegistry(std::make_index_sequence {})); -}; - // NOTE(dkofanov) Fix and enable ImportExportAccessValid: using InvariantsRegistry = InvariantsRegistryImpl; + SequenceExpressionHasLastType, ForLoopCorrectlyInitialized, VariableHasEnclosingScope, + ModifierAccessValid, VariableNameIdentifierNameSame, CheckAbstractMethod, + GetterSetterValidation, CheckScopeDeclaration, CheckConstProperties>; /* * ASTVerifier checks whether various conditions are invariant (across AST transformations). @@ -117,7 +83,7 @@ public: NO_MOVE_SEMANTIC(ASTVerifier); ASTVerifier(const public_lib::Context &context, const parser::Program &program) - : program_ {program}, options_ {*context.config->options} + : program_ {program}, context_ {context} { for (size_t i = VerifierInvariants::BASE_FIRST; i <= VerifierInvariants::BASE_LAST; i++) { allowed_[i] = true; @@ -125,7 +91,7 @@ public: for (size_t i = 0; i < VerifierInvariants::COUNT; i++) { enabled_[i] = TreatAsWarning(VerifierInvariants {i}) || TreatAsError(VerifierInvariants {i}); } - if (options_.IsAstVerifierBeforePhases()) { + if (Options().IsAstVerifierBeforePhases()) { Verify("before"); } } @@ -133,7 +99,7 @@ public: ~ASTVerifier() { if (!suppressed_) { - if (options_.IsAstVerifierAfterPhases()) { + if (Options().IsAstVerifierAfterPhases()) { Verify("after"); } if (HasErrors() || HasWarnings()) { @@ -164,10 +130,10 @@ public: allowed_[i] = true; } // NOTE(dkofanov): This should be called after "NumberLowering" phase: - std::get(invariants_).SetNumberLoweringOccured(); + Get()->SetNumberLoweringOccured(); } if (occurredPhaseName == "UnionLowering") { - std::get(invariants_).SetUnionLoweringOccurred(); + Get()->SetUnionLoweringOccurred(); } } @@ -180,11 +146,11 @@ public: bool TreatAsWarning(VerifierInvariants id) const { - return options_.GetAstVerifierWarnings()[id]; + return Options().GetAstVerifierWarnings()[id]; } bool TreatAsError(VerifierInvariants id) const { - return options_.GetAstVerifierErrors()[id]; + return Options().GetAstVerifierErrors()[id]; } bool HasErrors() const { @@ -196,12 +162,17 @@ public: } private: - template , T>, void *> = nullptr> + template , void *> = nullptr> bool NeedCheckInvariant(const T & /*unused*/) { return enabled_[T::ID] && allowed_[T::ID]; } + const util::Options &Options() const + { + return *context_.config->options; + } + public: using SourcePath = std::string_view; using PhaseName = std::string_view; @@ -212,7 +183,7 @@ public: private: const parser::Program &program_; - const util::Options &options_; + const public_lib::Context &context_; InvArray enabled_ {}; InvArray allowed_ {}; @@ -224,30 +195,6 @@ private: struct SinglePassVerifier; }; -template -CheckResult InvariantBase::VerifyNode(const ir::AstNode *ast) -{ - auto [res, action] = (*static_cast *>(this))(ast); - if (action == CheckAction::SKIP_SUBTREE) { - LOG_ASTV(DEBUG, util::gen::ast_verifier::ToString(ID) << ": SKIP_SUBTREE"); - } - return {res, action}; -} - -template -void RecursiveInvariant::VerifyAst(const ir::AstNode *ast) -{ - std::function aux {}; - aux = [this, &aux](const ir::AstNode *child) -> void { - const auto [_, action] = this->VerifyNode(child); - if (action == CheckAction::SKIP_SUBTREE) { - return; - } - child->Iterate(aux); - }; - aux(ast); -} - } // namespace ark::es2panda::compiler::ast_verifier #endif // ES2PANDA_COMPILER_CORE_ASTVERIFIER_H diff --git a/ets2panda/ast_verifier/checkInfiniteLoop.cpp b/ets2panda/ast_verifier/checkInfiniteLoop.cpp deleted file mode 100644 index 8c64b7d16850b8f97b7a7d9cdfdacdf629698445..0000000000000000000000000000000000000000 --- a/ets2panda/ast_verifier/checkInfiniteLoop.cpp +++ /dev/null @@ -1,124 +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. - */ - -#include "checkInfiniteLoop.h" -#include "ir/expression.h" -#include "ir/statements/forUpdateStatement.h" -#include "checker/types/type.h" -#include "ir/statements/doWhileStatement.h" -#include "ir/statements/whileStatement.h" - -namespace ark::es2panda::compiler::ast_verifier { - -[[nodiscard]] CheckResult CheckInfiniteLoop::operator()(const ir::AstNode *ast) -{ - if (ast->IsDoWhileStatement()) { - return HandleDoWhileStatement(ast->AsDoWhileStatement()); - } - - if (ast->IsWhileStatement()) { - return HandleWhileStatement(ast->AsWhileStatement()); - } - - if (ast->IsForUpdateStatement()) { - return HandleForUpdateStatement(ast->AsForUpdateStatement()); - } - - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; -} - -bool CheckInfiniteLoop::ConditionIsAlwaysTrue(const ir::Expression *const test) const -{ - ES2PANDA_ASSERT(test); - auto const *const type = test->TsType(); - if (type == nullptr) { - return false; - } - - if (!type->IsConditionalExprType()) { - // Cannot be tested for truthiness - return false; - } - - const auto [constant, truthy] = type->ResolveConditionExpr(); - return (constant && truthy); -} - -bool CheckInfiniteLoop::HasBreakOrReturnStatement(const ir::Statement *const body) const -{ - ES2PANDA_ASSERT(body); - bool hasExit = body->IsBreakStatement() || body->IsReturnStatement(); - body->IterateRecursively( - [&hasExit](ir::AstNode *child) { hasExit |= child->IsBreakStatement() || child->IsReturnStatement(); }); - - return hasExit; -} - -[[nodiscard]] CheckResult CheckInfiniteLoop::HandleWhileStatement(const ir::WhileStatement *const stmt) -{ - auto const *body = stmt->Body(); - auto const *test = stmt->Test(); - if ((body == nullptr) || (test == nullptr)) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - if (ConditionIsAlwaysTrue(test)) { - if (!HasBreakOrReturnStatement(body)) { - AddCheckMessage("INFINITE LOOP", *stmt); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - } - - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; -} - -[[nodiscard]] CheckResult CheckInfiniteLoop::HandleDoWhileStatement(const ir::DoWhileStatement *const stmt) -{ - auto const *body = stmt->Body(); - auto const *test = stmt->Test(); - if ((body == nullptr) || (test == nullptr)) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - if (ConditionIsAlwaysTrue(test)) { - if (!HasBreakOrReturnStatement(body)) { - AddCheckMessage("INFINITE LOOP", *stmt); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - } - - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; -} - -[[nodiscard]] CheckResult CheckInfiniteLoop::HandleForUpdateStatement(const ir::ForUpdateStatement *const stmt) -{ - auto const *body = stmt->Body(); - if (body == nullptr) { - // Body existence is checked in ForLoopCorrectlyInitialized - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - - // Test can be null for for-update statements - auto const *test = stmt->Test(); - if (test == nullptr || ConditionIsAlwaysTrue(test)) { - if (!HasBreakOrReturnStatement(body)) { - AddCheckMessage("INFINITE LOOP", *stmt); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } - } - - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; -} -} // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/helpers.cpp b/ets2panda/ast_verifier/helpers.cpp index 2d301294b875c37162c6523b5c75def0eb7f6a2a..13d55e496cb3a1ff72fa56415462b0b8b08664a9 100644 --- a/ets2panda/ast_verifier/helpers.cpp +++ b/ets2panda/ast_verifier/helpers.cpp @@ -18,6 +18,7 @@ #include "checker/types/typeFlag.h" #include "checker/types/type.h" #include "checker/types/ets/etsObjectType.h" +#include "checker/types/ets/etsUnionType.h" #include "ir/statements/blockStatement.h" #include "ir/ets/etsModule.h" #include "parser/program/program.h" @@ -261,6 +262,22 @@ bool ValidateVariableAccess(const varbinder::LocalVariable *propVar, const ir::M if (propVarDeclNode == nullptr) { return false; } + + // NOTE: need to refactor: type of member expression object can be obtained via + // me->ObjType() or me->Object()->TsType() and they may differ!!!! + if (auto objType = const_cast(ast)->Object()->TsType(); objType->IsETSUnionType()) { + bool res = true; + for (auto type : objType->AsETSUnionType()->ConstituentTypes()) { + const_cast(ast)->SetObjectType(type->AsETSObjectType()); + // Just to skip enclosing if clause checking whether object tsType is ETSUnionType in subsequent recursive + // call + const_cast(ast)->Object()->SetTsType(type->AsETSObjectType()); + } + const_cast(ast)->SetObjectType(ast->ObjType()); + const_cast(ast)->Object()->SetTsType(objType); + return res; + } + auto *objType = ast->ObjType(); if (objType == nullptr) { return false; @@ -285,6 +302,8 @@ bool ValidateVariableAccess(const varbinder::LocalVariable *propVar, const ir::M bool ValidateMethodAccess(const ir::MemberExpression *memberExpression, const ir::CallExpression *ast) { + // NOTE: need to refactor: type of member expression object can be obtained via + // me->ObjType() or me->Object()->TsType() and they may differ!!!! if (memberExpression->Object()->TsType() != nullptr) { // When calling enum methods member expression // object has ETSEnumType instead of ETSObjectType. @@ -292,6 +311,12 @@ bool ValidateMethodAccess(const ir::MemberExpression *memberExpression, const ir if (type->IsETSEnumType()) { return true; } + + // When calling enum methods member expression + // object has ETSUnionType instead of ETSObjectType. + if (type->IsETSUnionType()) { + return true; + } } auto *memberObjType = memberExpression->ObjType(); diff --git a/ets2panda/ast_verifier/checkContext.h b/ets2panda/ast_verifier/invariantBase.h similarity index 41% rename from ets2panda/ast_verifier/checkContext.h rename to ets2panda/ast_verifier/invariantBase.h index ef5d5b2de579b127deec2132c4d3ef03c0bfb382..7ce416e98a5af28bf4147724c1564974a61ba691 100644 --- a/ets2panda/ast_verifier/checkContext.h +++ b/ets2panda/ast_verifier/invariantBase.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKCONTEXT_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKCONTEXT_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTBASE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTBASE_H #include "generated/options.h" #include "ir/astNode.h" @@ -29,6 +29,58 @@ using CheckResult = std::tuple; using VerifierInvariants = util::gen::ast_verifier::Enum; using Enum = VerifierInvariants; +template +class InvariantsRegistryImpl { +public: + InvariantsRegistryImpl() : invariants_ {Invs(this)...} {} + + using Invariants = std::tuple; + template + using InvariantClass = std::tuple_element_t; + template + using InvArray = std::array; + + template + constexpr auto *Get() + { + return Get>(); + } + + template + constexpr auto *Get() + { + return &std::get(invariants_); + } + + template + auto Apply(Func &&f) + { + return std::apply(std::forward(f), invariants_); + } + +private: + Invariants invariants_; + + template + static constexpr bool CheckRegistry(std::integer_sequence /*unused*/) + { + return ((CheckRegistry()) && ...); + } + + template + static constexpr bool CheckRegistry() + { + static_assert(ORDER_IN_PARAMETER_LIST == DEFINED_ENUM, + "Invariant's `ID` must be equal to" + "index of the invariant in `InvariantsRegistryImpl` parameter-list"); + return true; + } + + static_assert(sizeof...(Invs) == VerifierInvariants::COUNT, + "Parameter-list is inconsistent with invaraints' declararation in 'options.yaml'"); + static_assert(CheckRegistry(std::make_index_sequence {})); +}; + class CheckMessage { public: explicit CheckMessage(util::StringView cause, const ir::AstNode *node) : cause_ {cause}, node_ {node} {} @@ -44,8 +96,14 @@ public: std::string ToString() const { - return cause_ + "(AstNodeType::" + std::string(ir::ToString(node_->Type())) + ", line " + - std::to_string(node_->Start().line + 1) + ')'; + auto nodeLocation = std::string(ir::ToString(node_->Type())); + auto parent = node_->Parent(); + while (parent != nullptr) { + nodeLocation = std::string(ir::ToString(parent->Type())).append("->").append(nodeLocation); + parent = parent->Parent(); + } + + return cause_ + "(" + nodeLocation + ", line " + std::to_string(node_->Start().line + 1) + ')'; } const auto &Cause() const @@ -60,7 +118,7 @@ private: using Messages = std::vector; -class CheckContext { +class InvariantMessages { public: void Init() { @@ -88,20 +146,42 @@ private: Messages messages_; }; -template -class InvariantBase : public CheckContext { +template +class RequiredInvariants { public: - constexpr static VerifierInvariants ID = ENUM; - constexpr static std::string_view NAME = util::gen::ast_verifier::ToString(ID); - CheckResult VerifyNode(const ir::AstNode *ast); + template + explicit constexpr RequiredInvariants([[maybe_unused]] InvariantsReg *reg) + : required_ {*reg->template Get()...} + { + } + + const auto &GetRequired() const + { + return required_; + } + +protected: + template + const auto &Get() + { + return std::get(required_); + } + +private: + static_assert(((RequiredInvs::ID < ENUM) && ...), "'Required' invariants should precede the related invariant"); + std::tuple required_; }; -template -class RecursiveInvariant : public InvariantBase { +template +// NOLINTNEXTLINE(fuchsia-multiple-inheritance) +class InvariantBase : public RequiredInvariants, public InvariantMessages { public: - void VerifyAst(const ir::AstNode *ast); + using RequiredInvariants::RequiredInvariants; + using Base = InvariantBase; + constexpr static VerifierInvariants ID = ENUM; + constexpr static std::string_view NAME = util::gen::ast_verifier::ToString(ID); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKCONTEXT_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTBASE_H diff --git a/ets2panda/ast_verifier/arithmeticOperationValid.cpp b/ets2panda/ast_verifier/invariants/arithmeticOperationValid.cpp similarity index 97% rename from ets2panda/ast_verifier/arithmeticOperationValid.cpp rename to ets2panda/ast_verifier/invariants/arithmeticOperationValid.cpp index ed0794f19e63baf7be5f4048eb88204257264907..bb77859aed5faaa10db8e382b720112625617808 100644 --- a/ets2panda/ast_verifier/arithmeticOperationValid.cpp +++ b/ets2panda/ast_verifier/invariants/arithmeticOperationValid.cpp @@ -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 @@ -19,7 +19,7 @@ #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/ts/tsEnumDeclaration.h" #include "ir/ts/tsInterfaceBody.h" -#include "helpers.h" +#include "../helpers.h" namespace ark::es2panda::compiler::ast_verifier { diff --git a/ets2panda/ast_verifier/arithmeticOperationValid.h b/ets2panda/ast_verifier/invariants/arithmeticOperationValid.h similarity index 62% rename from ets2panda/ast_verifier/arithmeticOperationValid.h rename to ets2panda/ast_verifier/invariants/arithmeticOperationValid.h index c9177b562cb42c1499e312d7ab585ea35b2a3770..1afed1ea7fb3564257f089b7ccda30e024f3bbd2 100644 --- a/ets2panda/ast_verifier/arithmeticOperationValid.h +++ b/ets2panda/ast_verifier/invariants/arithmeticOperationValid.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 @@ -13,20 +13,20 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_ARITHMETICOPERATIONVALID_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_ARITHMETICOPERATIONVALID_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_ARITHMETICOPERATIONVALID_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_ARITHMETICOPERATIONVALID_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class ArithmeticOperationValid : public RecursiveInvariant { - template - friend class InvariantBase; +class ArithmeticOperationValid : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); CheckResult CheckCompound(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_ARITHMETICOPERATIONVALID_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_ARITHMETICOPERATIONVALID_H diff --git a/ets2panda/ast_verifier/checkAbstractMethod.cpp b/ets2panda/ast_verifier/invariants/checkAbstractMethod.cpp similarity index 96% rename from ets2panda/ast_verifier/checkAbstractMethod.cpp rename to ets2panda/ast_verifier/invariants/checkAbstractMethod.cpp index b74f0fd82eb85aea0ca12511be32f41ecb7803b6..efd25e797ce6e97e5fc5c6e042387c9d16c543eb 100644 --- a/ets2panda/ast_verifier/checkAbstractMethod.cpp +++ b/ets2panda/ast_verifier/invariants/checkAbstractMethod.cpp @@ -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 diff --git a/ets2panda/ast_verifier/checkAbstractMethod.h b/ets2panda/ast_verifier/invariants/checkAbstractMethod.h similarity index 62% rename from ets2panda/ast_verifier/checkAbstractMethod.h rename to ets2panda/ast_verifier/invariants/checkAbstractMethod.h index 0abd1ab3d99cc96e39c564ebf5f313f910fe980c..d2534f5483ea3017becd4dd6108ce2d7d4efde2a 100644 --- a/ets2panda/ast_verifier/checkAbstractMethod.h +++ b/ets2panda/ast_verifier/invariants/checkAbstractMethod.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 @@ -13,19 +13,19 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKABSTRACTMETHOD_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKABSTRACTMETHOD_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKABSTRACTMETHOD_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKABSTRACTMETHOD_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class CheckAbstractMethod : public RecursiveInvariant { - template - friend class InvariantBase; +class CheckAbstractMethod : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKABSTRACTMETHOD_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKABSTRACTMETHOD_H diff --git a/ets2panda/ast_verifier/checkConstProperties.cpp b/ets2panda/ast_verifier/invariants/checkConstProperties.cpp similarity index 100% rename from ets2panda/ast_verifier/checkConstProperties.cpp rename to ets2panda/ast_verifier/invariants/checkConstProperties.cpp diff --git a/ets2panda/ast_verifier/checkConstProperties.h b/ets2panda/ast_verifier/invariants/checkConstProperties.h similarity index 62% rename from ets2panda/ast_verifier/checkConstProperties.h rename to ets2panda/ast_verifier/invariants/checkConstProperties.h index e2302d0073bf5e31e656b262b27089da4ad1c020..379e446e7a90a5c09a018c1be19cf2a41f616c09 100644 --- a/ets2panda/ast_verifier/checkConstProperties.h +++ b/ets2panda/ast_verifier/invariants/checkConstProperties.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 @@ -13,19 +13,19 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKCONSTPROPERTIES_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKCONSTPROPERTIES_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKCONSTPROPERTIES_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKCONSTPROPERTIES_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class CheckConstProperties : public RecursiveInvariant { - template - friend class InvariantBase; +class CheckConstProperties : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKCONSTPROPERTIES_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKCONSTPROPERTIES_H diff --git a/ets2panda/ast_verifier/checkScopeDeclaration.cpp b/ets2panda/ast_verifier/invariants/checkScopeDeclaration.cpp similarity index 98% rename from ets2panda/ast_verifier/checkScopeDeclaration.cpp rename to ets2panda/ast_verifier/invariants/checkScopeDeclaration.cpp index aac5ec0141c94e353cc5aa7d4384797e62007058..b76e622e299903ce3696a4c844f8a40d9d541879 100644 --- a/ets2panda/ast_verifier/checkScopeDeclaration.cpp +++ b/ets2panda/ast_verifier/invariants/checkScopeDeclaration.cpp @@ -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 diff --git a/ets2panda/ast_verifier/checkScopeDeclaration.h b/ets2panda/ast_verifier/invariants/checkScopeDeclaration.h similarity index 63% rename from ets2panda/ast_verifier/checkScopeDeclaration.h rename to ets2panda/ast_verifier/invariants/checkScopeDeclaration.h index 7b4308d46b38d7e7456286a0c040b9996a65ea56..f7766ab0b8370e8bb76bbada509f4aec9589033d 100644 --- a/ets2panda/ast_verifier/checkScopeDeclaration.h +++ b/ets2panda/ast_verifier/invariants/checkScopeDeclaration.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 @@ -13,20 +13,22 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKSCOPEDECLARATION_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKSCOPEDECLARATION_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKSCOPEDECLARATION_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKSCOPEDECLARATION_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class CheckScopeDeclaration : public RecursiveInvariant { - template - friend class InvariantBase; +class CheckScopeDeclaration : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); + +private: CheckResult CheckScope(varbinder::Scope const *const scope); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKSCOPEDECLARATION_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKSCOPEDECLARATION_H diff --git a/ets2panda/ast_verifier/checkStructDeclaration.cpp b/ets2panda/ast_verifier/invariants/checkStructDeclaration.cpp similarity index 100% rename from ets2panda/ast_verifier/checkStructDeclaration.cpp rename to ets2panda/ast_verifier/invariants/checkStructDeclaration.cpp diff --git a/ets2panda/ast_verifier/checkStructDeclaration.h b/ets2panda/ast_verifier/invariants/checkStructDeclaration.h similarity index 66% rename from ets2panda/ast_verifier/checkStructDeclaration.h rename to ets2panda/ast_verifier/invariants/checkStructDeclaration.h index cfb7f6be0899110787f12864c4d6cf1966d7eac5..931279a83c25db407b4612749cf19ec4b4849ee6 100644 --- a/ets2panda/ast_verifier/checkStructDeclaration.h +++ b/ets2panda/ast_verifier/invariants/checkStructDeclaration.h @@ -13,19 +13,19 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKSTRUCTDECLARATION_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKSTRUCTDECLARATION_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKSTRUCTDECLARATION_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_CHECKSTRUCTDECLARATION_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class CheckStructDeclaration : public RecursiveInvariant { - template - friend class InvariantBase; +class CheckStructDeclaration : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASPARENT_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASPARENT_H diff --git a/ets2panda/ast_verifier/everyChildHasValidParent.cpp b/ets2panda/ast_verifier/invariants/everyChildHasValidParent.cpp similarity index 100% rename from ets2panda/ast_verifier/everyChildHasValidParent.cpp rename to ets2panda/ast_verifier/invariants/everyChildHasValidParent.cpp diff --git a/ets2panda/ast_verifier/everyChildInParentRange.h b/ets2panda/ast_verifier/invariants/everyChildHasValidParent.h similarity index 61% rename from ets2panda/ast_verifier/everyChildInParentRange.h rename to ets2panda/ast_verifier/invariants/everyChildHasValidParent.h index b9b976f21acf116ed08688d45dc48a7b4b35dbb9..d18220f781f94a2e7563cdc420aca729529d7714 100644 --- a/ets2panda/ast_verifier/everyChildInParentRange.h +++ b/ets2panda/ast_verifier/invariants/everyChildHasValidParent.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 @@ -13,19 +13,19 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDINPARENTRANGE_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDINPARENTRANGE_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_EVERYCHILDHASVALIDPARENT_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_EVERYCHILDHASVALIDPARENT_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class EveryChildInParentRange : public RecursiveInvariant { - template - friend class InvariantBase; +class EveryChildHasValidParent : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDINPARENTRANGE_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_EVERYCHILDHASVALIDPARENT_H diff --git a/ets2panda/ast_verifier/everyChildInParentRange.cpp b/ets2panda/ast_verifier/invariants/everyChildInParentRange.cpp similarity index 97% rename from ets2panda/ast_verifier/everyChildInParentRange.cpp rename to ets2panda/ast_verifier/invariants/everyChildInParentRange.cpp index 91a6bb998344c11babc072f2bc59581796b09594..397aeb27eaaa815818322c5eff49d2076cf01fbe 100644 --- a/ets2panda/ast_verifier/everyChildInParentRange.cpp +++ b/ets2panda/ast_verifier/invariants/everyChildInParentRange.cpp @@ -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 diff --git a/ets2panda/ast_verifier/invariants/everyChildInParentRange.h b/ets2panda/ast_verifier/invariants/everyChildInParentRange.h new file mode 100644 index 0000000000000000000000000000000000000000..c3406de3e0b04c9285e9b1b5dc8c4abb2ff482e2 --- /dev/null +++ b/ets2panda/ast_verifier/invariants/everyChildInParentRange.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_EVERYCHILDINPARENTRANGE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_EVERYCHILDINPARENTRANGE_H + +#include "../invariantBase.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class EveryChildInParentRange : public InvariantBase { +public: + using Base::Base; + [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_EVERYCHILDINPARENTRANGE_H diff --git a/ets2panda/ast_verifier/forLoopCorrectlyInitialized.cpp b/ets2panda/ast_verifier/invariants/forLoopCorrectlyInitialized.cpp similarity index 98% rename from ets2panda/ast_verifier/forLoopCorrectlyInitialized.cpp rename to ets2panda/ast_verifier/invariants/forLoopCorrectlyInitialized.cpp index 6c92add48dbf4f92270cf52e5d85c0d4f40252a9..9ccb62e9698031dd71a50d59eaa004ed9020517c 100644 --- a/ets2panda/ast_verifier/forLoopCorrectlyInitialized.cpp +++ b/ets2panda/ast_verifier/invariants/forLoopCorrectlyInitialized.cpp @@ -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 diff --git a/ets2panda/ast_verifier/forLoopCorrectlyInitialized.h b/ets2panda/ast_verifier/invariants/forLoopCorrectlyInitialized.h similarity index 66% rename from ets2panda/ast_verifier/forLoopCorrectlyInitialized.h rename to ets2panda/ast_verifier/invariants/forLoopCorrectlyInitialized.h index 1afe3a0ee06dd80f7233c2118ba6b80f058b4b92..15c3e45451cf0457a420023a642fbadd4140f302 100644 --- a/ets2panda/ast_verifier/forLoopCorrectlyInitialized.h +++ b/ets2panda/ast_verifier/invariants/forLoopCorrectlyInitialized.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 @@ -13,17 +13,19 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_FORLOOPCORRECTLYINITIALIZED_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_FORLOOPCORRECTLYINITIALIZED_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_FORLOOPCORRECTLYINITIALIZED_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_FORLOOPCORRECTLYINITIALIZED_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class ForLoopCorrectlyInitialized : public RecursiveInvariant { - template - friend class InvariantBase; +class ForLoopCorrectlyInitialized : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); + +private: [[nodiscard]] CheckResult HandleForInStatement(const ir::AstNode *ast); [[nodiscard]] CheckResult HandleForOfStatement(const ir::AstNode *ast); [[nodiscard]] CheckResult HandleForUpdateStatement(const ir::AstNode *ast); @@ -31,4 +33,4 @@ class ForLoopCorrectlyInitialized : public RecursiveInvariant { - template - friend class InvariantBase; +class GetterSetterValidation : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); + +private: bool ValidateGetter(ir::MethodDefinition const *const method); bool ValidateSetter(ir::MethodDefinition const *const method); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_GETTERSETTERVALIDATION_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_GETTERSETTERVALIDATION_H diff --git a/ets2panda/ast_verifier/identifierHasVariable.cpp b/ets2panda/ast_verifier/invariants/identifierHasVariable.cpp similarity index 100% rename from ets2panda/ast_verifier/identifierHasVariable.cpp rename to ets2panda/ast_verifier/invariants/identifierHasVariable.cpp diff --git a/ets2panda/ast_verifier/identifierHasVariable.h b/ets2panda/ast_verifier/invariants/identifierHasVariable.h similarity index 72% rename from ets2panda/ast_verifier/identifierHasVariable.h rename to ets2panda/ast_verifier/invariants/identifierHasVariable.h index 80939333d6dc492dbeb40ad83560d565078c7378..8fc17ff9bba58291a17e394043688350b22342f1 100644 --- a/ets2panda/ast_verifier/identifierHasVariable.h +++ b/ets2panda/ast_verifier/invariants/identifierHasVariable.h @@ -13,21 +13,22 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_IDENTIFIERHASVARIABLE_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_IDENTIFIERHASVARIABLE_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_IDENTIFIERHASVARIABLE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_IDENTIFIERHASVARIABLE_H -#include "checkContext.h" +#include "../invariantBase.h" #include "ir/expressions/identifier.h" namespace ark::es2panda::compiler::ast_verifier { -class IdentifierHasVariable : public RecursiveInvariant { - template - friend class InvariantBase; +class IdentifierHasVariable : public InvariantBase { +public: + using Base::Base; class ExceptionsMatcher; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); +private: auto UnionLoweringOccurred() const { return unionLoweringOccurred_; @@ -45,4 +46,4 @@ private: } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_IDENTIFIERHASVARIABLE_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_IDENTIFIERHASVARIABLE_H diff --git a/ets2panda/ast_verifier/importExportAccessValid.cpp b/ets2panda/ast_verifier/invariants/importExportAccessValid.cpp similarity index 98% rename from ets2panda/ast_verifier/importExportAccessValid.cpp rename to ets2panda/ast_verifier/invariants/importExportAccessValid.cpp index 8e7ac7e6b7c824f70f6ef898dd2627c28f9a1884..bf7351956a7b3bae812a360c9c28f6a777633fae 100644 --- a/ets2panda/ast_verifier/importExportAccessValid.cpp +++ b/ets2panda/ast_verifier/invariants/importExportAccessValid.cpp @@ -14,7 +14,7 @@ */ #include "importExportAccessValid.h" -#include "helpers.h" +#include "../helpers.h" #include "ir/expressions/callExpression.h" #include "checker/types/ets/etsObjectType.h" #include "ir/module/importSpecifier.h" @@ -70,7 +70,7 @@ bool ImportExportAccessValid::ValidateExport(const varbinder::Variable *var) if (node == nullptr) { return false; } - return node->IsExported() || node->IsExportedType(); + return node->IsExported(); } bool ImportExportAccessValid::InvariantImportExportMethod(const std::unordered_set &importedVariables, diff --git a/ets2panda/ast_verifier/importExportAccessValid.h b/ets2panda/ast_verifier/invariants/importExportAccessValid.h similarity index 74% rename from ets2panda/ast_verifier/importExportAccessValid.h rename to ets2panda/ast_verifier/invariants/importExportAccessValid.h index 7c539217fcf8f4356da89b9e37441ef534b94d01..7977ee3a56e9059fec269c1bc737b4122cf94bf6 100644 --- a/ets2panda/ast_verifier/importExportAccessValid.h +++ b/ets2panda/ast_verifier/invariants/importExportAccessValid.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 @@ -13,17 +13,16 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_IMPORTEXPORTACCESSVALID_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_IMPORTEXPORTACCESSVALID_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_IMPORTEXPORTACCESSVALID_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_IMPORTEXPORTACCESSVALID_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -// NOTE(dkofanov) Fix and enable via `RecursiveInvariant` -class ImportExportAccessValid : public RecursiveInvariant { - template - friend class InvariantBase; +// NOTE(dkofanov) Fix and enable via `InvariantBase` +class ImportExportAccessValid : public InvariantBase { +public: [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); bool ValidateExport(const varbinder::Variable *var); bool InvariantImportExportMethod(const std::unordered_set &importedVariables, @@ -38,4 +37,4 @@ class ImportExportAccessValid : public RecursiveInvariant { - template - friend class InvariantBase; +class ModifierAccessValid : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); + +private: CheckResult HandleMethodExpression(const ir::AstNode *ast); CheckResult HandleCallExpression(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_MODIFIERACCESSVALID_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_MODIFIERACCESSVALID_H diff --git a/ets2panda/ast_verifier/nodeHasParent.cpp b/ets2panda/ast_verifier/invariants/nodeHasParent.cpp similarity index 100% rename from ets2panda/ast_verifier/nodeHasParent.cpp rename to ets2panda/ast_verifier/invariants/nodeHasParent.cpp diff --git a/ets2panda/ast_verifier/nodeHasParent.h b/ets2panda/ast_verifier/invariants/nodeHasParent.h similarity index 64% rename from ets2panda/ast_verifier/nodeHasParent.h rename to ets2panda/ast_verifier/invariants/nodeHasParent.h index 90d9800b367c693b99f95f8d7efcce434f4b6307..c3f583c8d9b7cc72bbe2bdec15904481e9817b95 100644 --- a/ets2panda/ast_verifier/nodeHasParent.h +++ b/ets2panda/ast_verifier/invariants/nodeHasParent.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 @@ -13,19 +13,19 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASPARENT_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASPARENT_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASPARENT_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASPARENT_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class NodeHasParent : public RecursiveInvariant { - template - friend class InvariantBase; +class NodeHasParent : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASPARENT_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASPARENT_H diff --git a/ets2panda/ast_verifier/nodeHasSourceRange.cpp b/ets2panda/ast_verifier/invariants/nodeHasSourceRange.cpp similarity index 95% rename from ets2panda/ast_verifier/nodeHasSourceRange.cpp rename to ets2panda/ast_verifier/invariants/nodeHasSourceRange.cpp index efb690e4f94e5a3fc9af42aed7ac8b6c1d75adcd..5af7313ec63f4fe3e094c887772be14a6a0f1468 100644 --- a/ets2panda/ast_verifier/nodeHasSourceRange.cpp +++ b/ets2panda/ast_verifier/invariants/nodeHasSourceRange.cpp @@ -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 diff --git a/ets2panda/ast_verifier/nodeHasSourceRange.h b/ets2panda/ast_verifier/invariants/nodeHasSourceRange.h similarity index 62% rename from ets2panda/ast_verifier/nodeHasSourceRange.h rename to ets2panda/ast_verifier/invariants/nodeHasSourceRange.h index 95f713e47eb7570e71098fdbce692cb0426fb1d6..fed802ecb7d531d87106868fedb7def3bebbd026 100644 --- a/ets2panda/ast_verifier/nodeHasSourceRange.h +++ b/ets2panda/ast_verifier/invariants/nodeHasSourceRange.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 @@ -13,19 +13,19 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASSOURCERANGE_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASSOURCERANGE_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASSOURCERANGE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASSOURCERANGE_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class NodeHasSourceRange : public RecursiveInvariant { - template - friend class InvariantBase; +class NodeHasSourceRange : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASSOURCERANGE_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASSOURCERANGE_H diff --git a/ets2panda/ast_verifier/nodeHasType.cpp b/ets2panda/ast_verifier/invariants/nodeHasType.cpp similarity index 31% rename from ets2panda/ast_verifier/nodeHasType.cpp rename to ets2panda/ast_verifier/invariants/nodeHasType.cpp index 42ff41a03622ad0f3e13d3e3a941f56442bb5a0b..4cfa95f5ca829f7252625b4821008f7f71411770 100644 --- a/ets2panda/ast_verifier/nodeHasType.cpp +++ b/ets2panda/ast_verifier/invariants/nodeHasType.cpp @@ -13,10 +13,15 @@ * limitations under the License. */ -#include "helpers.h" +#include "../helpers.h" #include "nodeHasType.h" #include "ir/base/classDefinition.h" +#include "ir/base/methodDefinition.h" +#include "ir/base/scriptFunction.h" +#include "ir/base/spreadElement.h" +#include "ir/expressions/functionExpression.h" #include "ir/expressions/identifier.h" +#include "ir/ets/etsParameterExpression.h" #include "ir/statements/annotationDeclaration.h" #include "ir/ts/tsEnumDeclaration.h" #include "ir/ts/tsInterfaceBody.h" @@ -24,71 +29,75 @@ namespace ark::es2panda::compiler::ast_verifier { -CheckResult NodeHasType::operator()(const ir::AstNode *ast) -{ - // NOTE(orlovskymaxim) In TS some ETS constructs are expressions (i.e. class/interface definition) - // Because ETS uses some AST classes from TS this introduces semantical problem - // Solution for now - manually filter expressions that are statements in ETS - if (ast->IsETSPackageDeclaration()) { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; +// NOTE(dkofanov): These exceptions are inadequate and are not actual exceptions. +class NodeHasType::ExceptionsMatcher { +public: + explicit ExceptionsMatcher(const ir::AstNode *ast) : nulltypeNode_(ast) {} + + auto ShouldSkipNode() const + { + return nulltypeNode_->IsIdentifier() || MatchFunctionExpression() || nulltypeNode_->IsTSClassImplements() || + nulltypeNode_->IsSpreadElement() || nulltypeNode_->IsTSThisType() || nulltypeNode_->IsETSNullType() || + nulltypeNode_->IsStringLiteral() || AnyChildStringLiteral(); } - if (IsImportLike(ast)) { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + + auto ShouldSkipSubtree() const + { + return nulltypeNode_->IsAnnotationUsage() || nulltypeNode_->IsVariableDeclarator() || MatchTypeParameter() || + nulltypeNode_->IsTSEnumDeclaration() || nulltypeNode_->IsTSInterfaceDeclaration() || + nulltypeNode_->IsTSQualifiedName() || nulltypeNode_->IsETSParameterExpression() || + nulltypeNode_->IsETSTypeReference() || MatchImportExport() || nulltypeNode_->IsTryStatement() || + nulltypeNode_->IsAssignmentExpression(); } - if (IsExportLike(ast)) { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + +private: + bool MatchFunctionExpression() const + { + if (!nulltypeNode_->IsFunctionExpression()) { + return false; + } + auto fe = nulltypeNode_->AsFunctionExpression(); + return (fe->Parent() != nullptr) && (fe->Parent()->IsMethodDefinition() || fe->Parent()->IsClassStaticBlock()); } - if (ast->IsTSTypeAliasDeclaration()) { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + bool MatchTypeParameter() const + { + return nulltypeNode_->IsTSTypeParameterInstantiation() || nulltypeNode_->IsTSTypeParameterDeclaration(); } - if (auto [decision, action] = CheckCompound(ast); action == CheckAction::SKIP_SUBTREE) { - return {decision, action}; + + bool MatchImportExport() const + { + return nulltypeNode_->IsETSReExportDeclaration() || nulltypeNode_->IsETSImportDeclaration(); } - if (ast->IsTyped() && ast->IsExpression()) { - if (ast->IsClassDefinition() && ast->AsClassDefinition()->Ident()->Name() == Signatures::ETS_GLOBAL) { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (ast->IsIdentifier() && ast->AsIdentifier()->Name() == "") { - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - const auto *typed = static_cast(ast); - if (typed->TsType() == nullptr) { - AddCheckMessage("NULL_TS_TYPE", *ast); - return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; - } + bool AnyChildStringLiteral() const + { + return nulltypeNode_->IsAnyChild([](auto *child) { return child->IsStringLiteral(); }); } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; -} -CheckResult NodeHasType::CheckCompound(const ir::AstNode *ast) +private: + const ir::AstNode *nulltypeNode_ {}; +}; + +CheckResult NodeHasType::operator()(const ir::AstNode *ast) { - if (ast->IsTSInterfaceDeclaration()) { - for (const auto &member : ast->AsTSInterfaceDeclaration()->Body()->Body()) { - [[maybe_unused]] auto _ = (*this)(member); - } - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; - } - if (ast->IsTSEnumDeclaration()) { - for (const auto &member : ast->AsTSEnumDeclaration()->Members()) { - [[maybe_unused]] auto _ = (*this)(member); - } + type_ = nullptr; + + if (ExceptionsMatcher {ast}.ShouldSkipSubtree()) { return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; } - if (ast->IsClassDefinition()) { - for (const auto &member : ast->AsClassDefinition()->Body()) { - [[maybe_unused]] auto _ = (*this)(member); - } - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + + if (!ast->IsTyped()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } - if (ast->IsAnnotationDeclaration()) { - for (const auto &member : ast->AsAnnotationDeclaration()->Properties()) { - [[maybe_unused]] auto _ = (*this)(member); - } - return {CheckDecision::CORRECT, CheckAction::SKIP_SUBTREE}; + + type_ = ast->AsTyped()->TsType(); + if (type_ != nullptr || ExceptionsMatcher {ast}.ShouldSkipNode()) { + return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; + + AddCheckMessage("NULL_TS_TYPE", *ast); + return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; } } // namespace ark::es2panda::compiler::ast_verifier diff --git a/ets2panda/ast_verifier/nodeHasType.h b/ets2panda/ast_verifier/invariants/nodeHasType.h similarity index 65% rename from ets2panda/ast_verifier/nodeHasType.h rename to ets2panda/ast_verifier/invariants/nodeHasType.h index 6d4fe1e360444592741e1b88eb76a0a21a85b13f..81769166cf67988b5c87153d932072722614aca2 100644 --- a/ets2panda/ast_verifier/nodeHasType.h +++ b/ets2panda/ast_verifier/invariants/nodeHasType.h @@ -13,24 +13,31 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASTYPE_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASTYPE_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASTYPE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASTYPE_H -#include "checkContext.h" +#include "../invariantBase.h" #include "checker/types/type.h" namespace ark::es2panda::compiler::ast_verifier { -class NodeHasType : public RecursiveInvariant { - template - friend class InvariantBase; +class NodeHasType : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); - CheckResult CheckCompound(const ir::AstNode *ast); + +private: + const checker::Type *type_ {}; + + class ExceptionsMatcher; + + friend class NoPrimitiveTypes; }; -// NOTE(dkofanov): explicitly mark as dependent on NodeHasType: -class NoPrimitiveTypes : public RecursiveInvariant { +class NoPrimitiveTypes : public InvariantBase { public: + using Base::Base; + void SetNumberLoweringOccured(bool v = true) { numberLoweringOccurred_ = v; @@ -38,15 +45,10 @@ public: [[nodiscard]] CheckResult operator()(const ir::AstNode *ast) { - if (!ast->IsTyped()) { - return {CheckDecision::CORRECT, CheckAction::CONTINUE}; - } - auto type = ast->AsTyped()->TsType(); + const auto *type = Get().type_; if (type == nullptr) { - // Checked during NodeHasType. return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } - if (!numberLoweringOccurred_ && type->IsETSPrimitiveType()) { AddCheckMessage("PRIMITIVE_BEFORE_LOWERING", *ast); return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; @@ -59,4 +61,4 @@ private: }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_NODEHASTYPE_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_NODEHASTYPE_H diff --git a/ets2panda/ast_verifier/referenceTypeAnnotationIsNull.cpp b/ets2panda/ast_verifier/invariants/referenceTypeAnnotationIsNull.cpp similarity index 100% rename from ets2panda/ast_verifier/referenceTypeAnnotationIsNull.cpp rename to ets2panda/ast_verifier/invariants/referenceTypeAnnotationIsNull.cpp diff --git a/ets2panda/ast_verifier/referenceTypeAnnotationIsNull.h b/ets2panda/ast_verifier/invariants/referenceTypeAnnotationIsNull.h similarity index 61% rename from ets2panda/ast_verifier/referenceTypeAnnotationIsNull.h rename to ets2panda/ast_verifier/invariants/referenceTypeAnnotationIsNull.h index c2a887beb81be75794f4e7488feb001a602c3b23..e0e7bcaf36f3583d834edf86ef9372a467920f48 100644 --- a/ets2panda/ast_verifier/referenceTypeAnnotationIsNull.h +++ b/ets2panda/ast_verifier/invariants/referenceTypeAnnotationIsNull.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 @@ -13,20 +13,20 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_REFERENCETYPEANNOTATIONISNULL_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_REFERENCETYPEANNOTATIONISNULL_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_REFERENCETYPEANNOTATIONISNULL_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_REFERENCETYPEANNOTATIONISNULL_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class ReferenceTypeAnnotationIsNull : public RecursiveInvariant { - template - friend class InvariantBase; +class ReferenceTypeAnnotationIsNull : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); bool CheckExceptions(ir::Identifier const *const id) const; }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_REFERENCETYPEANNOTATIONISNULL_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_REFERENCETYPEANNOTATIONISNULL_H diff --git a/ets2panda/ast_verifier/sequenceExpressionHasLastType.cpp b/ets2panda/ast_verifier/invariants/sequenceExpressionHasLastType.cpp similarity index 100% rename from ets2panda/ast_verifier/sequenceExpressionHasLastType.cpp rename to ets2panda/ast_verifier/invariants/sequenceExpressionHasLastType.cpp diff --git a/ets2panda/ast_verifier/everyChildHasValidParent.h b/ets2panda/ast_verifier/invariants/sequenceExpressionHasLastType.h similarity index 60% rename from ets2panda/ast_verifier/everyChildHasValidParent.h rename to ets2panda/ast_verifier/invariants/sequenceExpressionHasLastType.h index 8c5b6c13758ad74a29c4f7411df136b8c892e9f3..c39f50507244ae115b4c818cee22b899a8daface 100644 --- a/ets2panda/ast_verifier/everyChildHasValidParent.h +++ b/ets2panda/ast_verifier/invariants/sequenceExpressionHasLastType.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 @@ -13,19 +13,19 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDHASVALIDPARENT_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDHASVALIDPARENT_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_SEQUENCEEXPRESSIONHASLASTTYPE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_SEQUENCEEXPRESSIONHASLASTTYPE_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class EveryChildHasValidParent : public RecursiveInvariant { - template - friend class InvariantBase; +class SequenceExpressionHasLastType : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_EVERYCHILDHASVALIDPARENT_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_SEQUENCEEXPRESSIONHASLASTTYPE_H diff --git a/ets2panda/ast_verifier/variableHasEnclosingScope.cpp b/ets2panda/ast_verifier/invariants/variableHasEnclosingScope.cpp similarity index 99% rename from ets2panda/ast_verifier/variableHasEnclosingScope.cpp rename to ets2panda/ast_verifier/invariants/variableHasEnclosingScope.cpp index a6946e3fdd28e4f300eb5e13cd32306f31f42d68..1aa6f1abf062c4b37663c31cb50160668839ef1a 100644 --- a/ets2panda/ast_verifier/variableHasEnclosingScope.cpp +++ b/ets2panda/ast_verifier/invariants/variableHasEnclosingScope.cpp @@ -15,7 +15,7 @@ #include "variableHasEnclosingScope.h" #include "variableHasScope.h" -#include "helpers.h" +#include "../helpers.h" namespace ark::es2panda::compiler::ast_verifier { diff --git a/ets2panda/ast_verifier/variableHasEnclosingScope.h b/ets2panda/ast_verifier/invariants/variableHasEnclosingScope.h similarity index 66% rename from ets2panda/ast_verifier/variableHasEnclosingScope.h rename to ets2panda/ast_verifier/invariants/variableHasEnclosingScope.h index 3b12cba7441145a8c935d0f647e63ba60b98a483..5d0cf636988ba868da9edffb947b4f22d6c8520f 100644 --- a/ets2panda/ast_verifier/variableHasEnclosingScope.h +++ b/ets2panda/ast_verifier/invariants/variableHasEnclosingScope.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 @@ -13,16 +13,16 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLEHASENCLOSINGSCOPE_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLEHASENCLOSINGSCOPE_H +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_VARIABLEHASENCLOSINGSCOPE_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_VARIABLEHASENCLOSINGSCOPE_H -#include "checkContext.h" +#include "../invariantBase.h" namespace ark::es2panda::compiler::ast_verifier { -class VariableHasEnclosingScope : public RecursiveInvariant { - template - friend class InvariantBase; +class VariableHasEnclosingScope : public InvariantBase { +public: + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); bool CheckCatchClause(const ir::AstNode *ast, const ir::AstNode *node) const; bool CheckScopeNodeExceptions(const ir::AstNode *node) const; @@ -31,4 +31,4 @@ class VariableHasEnclosingScope : public RecursiveInvariant { +class VariableHasScope : public InvariantBase { public: - template - friend class InvariantBase; + using Base::Base; [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); +private: bool ScopeEncloseVariable(const varbinder::LocalVariable *var); bool CheckAstExceptions(const ir::AstNode *ast); }; } // namespace ark::es2panda::compiler::ast_verifier -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLEHASSCOPE_H +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_VARIABLEHASSCOPE_H diff --git a/ets2panda/ast_verifier/variableNameIdentifierNameSame.cpp b/ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.cpp similarity index 92% rename from ets2panda/ast_verifier/variableNameIdentifierNameSame.cpp rename to ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.cpp index f5ab1a349bd5e344270b7177c0e5dddc76234b01..f3d85ee0a0b15c40b6d821c4930a88875a1c6fad 100644 --- a/ets2panda/ast_verifier/variableNameIdentifierNameSame.cpp +++ b/ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.cpp @@ -32,8 +32,8 @@ namespace ark::es2panda::compiler::ast_verifier { } const auto variableNode = variable->Declaration()->Node(); // NOTE(psaykerone): skip because, this exceptions need to be fixed in checker and lowering - if (variableNode->IsExported() || variableNode->IsExportedType() || variableNode->IsDefaultExported() || - id->Name().Utf8().find("field") == 0 || variable->Name().Utf8().find("field") == 0) { + if (variableNode->IsExported() || variableNode->IsDefaultExported() || id->Name().Utf8().find("field") == 0 || + variable->Name().Utf8().find("field") == 0) { return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } if (id->Name() == variable->Name()) { diff --git a/ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.h b/ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.h new file mode 100644 index 0000000000000000000000000000000000000000..5eb9e85e2162d29c4f8d695879da3c12cc63d44d --- /dev/null +++ b/ets2panda/ast_verifier/invariants/variableNameIdentifierNameSame.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_VARIABLENAMEIDENTIFIERNAMESAME_H +#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_VARIABLENAMEIDENTIFIERNAMESAME_H + +#include "../invariantBase.h" + +namespace ark::es2panda::compiler::ast_verifier { + +class VariableNameIdentifierNameSame : public InvariantBase { +public: + using Base::Base; + [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); +}; + +} // namespace ark::es2panda::compiler::ast_verifier + +#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_INVARIANTS_VARIABLENAMEIDENTIFIERNAMESAME_H diff --git a/ets2panda/ast_verifier/sequenceExpressionHasLastType.h b/ets2panda/ast_verifier/sequenceExpressionHasLastType.h deleted file mode 100644 index 3cf7c53cd588bf0e222e2582653cc5a8c7b553de..0000000000000000000000000000000000000000 --- a/ets2panda/ast_verifier/sequenceExpressionHasLastType.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2024 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_CORE_AST_VERIFIER_SEQUENCEEXPRESSIONHASLASTTYPE_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_SEQUENCEEXPRESSIONHASLASTTYPE_H - -#include "checkContext.h" - -namespace ark::es2panda::compiler::ast_verifier { - -class SequenceExpressionHasLastType : public RecursiveInvariant { - template - friend class InvariantBase; - [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); -}; - -} // namespace ark::es2panda::compiler::ast_verifier - -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_SEQUENCEEXPRESSIONHASLASTTYPE_H diff --git a/ets2panda/ast_verifier/variableNameIdentifierNameSame.h b/ets2panda/ast_verifier/variableNameIdentifierNameSame.h deleted file mode 100644 index f30c6dd563d78c5f4af149ce2ab3ccbebbd8a7f6..0000000000000000000000000000000000000000 --- a/ets2panda/ast_verifier/variableNameIdentifierNameSame.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2024 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_CORE_AST_VERIFIER_VARIABLENAMEIDENTIFIERNAMESAME_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLENAMEIDENTIFIERNAMESAME_H - -#include "checkContext.h" - -namespace ark::es2panda::compiler::ast_verifier { - -class VariableNameIdentifierNameSame - : public RecursiveInvariant { - template - friend class InvariantBase; - [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); -}; - -} // namespace ark::es2panda::compiler::ast_verifier - -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_VARIABLENAMEIDENTIFIERNAMESAME_H diff --git a/ets2panda/bindings/.gitignore b/ets2panda/bindings/.gitignore index 615082737ba31f82a95ad9975c7b9a6be7894bbb..f6853a729b092d4068745baf5c1abafe7cd244d3 100644 --- a/ets2panda/bindings/.gitignore +++ b/ets2panda/bindings/.gitignore @@ -1,4 +1,8 @@ node_modules/* dist/* +dist-test/* package-lock.json tsconfig.tsbuildinfo +ets/ +ets2panda +.idea/ \ No newline at end of file diff --git a/ets2panda/bindings/.prettierignore b/ets2panda/bindings/.prettierignore new file mode 100644 index 0000000000000000000000000000000000000000..2f3613c27765c7087fcd45acc3d317ba0611d214 --- /dev/null +++ b/ets2panda/bindings/.prettierignore @@ -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. +# + +native/ +dist/** +dist-test/** +node_modules/** +**.json +**.js +**.md +**.ets diff --git a/ets2panda/bindings/.prettierrc.json b/ets2panda/bindings/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..813963a8211a5529c7f71beb13f34a8e349c2ddf --- /dev/null +++ b/ets2panda/bindings/.prettierrc.json @@ -0,0 +1,10 @@ +{ + "singleQuote": true, + "jsxSingleQuote": true, + "arrowParens": "always", + "printWidth": 120, + "tabWidth": 2, + "useTabs": false, + "semi": true, + "trailingComma": "none" +} diff --git a/ets2panda/bindings/BUILD.gn b/ets2panda/bindings/BUILD.gn index a94c16de113fcb58f6df116e92b14d57405db290..e6dbc5c5f4c3b2c6b686a994dcb23a4d4493a693 100644 --- a/ets2panda/bindings/BUILD.gn +++ b/ets2panda/bindings/BUILD.gn @@ -22,12 +22,9 @@ npm_path = "//prebuilts/build-tools/common/nodejs/current/bin/npm" shared_library("ts_bindings") { sources = [ - "./native/src/bridges.cpp", "./native/src/callback-resource.cpp", "./native/src/common-interop.cpp", - "./native/src/common.cpp", "./native/src/convertors-napi.cpp", - "./native/src/generated/bridges.cpp", "./native/src/lsp.cpp", ] configs += [ @@ -77,6 +74,159 @@ shared_library("ts_bindings") { configs -= [ "//build/config/compiler:compiler" ] } + if (is_linux) { + libs = [ "stdc++fs" ] + cflags_cc = [ + "-std=c++17", + "-Wall", + "-Werror", + "-Wno-unused-variable", + "-fPIC", + ] + + ldflags = [ + "-Wl,--allow-shlib-undefined", + "-Wl,--fatal-warnings", + "-Wl,--build-id=md5", + "-fPIC", + "-Wl,-z,noexecstack", + "-Wl,-z,now", + "-Wl,-z,relro", + "-Wl,--as-needed", + "-fuse-ld=lld", + "-Wl,--icf=all", + "-Wl,--color-diagnostics", + "-m64", + ] + output_extension = "node" + output_prefix_override = true + } else if (is_mingw) { + output_extension = "dll" + cflags_cc = [ + "-std=c++17", + "-Wall", + "-Werror", + "-Wno-unused-variable", + "-fPIC", + "-Wno-error=deprecated-copy", + "-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang", + "-ftrivial-auto-var-init=zero", + "-fcolor-diagnostics", + "-fmerge-all-constants", + "-Xclang", + "-mllvm", + "-Xclang", + "-instcombine-lower-dbg-declare=0", + "-no-canonical-prefixes", + "-static", + "-rtlib=compiler-rt", + "-stdlib=libc++", + "-lunwind", + "-lpthread", + "-Qunused-arguments", + "-fuse-ld=lld", + "-fno-stack-protector", + "-fno-strict-aliasing", + "-Wno-builtin-macro-redefined", + "-fms-extensions", + "-static", + "-rtlib=compiler-rt", + "-stdlib=libc++", + "-std=c++17", + "-lunwind", + "-lpthread", + "-Qunused-arguments", + "-target", + "x86_64-pc-windows-gnu", + "-D__CUSTOM_SECURITY_LIBRARY", + ] + + ldflags = [ + "-Wl,--fatal-warnings", + "-fPIC", + "-Wl,--as-needed", + "-fuse-ld=lld", + "-Wl,--icf=all", + "-m64", + "-static", + "-rtlib=compiler-rt", + "-stdlib=libc++", + "-std=c++17", + "-lunwind", + "-lpthread", + "-Qunused-arguments", + "-target", + "x86_64-pc-windows-gnu", + ] + sources += [ "./native/src/win-dynamic-node.cpp" ] + } else if (is_mac) { + cflags_cc = [ + "-std=c++17", + "-Wall", + "-Werror", + "-Wno-unused-variable", + "-fPIC", + ] + + ldflags = [ + "-fPIC", + "-fuse-ld=lld", + "-Wl,--icf=all", + "-Wl,--color-diagnostics", + "-m64", + "-Wl,-undefined,dynamic_lookup", + ] + output_extension = "node" + output_prefix_override = true + } +} + +shared_library("public") { + sources = [ + "./native/src/bridges.cpp", + "./native/src/callback-resource.cpp", + "./native/src/common-interop.cpp", + "./native/src/common.cpp", + "./native/src/convertors-napi.cpp", + ] + + configs += [ + "$ark_root/assembler:arkassembler_public_config", + "../:libes2panda_public_config", + "../:libes2panda_config", + "$ark_root/libpandabase:arkbase_public_config", + "$ark_root/libpandafile:arkfile_public_config", + ] + + include_dirs = [ + "./native/include", + "../public/", + "//third_party/node/src", + rebase_path("$root_gen_dir/arkcompiler/ets_frontend/ets2panda/"), + ] + + if (!is_mac) { + deps = [ "../aot:ets2panda" ] + } + + if (ark_standalone_build) { + deps += [ "$ark_third_party_root/bounds_checking_function:libsec_shared" ] + } else { + external_deps = [ sdk_libc_secshared_dep ] + } + + defines = [ + "TS_INTEROP_MODULE=NativeModule", + "INTEROP_LIBRARY_NAME=ts_bindings", + "TS_USE_NODE_VM", + "TS_NAPI", + ] + if (ark_standalone_build) { + configs -= [ "$build_root/config/compiler:compiler" ] + } else { + configs -= [ "//build/config/compiler:compiler" ] + } + if (is_linux) { cflags_cc = [ "-std=c++17", @@ -161,11 +311,33 @@ shared_library("ts_bindings") { "x86_64-pc-windows-gnu", ] sources += [ "./native/src/win-dynamic-node.cpp" ] + } else if (is_mac) { + cflags_cc = [ + "-std=c++17", + "-Wall", + "-Werror", + "-Wno-unused-variable", + "-fPIC", + ] + + ldflags = [ + "-fPIC", + "-fuse-ld=lld", + "-Wl,--icf=all", + "-Wl,--color-diagnostics", + "-m64", + "-Wl,-undefined,dynamic_lookup", + ] + output_extension = "node" + output_prefix_override = true } } action("build_bindings") { - deps = [ ":ts_bindings" ] + deps = [ + ":public", + ":ts_bindings", + ] sources = [ "./src/Es2pandaNativeModule.ts", "./src/InteropNativeModule.ts", diff --git a/ets2panda/bindings/build_bindings.py b/ets2panda/bindings/build_bindings.py index 4ad6c76874b9216bda3490b521f85f4756c3abd6..0754cfa7365c16a36a79d43e573c8ff5270ed611 100755 --- a/ets2panda/bindings/build_bindings.py +++ b/ets2panda/bindings/build_bindings.py @@ -61,10 +61,14 @@ def copy_output(options): if options.current_os == "mingw" : copy_files(os.path.join(options.root_out_dir, 'libts_bindings.dll'), os.path.join(options.output_path, 'ts_bindings.node'), True) + copy_files(os.path.join(options.root_out_dir, 'libpublic.dll'), + os.path.join(options.output_path, 'public.node'), True) - if options.current_os == "linux" : + if options.current_os == "linux" or options.current_os == "mac": copy_files(os.path.join(options.root_out_dir, 'ts_bindings.node'), os.path.join(options.output_path, 'ts_bindings.node'), True) + copy_files(os.path.join(options.root_out_dir, 'public.node'), + os.path.join(options.output_path, 'public.node'), True) def parse_args(): diff --git a/ets2panda/bindings/native/CMakeLists.txt b/ets2panda/bindings/native/CMakeLists.txt index b7794eba99e35cfbf120d63bc282fb00821b06b6..60dcbb51deb07e07eb70997d893412ccc8075766 100644 --- a/ets2panda/bindings/native/CMakeLists.txt +++ b/ets2panda/bindings/native/CMakeLists.txt @@ -65,12 +65,9 @@ set(NODE_BINARY ${PANDA_ROOT}/third_party/nodejs/node-${NODE_VERSION}-${DISTRO}/ set(NAPI_BINDINGS_LIB "ts_bindings") set(BINDINGS_NAPI_SRC - ./src/bridges.cpp - ./src/common.cpp ./src/common-interop.cpp ./src/convertors-napi.cpp ./src/callback-resource.cpp - ./src/generated/bridges.cpp ./src/lsp.cpp ) diff --git a/ets2panda/bindings/native/include/common.h b/ets2panda/bindings/native/include/common.h index c23a821f471047e61bebd921b0f5708b53c8d55c..b92a49f9f1746eb2167950381ad6bee374531452 100644 --- a/ets2panda/bindings/native/include/common.h +++ b/ets2panda/bindings/native/include/common.h @@ -23,7 +23,7 @@ #include #include "public/es2panda_lib.h" -es2panda_Impl *GetPublicImpl(); +const es2panda_Impl *GetPublicImpl(); // CC-OFFNXT(G.NAM.01) false positive std::string GetString(KStringPtr ptr); @@ -32,4 +32,7 @@ char *GetStringCopy(KStringPtr &ptr); inline KUInt UnpackUInt(const KByte *bytes); +// NOLINTBEGIN(fuchsia-statically-constructed-objects) +static std::string g_pandaLibPath; +// NOLINTEND(fuchsia-statically-constructed-objects) #endif // COMMON_H_ diff --git a/ets2panda/bindings/native/include/dynamic-loader.h b/ets2panda/bindings/native/include/dynamic-loader.h index cf3d487aeeea29028f535939a4399632a24724f2..ec4fc5077c89ce09146450a83541d4053b38f94c 100644 --- a/ets2panda/bindings/native/include/dynamic-loader.h +++ b/ets2panda/bindings/native/include/dynamic-loader.h @@ -43,7 +43,7 @@ inline std::string LibName(const char *lib) return std::string(lib) + ".dll"; } -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) #include inline void *LoadLibrary(const std::string &libPath) @@ -55,7 +55,8 @@ inline void *LoadLibrary(const std::string &libPath) return handle; } -inline const char *LibraryError() +// NOLINTNEXTLINE(modernize-redundant-void-arg) +inline const char *LibraryError(void) { return dlerror(); } diff --git a/ets2panda/bindings/native/src/bridges.cpp b/ets2panda/bindings/native/src/bridges.cpp index f90652abc4d88fe9b61a3ee2197cd2b7b5f66951..2757d4b9efc5081982efaa7c6d2959a303405bd9 100644 --- a/ets2panda/bindings/native/src/bridges.cpp +++ b/ets2panda/bindings/native/src/bridges.cpp @@ -66,11 +66,3 @@ KNativePointer impl_ContextErrorMessage(KNativePointer contextPtr) return new std::string(GetPublicImpl()->ContextErrorMessage(context)); } TS_INTEROP_1(ContextErrorMessage, KNativePointer, KNativePointer) - -KNativePointer impl_ProgramAst(KNativePointer programPtr) -{ - auto context = reinterpret_cast(programPtr); - auto program = reinterpret_cast(programPtr); - return GetPublicImpl()->ProgramAst(context, program); -} -TS_INTEROP_1(ProgramAst, KNativePointer, KNativePointer) diff --git a/ets2panda/bindings/native/src/common.cpp b/ets2panda/bindings/native/src/common.cpp index d22bfae7671facb56d955f9ba121a13f83163293..78f051246e1ae3d1ab4313b6e2f5dc18a2581b35 100644 --- a/ets2panda/bindings/native/src/common.cpp +++ b/ets2panda/bindings/native/src/common.cpp @@ -23,7 +23,7 @@ using std::string, std::cout, std::endl, std::vector; -static es2panda_Impl *impl = nullptr; +static es2panda_Impl const *impl = nullptr; #ifdef _WIN32 #include @@ -52,12 +52,16 @@ void *FindLibrary() if (envValue) { libraryName = string(envValue) + ("/" PLUGIN_DIR "/lib/") + LIB_ES2PANDA_PUBLIC; } else { - libraryName = LIB_ES2PANDA_PUBLIC; + if (g_pandaLibPath == "") { + libraryName = LIB_ES2PANDA_PUBLIC; + } else { + libraryName = g_pandaLibPath + "/" + LIB_ES2PANDA_PUBLIC; + } } return LoadLibrary(libraryName); } -es2panda_Impl *GetPublicImpl() +const es2panda_Impl *GetPublicImpl() { if (impl) { return impl; @@ -89,10 +93,15 @@ inline KUInt UnpackUInt(const KByte *bytes) return (bytes[0] | (bytes[1] << 8U) | (bytes[2U] << 16U) | (bytes[3U] << 24U)); } -KNativePointer impl_CreateConfig(KInt argc, KStringArray argvPtr) +inline std::string_view GetStringView(KStringPtr &ptr) { - const std::size_t HEADER_LEN = 4; + return std::string_view(ptr.c_str(), static_cast(ptr.length())); +} +KNativePointer impl_CreateConfig(KInt argc, KStringArray argvPtr, KStringPtr &pandaLibPath) +{ + const std::size_t HEADER_LEN = 4; + g_pandaLibPath = GetStringView(pandaLibPath); const char **argv = new const char *[static_cast(argc)]; std::size_t position = HEADER_LEN; std::size_t strLen; @@ -104,7 +113,7 @@ KNativePointer impl_CreateConfig(KInt argc, KStringArray argvPtr) } return GetPublicImpl()->CreateConfig(argc, argv); } -TS_INTEROP_2(CreateConfig, KNativePointer, KInt, KStringArray) +TS_INTEROP_3(CreateConfig, KNativePointer, KInt, KStringArray, KStringPtr) KNativePointer impl_DestroyConfig(KNativePointer configPtr) { diff --git a/ets2panda/bindings/native/src/lsp.cpp b/ets2panda/bindings/native/src/lsp.cpp index e7cbd65c474fd0026750dca83a11d0981416deee..a74ee5ae805bb827e2a30cb215af6fa3861b3af5 100644 --- a/ets2panda/bindings/native/src/lsp.cpp +++ b/ets2panda/bindings/native/src/lsp.cpp @@ -25,6 +25,17 @@ #include #include +namespace { +using ark::es2panda::lsp::ClassHierarchy; +using ark::es2panda::lsp::ClassHierarchyInfo; +using ark::es2panda::lsp::ClassMethodItem; +} // namespace + +char *GetStringCopy(KStringPtr &ptr) +{ + return strdup(ptr.c_str()); +} + KNativePointer impl_getCurrentTokenValue(KNativePointer context, KInt position) { LSPAPI const *ctx = GetImpl(); @@ -43,6 +54,83 @@ KNativePointer impl_getSemanticDiagnostics(KNativePointer context) } TS_INTEROP_1(getSemanticDiagnostics, KNativePointer, KNativePointer) +KNativePointer impl_getClassPropertyInfo(KNativePointer context, KInt position, KBoolean shouldCollectInherited) +{ + LSPAPI const *ctx = GetImpl(); + auto info = ctx->getClassPropertyInfo(reinterpret_cast(context), + static_cast(position), shouldCollectInherited != 0); + return new std::vector(info); +} +TS_INTEROP_3(getClassPropertyInfo, KNativePointer, KNativePointer, KInt, KBoolean) + +KNativePointer impl_getFieldsInfoFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast *>(infoPtr); + std::vector ptrs; + for (auto &el : *info) { + ptrs.push_back(new FieldsInfo(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getFieldsInfoFromPropertyInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getNameFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast(infoPtr); + return new std::string(info->name); +} +TS_INTEROP_1(getNameFromPropertyInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getFieldListPropertyFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast(infoPtr); + std::vector ptrs; + for (auto &el : info->properties) { + ptrs.push_back(new FieldListProperty(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getFieldListPropertyFromPropertyInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getKindFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast(infoPtr); + return new std::string(info->kind); +} +TS_INTEROP_1(getKindFromPropertyInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getModifierKindsFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast(infoPtr); + std::vector ptrs; + for (auto &el : info->modifierKinds.value()) { + ptrs.push_back(new std::string(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getModifierKindsFromPropertyInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getDisplayNameFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast(infoPtr); + return new std::string(info->displayName); +} +TS_INTEROP_1(getDisplayNameFromPropertyInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getStartFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast(infoPtr); + return new std::size_t(info->start); +} +TS_INTEROP_1(getStartFromPropertyInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getEndFromPropertyInfo(KNativePointer infoPtr) +{ + auto info = reinterpret_cast(infoPtr); + return new std::size_t(info->end); +} +TS_INTEROP_1(getEndFromPropertyInfo, KNativePointer, KNativePointer) + KNativePointer impl_getSyntacticDiagnostics(KNativePointer context) { LSPAPI const *ctx = GetImpl(); @@ -223,6 +311,194 @@ KNativePointer impl_getDeclInfo(KNativePointer context, KInt position) } TS_INTEROP_2(getDeclInfo, KNativePointer, KNativePointer, KInt) +KNativePointer impl_getClassConstructorInfo(KNativePointer context, KInt position, KStringArray strArrayPtr) +{ + std::vector properties; + for (const auto &el : MakeStringVector(strArrayPtr)) { + properties.emplace_back(GetStringCopy(const_cast(el))); + } + LSPAPI const *ctx = GetImpl(); + auto *info = new RefactorEditInfo(ctx->getClassConstructorInfo(reinterpret_cast(context), + static_cast(position), properties)); + return info; +} +TS_INTEROP_3(getClassConstructorInfo, KNativePointer, KNativePointer, KInt, KStringArray) + +KNativePointer impl_getFileTextChangesFromConstructorInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + std::vector ptrs; + for (auto &el : info->GetFileTextChanges()) { + ptrs.push_back(new FileTextChanges(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getFileTextChangesFromConstructorInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getFileNameFromConstructorInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->fileName); +} +TS_INTEROP_1(getFileNameFromConstructorInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getTextChangeFromConstructorInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + std::vector ptrs; + for (auto &el : info->textChanges) { + ptrs.push_back(new TextChange(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getTextChangeFromConstructorInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getNewTextFromConstructorInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->newText); +} +TS_INTEROP_1(getNewTextFromConstructorInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getTextSpanFromConstructorInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new TextSpan(info->span); +} +TS_INTEROP_1(getTextSpanFromConstructorInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getRefactorActionName(KNativePointer refactorActionPtr) +{ + auto *refactorAction = reinterpret_cast(refactorActionPtr); + return new std::string(refactorAction->name); +} +TS_INTEROP_1(getRefactorActionName, KNativePointer, KNativePointer) + +KNativePointer impl_getRefactorActionDescription(KNativePointer refactorActionPtr) +{ + auto *refactorAction = reinterpret_cast(refactorActionPtr); + return new std::string(refactorAction->description); +} +TS_INTEROP_1(getRefactorActionDescription, KNativePointer, KNativePointer) + +KNativePointer impl_getRefactorActionKind(KNativePointer refactorActionPtr) +{ + auto *refactorAction = reinterpret_cast(refactorActionPtr); + return new std::string(refactorAction->kind); +} +TS_INTEROP_1(getRefactorActionKind, KNativePointer, KNativePointer) + +KNativePointer impl_getApplicableRefactors(KNativePointer context, KStringPtr &kindPtr, KInt position) +{ + LSPAPI const *ctx = GetImpl(); + auto *applicableRefactorInfo = new ark::es2panda::lsp::ApplicableRefactorInfo(ctx->getApplicableRefactors( + reinterpret_cast(context), GetStringCopy(kindPtr), static_cast(position))); + return applicableRefactorInfo; +} +TS_INTEROP_3(getApplicableRefactors, KNativePointer, KNativePointer, KStringPtr, KInt) + +KNativePointer impl_getApplicableRefactorName(KNativePointer applRefsPtr) +{ + auto *applRefsInfo = reinterpret_cast(applRefsPtr); + return new std::string(applRefsInfo->name); +} +TS_INTEROP_1(getApplicableRefactorName, KNativePointer, KNativePointer) + +KNativePointer impl_getApplicableRefactorDescription(KNativePointer applRefsPtr) +{ + auto *applRefsInfo = reinterpret_cast(applRefsPtr); + return new std::string(applRefsInfo->description); +} +TS_INTEROP_1(getApplicableRefactorDescription, KNativePointer, KNativePointer) + +KNativePointer impl_getRefactorAction(KNativePointer applRefsPtr) +{ + auto *applRefsInfo = reinterpret_cast(applRefsPtr); + return new ark::es2panda::lsp::RefactorAction(applRefsInfo->action); +} +TS_INTEROP_1(getRefactorAction, KNativePointer, KNativePointer) + +KNativePointer impl_getCompletionEntryDetailsSymbolDisplayPart(KNativePointer completionEntryDetailsPtr) +{ + auto *completionEntryDetails = reinterpret_cast(completionEntryDetailsPtr); + std::vector ptrs; + for (auto &el : completionEntryDetails->GetDisplayParts()) { + ptrs.push_back(new SymbolDisplayPart(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getCompletionEntryDetailsSymbolDisplayPart, KNativePointer, KNativePointer) + +KNativePointer impl_getCompletionEntryDetailsKind(KNativePointer completionEntryDetailsPtr) +{ + auto *completionEntryDetails = reinterpret_cast(completionEntryDetailsPtr); + return new std::string(completionEntryDetails->GetKind()); +} +TS_INTEROP_1(getCompletionEntryDetailsKind, KNativePointer, KNativePointer) + +KNativePointer impl_getCompletionEntryDetailsKindModifier(KNativePointer ref) +{ + auto *refPtr = reinterpret_cast(ref); + return new std::string(refPtr->GetKindModifiers()); +} +TS_INTEROP_1(getCompletionEntryDetailsKindModifier, KNativePointer, KNativePointer) + +KNativePointer impl_getCompletionEntryDetailsFileName(KNativePointer ref) +{ + auto *refPtr = reinterpret_cast(ref); + return new std::string(refPtr->GetFileName()); +} +TS_INTEROP_1(getCompletionEntryDetailsFileName, KNativePointer, KNativePointer) + +KNativePointer impl_getCompletionEntryDetailsEntryName(KNativePointer ref) +{ + auto *refPtr = reinterpret_cast(ref); + return new std::string(refPtr->GetName()); +} +TS_INTEROP_1(getCompletionEntryDetailsEntryName, KNativePointer, KNativePointer) + +KNativePointer impl_findSafeDeleteLocation(KNativePointer context, KNativePointer declInfo) +{ + LSPAPI const *ctx = GetImpl(); + auto *result = new std::vector( + ctx->FindSafeDeleteLocation(reinterpret_cast(context), + reinterpret_cast *>(declInfo))); + return result; +} +TS_INTEROP_2(findSafeDeleteLocation, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_getSafeDeleteLocations(KNativePointer safeDeleteLocationsPtr) +{ + auto *locations = reinterpret_cast *>(safeDeleteLocationsPtr); + std::vector ptrs; + for (auto &loc : *locations) { + ptrs.push_back(new SafeDeleteLocation(loc)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSafeDeleteLocations, KNativePointer, KNativePointer) + +KNativePointer impl_getSafeDeleteLocationUri(KNativePointer locationPtr) +{ + auto *location = reinterpret_cast(locationPtr); + return new std::string(location->uri); +} +TS_INTEROP_1(getSafeDeleteLocationUri, KNativePointer, KNativePointer) + +KInt impl_getSafeDeleteLocationStart(KNativePointer locationPtr) +{ + auto *location = reinterpret_cast(locationPtr); + return static_cast(location->start); +} +TS_INTEROP_1(getSafeDeleteLocationStart, KInt, KNativePointer) + +KInt impl_getSafeDeleteLocationLength(KNativePointer locationPtr) +{ + auto *location = reinterpret_cast(locationPtr); + return static_cast(location->length); +} +TS_INTEROP_1(getSafeDeleteLocationLength, KInt, KNativePointer) + KNativePointer impl_getReferencesAtPosition(KNativePointer context, KNativePointer declInfo) { LSPAPI const *ctx = GetImpl(); @@ -296,6 +572,68 @@ KNativePointer impl_getCompletionAtPosition(KNativePointer context, KInt positio } TS_INTEROP_2(getCompletionAtPosition, KNativePointer, KNativePointer, KInt) +KNativePointer impl_organizeImports(KNativePointer context, KStringPtr &filenamePtr) +{ + LSPAPI const *ctx = GetImpl(); + auto result = ctx->OrganizeImportsImpl(reinterpret_cast(context), GetStringCopy(filenamePtr)); + return new std::vector(result); +} +TS_INTEROP_2(organizeImports, KNativePointer, KNativePointer, KStringPtr) + +KNativePointer impl_getFileTextChanges(KNativePointer fileTextChangesVecPtr) +{ + auto *vec = reinterpret_cast *>(fileTextChangesVecPtr); + std::vector ptrs; + for (auto &el : *vec) { + ptrs.push_back(new FileTextChanges(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getFileTextChanges, KNativePointer, KNativePointer) + +KNativePointer impl_getFileNameFromFileTextChanges(KNativePointer fileTextChangesPtr) +{ + auto *ftc = reinterpret_cast(fileTextChangesPtr); + return new std::string(ftc->fileName); +} +TS_INTEROP_1(getFileNameFromFileTextChanges, KNativePointer, KNativePointer) + +KNativePointer impl_getTextChangesFromFileTextChanges(KNativePointer fileTextChangesPtr) +{ + auto *ftc = reinterpret_cast(fileTextChangesPtr); + std::vector ptrs; + for (auto &el : ftc->textChanges) { + ptrs.push_back(new TextChange(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getTextChangesFromFileTextChanges, KNativePointer, KNativePointer) + +KNativePointer impl_getTextSpanFromTextChange(KNativePointer textChangePtr) +{ + auto *tc = reinterpret_cast(textChangePtr); + return new TextSpan(tc->span); +} +TS_INTEROP_1(getTextSpanFromTextChange, KNativePointer, KNativePointer) + +KNativePointer impl_getNewTextFromTextChange(KNativePointer textChangePtr) +{ + auto *tc = reinterpret_cast(textChangePtr); + return new std::string(tc->newText); +} +TS_INTEROP_1(getNewTextFromTextChange, KNativePointer, KNativePointer) + +KNativePointer impl_getCompletionEntryDetails(KStringPtr &entrynamePtr, KStringPtr &filenamePtr, KNativePointer context, + KInt position) +{ + LSPAPI const *ctx = GetImpl(); + auto *ci = new CompletionEntryDetails( + ctx->getCompletionEntryDetails(GetStringCopy(entrynamePtr), GetStringCopy(filenamePtr), + reinterpret_cast(context), position)); + return ci; +} +TS_INTEROP_4(getCompletionEntryDetails, KNativePointer, KStringPtr, KStringPtr, KNativePointer, KInt) + KNativePointer impl_getImplementationAtPosition(KNativePointer context, KInt position) { LSPAPI const *ctx = GetImpl(); @@ -399,6 +737,228 @@ KNativePointer impl_getQuickInfoFileName(KNativePointer ref) } TS_INTEROP_1(getQuickInfoFileName, KNativePointer, KNativePointer) +KNativePointer impl_getClassHierarchyInfo(KNativePointer context, KInt position) +{ + LSPAPI const *ctx = GetImpl(); + if (ctx == nullptr) { + return nullptr; + } + auto *classHierarchyPtr = + new ClassHierarchy(ctx->getClassHierarchyInfo(reinterpret_cast(context), position)); + return classHierarchyPtr; +} +TS_INTEROP_2(getClassHierarchyInfo, KNativePointer, KNativePointer, KInt) + +KNativePointer impl_castToClassHierarchyInfos(KNativePointer infos) +{ + auto *infosPtr = reinterpret_cast(infos); + if (infosPtr == nullptr) { + return nullptr; + } + std::vector ptrs; + for (const auto &element : *infosPtr) { + ptrs.push_back(new ClassHierarchyInfo(element)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(castToClassHierarchyInfos, KNativePointer, KNativePointer) + +KNativePointer impl_getClassNameFromClassHierarchyInfo(KNativePointer info) +{ + auto *infoPtr = reinterpret_cast(info); + if (infoPtr == nullptr) { + return nullptr; + } + return new std::string(infoPtr->GetClassName()); +} +TS_INTEROP_1(getClassNameFromClassHierarchyInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getMethodListFromClassHierarchyInfo(KNativePointer info) +{ + auto *infoPtr = reinterpret_cast(info); + if (infoPtr == nullptr) { + return nullptr; + } + std::vector ptrs; + for (const auto &element : infoPtr->GetMethodList()) { + if (element.second == nullptr) { + continue; + } + ptrs.push_back(new ClassMethodItem(*(element.second))); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getMethodListFromClassHierarchyInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getDetailFromClassMethodItem(KNativePointer item) +{ + auto *itemPtr = reinterpret_cast(item); + if (itemPtr == nullptr) { + return nullptr; + } + return new std::string(itemPtr->GetFunctionDetail()); +} +TS_INTEROP_1(getDetailFromClassMethodItem, KNativePointer, KNativePointer) + +KInt impl_getSetterStyleFromClassMethodItem(KNativePointer item) +{ + auto *itemPtr = reinterpret_cast(item); + if (itemPtr == nullptr) { + return 0; + } + return static_cast(itemPtr->GetSetterStyle()); +} +TS_INTEROP_1(getSetterStyleFromClassMethodItem, KInt, KNativePointer) + +KInt impl_getAccessModifierStyleFromClassMethodItem(KNativePointer item) +{ + auto *itemPtr = reinterpret_cast(item); + if (itemPtr == nullptr) { + return 0; + } + return static_cast(itemPtr->GetAccessModifierStyle()); +} +TS_INTEROP_1(getAccessModifierStyleFromClassMethodItem, KInt, KNativePointer) + +KInt impl_getAliasScriptElementKind(KNativePointer context, KInt position) +{ + LSPAPI const *ctx = GetImpl(); + if (ctx == nullptr) { + return 1; + } + auto kind = + static_cast(ctx->getAliasScriptElementKind(reinterpret_cast(context), position)); + return kind; +} +TS_INTEROP_2(getAliasScriptElementKind, KInt, KNativePointer, KInt) + +KNativePointer impl_getClassHierarchies(KNativePointer context, KStringPtr &fileNamePtr, KInt pos) +{ + LSPAPI const *ctx = GetImpl(); + if (ctx == nullptr) { + return nullptr; + } + auto infos = + ctx->getClassHierarchiesImpl(reinterpret_cast(context), GetStringCopy(fileNamePtr), pos); + std::vector ptrs; + ptrs.reserve(infos.size()); + for (auto &info : infos) { + ptrs.push_back(new ark::es2panda::lsp::ClassHierarchyItemInfo(info)); + } + return new std::vector(std::move(ptrs)); +} +TS_INTEROP_3(getClassHierarchies, KNativePointer, KNativePointer, KStringPtr, KInt) + +KNativePointer impl_getClassHierarchyList(KNativePointer infosPtr) +{ + auto *infos = reinterpret_cast *>(infosPtr); + std::vector infoPtrList; + for (auto &info : *infos) { + infoPtrList.push_back(new ark::es2panda::lsp::ClassHierarchyItemInfo(info)); + } + return new std::vector(infoPtrList); +} +TS_INTEROP_1(getClassHierarchyList, KNativePointer, KNativePointer) + +KInt impl_getPosFromClassHierarchyItemInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return static_cast(info->pos); +} +TS_INTEROP_1(getPosFromClassHierarchyItemInfo, KInt, KNativePointer) + +KInt impl_getKindFromClassHierarchyItemInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return static_cast(info->kind); +} +TS_INTEROP_1(getKindFromClassHierarchyItemInfo, KInt, KNativePointer) + +KNativePointer impl_getDescriptionFromClassHierarchyItemInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + auto description = info->description; + return new std::string(description); +} +TS_INTEROP_1(getDescriptionFromClassHierarchyItemInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getOverriddenFromClassHierarchyItemInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + auto &overridden = info->overridden; + std::vector overriddenPtrList; + overriddenPtrList.reserve(overridden.size()); + size_t idx = 0; + for (auto &details : overridden) { + overriddenPtrList[idx++] = new ark::es2panda::lsp::ClassRelationDetails(details); + } + return new std::vector(std::move(overriddenPtrList)); +} +TS_INTEROP_1(getOverriddenFromClassHierarchyItemInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getOverridingFromClassHierarchyItemInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + auto &overriding = info->overriding; + std::vector overridingPtrList; + overridingPtrList.reserve(overriding.size()); + size_t idx = 0; + for (auto &details : overriding) { + overridingPtrList[idx++] = new ark::es2panda::lsp::ClassRelationDetails(details); + } + return new std::vector(std::move(overridingPtrList)); +} +TS_INTEROP_1(getOverridingFromClassHierarchyItemInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getImplementedFromClassHierarchyItemInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + auto implemented = info->implemented; + std::vector implementedPtrList; + implementedPtrList.reserve(implemented.size()); + size_t idx = 0; + for (auto &details : implemented) { + implementedPtrList[idx++] = new ark::es2panda::lsp::ClassRelationDetails(details); + } + return new std::vector(std::move(implementedPtrList)); +} +TS_INTEROP_1(getImplementedFromClassHierarchyItemInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getImplementingFromClassHierarchyItemInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + auto implementing = info->implementing; + std::vector implementingPtrList; + implementingPtrList.reserve(implementing.size()); + size_t idx = 0; + for (auto &details : implementing) { + implementingPtrList[idx++] = new ark::es2panda::lsp::ClassRelationDetails(details); + } + return new std::vector(std::move(implementingPtrList)); +} +TS_INTEROP_1(getImplementingFromClassHierarchyItemInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getFileNameFromClassRelationDetails(KNativePointer detailsPtr) +{ + auto *details = reinterpret_cast(detailsPtr); + return new std::string(details->fileName); +} +TS_INTEROP_1(getFileNameFromClassRelationDetails, KNativePointer, KNativePointer) + +KInt impl_getPosFromClassRelationDetails(KNativePointer detailsPtr) +{ + auto *details = reinterpret_cast(detailsPtr); + return static_cast(details->pos); +} +TS_INTEROP_1(getPosFromClassRelationDetails, KInt, KNativePointer) + +KInt impl_getKindFromClassRelationDetails(KNativePointer detailsPtr) +{ + auto *details = reinterpret_cast(detailsPtr); + return static_cast(details->kind); +} +TS_INTEROP_1(getKindFromClassRelationDetails, KInt, KNativePointer) + KNativePointer impl_getSymbolDisplayPart(KNativePointer quickInfoPtr) { auto *quickInfo = reinterpret_cast(quickInfoPtr); @@ -431,6 +991,26 @@ KNativePointer impl_getTextSpan(KNativePointer quickInfoPtr) } TS_INTEROP_1(getTextSpan, KNativePointer, KNativePointer) +KNativePointer impl_createTextSpan(KInt start, KInt length) +{ + return new TextSpan(start, length); +} +TS_INTEROP_2(createTextSpan, KNativePointer, KInt, KInt) + +KNativePointer impl_getHighlightTextSpan(KNativePointer highlightPtr) +{ + auto *highlight = reinterpret_cast(highlightPtr); + return new TextSpan(highlight->textSpan_); +} +TS_INTEROP_1(getHighlightTextSpan, KNativePointer, KNativePointer) + +KNativePointer impl_getHighlightContextSpan(KNativePointer highlightPtr) +{ + auto *highlight = reinterpret_cast(highlightPtr); + return new TextSpan(highlight->contextSpan_); +} +TS_INTEROP_1(getHighlightContextSpan, KNativePointer, KNativePointer) + KNativePointer impl_getHighlightFileName(KNativePointer highlightPtr) { auto *highlight = reinterpret_cast(highlightPtr); @@ -607,6 +1187,14 @@ KNativePointer impl_getLocationFromList(KNativePointer listPtr) } TS_INTEROP_1(getLocationFromList, KNativePointer, KNativePointer) +KBoolean impl_getSafeDeleteInfo(KNativePointer context, KInt position, KStringPtr &path) +{ + LSPAPI const *ctx = GetImpl(); + return static_cast( + ctx->getSafeDeleteInfo(reinterpret_cast(context), position, GetStringCopy(path))); +} +TS_INTEROP_3(getSafeDeleteInfo, KBoolean, KNativePointer, KInt, KStringPtr) + KNativePointer impl_toLineColumnOffset(KNativePointer context, KInt position) { LSPAPI const *ctx = GetImpl(); @@ -628,4 +1216,291 @@ KInt impl_getChar(KNativePointer locPtr) auto *loc = reinterpret_cast(locPtr); return loc->GetCharacter(); } -TS_INTEROP_1(getChar, KInt, KNativePointer) \ No newline at end of file +TS_INTEROP_1(getChar, KInt, KNativePointer) + +KNativePointer impl_getTypeHierarchies(KNativePointer searchContext, KNativePointer context, KInt position) +{ + LSPAPI const *ctx = GetImpl(); + auto *info = new TypeHierarchiesInfo(ctx->getTypeHierarchies(reinterpret_cast(searchContext), + reinterpret_cast(context), + static_cast(position))); + return info; +} +TS_INTEROP_3(getTypeHierarchies, KNativePointer, KNativePointer, KNativePointer, KInt) + +KNativePointer impl_getFileNameFromTypeHierarchiesInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->fileName); +} +TS_INTEROP_1(getFileNameFromTypeHierarchiesInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getNameFromTypeHierarchiesInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->name); +} +TS_INTEROP_1(getNameFromTypeHierarchiesInfo, KNativePointer, KNativePointer) + +KInt impl_getTypeFromTypeHierarchiesInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return static_cast(info->type); +} +TS_INTEROP_1(getTypeFromTypeHierarchiesInfo, KInt, KNativePointer) + +KInt impl_getPositionFromTypeHierarchiesInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return static_cast(info->pos); +} +TS_INTEROP_1(getPositionFromTypeHierarchiesInfo, KInt, KNativePointer) + +KNativePointer impl_getSuperFromTypeHierarchiesInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new TypeHierarchies(info->superHierarchies); +} +TS_INTEROP_1(getSuperFromTypeHierarchiesInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getSubFromTypeHierarchiesInfo(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new TypeHierarchies(info->subHierarchies); +} +TS_INTEROP_1(getSubFromTypeHierarchiesInfo, KNativePointer, KNativePointer) + +KNativePointer impl_getFileNameFromTypeHierarchies(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->fileName); +} +TS_INTEROP_1(getFileNameFromTypeHierarchies, KNativePointer, KNativePointer) + +KNativePointer impl_getNameFromTypeHierarchies(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return new std::string(info->name); +} +TS_INTEROP_1(getNameFromTypeHierarchies, KNativePointer, KNativePointer) + +KInt impl_getPosFromTypeHierarchies(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return static_cast(info->pos); +} +TS_INTEROP_1(getPosFromTypeHierarchies, KInt, KNativePointer) + +KNativePointer impl_getSubOrSuper(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + std::vector ptrs; + for (auto &el : info->subOrSuper) { + ptrs.push_back(new TypeHierarchies(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSubOrSuper, KNativePointer, KNativePointer) + +KInt impl_getTypeFromTypeHierarchies(KNativePointer infoPtr) +{ + auto *info = reinterpret_cast(infoPtr); + return static_cast(info->type); +} +TS_INTEROP_1(getTypeFromTypeHierarchies, KInt, KNativePointer) + +KNativePointer impl_getSpanOfEnclosingComment(KNativePointer context, KInt position, KBoolean onlyMultiLine) +{ + LSPAPI const *ctx = GetImpl(); + auto *textSpan = new TextSpan( + ctx->getSpanOfEnclosingComment(reinterpret_cast(context), position, onlyMultiLine != 0)); + return textSpan; +} +TS_INTEROP_3(getSpanOfEnclosingComment, KNativePointer, KNativePointer, KInt, KBoolean) + +KNativePointer impl_getInlayHintText(KNativePointer hintPtr) +{ + auto *hint = reinterpret_cast(hintPtr); + return &hint->text; +} +TS_INTEROP_1(getInlayHintText, KNativePointer, KNativePointer) + +KInt impl_getInlayHintNumber(KNativePointer hintPtr) +{ + auto *hint = reinterpret_cast(hintPtr); + return hint->number; +} +TS_INTEROP_1(getInlayHintNumber, KInt, KNativePointer) + +KInt impl_getInlayHintKind(KNativePointer hintPtr) +{ + auto *hint = reinterpret_cast(hintPtr); + return static_cast(hint->kind); +} +TS_INTEROP_1(getInlayHintKind, KInt, KNativePointer) + +KBoolean impl_getInlayHintWhitespaceBefore(KNativePointer hintPtr) +{ + auto *hint = reinterpret_cast(hintPtr); + return hint->whitespaceBefore ? 1 : 0; +} +TS_INTEROP_1(getInlayHintWhitespaceBefore, KBoolean, KNativePointer) + +KBoolean impl_getInlayHintWhitespaceAfter(KNativePointer hintPtr) +{ + auto *hint = reinterpret_cast(hintPtr); + return hint->whitespaceAfter ? 1 : 0; +} +TS_INTEROP_1(getInlayHintWhitespaceAfter, KBoolean, KNativePointer) + +KNativePointer impl_getInlayHints(KNativePointer inlayHintListPtr) +{ + auto *inlayHintList = reinterpret_cast(inlayHintListPtr); + std::vector ptrs; + for (auto &el : inlayHintList->hints) { + ptrs.push_back(new InlayHint(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getInlayHints, KNativePointer, KNativePointer) + +KNativePointer impl_getInlayHintList(KNativePointer context, KNativePointer span) +{ + LSPAPI const *ctx = GetImpl(); + auto *inlayHints = new InlayHintList( + ctx->provideInlayHints(reinterpret_cast(context), reinterpret_cast(span))); + return inlayHints; +} +TS_INTEROP_2(getInlayHintList, KNativePointer, KNativePointer, KNativePointer) + +KNativePointer impl_getSignatureHelpParameterName(KNativePointer parameterPtr) +{ + auto *parameterRef = reinterpret_cast(parameterPtr); + return ¶meterRef->GetName(); +} +TS_INTEROP_1(getSignatureHelpParameterName, KNativePointer, KNativePointer) + +KNativePointer impl_getSignatureHelpParameterDocumentation(KNativePointer parameterPtr) +{ + auto *parameterRef = reinterpret_cast(parameterPtr); + std::vector ptrs; + for (auto &el : parameterRef->GetDocumentation()) { + ptrs.push_back(new SymbolDisplayPart(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSignatureHelpParameterDocumentation, KNativePointer, KNativePointer) + +KNativePointer impl_getSignatureHelpParameterDisplayParts(KNativePointer parameterPtr) +{ + auto *parameterRef = reinterpret_cast(parameterPtr); + std::vector ptrs; + for (auto &el : parameterRef->GetDisplayParts()) { + ptrs.push_back(new SymbolDisplayPart(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSignatureHelpParameterDisplayParts, KNativePointer, KNativePointer) + +KNativePointer impl_getSignatureHelpItemPrefix(KNativePointer itemPtr) +{ + auto *itemRef = reinterpret_cast(itemPtr); + std::vector ptrs; + for (auto &el : itemRef->GetPrefixDisplayParts()) { + ptrs.push_back(new SymbolDisplayPart(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSignatureHelpItemPrefix, KNativePointer, KNativePointer) + +KNativePointer impl_getSignatureHelpItemSuffix(KNativePointer itemPtr) +{ + auto *itemRef = reinterpret_cast(itemPtr); + std::vector ptrs; + for (auto &el : itemRef->GetSuffixDisplayParts()) { + ptrs.push_back(new SymbolDisplayPart(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSignatureHelpItemSuffix, KNativePointer, KNativePointer) + +KNativePointer impl_getSignatureHelpItemSeparator(KNativePointer itemPtr) +{ + auto *itemRef = reinterpret_cast(itemPtr); + std::vector ptrs; + for (auto &el : itemRef->GetSeparatorDisplayParts()) { + ptrs.push_back(new SymbolDisplayPart(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSignatureHelpItemSeparator, KNativePointer, KNativePointer) + +KNativePointer impl_getSignatureHelpItemParameter(KNativePointer itemPtr) +{ + auto *itemRef = reinterpret_cast(itemPtr); + std::vector ptrs; + for (auto &el : itemRef->GetParameters()) { + ptrs.push_back(new SignatureHelpParameter(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSignatureHelpItemParameter, KNativePointer, KNativePointer) + +KNativePointer impl_getSignatureHelpItemDocumentation(KNativePointer itemPtr) +{ + auto *itemRef = reinterpret_cast(itemPtr); + std::vector ptrs; + for (auto &el : itemRef->GetDocumentation()) { + ptrs.push_back(new SymbolDisplayPart(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSignatureHelpItemDocumentation, KNativePointer, KNativePointer) + +KNativePointer impl_getSignatureHelpItem(KNativePointer itemsPtr) +{ + auto *itemsRef = reinterpret_cast(itemsPtr); + std::vector ptrs; + for (auto &el : itemsRef->GetItems()) { + ptrs.push_back(new SignatureHelpItem(el)); + } + return new std::vector(ptrs); +} +TS_INTEROP_1(getSignatureHelpItem, KNativePointer, KNativePointer) + +KNativePointer impl_getApplicableSpan(KNativePointer itemsPtr) +{ + auto *itemsRef = reinterpret_cast(itemsPtr); + return new TextSpan(itemsRef->GetApplicableSpan()); +} +TS_INTEROP_1(getApplicableSpan, KNativePointer, KNativePointer) + +KInt impl_getSelectedItemIndex(KNativePointer itemsPtr) +{ + auto *itemsRef = reinterpret_cast(itemsPtr); + return itemsRef->GetSelectedItemIndex(); +} +TS_INTEROP_1(getSelectedItemIndex, KInt, KNativePointer) + +KInt impl_getArgumentIndex(KNativePointer itemsPtr) +{ + auto *itemsRef = reinterpret_cast(itemsPtr); + return itemsRef->GetArgumentIndex(); +} +TS_INTEROP_1(getArgumentIndex, KInt, KNativePointer) + +KInt impl_getArgumentCount(KNativePointer itemsPtr) +{ + auto *itemsRef = reinterpret_cast(itemsPtr); + return itemsRef->GetArgumentCount(); +} +TS_INTEROP_1(getArgumentCount, KInt, KNativePointer) + +KNativePointer impl_getSignatureHelpItems(KNativePointer context, KInt position) +{ + LSPAPI const *ctx = GetImpl(); + auto *textSpan = + new SignatureHelpItems(ctx->getSignatureHelpItems(reinterpret_cast(context), position)); + return textSpan; +} +TS_INTEROP_2(getSignatureHelpItems, KNativePointer, KNativePointer, KInt) \ No newline at end of file diff --git a/ets2panda/bindings/native/src/win-dynamic-node.cpp b/ets2panda/bindings/native/src/win-dynamic-node.cpp index 5a7a68fc8b36e5cec6c4cc96fc54eaadcbc94d05..85bb3cb4da61e7cde2ee782aefb8d404b7c9bb18 100644 --- a/ets2panda/bindings/native/src/win-dynamic-node.cpp +++ b/ets2panda/bindings/native/src/win-dynamic-node.cpp @@ -66,8 +66,9 @@ bool LoadNapiFunctions() FARPROC fn_addr = GetProcAddress(nodeModule, "napi_module_register"); if (fn_addr == NULL) { nodeModule = GetModuleHandleA("node.dll"); - if (nodeModule == NULL) + if (nodeModule == NULL) { return false; + } fn_addr = GetProcAddress(nodeModule, "napi_module_register"); if (fn_addr == NULL) { return false; @@ -87,8 +88,9 @@ bool LoadNapiFunctions() NAPI_FUNCTIONS(GET_NAPI_IMPL); // If any required APIs failed to load, return false - if (apiLoadFailed) + if (apiLoadFailed) { return false; + } isLoaded = true; diff --git a/ets2panda/bindings/package.json b/ets2panda/bindings/package.json index bd5a42e3f2fe9b8716637eea7aad01caaebf0a29..92d680af8d08a135101997e4752810d95b16fca5 100644 --- a/ets2panda/bindings/package.json +++ b/ets2panda/bindings/package.json @@ -5,16 +5,21 @@ "devDependencies": { "@tsconfig/recommended": "^1.0.2", "@types/node": "^18.0.0", + "prettier": "latest", "rimraf": "^6.0.1", "typescript": "4.9.5", "node-api-headers": "^1.4.0" }, "main": "dist/index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test:clean": "rimraf dist-test", + "test:compile": "tsc --build --verbose test/tsconfig.json", + "test:build": "npm run test:clean && npm run test:compile", + "test": "npm run test:build && node dist-test/test/run_tests.js ./test", "compile": "tsc --build --verbose tsconfig.json", "clean": "rimraf dist tsconfig.tsbuildinfo package-lock.json", - "run": "npm run clean && npm run compile" + "run": "npm run clean && npm run compile", + "format": "npx prettier --write ." }, "author": "", "license": "ISC", diff --git a/ets2panda/bindings/src/Es2pandaNativeModule.ts b/ets2panda/bindings/src/Es2pandaNativeModule.ts index 0d6448da9c79a76759ffa9839df448402a2e5ec9..210ad83e1cdbc4ee92919e027e49b61c61c67017 100644 --- a/ets2panda/bindings/src/Es2pandaNativeModule.ts +++ b/ets2panda/bindings/src/Es2pandaNativeModule.ts @@ -13,432 +13,863 @@ */ import * as fs from 'fs'; -import * as path from 'path' -import { KNativePointer as KPtr, KInt, KBoolean, KNativePointer, KDouble, KUInt } from "./InteropTypes" -import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from "./generated/Es2pandaNativeModule" -import { loadNativeModuleLibrary, registerNativeModuleLibraryName } from "./loadLibraries" -import { throwError } from "./utils" +import * as path from 'path'; +import { KNativePointer as KPtr, KInt, KBoolean, KNativePointer, KDouble, KUInt, KStringPtr } from './InteropTypes'; +import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from './generated/Es2pandaNativeModule'; +import { loadNativeModuleLibrary, registerNativeModuleLibraryName } from './loadLibraries'; +import { throwError } from './utils'; -export type KPtrArray = BigUint64Array +export type KPtrArray = BigUint64Array; export class Es2pandaNativeModule { _ClassDefinitionSuper(context: KPtr, node: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } - _CreateTSInterfaceDeclaration(_context: KPtr, _extends: KPtrArray, _extendsLen: KInt, _id: KPtr, _typeParams: KPtr, _body: KPtr, _isStatic: KBoolean, _isExternal: KBoolean): KPtr { - throw new Error("Not implemented") + _CreateTSInterfaceDeclaration( + _context: KPtr, + _extends: KPtrArray, + _extendsLen: KInt, + _id: KPtr, + _typeParams: KPtr, + _body: KPtr, + _isStatic: KBoolean, + _isExternal: KBoolean + ): KPtr { + throw new Error('Not implemented'); } _ContextState(context: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _ContextErrorMessage(context: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _AstNodeDumpModifiers(context: KPtr, node: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _CreateAstDumper(context: KPtr, node: KPtr, source: String): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } - _CreateConfig(argc: number, argv: string[] | Uint8Array): KPtr { - throw new Error("Not implemented") + _CreateConfig(argc: number, argv: string[] | Uint8Array, pandaLibPath: KStringPtr): KPtr { + throw new Error('Not implemented'); } _DestroyConfig(config: KPtr): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _CreateContextFromString(config: KPtr, source: String, filename: String): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } - _GenerateTsDeclarationsFromContext(config: KPtr, outputDeclEts: String, outputEts: String, exportAll: KBoolean): KPtr { - throw new Error("Not implemented") + _GenerateTsDeclarationsFromContext( + config: KPtr, + outputDeclEts: String, + outputEts: String, + exportAll: KBoolean + ): KPtr { + throw new Error('Not implemented'); } _CreateContextFromFile(config: KPtr, filename: String): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _DestroyContext(context: KPtr): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _ProceedToState(context: KPtr, state: number): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _ContextProgram(context: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _ProgramAst(program: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _CheckerStartChecker(context: KPtr): KBoolean { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _IsProgram(context: KPtr, node: KPtr): KBoolean { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _AstNodeDumpJsonConst(context: KPtr, node: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _AstNodeDumpEtsSrcConst(context: KPtr, node: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _AstNodeUpdateChildren(context: KPtr, node: KPtr): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _AstNodeUpdateAll(context: KPtr, node: KPtr): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _AstNodeSetOriginalNode(context: KPtr, ast: KPtr, originalNode: KPtr): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _AstNodeOriginalNodeConst(context: KPtr, ast: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _VarBinderSetProgram(context: KPtr): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _VarBinderSetContext(context: KPtr): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getCurrentTokenValue(context: KNativePointer, position: KInt): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getSemanticDiagnostics(context: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getSyntacticDiagnostics(context: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiags(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiagMsg(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiagSource(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDefinitionAtPosition(context: KNativePointer, position: KInt): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); + } + + _getTypeHierarchies(searchContext: KNativePointer, context: KNativePointer, position: KInt): KPtr { + throw new Error('Not implemented'); + } + + _getFileNameFromTypeHierarchiesInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getNameFromTypeHierarchiesInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getTypeFromTypeHierarchiesInfo(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getPositionFromTypeHierarchiesInfo(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getSuperFromTypeHierarchiesInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getSubFromTypeHierarchiesInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getFileNameFromTypeHierarchies(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getNameFromTypeHierarchies(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getTypeFromTypeHierarchies(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getPosFromTypeHierarchies(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getSubOrSuper(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getClassHierarchyInfo(context: KNativePointer, position: KInt): KPtr { + throw new Error('Not implemented'); + } + + _castToClassHierarchyInfos(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getClassNameFromClassHierarchyInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getMethodListFromClassHierarchyInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getDetailFromClassMethodItem(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getSetterStyleFromClassMethodItem(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getAccessModifierStyleFromClassMethodItem(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getAliasScriptElementKind(ptr: KNativePointer, position: KInt): KInt { + throw new Error('Not implemented'); + } + + _getClassPropertyInfo(context: KNativePointer, position: KInt, shouldCollectInherited: boolean): KPtr { + throw new Error('Not implemented'); + } + + _getFieldsInfoFromPropertyInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getNameFromPropertyInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getFieldListPropertyFromPropertyInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getModifierKindsFromPropertyInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getDisplayNameFromPropertyInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getStartFromPropertyInfo(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getEndFromPropertyInfo(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getKindFromPropertyInfo(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _organizeImports(context: KNativePointer, filename: String): KPtr { + throw new Error('Not implemented'); + } + + _getFileTextChanges(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getTextChangesFromFileTextChanges(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getFileNameFromFileTextChanges(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getTextSpanFromTextChange(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getNewTextFromTextChange(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _findSafeDeleteLocation(context: KNativePointer, declInfo: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getSafeDeleteLocations(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getSafeDeleteLocationUri(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getSafeDeleteLocationStart(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getSafeDeleteLocationLength(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getCompletionEntryDetails(entryName: String, filename: String, context: KNativePointer, position: KInt): KPtr { + throw new Error('Not implemented'); + } + + _getCompletionEntryDetailsEntryName(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getCompletionEntryDetailsKind(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getCompletionEntryDetailsKindModifier(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getCompletionEntryDetailsFileName(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getCompletionEntryDetailsSymbolDisplayPart(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getRefactorActionName(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getRefactorActionDescription(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getRefactorActionKind(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getRefactorAction(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getApplicableRefactors(context: KNativePointer, kind: String, position: number): KPtr { + throw new Error('Not implemented'); + } + + _getApplicableRefactorName(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getApplicableRefactorDescription(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getClassConstructorInfo(context: KNativePointer, position: number, strArryPtr: string[] | Uint8Array): KPtr { + throw new Error('Not implemented'); + } + + _getFileTextChangesFromConstructorInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getFileNameFromConstructorInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getTextChangeFromConstructorInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getNewTextFromConstructorInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getTextSpanFromConstructorInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getClassHierarchies(context: KNativePointer, fileName: String, position: number): KPtr { + throw new Error('Not implemented'); + } + + _getClassHierarchyList(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getPosFromClassHierarchyItemInfo(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getKindFromClassHierarchyItemInfo(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getDescriptionFromClassHierarchyItemInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getOverriddenFromClassHierarchyItemInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getOverridingFromClassHierarchyItemInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getImplementedFromClassHierarchyItemInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getImplementingFromClassHierarchyItemInfo(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getFileNameFromClassRelationDetails(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getPosFromClassRelationDetails(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); + } + + _getKindFromClassRelationDetails(ptr: KNativePointer): KInt { + throw new Error('Not implemented'); } _getFileNameFromDef(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getStartFromDef(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getLengthFromDef(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiagRange(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getRangeEnd(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getRangeStart(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getPosLine(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getPosChar(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiagSeverity(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiagCode(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiagCodeDescription(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getCodeDescriptionHref(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiagTags(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiagData(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDiagRelatedInfo(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getRelatedInfoMsg(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getRelatedInfoLoc(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getLocUri(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getLocRange(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getImplementationAtPosition(context: KNativePointer, position: KInt): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getReferenceStart(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getReferenceLength(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getReferenceFileName(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getReferencesFromRefs(ptr: KNativePointer): KPtr[] { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getReferenceInfos(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDeclInfo(context: KNativePointer, position: KInt): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDeclInfoFileText(declInfo: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDeclInfoFileName(declInfo: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getReferencesAtPosition(context: KNativePointer, declInfo: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _isPackageModule(context: KNativePointer): boolean { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getFileReferences(filename: String, context: KNativePointer, isPackageModule: boolean): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } - _getSpanOfEnclosingComment(filename: String, position: KInt): KPtr { - throw new Error("Not implemented") + _getSpanOfEnclosingComment(context: KNativePointer, position: KInt, onlyMultiLine: boolean): KPtr { + throw new Error('Not implemented'); } _getSuggestionDiagnostics(context: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getQuickInfoAtPosition(filename: String, context: KNativePointer, position: KInt): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDisplayPartsText(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDisplayPartsKind(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getQuickInfoKind(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getQuickInfoKindModifier(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getQuickInfoFileName(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getSymbolDisplayPart(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getTextSpanStart(ptr: KNativePointer): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getTextSpanLength(ptr: KNativePointer): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getTextSpan(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); + } + + _getHighlightTextSpan(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); + } + + _getHighlightContextSpan(ptr: KNativePointer): KPtr { + throw new Error('Not implemented'); } _getHighlightFileName(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getHighlightIsInString(ptr: KNativePointer): boolean { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getHighlightKind(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getHighlightSpanFromHighlights(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDocumentHighlightsFromRef(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDocumentHighlights(context: KNativePointer, position: KInt): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getCompletionAtPosition(context: KNativePointer, position: KInt): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getFileNameFromEntryData(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getNamedExportFromEntryData(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getImportDeclarationFromEntryData(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getStatusFromEntryData(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getNameFromEntry(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getSortTextFromEntry(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getInsertTextFromEntry(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getKindFromEntry(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getDataFromEntry(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getEntriesFromCompletionInfo(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getUriFromLocation(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getStartFromLocation(ptr: KNativePointer): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getEndFromLocation(ptr: KNativePointer): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getIsDefinitionFromLocation(ptr: KNativePointer): boolean { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getIsImportFromLocation(ptr: KNativePointer): boolean { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getAccessKindFromLocation(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getLocationFromList(ptr: KNativePointer): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getLine(ptr: KNativePointer): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getChar(ptr: KNativePointer): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _toLineColumnOffset(context: KNativePointer, position: KInt): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); + } + + _getSafeDeleteInfo(context: KNativePointer, position: KInt, path: String): boolean { + throw new Error('Not implemented'); + } + + _getInlayHintText(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getInlayHintNumber(ptr: KPtr): KInt { + throw new Error('Not implemented'); + } + + _getInlayHintKind(ptr: KPtr): KInt { + throw new Error('Not implemented'); } + + _getInlayHintWhitespaceBefore(ptr: KPtr): KBoolean { + throw new Error('Not implemented'); + } + + _getInlayHintWhitespaceAfter(ptr: KPtr): KBoolean { + throw new Error('Not implemented'); + } + + _getInlayHintList(context: KPtr, span: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getInlayHints(context: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _createTextSpan(start: KInt, length: KInt): KPtr { + throw new Error('Not implemented'); + } + + _getSignatureHelpParameterDocumentation(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getSignatureHelpParameterDisplayParts(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getSignatureHelpParameterName(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getSignatureHelpItemPrefix(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getSignatureHelpItemSuffix(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getSignatureHelpItemSeparator(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getSignatureHelpItemParameter(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getSignatureHelpItemDocumentation(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getSignatureHelpItem(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getApplicableSpan(ptr: KPtr): KPtr { + throw new Error('Not implemented'); + } + + _getSelectedItemIndex(ptr: KPtr): KInt { + throw new Error('Not implemented'); + } + + _getArgumentIndex(ptr: KPtr): KInt { + throw new Error('Not implemented'); + } + + _getArgumentCount(ptr: KPtr): KInt { + throw new Error('Not implemented'); + } + + _getSignatureHelpItems(context: KPtr, position: KInt): KPtr { + throw new Error('Not implemented'); + } + } export function initEs2panda(): Es2pandaNativeModule { - let libPath = process.env.BINDINGS_PATH - if (libPath == undefined) { - libPath = path.resolve(__dirname, "../ts_bindings.node") + let libPath = process.env.BINDINGS_PATH; + if (libPath === undefined) { + libPath = path.resolve(__dirname, '../ts_bindings.node'); } else { - libPath = path.join(libPath, "ts_bindings.node") + libPath = path.join(libPath, 'ts_bindings.node'); } if (!fs.existsSync(libPath)) { - throwError(`Cannot find lib path ${libPath}`) + throwError(`Cannot find lib path ${libPath}`); } - registerNativeModuleLibraryName("NativeModule", libPath) - const instance = new Es2pandaNativeModule() - loadNativeModuleLibrary("NativeModule", instance) - return instance + registerNativeModuleLibraryName('NativeModule', libPath); + const instance = new Es2pandaNativeModule(); + loadNativeModuleLibrary('NativeModule', instance); + return instance; } export function initGeneratedEs2panda(): GeneratedEs2pandaNativeModule { - let libPath = process.env.BINDINGS_PATH - if (libPath == undefined) { - libPath = path.resolve(__dirname, "../ts_bindings.node") + let libPath = process.env.BINDINGS_PATH; + if (libPath === undefined) { + libPath = path.resolve(__dirname, '../ts_bindings.node'); + } else { + libPath = path.join(libPath, 'ts_bindings.node'); + } + if (!fs.existsSync(libPath)) { + throwError(`Cannot find lib path ${libPath}`); + } + registerNativeModuleLibraryName('NativeModule', libPath); + const instance = new GeneratedEs2pandaNativeModule(); + loadNativeModuleLibrary('NativeModule', instance); + return instance; +} + +export function initPublicEs2panda(): Es2pandaNativeModule { + let libPath = process.env.BINDINGS_PATH; + if (libPath === undefined) { + libPath = path.resolve(__dirname, '../public.node'); + } else { + libPath = path.join(libPath, 'public.node'); + } + if (!fs.existsSync(libPath)) { + throwError(`Cannot find lib path ${libPath}`); + } + registerNativeModuleLibraryName('NativeModule', libPath); + const instance = new Es2pandaNativeModule(); + loadNativeModuleLibrary('NativeModule', instance); + return instance; +} + +export function initPublicGeneratedEs2panda(): GeneratedEs2pandaNativeModule { + let libPath = process.env.BINDINGS_PATH; + if (libPath === undefined) { + libPath = path.resolve(__dirname, '../public.node'); } else { - libPath = path.join(libPath, "ts_bindings.node") + libPath = path.join(libPath, 'public.node'); } if (!fs.existsSync(libPath)) { - throwError(`Cannot find lib path ${libPath}`) + throwError(`Cannot find lib path ${libPath}`); } - registerNativeModuleLibraryName("NativeModule", libPath) - const instance = new GeneratedEs2pandaNativeModule() - loadNativeModuleLibrary("NativeModule", instance) - return instance + registerNativeModuleLibraryName('NativeModule', libPath); + const instance = new GeneratedEs2pandaNativeModule(); + loadNativeModuleLibrary('NativeModule', instance); + return instance; } diff --git a/ets2panda/bindings/src/InteropNativeModule.ts b/ets2panda/bindings/src/InteropNativeModule.ts index 58281df340ba4e3e65d1bf539a0a02faed581bbb..35eac9b80641b233c9e1c5e4add9fb2f7d995224 100644 --- a/ets2panda/bindings/src/InteropNativeModule.ts +++ b/ets2panda/bindings/src/InteropNativeModule.ts @@ -14,62 +14,77 @@ */ import * as fs from 'fs'; -import * as path from 'path' -import { KNativePointer as KPtr, KInt, KUInt } from "./InteropTypes" -import { loadNativeModuleLibrary, registerNativeModuleLibraryName } from "./loadLibraries" -import { throwError } from "./utils" +import * as path from 'path'; +import { KNativePointer as KPtr, KInt, KUInt } from './InteropTypes'; +import { loadNativeModuleLibrary, registerNativeModuleLibraryName } from './loadLibraries'; +import { throwError } from './utils'; export class InteropNativeModule { - _StringLength(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _StringData(ptr: KPtr, buffer: KPtr, length: KInt): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _GetStringFinalizer(): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _InvokeFinalizer(ptr: KPtr, finalizer: KPtr): void { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _GetPtrVectorSize(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _GetPtrVectorElement(ptr: KPtr, index: KInt): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getTypeOfVariant(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getIntFromVariant(ptr: KPtr): KInt { - throw new Error("Not implemented") + throw new Error('Not implemented'); } _getStringFromVariant(ptr: KPtr): KPtr { - throw new Error("Not implemented") + throw new Error('Not implemented'); } } export function initInterop(): InteropNativeModule { - let libPath = process.env.BINDINGS_PATH - if (libPath == undefined) { - libPath = path.resolve(__dirname, "../ts_bindings.node") + let libPath = process.env.BINDINGS_PATH; + if (libPath === undefined) { + libPath = path.resolve(__dirname, '../ts_bindings.node'); + } else { + libPath = path.join(libPath, 'ts_bindings.node'); + } + if (!fs.existsSync(libPath)) { + throwError(`Cannot find lib path ${libPath}`); + } + registerNativeModuleLibraryName('InteropNativeModule', libPath); + const instance = new InteropNativeModule(); + loadNativeModuleLibrary('InteropNativeModule', instance); + return instance; +} + +export function initPublicInterop(): InteropNativeModule { + let libPath = process.env.BINDINGS_PATH; + if (libPath === undefined) { + libPath = path.resolve(__dirname, '../public.node'); } else { - libPath = path.join(libPath, "ts_bindings.node") + libPath = path.join(libPath, 'public.node'); } if (!fs.existsSync(libPath)) { - throwError(`Cannot find lib path ${libPath}`) + throwError(`Cannot find lib path ${libPath}`); } - registerNativeModuleLibraryName("InteropNativeModule", libPath) - const instance = new InteropNativeModule() - loadNativeModuleLibrary("InteropNativeModule", instance) - return instance + registerNativeModuleLibraryName('InteropNativeModule', libPath); + const instance = new InteropNativeModule(); + loadNativeModuleLibrary('InteropNativeModule', instance); + return instance; } diff --git a/ets2panda/bindings/src/InteropTypes.ts b/ets2panda/bindings/src/InteropTypes.ts index 3e6d51a5a7244f3e0832c79af7e90c9262eb2a69..4a3a3d86788678d33dc1bd0583b3e9c6da5ba6b1 100644 --- a/ets2panda/bindings/src/InteropTypes.ts +++ b/ets2panda/bindings/src/InteropTypes.ts @@ -13,26 +13,26 @@ * limitations under the License. */ -export const nullptr: int | bigint = BigInt(0) -export type int = number -export type int32 = int -export type int64 = int -export type float = number -export type float32 = float -export type float64 = float +export const nullptr: int | bigint = BigInt(0); +export type int = number; +export type int32 = int; +export type int64 = int; +export type float = number; +export type float32 = float; +export type float64 = float; -export type KStringPtr = int32 | string | null -export type KStringArrayPtr = int32 | Uint8Array | null -export type KInt32ArrayPtr = int32 | Int32Array | null -export type KFloat32ArrayPtr = int32 | Float32Array | null -export type KUint8ArrayPtr = int32 | Uint8Array | null -export type KInt = int32 -export type KUInt = int32 -export type KLong = int64 -export type KFloat = float32 -export type KDouble = float64 -export type KBoolean = int32 -export type KPointer = Uint8Array | number | bigint -export type pointer = KPointer -export type KNativePointer = KPointer -export type KNativePointerArray = BigUint64Array +export type KStringPtr = int32 | string | null; +export type KStringArrayPtr = int32 | Uint8Array | null; +export type KInt32ArrayPtr = int32 | Int32Array | null; +export type KFloat32ArrayPtr = int32 | Float32Array | null; +export type KUint8ArrayPtr = int32 | Uint8Array | null; +export type KInt = int32; +export type KUInt = int32; +export type KLong = int64; +export type KFloat = float32; +export type KDouble = float64; +export type KBoolean = int32; +export type KPointer = Uint8Array | number | bigint; +export type pointer = KPointer; +export type KNativePointer = KPointer; +export type KNativePointerArray = BigUint64Array; diff --git a/ets2panda/bindings/src/Platform.ts b/ets2panda/bindings/src/Platform.ts index 805e92003cb0f1fa35455ac10e30052480c58b18..b0e3fa192f9d9515a5f3a2f7b97cb7a24f5c1298 100644 --- a/ets2panda/bindings/src/Platform.ts +++ b/ets2panda/bindings/src/Platform.ts @@ -13,50 +13,50 @@ * limitations under the License. */ -import { isNullPtr } from "./Wrapper" -import { decodeToString } from "./arrays" -import { Wrapper } from "./mainWrapper" -import { global } from "./global" -import { int32, KPointer, nullptr } from "./InteropTypes" +import { isNullPtr } from './Wrapper'; +import { decodeToString } from './arrays'; +import { Wrapper } from './mainWrapper'; +import { global } from './global'; +import { int32, KInt, KPointer, nullptr } from './InteropTypes'; export abstract class NativeStringBase extends Wrapper { constructor(ptr: KPointer) { - super(ptr) + super(ptr); } - protected abstract bytesLength(): int32 - protected abstract getData(data: Uint8Array): void + protected abstract bytesLength(): int32; + protected abstract getData(data: Uint8Array): void; toString(): string { - let length = this.bytesLength() - let data = new Uint8Array(length) - this.getData(data) - return decodeToString(data) + let length = this.bytesLength(); + let data = new Uint8Array(length); + this.getData(data); + return decodeToString(data); } - abstract close(): void + abstract close(): void; } export abstract class ArrayDecoder { - abstract getArraySize(blob: KPointer): int32 - abstract disposeArray(blob: KPointer): void - abstract getArrayElement(blob: KPointer, index: int32): T + abstract getArraySize(blob: KPointer): int32; + abstract disposeArray(blob: KPointer): void; + abstract getArrayElement(blob: KPointer, index: int32): T; decode(blob: KPointer): Array { - const size = this.getArraySize(blob) - const result = new Array(size) + const size = this.getArraySize(blob); + const result = new Array(size); for (let index = 0; index < size; index++) { - result[index] = this.getArrayElement(blob, index) + result[index] = this.getArrayElement(blob, index); } - this.disposeArray(blob) - return result + this.disposeArray(blob); + return result; } } - // TODO: the semicolons after methods in these interfaces are to // workaround ArkTS compiler parser bug export interface CallbackRegistry { + // CC-OFFNXT(no_explicit_any) project code style registerCallback(callback: any, obj: any): KPointer; } @@ -67,37 +67,39 @@ export interface PlatformDefinedData { } export function withStringResult(ptr: KPointer): string | undefined { - if (isNullPtr(ptr)) return undefined - let managedString = new NativeString(ptr) - let result = managedString?.toString() - managedString?.close() - return result + if (isNullPtr(ptr)) { + return undefined; + } + let managedString = new NativeString(ptr); + let result = managedString?.toString(); + managedString?.close(); + return result; } export class NativeString extends NativeStringBase { constructor(ptr: KPointer) { - super(ptr) + super(ptr); } protected bytesLength(): int32 { - return global.interop._StringLength(this.ptr) + return global.interop._StringLength(this.ptr); } protected getData(data: Uint8Array): void { - global.interop._StringData(this.ptr, data, data.length) + global.interop._StringData(this.ptr, data, data.length); } close(): void { - global.interop._InvokeFinalizer(this.ptr, global.interop._GetStringFinalizer()) - this.ptr = nullptr + global.interop._InvokeFinalizer(this.ptr, global.interop._GetStringFinalizer()); + this.ptr = nullptr; } } export class NativePtrDecoder extends ArrayDecoder { - getArraySize(blob: KPointer) { - return global.interop._GetPtrVectorSize(blob) + getArraySize(blob: KPointer): KInt { + return global.interop._GetPtrVectorSize(blob); } disposeArray(blob: KPointer): void { // TODO } getArrayElement(blob: KPointer, index: int32): KPointer { - return global.interop._GetPtrVectorElement(blob, index) + return global.interop._GetPtrVectorElement(blob, index); } } diff --git a/ets2panda/bindings/src/Wrapper.ts b/ets2panda/bindings/src/Wrapper.ts index b5d04420b5d69ed22be6baf589b22e55c0e8030c..26d9ac15f6c0e792294873b7ab0bfe27da4b9add 100644 --- a/ets2panda/bindings/src/Wrapper.ts +++ b/ets2panda/bindings/src/Wrapper.ts @@ -13,30 +13,30 @@ * limitations under the License. */ -import { int32, KPointer, nullptr } from "./InteropTypes" +import { int32, KPointer, nullptr } from './InteropTypes'; export function isNullPtr(value: KPointer): boolean { - return value === nullptr + return value === nullptr; } -export function ptrToString(ptr: KPointer) { - return `0x${ptr!.toString(16).padStart(8, "0")}` +export function ptrToString(ptr: KPointer): string { + return `0x${ptr!.toString(16).padStart(8, '0')}`; } -export function isSamePtr(a: KPointer, b: KPointer) { - return (a === b) +export function isSamePtr(a: KPointer, b: KPointer): boolean { + return a === b; } export function ptrToBits(ptr: KPointer): Uint32Array | null { - let result = new Uint32Array(2) - let ptrBigInt = ptr as bigint - result[0] = Number(ptrBigInt & BigInt(0xFFFFFFFF)) - result[1] = Number((ptrBigInt >> BigInt(32)) & BigInt(0xFFFFFFFF)) - return result + let result = new Uint32Array(2); + let ptrBigInt = ptr as bigint; + result[0] = Number(ptrBigInt & BigInt(0xffffffff)); + result[1] = Number((ptrBigInt >> BigInt(32)) & BigInt(0xffffffff)); + return result; } export function bitsToPtr(array: Int32Array, offset: int32): KPointer { - let ptrBigInt: bigint = BigInt(array[offset + 1]) & BigInt(0xFFFFFFFF) - ptrBigInt = (ptrBigInt << BigInt(32)) | (BigInt(array[offset]) & BigInt(0xFFFFFFFF)) - return ptrBigInt + let ptrBigInt: bigint = BigInt(array[offset + 1]) & BigInt(0xffffffff); + ptrBigInt = (ptrBigInt << BigInt(32)) | (BigInt(array[offset]) & BigInt(0xffffffff)); + return ptrBigInt; } diff --git a/ets2panda/bindings/src/arktsConfigGenerate.ts b/ets2panda/bindings/src/arktsConfigGenerate.ts index 2886f41c8b219877f4e7a222d6317f7e0080eb33..56f00052edfbf3e3b8fa7090facefb977730077b 100644 --- a/ets2panda/bindings/src/arktsConfigGenerate.ts +++ b/ets2panda/bindings/src/arktsConfigGenerate.ts @@ -16,9 +16,7 @@ import { BuildMode } from './build/buildMode'; import { BuildConfig } from './types'; import { ModuleDescriptor, generateBuildConfigs } from './buildConfigGenerate'; -import { - PANDA_SDK_PATH_FROM_SDK -} from './preDefine'; +import { PANDA_SDK_PATH_FROM_SDK } from './preDefine'; import * as fs from 'fs'; import * as path from 'path'; @@ -32,14 +30,16 @@ function processBuildConfig(projectConfig: BuildConfig): BuildConfig { return buildConfig; } -export function generateArkTsConfigByModules(buildSdkPath: string, projectRoot: string, modules?: ModuleDescriptor[]) { +export function generateArkTsConfigByModules( + buildSdkPath: string, + projectRoot: string, + modules?: ModuleDescriptor[] +): void { const allBuildConfig = generateBuildConfigs(buildSdkPath, projectRoot, modules); let compileFileInfos: Record = {}; - const compileFileInfosPath = path.join( - path.join(projectRoot, '.idea', '.deveco'), - 'lsp_compileFileInfos.json' - ) - Object.keys(allBuildConfig).forEach(moduleName => { + const cacheDir = path.join(projectRoot, '.idea', '.deveco'); + const compileFileInfosPath = path.join(cacheDir, 'lsp_compileFileInfos.json'); + Object.keys(allBuildConfig).forEach((moduleName) => { const moduleConfig = allBuildConfig[moduleName] as BuildConfig; const processedConfig = processBuildConfig(moduleConfig); @@ -48,6 +48,9 @@ export function generateArkTsConfigByModules(buildSdkPath: string, projectRoot: }); try { const jsonCompileFileInfos = JSON.stringify(compileFileInfos, null, 2); + if (!fs.existsSync(cacheDir)) { + fs.mkdirSync(cacheDir, { recursive: true }); + } fs.writeFileSync(compileFileInfosPath, jsonCompileFileInfos, 'utf-8'); } catch (err) { console.error(`Failed to write compileFileInfos to ${compileFileInfosPath} with error: ${err}`); diff --git a/ets2panda/bindings/src/arrays.ts b/ets2panda/bindings/src/arrays.ts index 9f2ca7629d65b324514996c97779652d40c9c1fb..d0fe7499458c408d5b0467407f3d97bfc65007ab 100644 --- a/ets2panda/bindings/src/arrays.ts +++ b/ets2panda/bindings/src/arrays.ts @@ -13,126 +13,159 @@ * limitations under the License. */ -import { KPointer, int32 } from "./InteropTypes" -import { Wrapper } from "./mainWrapper" -import { CustomTextDecoder, CustomTextEncoder } from "./strings" -import { throwError } from "./utils" +import { KPointer, int32 } from './InteropTypes'; +import { Wrapper } from './mainWrapper'; +import { CustomTextDecoder, CustomTextEncoder } from './strings'; +import { throwError } from './utils'; -const encoder = new CustomTextEncoder() -const decoder = new CustomTextDecoder() +const encoder = new CustomTextEncoder(); +const decoder = new CustomTextDecoder(); export function decodeToString(array: Uint8Array): string { - return decoder.decode(array) + return decoder.decode(array); } export function encodeToData(string: string): Uint8Array { - return encoder.encode(string, false) + return encoder.encode(string, false); } export function withString(data: string, exec: Exec): R { - return exec(data) + return exec(data); } export function withStringArray(strings: Array | undefined): Uint8Array { if (strings === undefined || strings.length === 0) { - throwError('Error in strings array') + throwError('Error in strings array'); } - let array = encoder.encodeArray(strings) - return array + let array = encoder.encodeArray(strings); + return array; } -function withArray( - data: C | undefined, - exec: ExecWithLength -): R { - return exec(data ?? null, data?.length ?? 0) +function withArray(data: C | undefined, exec: ExecWithLength): R { + return exec(data ?? null, data?.length ?? 0); } -export function withPtrArray(data: BigUint64Array, access: Access, exec: ExecWithLength) { - return exec(data ?? null, data?.length ?? 0) // TODO rethink +export function withPtrArray( + data: BigUint64Array, + access: Access, + exec: ExecWithLength +): R { + return exec(data ?? null, data?.length ?? 0); // TODO rethink } export function toPtrArray(data: Array | undefined): BigUint64Array { - if (data == undefined || data.length === 0) { - return new BigUint64Array(0) - } - const array = new BigUint64Array(data.length) - for (let i = 0; i < data.length; i++) { - let item = data[i] - array[i] = item != undefined ? item.ptr as bigint : nullptr - } - return array + if (data === undefined || data.length === 0) { + return new BigUint64Array(0); + } + const array = new BigUint64Array(data.length); + for (let i = 0; i < data.length; i++) { + let item = data[i]; + array[i] = item !== undefined ? (item.ptr as bigint) : nullptr; + } + return array; } -export function fromPtrArray(array: PtrArray, factory: (ptr: KPointer) => T) : Array { - if (array.length === 0) { - return new Array(0) - } - const result = new Array(array.length) - for (let i = 0; i < array.length; i++) { - let ptr = array[i] - if (ptr == nullptr) { - result[i] = undefined - } else { - result[i] = factory(ptr) - } +export function fromPtrArray(array: PtrArray, factory: (ptr: KPointer) => T): Array { + if (array.length === 0) { + return new Array(0); + } + const result = new Array(array.length); + for (let i = 0; i < array.length; i++) { + let ptr = array[i]; + if (ptr === nullptr) { + result[i] = undefined; + } else { + result[i] = factory(ptr); } - return result -} - -export function withUint8Array(data: Uint8Array | undefined, access: Access, exec: ExecWithLength): T { - return withArray(data, exec) -} -export function withInt8Array(data: Int8Array | undefined, access: Access, exec: ExecWithLength) { - return withArray(data, exec) -} -export function withUint16Array(data: Uint16Array | undefined, access: Access, exec: ExecWithLength) { - return withArray(data, exec) -} -export function withInt16Array(data: Int16Array | undefined, access: Access, exec: ExecWithLength) { - return withArray(data, exec) -} -export function withUint32Array(data: Uint32Array | undefined, access: Access, exec: ExecWithLength) { - return withArray(data, exec) -} -export function withInt32Array(data: Int32Array | undefined, access: Access, exec: ExecWithLength) { - return withArray(data, exec) -} -export function withFloat32Array(data: Float32Array | undefined, access: Access, exec: ExecWithLength) { - return withArray(data, exec) -} -export function withFloat64Array(data: Float64Array | undefined, access: Access, exec: ExecWithLength) { - return withArray(data, exec) + } + return result; +} + +export function withUint8Array( + data: Uint8Array | undefined, + access: Access, + exec: ExecWithLength +): T { + return withArray(data, exec); +} +export function withInt8Array( + data: Int8Array | undefined, + access: Access, + exec: ExecWithLength +): T { + return withArray(data, exec); +} +export function withUint16Array( + data: Uint16Array | undefined, + access: Access, + exec: ExecWithLength +): T { + return withArray(data, exec); +} +export function withInt16Array( + data: Int16Array | undefined, + access: Access, + exec: ExecWithLength +): T { + return withArray(data, exec); +} +export function withUint32Array( + data: Uint32Array | undefined, + access: Access, + exec: ExecWithLength +): T { + return withArray(data, exec); +} +export function withInt32Array( + data: Int32Array | undefined, + access: Access, + exec: ExecWithLength +): T { + return withArray(data, exec); +} +export function withFloat32Array( + data: Float32Array | undefined, + access: Access, + exec: ExecWithLength +): T { + return withArray(data, exec); +} +export function withFloat64Array( + data: Float64Array | undefined, + access: Access, + exec: ExecWithLength +): T { + return withArray(data, exec); } export function wasmHeap(): ArrayBuffer { - throw new Error("Unused") + throw new Error('Unused'); } export enum Access { READ = 1, // 1 << 0, WRITE = 2, // 1 << 1, - READWRITE = 3, // READ | WRITE + READWRITE = 3 // READ | WRITE } -export function isRead(access: Access) { - return access & Access.READ +export function isRead(access: Access): boolean { + return !!(access & Access.READ); } -export function isWrite(access: Access) { - return access & Access.WRITE +export function isWrite(access: Access): boolean { + return !!(access & Access.WRITE); } -export type Exec = (pointer: P) => R -export type ExecWithLength = (pointer: P, length: int32) => R +export type Exec = (pointer: P) => R; +export type ExecWithLength = (pointer: P, length: int32) => R; export type TypedArray = - Uint8Array + | Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array - | Float64Array + | Float64Array; -export const nullptr: bigint = BigInt(0) -export type PtrArray = Uint32Array | BigUint64Array +export const nullptr: bigint = BigInt(0); +export type PtrArray = Uint32Array | BigUint64Array; diff --git a/ets2panda/bindings/src/build/buildMode.ts b/ets2panda/bindings/src/build/buildMode.ts index 172ac4847f660c13266797604da361a373701934..d1be834b99fda47c40eb4787f8670bfa76be6268 100644 --- a/ets2panda/bindings/src/build/buildMode.ts +++ b/ets2panda/bindings/src/build/buildMode.ts @@ -15,20 +15,9 @@ import * as path from 'path'; -import { - ABC_SUFFIX, - ARKTSCONFIG_JSON_FILE, - LANGUAGE_VERSION, -} from '../preDefine'; -import { - changeFileExtension, -} from '../utils'; -import { - BuildConfig, - DependentModuleConfig, - ModuleInfo, - CompileFileInfo -} from '../types'; +import { ABC_SUFFIX, ARKTSCONFIG_JSON_FILE, LANGUAGE_VERSION } from '../preDefine'; +import { changeFileExtension } from '../utils'; +import { BuildConfig, DependentModuleConfig, ModuleInfo, CompileFileInfo } from '../types'; import { ArkTSConfigGenerator } from './generateArkTSConfig'; export class BuildMode { @@ -77,8 +66,9 @@ export class BuildMode { if (module.isMainModule) { return; } - module.language === LANGUAGE_VERSION.ARKTS_1_2 ? - staticDepModules.set(packageName, module) : dynamicDepModules.set(packageName, module); + module.language === LANGUAGE_VERSION.ARKTS_1_2 + ? staticDepModules.set(packageName, module) + : dynamicDepModules.set(packageName, module); }); return [dynamicDepModules, staticDepModules]; } @@ -89,8 +79,9 @@ export class BuildMode { if (!depModuleInfo) { console.error(`Module ${packageName} not found in moduleInfos`); } else { - depModuleInfo.language === LANGUAGE_VERSION.ARKTS_1_2 ? - staticDepModules.set(packageName, depModuleInfo) : dynamicDepModules.set(packageName, depModuleInfo); + depModuleInfo.language === LANGUAGE_VERSION.ARKTS_1_2 + ? staticDepModules.set(packageName, depModuleInfo) + : dynamicDepModules.set(packageName, depModuleInfo); } }); } @@ -132,7 +123,7 @@ export class BuildMode { compileFileInfos: [], declgenV1OutPath: this.declgenV1OutPath, declgenBridgeCodePath: this.declgenBridgeCodePath - } + }; this.moduleInfos.set(this.packageName, mainModuleInfo); this.dependentModuleList.forEach((module: DependentModuleConfig) => { if (!module.packageName || !module.modulePath || !module.sourceRoots || !module.entryFile) { @@ -154,7 +145,7 @@ export class BuildMode { language: module.language, declFilesPath: module.declFilesPath, dependencies: module.dependencies - } + }; this.moduleInfos.set(module.packageName, moduleInfo); }); this.collectDepModuleInfos(); diff --git a/ets2panda/bindings/src/build/generateArkTSConfig.ts b/ets2panda/bindings/src/build/generateArkTSConfig.ts index a981dfb5cd8dcb085b6986ab8f3c02b871920086..fe1dc108fc57d5604614ef0e4498e76d8f1b21c5 100644 --- a/ets2panda/bindings/src/build/generateArkTSConfig.ts +++ b/ets2panda/bindings/src/build/generateArkTSConfig.ts @@ -16,35 +16,26 @@ import * as path from 'path'; import * as fs from 'fs'; -import { - changeFileExtension, - ensurePathExists -} from '../utils'; -import { - BuildConfig, - ModuleInfo -} from '../types'; -import { - LANGUAGE_VERSION, - SYSTEM_SDK_PATH_FROM_SDK -} from '../preDefine'; +import { changeFileExtension, ensurePathExists } from '../utils'; +import { BuildConfig, ModuleInfo } from '../types'; +import { LANGUAGE_VERSION, SYSTEM_SDK_PATH_FROM_SDK } from '../preDefine'; interface DynamicPathItem { - language: string, - declPath: string, - runtimeName: string + language: string; + declPath: string; + runtimeName: string; } interface ArkTSConfigObject { compilerOptions: { - package: string, - baseUrl: string, + package: string; + baseUrl: string; paths: Record; dependencies: string[] | undefined; entry: string; dynamicPaths: Record; - } -}; + }; +} export class ArkTSConfigGenerator { private static instance: ArkTSConfigGenerator | undefined; @@ -56,8 +47,8 @@ export class ArkTSConfigGenerator { private pathSection: Record; private constructor(buildConfig: BuildConfig, moduleInfos: Map) { - let pandaStdlibPath: string = buildConfig.pandaStdlibPath ?? - path.resolve(buildConfig.pandaSdkPath!!, 'lib', 'stdlib'); + let pandaStdlibPath: string = + buildConfig.pandaStdlibPath ?? path.resolve(buildConfig.pandaSdkPath!!, 'lib', 'stdlib'); this.stdlibStdPath = path.resolve(pandaStdlibPath, 'std'); this.stdlibEscompatPath = path.resolve(pandaStdlibPath, 'escompat'); this.systemSdkPath = path.resolve(buildConfig.buildSdkPath, SYSTEM_SDK_PATH_FROM_SDK); @@ -69,8 +60,7 @@ export class ArkTSConfigGenerator { public static getInstance(buildConfig?: BuildConfig, moduleInfos?: Map): ArkTSConfigGenerator { if (!ArkTSConfigGenerator.instance) { if (!buildConfig || !moduleInfos) { - throw new Error( - 'buildConfig and moduleInfos is required for the first instantiation of ArkTSConfigGenerator.'); + throw new Error('buildConfig and moduleInfos is required for the first instantiation of ArkTSConfigGenerator.'); } ArkTSConfigGenerator.instance = new ArkTSConfigGenerator(buildConfig, moduleInfos); } @@ -86,7 +76,7 @@ export class ArkTSConfigGenerator { } private generateSystemSdkPathSection(pathSection: Record): void { - function traverse(currentDir: string, relativePath: string = '', isExcludedDir: boolean = false) { + function traverse(currentDir: string, relativePath: string = '', isExcludedDir: boolean = false): void { const items = fs.readdirSync(currentDir); for (const item of items) { const itemPath = path.join(currentDir, item); @@ -94,7 +84,7 @@ export class ArkTSConfigGenerator { if (stat.isFile()) { const basename = path.basename(item, '.d.ets'); - const key = isExcludedDir ? basename : (relativePath ? `${relativePath}.${basename}` : basename); + const key = isExcludedDir ? basename : relativePath ? `${relativePath}.${basename}` : basename; pathSection[key] = [changeFileExtension(itemPath, '', '.d.ets')]; } if (stat.isDirectory()) { @@ -103,7 +93,7 @@ export class ArkTSConfigGenerator { // For arkui files under api dir, // fill path section with `"fileName" = [${absolute_path_to_file}]`. const isCurrentDirExcluded = path.basename(currentDir) === 'arkui' && item === 'runtime-api'; - const newRelativePath = isCurrentDirExcluded ? '' : (relativePath ? `${relativePath}.${item}` : item); + const newRelativePath = isCurrentDirExcluded ? '' : relativePath ? `${relativePath}.${item}` : item; traverse(path.resolve(currentDir, item), newRelativePath, isCurrentDirExcluded || isExcludedDir); } } @@ -124,18 +114,15 @@ export class ArkTSConfigGenerator { return this.pathSection; } - this.pathSection['std'] = [this.stdlibStdPath]; - this.pathSection['escompat'] = [this.stdlibEscompatPath]; + this.pathSection.std = [this.stdlibStdPath]; + this.pathSection.escompat = [this.stdlibEscompatPath]; this.generateSystemSdkPathSection(this.pathSection); this.moduleInfos.forEach((moduleInfo: ModuleInfo, packageName: string) => { if (moduleInfo.language === LANGUAGE_VERSION.ARKTS_1_2) { - this.pathSection[moduleInfo.packageName] = [ - path.resolve(moduleInfo.moduleRootPath, moduleInfo.sourceRoots[0]) - ] + this.pathSection[moduleInfo.packageName] = [path.resolve(moduleInfo.moduleRootPath, moduleInfo.sourceRoots[0])]; } - }); return this.pathSection; @@ -154,7 +141,7 @@ export class ArkTSConfigGenerator { return changeFileExtension(ohmurl, ''); } - private getDynamicPathSection(moduleInfo: ModuleInfo, dynamicPathSection: Record) { + private getDynamicPathSection(moduleInfo: ModuleInfo, dynamicPathSection: Record): void { let depModules: Map = moduleInfo.dynamicDepModuleInfos; depModules.forEach((depModuleInfo: ModuleInfo) => { @@ -167,10 +154,10 @@ export class ArkTSConfigGenerator { Object.keys(declFilesObject.files).forEach((file: string) => { let ohmurl: string = this.getOhmurl(file, depModuleInfo); dynamicPathSection[ohmurl] = { - language: "js", + language: 'js', declPath: declFilesObject.files[file].declPath, runtimeName: declFilesObject.files[file].ohmUrl - } + }; let absFilePath: string = path.resolve(depModuleInfo.moduleRootPath, file); let entryFileWithoutExtension: string = changeFileExtension(depModuleInfo.entryFile, ''); @@ -182,7 +169,7 @@ export class ArkTSConfigGenerator { } public writeArkTSConfigFile(moduleInfo: ModuleInfo): void { - if (!moduleInfo.sourceRoots || moduleInfo.sourceRoots.length == 0) { + if (!moduleInfo.sourceRoots || moduleInfo.sourceRoots.length === 0) { console.error('SourceRoots not set from hvigor.'); } let pathSection = this.getPathSection(); diff --git a/ets2panda/bindings/src/buildConfigGenerate.ts b/ets2panda/bindings/src/buildConfigGenerate.ts index 2a921ca675efeef353d33612b0cdc4d1f4f22ed9..4d1b1c34d1b2f17fc3f4695db8601732c24d72e6 100644 --- a/ets2panda/bindings/src/buildConfigGenerate.ts +++ b/ets2panda/bindings/src/buildConfigGenerate.ts @@ -16,186 +16,215 @@ import * as fs from 'fs'; import * as path from 'path'; import * as JSON5 from 'json5'; +import { BuildConfig } from './types'; export interface ModuleDescriptor { - arktsversion: string; + arktsversion: string; + name: string; + moduleType: string; + srcPath: string; +} + +interface Json5Object { + module?: { + type?: string; + }; + modules?: Array<{ name: string; - moduleType: string; srcPath: string; + arktsversion?: string; + }>; + dependencies?: { + [packageName: string]: string; + }; } function removeTrailingCommas(jsonString: string): string { - return jsonString.replace(/,\s*([}\]])/g, '$1'); + return jsonString.replace(/,\s*([}\]])/g, '$1'); } -function parseJson5(filePath: string) { - try { - const rawContent = fs.readFileSync(filePath, 'utf8'); - const cleanedContent = removeTrailingCommas(rawContent); - return JSON5.parse(cleanedContent); - } catch (error) { - console.error(`Error parsing ${filePath}:`, error); - process.exit(1); - } +function parseJson5(filePath: string): Json5Object { + try { + const rawContent = fs.readFileSync(filePath, 'utf8'); + const cleanedContent = removeTrailingCommas(rawContent); + return JSON5.parse(cleanedContent) as Json5Object; + } catch (error) { + console.error(`Error parsing ${filePath}:`, error); + return {} as Json5Object; + } } function getModuleTypeFromConfig(modulePath: string): string { - const moduleConfigPath = path.join(modulePath, 'src/main/module.json5'); - if (fs.existsSync(moduleConfigPath)) { - try { - const moduleData = parseJson5(moduleConfigPath); - return moduleData.module?.type || "har"; - } catch (error) { - console.error(`Error parsing ${moduleConfigPath}:`, error); - } + const moduleConfigPath = path.join(modulePath, 'src/main/module.json5'); + if (fs.existsSync(moduleConfigPath)) { + try { + const moduleData = parseJson5(moduleConfigPath); + return moduleData.module?.type || 'har'; + } catch (error) { + console.error(`Error parsing ${moduleConfigPath}:`, error); } - return "har"; + } + return 'har'; } function getModulesFromBuildProfile(buildProfilePath: string): ModuleDescriptor[] { - if (!fs.existsSync(buildProfilePath)) { - console.error("Error: build-profile.json5 not found"); - process.exit(1); - } - - const buildProfile = parseJson5(buildProfilePath); - const modules = buildProfile.modules || []; - - return modules.map((module: any) => { - const moduleSrcPath = path.resolve(path.dirname(buildProfilePath), module.srcPath); - const arktsversion = module.arktsversion || "1.1"; - return { - name: module.name, - moduleType: getModuleTypeFromConfig(moduleSrcPath), - srcPath: moduleSrcPath, - arktsversion - }; - }); + if (!fs.existsSync(buildProfilePath)) { + console.error('Error: build-profile.json5 not found'); + process.exit(1); + } + + const buildProfile = parseJson5(buildProfilePath); + const modules = buildProfile.modules || []; + + return modules.map((module: { name: string; srcPath: string; arktsversion?: string }) => { + const moduleSrcPath = path.resolve(path.dirname(buildProfilePath), module.srcPath); + const arktsversion = module.arktsversion || '1.1'; + return { + name: module.name, + moduleType: getModuleTypeFromConfig(moduleSrcPath), + srcPath: moduleSrcPath, + arktsversion + }; + }); } function getEtsFiles(modulePath: string): string[] { - const files: string[] = []; - - const shouldSkipDirectory = (relativePath: string): boolean => { - const testDir1 = `src${path.sep}test`; - const testDir2 = `src${path.sep}ohosTest`; - return relativePath.startsWith(testDir1) || relativePath.startsWith(testDir2); - }; - - const processEntry = (dir: string, entry: fs.Dirent) => { - const fullPath = path.join(dir, entry.name); - const relativePath = path.relative(modulePath, fullPath); - - if (entry.isDirectory()) { - if (shouldSkipDirectory(relativePath)) return; - traverseDir(fullPath); - return; - } + const files: string[] = []; + + const shouldSkipDirectory = (relativePath: string): boolean => { + const testDir1 = `src${path.sep}test`; + const testDir2 = `src${path.sep}ohosTest`; + return relativePath.startsWith(testDir1) || relativePath.startsWith(testDir2); + }; + + const processEntry = (dir: string, entry: fs.Dirent): void => { + const fullPath = path.join(dir, entry.name); + const relativePath = path.relative(modulePath, fullPath); + + if (entry.isDirectory()) { + if (shouldSkipDirectory(relativePath)) { + return; + } + traverseDir(fullPath); + return; + } - if (entry.isFile() && entry.name.endsWith('.ets')) { - files.push(fullPath); - } - }; + if (entry.isFile() && entry.name.endsWith('.ets')) { + files.push(fullPath); + } + }; - const traverseDir = (dir: string) => { - if (!fs.existsSync(dir)) return; + const traverseDir = (dir: string): void => { + if (!fs.existsSync(dir)) { + return; + } - const entries = fs.readdirSync(dir, { withFileTypes: true }); - entries.forEach(entry => processEntry(dir, entry)); - }; + const entries = fs.readdirSync(dir, { withFileTypes: true }); + entries.forEach((entry) => processEntry(dir, entry)); + }; - traverseDir(modulePath); - return files; + traverseDir(modulePath); + return files; } function getModuleDependencies(modulePath: string, visited = new Set()): string[] { - if (visited.has(modulePath)) return []; - visited.add(modulePath); - - const extractDependencies = (): string[] => { - const packageFilePath = path.join(modulePath, 'oh-package.json5'); - if (!fs.existsSync(packageFilePath)) return []; - - try { - const packageData = parseJson5(packageFilePath); - return Object.entries(packageData.dependencies || {}) - .map(([_, depPath]) => (depPath as string).replace('file:', '')) - .map(depPath => path.resolve(modulePath, depPath)); - } catch (error) { - console.error(`Error parsing ${packageFilePath}:`, error); - return []; - } - }; + if (visited.has(modulePath)) { + return []; + } + visited.add(modulePath); + + const extractDependencies = (): string[] => { + const packageFilePath = path.join(modulePath, 'oh-package.json5'); + if (!fs.existsSync(packageFilePath)) { + return []; + } - const resolveNestedDependencies = (deps: string[]): string[] => { - return deps.flatMap(depPath => - visited.has(depPath) ? [] : [depPath, ...getModuleDependencies(depPath, visited)] - ); - }; + try { + const packageData = parseJson5(packageFilePath); + return Object.entries(packageData.dependencies || {}) + .map(([_, depPath]) => (depPath as string).replace('file:', '')) + .map((depPath) => path.resolve(modulePath, depPath)); + } catch (error) { + console.error(`Error parsing ${packageFilePath}:`, error); + return []; + } + }; - const dependencies = extractDependencies(); - const nestedDependencies = resolveNestedDependencies(dependencies); - return Array.from(new Set([...dependencies, ...nestedDependencies])); -} + const resolveNestedDependencies = (deps: string[]): string[] => { + return deps.flatMap((depPath) => + visited.has(depPath) ? [] : [depPath, ...getModuleDependencies(depPath, visited)] + ); + }; -export function generateBuildConfigs(buildSdkPath: string, projectRoot: string, modules?: ModuleDescriptor[]): Record { - const allBuildConfigs: Record = {}; + const dependencies = extractDependencies(); + const nestedDependencies = resolveNestedDependencies(dependencies); + return Array.from(new Set([...dependencies, ...nestedDependencies])); +} - if (!modules) { - const buildProfilePath = path.join(projectRoot, 'build-profile.json5'); - modules = getModulesFromBuildProfile(buildProfilePath); +export function generateBuildConfigs( + buildSdkPath: string, + projectRoot: string, + modules?: ModuleDescriptor[] +): Record { + const allBuildConfigs: Record = {}; + + if (!modules) { + const buildProfilePath = path.join(projectRoot, 'build-profile.json5'); + modules = getModulesFromBuildProfile(buildProfilePath); + } + + const definedModules = modules; + const cacheDir = path.join(projectRoot, '.idea', '.deveco'); + + for (const module of definedModules) { + const modulePath = module.srcPath; + const compileFiles = new Set(getEtsFiles(modulePath)); + + // Get recursive dependencies + const dependencies = getModuleDependencies(modulePath); + for (const depPath of dependencies) { + getEtsFiles(depPath).forEach((file) => compileFiles.add(file)); } - const definedModules = modules; - const cacheDir = path.join(projectRoot, '.idea', '.deveco') - - for (const module of definedModules) { - const modulePath = module.srcPath; - const compileFiles = new Set(getEtsFiles(modulePath)); - - // Get recursive dependencies - const dependencies = getModuleDependencies(modulePath); - for (const depPath of dependencies) { - getEtsFiles(depPath).forEach(file => compileFiles.add(file)); - } - - const buildConfig = { - plugins: { - "ui-plugins": path.join(buildSdkPath, 'build-tools', 'ui-plugins', 'lib', 'ui-plugins', 'index'), - "memo-plugin": path.join(buildSdkPath, 'build-tools', 'ui-plugins', 'lib', 'memo-plugins', 'index') - }, - compileFiles: Array.from(compileFiles), - packageName: module.name, - moduleType: module.moduleType, - buildType: "build", - buildMode: "Debug", - moduleRootPath: modulePath, - sourceRoots: ["./"], - hasMainModule: true, - loaderOutPath: path.join(modulePath, 'build', 'default', 'cache'), - cachePath: cacheDir, - buildSdkPath: buildSdkPath, - enableDeclgenEts2Ts: false, - declgenDtsOutPath: path.join(modulePath, 'build', 'default', 'cache'), - declgenTsOutPath: path.join(modulePath, 'build', 'default', 'cache'), - dependentModuleList: dependencies.map(dep => { - const depModule = definedModules.find(m => m.srcPath === dep); - return { - packageName: path.basename(dep), - moduleName: path.basename(dep), - moduleType: depModule ? depModule.moduleType : "har", - modulePath: dep, - sourceRoots: ["./"], - entryFile: "index.ets", - language: depModule ? depModule.arktsversion : "1.1" - }; - }) + allBuildConfigs[module.name] = { + plugins: { + 'ui-plugins': path.join(buildSdkPath, 'build-tools', 'ui-plugins', 'lib', 'ui-plugins', 'index'), + 'memo-plugin': path.join(buildSdkPath, 'build-tools', 'ui-plugins', 'lib', 'memo-plugins', 'index') + }, + arkts: {}, + arktsGlobal: {}, + compileFiles: Array.from(compileFiles), + packageName: module.name, + moduleType: module.moduleType, + buildType: 'build', + buildMode: 'Debug', + moduleRootPath: modulePath, + sourceRoots: ['./'], + hasMainModule: true, + loaderOutPath: path.join(modulePath, 'build', 'default', 'cache'), + cachePath: cacheDir, + buildSdkPath: buildSdkPath, + enableDeclgenEts2Ts: false, + declgenDtsOutPath: path.join(modulePath, 'build', 'default', 'cache'), + declgenTsOutPath: path.join(modulePath, 'build', 'default', 'cache'), + dependentModuleList: dependencies.map((dep) => { + const depModule = definedModules.find((m) => m.srcPath === dep); + return { + packageName: path.basename(dep), + moduleName: path.basename(dep), + moduleType: depModule ? depModule.moduleType : 'har', + modulePath: dep, + sourceRoots: ['./'], + entryFile: 'index.ets', + language: depModule ? depModule.arktsversion : '1.1' }; - - allBuildConfigs[module.name] = buildConfig; - } - - const outputPath = path.join(cacheDir, 'lsp_build_config.json'); - fs.writeFileSync(outputPath, JSON.stringify(allBuildConfigs, null, 4)); - return allBuildConfigs; + }) + }; + } + const outputPath = path.join(cacheDir, 'lsp_build_config.json'); + if (!fs.existsSync(cacheDir)) { + fs.mkdirSync(cacheDir, { recursive: true }); + } + fs.writeFileSync(outputPath, JSON.stringify(allBuildConfigs, null, 4)); + return allBuildConfigs; } diff --git a/ets2panda/bindings/src/driver_helper.ts b/ets2panda/bindings/src/driver_helper.ts index dde3f53aa675da66b90c97f15e8dc1459a5e486a..29f82f3d0133095d21558faa4e4d3a501234b6ac 100644 --- a/ets2panda/bindings/src/driver_helper.ts +++ b/ets2panda/bindings/src/driver_helper.ts @@ -13,111 +13,111 @@ * limitations under the License. */ -import { Context, Config } from "./types" -import { global } from "./global" -import { throwError } from "./utils" -import { Es2pandaContextState } from "./generated/Es2pandaEnums" -import { withStringResult } from "./Platform" -import { KBoolean, KNativePointer, KPointer } from "./InteropTypes" +import { Context, Config } from './types'; +import { global } from './global'; +import { throwError } from './utils'; +import { Es2pandaContextState } from './generated/Es2pandaEnums'; +import { withStringResult } from './Platform'; +import { KBoolean, KNativePointer, KPointer } from './InteropTypes'; export class DriverHelper { constructor(filePath: string, cmd: string[]) { - this._filePath = filePath - global.filePath = this._filePath - this._cfg = Config.create(cmd, filePath) + this._filePath = filePath; + global.filePath = this._filePath; + this._cfg = Config.create(cmd, filePath); } - private _ctx: Context | undefined - private _cfg: Config - private _filePath: string + private _ctx: Context | undefined; + private _cfg: Config; + private _filePath: string; public createCtx(source: string): KPointer { - this._ctx = Context.createFromString(source) - return this._ctx.peer + this._ctx = Context.createFromString(source); + return this._ctx.peer; } public toString(): string { - return `DriverHelper (filepath = ${this._filePath}, config = ${this._cfg}, context = ${this._ctx})` + return `DriverHelper (filepath = ${this._filePath}, config = ${this._cfg}, context = ${this._ctx})`; } - public proceedToState(state: Es2pandaContextState) { + public proceedToState(state: Es2pandaContextState): void { if (this._ctx === undefined) { - throwError("Trying to proceed to state while cts is undefined") + throwError('Trying to proceed to state while cts is undefined'); } if (state <= global.es2panda._ContextState(this._ctx.peer)) { - return + return; } try { - global.es2panda._ProceedToState(this._ctx.peer, state) + global.es2panda._ProceedToState(this._ctx.peer, state); if (global.es2panda._ContextState(this._ctx.peer) === Es2pandaContextState.ES2PANDA_STATE_ERROR) { - const errMsg = withStringResult(global.es2panda._ContextErrorMessage(this._ctx.peer)) + const errMsg = withStringResult(global.es2panda._ContextErrorMessage(this._ctx.peer)); if (errMsg === undefined) { - throwError(`Couldn't get context error msg`) + throwError(`Couldn't get context error msg`); } else { - throwError("Failed proceed to: " + Es2pandaContextState[state] + "\n" + errMsg) + throwError('Failed proceed to: ' + Es2pandaContextState[state] + '\n' + errMsg); } } } catch (e) { - global.es2panda._DestroyContext(this._ctx.peer) - throw e + global.es2panda._DestroyContext(this._ctx.peer); + throw e; } } - public finalize() { + public finalize(): void { if (this._cfg === undefined) { - throwError("Call finalize before initialized config") + throwError('Call finalize before initialized config'); } if (this._ctx === undefined) { - throwError("Call finalize before initialized context") + throwError('Call finalize before initialized context'); } - global.es2panda._DestroyContext(this._ctx.peer) - global.es2panda._DestroyConfig(this._cfg.peer) - this._ctx = undefined - global.destroyCfg() + global.es2panda._DestroyContext(this._ctx.peer); + global.es2panda._DestroyConfig(this._cfg.peer); + this._ctx = undefined; + global.destroyCfg(); } - public generateTsDecl(declOutPath: string, etsOutPath: string, exportAll: boolean) { - let exportAll_: KBoolean = exportAll ? 1 : 0 - global.es2panda._GenerateTsDeclarationsFromContext(this._cfg.peer, declOutPath, etsOutPath, exportAll_) + public generateTsDecl(declOutPath: string, etsOutPath: string, exportAll: boolean): void { + let exportAll_: KBoolean = exportAll ? 1 : 0; + global.es2panda._GenerateTsDeclarationsFromContext(this._cfg.peer, declOutPath, etsOutPath, exportAll_); } } export class LspDriverHelper { - public createCfg(cmd: string[], filePath: string): Config { - return Config.create(cmd, filePath, true) + public createCfg(cmd: string[], filePath: string, pandaLibPath: string): Config { + return Config.create(cmd, filePath, pandaLibPath, true); } public createCtx(source: string, filePath: string, cfg: Config): KNativePointer { - return Context.lspCreateFromString(source, filePath, cfg) + return Context.lspCreateFromString(source, filePath, cfg); } - public proceedToState(ctx: KNativePointer, state: Es2pandaContextState) { + public proceedToState(ctx: KNativePointer, state: Es2pandaContextState): void { if (ctx === undefined) { - throwError("Trying to proceed to state while cts is undefined") + throwError('Trying to proceed to state while cts is undefined'); } - if (state <= global.es2panda._ContextState(ctx)) { - return + if (state <= global.es2pandaPublic._ContextState(ctx)) { + return; } try { - global.es2panda._ProceedToState(ctx, state) + global.es2pandaPublic._ProceedToState(ctx, state); } catch (e) { - global.es2panda._DestroyContext(ctx) - throw e + global.es2pandaPublic._DestroyContext(ctx); + throw e; } } - public destroyContext(ctx: KNativePointer) { + public destroyContext(ctx: KNativePointer): void { if (ctx === undefined) { - return + return; } - global.es2panda._DestroyContext(ctx) + global.es2pandaPublic._DestroyContext(ctx); } - public destroyConfig(cfg: Config) { + public destroyConfig(cfg: Config): void { if (cfg === undefined) { - return + return; } - global.es2panda._DestroyConfig(cfg.peer) + global.es2pandaPublic._DestroyConfig(cfg.peer); } } diff --git a/ets2panda/bindings/src/generated/Es2pandaEnums.ts b/ets2panda/bindings/src/generated/Es2pandaEnums.ts index 95851a1ec8fdd09f66f2ded9a536c23e6d72d5ed..5638cddfaff08abd6bb89807cd16965825611186 100644 --- a/ets2panda/bindings/src/generated/Es2pandaEnums.ts +++ b/ets2panda/bindings/src/generated/Es2pandaEnums.ts @@ -17,13 +17,12 @@ export enum Es2pandaContextState { ES2PANDA_STATE_NEW = 0, ES2PANDA_STATE_PARSED = 1, - ES2PANDA_STATE_SCOPE_INITED = 2, - ES2PANDA_STATE_BOUND = 3, - ES2PANDA_STATE_CHECKED = 4, - ES2PANDA_STATE_LOWERED = 5, - ES2PANDA_STATE_ASM_GENERATED = 6, - ES2PANDA_STATE_BIN_GENERATED = 7, - ES2PANDA_STATE_ERROR = 8 + ES2PANDA_STATE_BOUND = 2, + ES2PANDA_STATE_CHECKED = 3, + ES2PANDA_STATE_LOWERED = 4, + ES2PANDA_STATE_ASM_GENERATED = 5, + ES2PANDA_STATE_BIN_GENERATED = 6, + ES2PANDA_STATE_ERROR = 7 } export enum Es2pandaScopeType { SCOPE_TYPE_PARAM = 0, diff --git a/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts b/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts index f83a5db66a0d1b9657e006cdc02a7d558fc6cb88..8bd49b74b2f0d7c05b5b93ba613015467b5282c1 100644 --- a/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts +++ b/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts @@ -13,23 +13,37 @@ * limitations under the License. */ - -import { KBoolean, KInt, KNativePointer } from "../InteropTypes" +import { KBoolean, KInt, KNativePointer } from '../InteropTypes'; export class Es2pandaNativeModule { - _CreateMemberExpression(context: KNativePointer, object_arg: KNativePointer, property: KNativePointer, kind: KInt, computed: KBoolean, optional_arg: KBoolean): KNativePointer { - throw new Error("This methods was not overloaded by native module initialization") + _CreateMemberExpression( + context: KNativePointer, + object_arg: KNativePointer, + property: KNativePointer, + kind: KInt, + computed: KBoolean, + optional_arg: KBoolean + ): KNativePointer { + throw new Error('This methods was not overloaded by native module initialization'); } - _UpdateMemberExpression(context: KNativePointer, original: KNativePointer, object_arg: KNativePointer, property: KNativePointer, kind: KInt, computed: KBoolean, optional_arg: KBoolean): KNativePointer { - throw new Error("This methods was not overloaded by native module initialization") + _UpdateMemberExpression( + context: KNativePointer, + original: KNativePointer, + object_arg: KNativePointer, + property: KNativePointer, + kind: KInt, + computed: KBoolean, + optional_arg: KBoolean + ): KNativePointer { + throw new Error('This methods was not overloaded by native module initialization'); } _MemberExpressionObject(context: KNativePointer, receiver: KNativePointer): KNativePointer { - throw new Error("This methods was not overloaded by native module initialization") + throw new Error('This methods was not overloaded by native module initialization'); } _MemberExpressionProperty(context: KNativePointer, receiver: KNativePointer): KNativePointer { - throw new Error("This methods was not overloaded by native module initialization") + throw new Error('This methods was not overloaded by native module initialization'); } _MemberExpressionKindConst(context: KNativePointer, receiver: KNativePointer): KInt { - throw new Error("This methods was not overloaded by native module initialization") + throw new Error('This methods was not overloaded by native module initialization'); } } diff --git a/ets2panda/bindings/src/global.ts b/ets2panda/bindings/src/global.ts index 6af40a7f733aff5283c5aed3df49ad6f7f2943be..2c99dce5caf8834048741b4c88d1f713df2cd8d1 100644 --- a/ets2panda/bindings/src/global.ts +++ b/ets2panda/bindings/src/global.ts @@ -13,63 +13,96 @@ * limitations under the License. */ -import { throwError } from "./utils" -import { KNativePointer } from "./InteropTypes" -import { initEs2panda, Es2pandaNativeModule, initGeneratedEs2panda } from "./Es2pandaNativeModule" -import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from "./generated/Es2pandaNativeModule" -import { initInterop, InteropNativeModule } from "./InteropNativeModule" -import { Context } from "./types" +import { throwError } from './utils'; +import { KNativePointer } from './InteropTypes'; +import { + initEs2panda, + Es2pandaNativeModule, + initGeneratedEs2panda, + initPublicEs2panda, + initPublicGeneratedEs2panda +} from './Es2pandaNativeModule'; +import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from './generated/Es2pandaNativeModule'; +import { initInterop, InteropNativeModule, initPublicInterop } from './InteropNativeModule'; +import { Context } from './types'; +// CC-OFFNXT(G.NAM.01) project code style export class global { - public static filePath: string = "./examples/input/main.ets" + public static filePath: string = './examples/input/main.ets'; - private static _config?: KNativePointer + private static _config?: KNativePointer; public static set config(config: KNativePointer) { if (global._config !== undefined) { - throwError('Global.config already initialized') + throwError('Global.config already initialized'); } - global._config = config + global._config = config; } public static get config(): KNativePointer { - return global._config ?? throwError('Global.config not initialized') + return global._config ?? throwError('Global.config not initialized'); } - public static destroyCfg() { - global._config = undefined + public static destroyCfg(): void { + global._config = undefined; } public static configIsInitialized(): boolean { - return global._config !== undefined + return global._config !== undefined; } - private static _context?: KNativePointer + private static _context?: KNativePointer; public static set context(context: KNativePointer) { - global._context = context + global._context = context; } public static get context(): KNativePointer { - return global._context ?? throwError('Global.context not initialized') + return global._context ?? throwError('Global.context not initialized'); } - private static _es2panda: Es2pandaNativeModule | undefined = undefined + private static _es2panda: Es2pandaNativeModule | undefined = undefined; + private static _es2pandaPublic: Es2pandaNativeModule | undefined = undefined; public static get es2panda(): Es2pandaNativeModule { if (this._es2panda === undefined) { - this._es2panda = initEs2panda() + this._es2panda = initEs2panda(); } - return this._es2panda + return this._es2panda; } - private static _generatedEs2panda: GeneratedEs2pandaNativeModule | undefined = undefined + public static get es2pandaPublic(): Es2pandaNativeModule { + if (this._es2pandaPublic === undefined) { + this._es2pandaPublic = initPublicEs2panda(); + } + return this._es2pandaPublic; + } + + private static _generatedEs2panda: GeneratedEs2pandaNativeModule | undefined = undefined; + private static _generatedEs2pandaPublic: GeneratedEs2pandaNativeModule | undefined = undefined; public static get generatedEs2panda(): GeneratedEs2pandaNativeModule { if (this._generatedEs2panda === undefined) { - this._generatedEs2panda = initGeneratedEs2panda() + this._generatedEs2panda = initGeneratedEs2panda(); + } + return this._generatedEs2panda; + } + + public static get generatedEs2pandaPublic(): GeneratedEs2pandaNativeModule { + if (this._generatedEs2pandaPublic === undefined) { + this._generatedEs2pandaPublic = initPublicGeneratedEs2panda(); } - return this._generatedEs2panda + return this._generatedEs2pandaPublic; } - private static _interop: InteropNativeModule | undefined = undefined + private static _interop: InteropNativeModule | undefined = undefined; + private static _interopPublic: InteropNativeModule | undefined = undefined; public static get interop(): InteropNativeModule { - if (this._interop === undefined) this._interop = initInterop() - return this._interop + if (this._interop === undefined) { + this._interop = initInterop(); + } + return this._interop; + } + + public static get interopPublic(): InteropNativeModule { + if (this._interopPublic === undefined) { + this._interopPublic = initPublicInterop(); + } + return this._interopPublic; } } diff --git a/ets2panda/bindings/src/index.ts b/ets2panda/bindings/src/index.ts index 4b83e7e6683e2e64060b7413ca46580e8a102b64..7f572287111d7951aa275ad6f477cfece9b7cc24 100644 --- a/ets2panda/bindings/src/index.ts +++ b/ets2panda/bindings/src/index.ts @@ -13,9 +13,19 @@ * limitations under the License. */ -export { Lsp } from "./lsp_helper"; -export { DriverHelper } from "./driver_helper"; -export { Es2pandaContextState } from "./generated/Es2pandaEnums" -export { LspCompletionInfo, LspCompletionEntryKind, LspDefinitionData, LspDiagsNode, LspDiagnosticNode, LspDiagSeverity, LspQuickInfo, LspSymbolDisplayPart } from './lspNode' -export { generateArkTsConfigByModules } from './arktsConfigGenerate' -export { ModuleDescriptor } from './buildConfigGenerate' +export { Lsp } from './lsp_helper'; +export { DriverHelper } from './driver_helper'; +export { Es2pandaContextState } from './generated/Es2pandaEnums'; +export { + LspCompletionInfo, + LspCompletionEntryKind, + LspDefinitionData, + LspDiagsNode, + LspDiagnosticNode, + LspDiagSeverity, + LspQuickInfo, + LspSymbolDisplayPart +} from './lspNode'; +export { generateArkTsConfigByModules } from './arktsConfigGenerate'; +export type { ModuleDescriptor } from './buildConfigGenerate'; +export type { TextDocumentChangeInfo } from './lsp_helper'; diff --git a/ets2panda/bindings/src/loadLibraries.ts b/ets2panda/bindings/src/loadLibraries.ts index d60bd020e736b939063ea1a8cd71c03e2f3f7060..f58ec7714a28addccc2f2c7c7b5836f1254a5a77 100644 --- a/ets2panda/bindings/src/loadLibraries.ts +++ b/ets2panda/bindings/src/loadLibraries.ts @@ -13,31 +13,38 @@ * limitations under the License. */ -import * as path from 'path' +import * as path from 'path'; -const nativeModuleLibraries: Map = new Map() +const nativeModuleLibraries: Map = new Map(); export function loadNativeLibrary(name: string): Record { - if ((globalThis as any).requireNapi) - return (globalThis as any).requireNapi(name, true) - else { - const suffixedName = name.endsWith(".node") ? name : `${name}.node` - const safePath = path.win32.resolve(process.cwd(), `${suffixedName}`).replace(/\\/g, '\\\\') - return eval(`let exports = {}; process.dlopen({ exports }, require.resolve("${safePath.replace(/ /g, '\\ ')}"), 2); exports`) + // CC-OFFNXT(no_explicit_any) project code style + if ((globalThis as any).requireNapi) { + // CC-OFFNXT(no_explicit_any) project code style + return (globalThis as any).requireNapi(name, true); + } else { + const suffixedName = name.endsWith('.node') ? name : `${name}.node`; + if (process.platform === 'win32') { + return require(suffixedName); + } else { + // CC-OFFNXT(no_eval) project code style + return eval(`let exports = {}; process.dlopen({ exports }, require.resolve("${suffixedName}"), 2); exports`); + } } } -export function registerNativeModuleLibraryName(nativeModule: string, libraryName: string) { - nativeModuleLibraries.set(nativeModule, libraryName) +export function registerNativeModuleLibraryName(nativeModule: string, libraryName: string): void { + nativeModuleLibraries.set(nativeModule, libraryName); } -export function loadNativeModuleLibrary(moduleName: string, module?: object) { - if (!module) - throw new Error(" argument is required and optional only for compatibility with ArkTS") - const library = loadNativeLibrary(nativeModuleLibraries.get(moduleName) ?? moduleName) +export function loadNativeModuleLibrary(moduleName: string, module?: object): void { + if (!module) { + throw new Error(' argument is required and optional only for compatibility with ArkTS'); + } + const library = loadNativeLibrary(nativeModuleLibraries.get(moduleName) ?? moduleName); if (!library || !library[moduleName]) { - console.error(`Failed to load library for module ${moduleName}`) - return + console.error(`Failed to load library for module ${moduleName}`); + return; } - Object.assign(module, library[moduleName]) + Object.assign(module, library[moduleName]); } diff --git a/ets2panda/bindings/src/lspNode.ts b/ets2panda/bindings/src/lspNode.ts index 28e013aa702664f62adb795e3195333c2a435123..17f846fce21df036fb1b966dca1ac0218aeff665 100644 --- a/ets2panda/bindings/src/lspNode.ts +++ b/ets2panda/bindings/src/lspNode.ts @@ -13,41 +13,57 @@ * limitations under the License. */ -import { KBoolean, KInt, KNativePointer, KUInt } from "./InteropTypes" -import { unpackString, VariantTypes } from "./private" -import { throwError } from "./utils" -import { isNullPtr } from "./Wrapper" -import { global } from "./global" -import { NativePtrDecoder } from "./Platform" +import { KBoolean, KInt, KNativePointer, KUInt } from './InteropTypes'; +import { unpackString, VariantTypes } from './private'; +import { throwError } from './utils'; +import { isNullPtr } from './Wrapper'; +import { global } from './global'; +import { NativePtrDecoder } from './Platform'; + +enum HierarchyType { OTHERS, INTERFACE, CLASS }; + +export enum SetterStyle { + METHOD = 0, + SETTER, + GETTER +} + +export enum AccessModifierStyle { + PUBLIC = 0, + PROTECTED, + PRIVATE +} + +enum ClassRelationKind { UNKNOWN, INTERFACE, CLASS, FIELD, METHOD, PROPERTY }; export abstract class LspNode { - readonly peer: KNativePointer + readonly peer: KNativePointer; protected constructor(peer: KNativePointer) { if (isNullPtr(peer)) { - throwError("nullptr from peer in lspnode constuctor") + throwError('nullptr from peer in lspnode constuctor'); } - this.peer = peer + this.peer = peer; } } export class LspPosition extends LspNode { - readonly line: number - readonly character: number + readonly line: number; + readonly character: number; constructor(peer: KNativePointer) { - super(peer) - this.line = global.es2panda._getPosLine(peer) - this.character = global.es2panda._getPosChar(peer) + super(peer); + this.line = global.es2panda._getPosLine(peer); + this.character = global.es2panda._getPosChar(peer); } } export class LspRange extends LspNode { - readonly start: LspPosition - readonly end: LspPosition + readonly start: LspPosition; + readonly end: LspPosition; constructor(peer: KNativePointer) { - super(peer) - this.start = new LspPosition(global.es2panda._getRangeStart(peer)) - this.end = new LspPosition(global.es2panda._getRangeEnd(peer)) + super(peer); + this.start = new LspPosition(global.es2panda._getRangeStart(peer)); + this.end = new LspPosition(global.es2panda._getRangeEnd(peer)); } } @@ -55,102 +71,102 @@ export enum LspDiagSeverity { Error = 1, Warning = 2, Information = 3, - Hint = 4, + Hint = 4 } export enum LspDiagTag { Unnecessary = 1, - Deprecated = 2, + Deprecated = 2 } export class LspLocation extends LspNode { constructor(peer: KNativePointer) { - super(peer) - this.uri = unpackString(global.es2panda._getLocUri(peer)) - this.range = new LspRange(global.es2panda._getLocRange(peer)) + super(peer); + this.uri = unpackString(global.es2panda._getLocUri(peer)); + this.range = new LspRange(global.es2panda._getLocRange(peer)); } - readonly uri: string - readonly range: LspRange + readonly uri: string; + readonly range: LspRange; } export class LspRelatedInfo extends LspNode { constructor(peer: KNativePointer) { - super(peer) - this.message = unpackString(global.es2panda._getRelatedInfoMsg(peer)) - this.location = new LspLocation(global.es2panda._getRelatedInfoLoc(peer)) + super(peer); + this.message = unpackString(global.es2panda._getRelatedInfoMsg(peer)); + this.location = new LspLocation(global.es2panda._getRelatedInfoLoc(peer)); } - readonly message: string - readonly location: LspLocation + readonly message: string; + readonly location: LspLocation; } export class LspCodeDescription extends LspNode { constructor(peer: KNativePointer) { - super(peer) - this.href = unpackString(global.es2panda._getCodeDescriptionHref(peer)) + super(peer); + this.href = unpackString(global.es2panda._getCodeDescriptionHref(peer)); } - readonly href: string + readonly href: string; } export class LspDiagnosticNode extends LspNode { constructor(peer: KNativePointer) { - super(peer) - this.message = unpackString(global.es2panda._getDiagMsg(peer)) - this.source = unpackString(global.es2panda._getDiagSource(peer)) - this.range = new LspRange(global.es2panda._getDiagRange(peer)) + super(peer); + this.message = unpackString(global.es2panda._getDiagMsg(peer)); + this.source = unpackString(global.es2panda._getDiagSource(peer)); + this.range = new LspRange(global.es2panda._getDiagRange(peer)); this.tags = new NativePtrDecoder() .decode(global.es2panda._getDiagTags(peer)) - .map((elPeer: KNativePointer) => elPeer as KInt) + .map((elPeer: KNativePointer) => elPeer as KInt); this.relatedInfo = new NativePtrDecoder() .decode(global.es2panda._getDiagRelatedInfo(peer)) - .map((elPeer: KNativePointer) => new LspRelatedInfo(elPeer)) - let codeVarPtr = global.es2panda._getDiagCode(peer) - if (global.interop._getTypeOfVariant(codeVarPtr) == VariantTypes.VARIANT_INT) { - this.code = global.interop._getIntFromVariant(codeVarPtr) + .map((elPeer: KNativePointer) => new LspRelatedInfo(elPeer)); + let codeVarPtr = global.es2panda._getDiagCode(peer); + if (global.interop._getTypeOfVariant(codeVarPtr) === VariantTypes.VARIANT_INT) { + this.code = global.interop._getIntFromVariant(codeVarPtr); } else { - this.code = unpackString(global.interop._getStringFromVariant(codeVarPtr)) + this.code = unpackString(global.interop._getStringFromVariant(codeVarPtr)); } - let dataPtr = global.es2panda._getDiagData(peer) - if (global.interop._getTypeOfVariant(dataPtr) == VariantTypes.VARIANT_INT) { - this.data = global.interop._getIntFromVariant(dataPtr) + let dataPtr = global.es2panda._getDiagData(peer); + if (global.interop._getTypeOfVariant(dataPtr) === VariantTypes.VARIANT_INT) { + this.data = global.interop._getIntFromVariant(dataPtr); } else { - this.data = unpackString(global.interop._getStringFromVariant(dataPtr)) + this.data = unpackString(global.interop._getStringFromVariant(dataPtr)); } - this.severity = global.es2panda._getDiagSeverity(peer) - this.codeDescription = new LspCodeDescription(global.es2panda._getDiagCodeDescription(peer)) + this.severity = global.es2panda._getDiagSeverity(peer); + this.codeDescription = new LspCodeDescription(global.es2panda._getDiagCodeDescription(peer)); } - readonly source: String - readonly message: String - readonly range: LspRange - readonly codeDescription: LspCodeDescription - readonly severity: LspDiagSeverity - readonly tags: LspDiagTag[] - readonly relatedInfo: LspRelatedInfo[] - readonly code: number | String - readonly data: number | string + readonly source: String; + readonly message: String; + readonly range: LspRange; + readonly codeDescription: LspCodeDescription; + readonly severity: LspDiagSeverity; + readonly tags: LspDiagTag[]; + readonly relatedInfo: LspRelatedInfo[]; + readonly code: number | String; + readonly data: number | string; } export class LspDiagsNode extends LspNode { constructor(peer: KNativePointer) { - super(peer) + super(peer); this.diagnostics = new NativePtrDecoder() .decode(global.es2panda._getDiags(this.peer)) .map((elPeer: KNativePointer) => { - return new LspDiagnosticNode(elPeer) - }) + return new LspDiagnosticNode(elPeer); + }); } - readonly diagnostics: LspDiagnosticNode[] + readonly diagnostics: LspDiagnosticNode[]; } export class LspDefinitionData extends LspNode { constructor(peer: KNativePointer) { - super(peer) - this.fileName = unpackString(global.es2panda._getFileNameFromDef(peer)) - this.start = global.es2panda._getStartFromDef(peer) - this.length = global.es2panda._getLengthFromDef(peer) + super(peer); + this.fileName = unpackString(global.es2panda._getFileNameFromDef(peer)); + this.start = global.es2panda._getStartFromDef(peer); + this.length = global.es2panda._getLengthFromDef(peer); } - readonly fileName: String - readonly start: KInt - readonly length: KInt + readonly fileName: String; + readonly start: KInt; + readonly length: KInt; } export class LspReferenceData extends LspNode { @@ -181,8 +197,8 @@ export class LspReferences extends LspNode { this.referenceInfos = new NativePtrDecoder() .decode(global.es2panda._getReferenceInfos(this.peer)) .map((elPeer: KNativePointer) => { - return new LspReferenceData(elPeer) - }) + return new LspReferenceData(elPeer); + }); } readonly referenceInfos: LspReferenceData[]; } @@ -197,6 +213,11 @@ export class LspTextSpan extends LspNode { readonly length: KInt; } +export interface TextSpan { + start: KInt; + length: KInt; +} + export class LspSymbolDisplayPart extends LspNode { constructor(peer: KNativePointer) { super(peer); @@ -207,6 +228,150 @@ export class LspSymbolDisplayPart extends LspNode { readonly kind: String; } +export class LspClassMethodItem extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.functionDetail = unpackString(global.es2panda._getDetailFromClassMethodItem(this.peer)); + this.setter = global.es2panda._getSetterStyleFromClassMethodItem(this.peer); + this.accessModifier = global.es2panda._getAccessModifierStyleFromClassMethodItem(this.peer); + } + readonly functionDetail: string; + readonly setter: SetterStyle; + readonly accessModifier: AccessModifierStyle; +} + +export class LspClassHierarchyInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.className = unpackString(global.es2panda._getClassNameFromClassHierarchyInfo(this.peer)); + this.items = new NativePtrDecoder() + .decode(global.es2panda._getMethodListFromClassHierarchyInfo(this.peer)) + .map((elPeer: KNativePointer) => { + return new LspClassMethodItem(elPeer); + }); + } + readonly className: string; + readonly items: LspClassMethodItem[]; +} + +export class LspClassHierarchy extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.infos = new NativePtrDecoder() + .decode(global.es2panda._castToClassHierarchyInfos(this.peer)) + .map((elPeer: KNativePointer) => { + return new LspClassHierarchyInfo(elPeer); + }); + } + readonly infos: LspClassHierarchyInfo[]; +} + +export class LspClassPropertyInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.fieldsInfo = new NativePtrDecoder() + .decode(global.es2panda._getFieldsInfoFromPropertyInfo(peer)) + .map((elPeer: KNativePointer) => { + return new FieldsInfo(elPeer); + }); + } + readonly fieldsInfo: FieldsInfo[]; +} + +export class FieldsInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.name = unpackString(global.es2panda._getNameFromPropertyInfo(peer)); + this.properties = new NativePtrDecoder() + .decode(global.es2panda._getFieldListPropertyFromPropertyInfo(peer)) + .map((elPeer: KNativePointer) => { + return new FieldListProperty(elPeer); + }); + } + readonly name: String; + readonly properties: FieldListProperty[]; +} + +export class FieldListProperty extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.kind = unpackString(global.es2panda._getKindFromPropertyInfo(peer)); + this.modifierKinds = new NativePtrDecoder() + .decode(global.es2panda._getModifierKindsFromPropertyInfo(peer)) + .map((elPeer: KNativePointer) => { + return new String(elPeer); + }); + this.displayName = unpackString(global.es2panda._getDisplayNameFromPropertyInfo(peer)); + this.start = global.es2panda._getStartFromPropertyInfo(peer); + this.end = global.es2panda._getEndFromPropertyInfo(peer); + } + readonly kind: String; + readonly modifierKinds: String[]; + readonly displayName: String; + readonly start: number; + readonly end: number; +} + +export class LspClassHierarchies extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.classHierarchies = new NativePtrDecoder() + .decode(global.es2panda._getClassHierarchyList(peer)) + .map((elPeer: KNativePointer) => { + return new ClassHierarchyItemInfo(elPeer); + }); + } + readonly classHierarchies: ClassHierarchyItemInfo[]; +} + +export class ClassHierarchyItemInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.pos = global.es2panda._getPosFromClassHierarchyItemInfo(peer); + this.kind = global.es2panda._getKindFromClassHierarchyItemInfo(peer); + this.description = unpackString(global.es2panda._getDescriptionFromClassHierarchyItemInfo(peer)); + this.overridden = new NativePtrDecoder() + .decode(global.es2panda._getOverriddenFromClassHierarchyItemInfo(peer)) + .map((elPeer: KNativePointer) => { + return new ClassRelationDetails(elPeer); + }); + this.overriding = new NativePtrDecoder() + .decode(global.es2panda._getOverridingFromClassHierarchyItemInfo(peer)) + .map((elPeer: KNativePointer) => { + return new ClassRelationDetails(elPeer); + }); + this.implemented = new NativePtrDecoder() + .decode(global.es2panda._getImplementedFromClassHierarchyItemInfo(peer)) + .map((elPeer: KNativePointer) => { + return new ClassRelationDetails(elPeer); + }); + this.implementing = new NativePtrDecoder() + .decode(global.es2panda._getImplementingFromClassHierarchyItemInfo(peer)) + .map((elPeer: KNativePointer) => { + return new ClassRelationDetails(elPeer); + }); + } + readonly pos: number; + readonly kind: ClassRelationKind; + readonly description: String; + readonly overridden: ClassRelationDetails[]; + readonly overriding: ClassRelationDetails[]; + readonly implemented: ClassRelationDetails[]; + readonly implementing: ClassRelationDetails[]; +} + +export class ClassRelationDetails extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.fileName = unpackString(global.es2panda._getFileNameFromClassRelationDetails(peer)); + this.pos = global.es2panda._getPosFromClassRelationDetails(peer); + this.kind = global.es2panda._getKindFromClassRelationDetails(peer); + } + readonly fileName: String; + readonly pos: number; + readonly kind: ClassRelationKind; +} + export class LspQuickInfo extends LspNode { constructor(peer: KNativePointer) { super(peer); @@ -217,8 +382,8 @@ export class LspQuickInfo extends LspNode { this.displayParts = new NativePtrDecoder() .decode(global.es2panda._getSymbolDisplayPart(peer)) .map((elPeer: KNativePointer) => { - return new LspSymbolDisplayPart(elPeer) - }) + return new LspSymbolDisplayPart(elPeer); + }); } readonly kind: String; readonly kindModifier: String; @@ -228,16 +393,19 @@ export class LspQuickInfo extends LspNode { } export enum LspHighlightSpanKind { - NONE, DEFINITION, REFERENCE, WRITTEN_REFERENCE + NONE, + DEFINITION, + REFERENCE, + WRITTEN_REFERENCE } export class LspHighlightSpan extends LspNode { constructor(peer: KNativePointer) { super(peer); this.fileName = unpackString(global.es2panda._getHighlightFileName(peer)); - this.textSpan = new LspTextSpan(global.es2panda._getTextSpan(peer)); - this.contextSpan = new LspTextSpan(global.es2panda._getTextSpan(peer)); - this.kind = global.es2panda._getHighlightKind(peer) + this.textSpan = new LspTextSpan(global.es2panda._getHighlightTextSpan(peer)); + this.contextSpan = new LspTextSpan(global.es2panda._getHighlightContextSpan(peer)); + this.kind = global.es2panda._getHighlightKind(peer); } readonly fileName: String; readonly textSpan: LspTextSpan; @@ -252,8 +420,8 @@ export class LspDocumentHighlights extends LspNode { this.highlightSpans = new NativePtrDecoder() .decode(global.es2panda._getHighlightSpanFromHighlights(peer)) .map((elPeer: KNativePointer) => { - return new LspHighlightSpan(elPeer) - }) + return new LspHighlightSpan(elPeer); + }); } readonly fileName: String; readonly highlightSpans: LspHighlightSpan[]; @@ -265,8 +433,8 @@ export class LspDocumentHighlightsReferences extends LspNode { this.documentHighlights = new NativePtrDecoder() .decode(global.es2panda._getDocumentHighlightsFromRef(peer)) .map((elPeer: KNativePointer) => { - return new LspDocumentHighlights(elPeer) - }) + return new LspDocumentHighlights(elPeer); + }); } readonly documentHighlights: LspDocumentHighlights[]; } @@ -300,7 +468,8 @@ export enum LspCompletionEntryKind { } export enum ResolutionStatus { - RESOLVED, UNRESOLVED + RESOLVED, + UNRESOLVED } export class LspCompletionEntryData extends LspNode { @@ -347,13 +516,17 @@ export class LspCompletionInfo extends LspNode { this.entries = new NativePtrDecoder() .decode(global.es2panda._getEntriesFromCompletionInfo(peer)) .map((elPeer: KNativePointer) => { - return new LspCompletionEntry(elPeer) - }) + return new LspCompletionEntry(elPeer); + }); } readonly entries: LspCompletionEntry[]; } -export enum AccessKind { READ, WRITE, READWRITE }; +export enum AccessKind { + READ, + WRITE, + READWRITE +} export class LspReferenceLocation extends LspNode { constructor(peer: KNativePointer) { @@ -375,18 +548,308 @@ export class LspReferenceLocationList extends LspNode { this.entries = new NativePtrDecoder() .decode(global.es2panda._getLocationFromList(peer)) .map((elPeer: KNativePointer) => { - return new LspReferenceLocation(elPeer) - }) + return new LspReferenceLocation(elPeer); + }); } readonly entries: LspReferenceLocation[]; } export class LspLineAndCharacter extends LspNode { - readonly line: number - readonly character: number + readonly line: number; + readonly character: number; + constructor(peer: KNativePointer) { + super(peer); + this.line = global.es2panda._getLine(peer); + this.character = global.es2panda._getChar(peer); + } +} + +export class LspClassConstructorInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.constructorInfoFileTextChanges = new NativePtrDecoder() + .decode(global.es2panda._getFileTextChangesFromConstructorInfo(peer)) + .map((elPeer: KNativePointer) => { + return new ConstructorInfoFileTextChanges(elPeer); + }); + } + readonly constructorInfoFileTextChanges: ConstructorInfoFileTextChanges[]; +} + +export class ConstructorInfoFileTextChanges extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.fileName = unpackString(global.es2panda._getFileNameFromConstructorInfo(peer)); + this.constructorInfoTextChanges = new NativePtrDecoder() + .decode(global.es2panda._getTextChangeFromConstructorInfo(peer)) + .map((elPeer: KNativePointer) => { + return new ConstructorInfoTextChange(elPeer); + }); + } + readonly fileName: String; + readonly constructorInfoTextChanges: ConstructorInfoTextChange[]; +} + +export class ConstructorInfoTextChange extends LspNode { constructor(peer: KNativePointer) { - super(peer) - this.line = global.es2panda._getLine(peer) - this.character = global.es2panda._getChar(peer) + super(peer); + this.span_ = new LspTextSpan(global.es2panda._getTextSpanFromConstructorInfo(peer)); + this.newText_ = unpackString(global.es2panda._getNewTextFromConstructorInfo(peer)); } -} \ No newline at end of file + readonly span_: LspTextSpan; + readonly newText_: String; +} + +export class CompletionEntryDetails extends LspNode { + readonly name: String; + readonly kind: String; + readonly kindModifier: String; + readonly fileName: String; + readonly displayParts: LspSymbolDisplayPart[]; + constructor(peer: KNativePointer) { + super(peer); + this.name = unpackString(global.es2panda._getCompletionEntryDetailsEntryName(peer)); + this.kind = unpackString(global.es2panda._getCompletionEntryDetailsKind(peer)); + this.kindModifier = unpackString(global.es2panda._getCompletionEntryDetailsKindModifier(peer)); + this.fileName = unpackString(global.es2panda._getCompletionEntryDetailsFileName(peer)); + this.displayParts = new NativePtrDecoder() + .decode(global.es2panda._getCompletionEntryDetailsSymbolDisplayPart(peer)) + .map((elPeer: KNativePointer) => { + return new LspSymbolDisplayPart(elPeer); + }); + } +} + +export class TextChange extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.span = new LspTextSpan(global.es2panda._getTextSpanFromTextChange(peer)); + this.newText = unpackString(global.es2panda._getNewTextFromTextChange(peer)); + } + readonly span: LspTextSpan; + readonly newText: String; +} + +export class FileTextChanges extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.fileName = unpackString(global.es2panda._getFileNameFromFileTextChanges(peer)); + this.textChanges = new NativePtrDecoder() + .decode(global.es2panda._getTextChangesFromFileTextChanges(peer)) + .map((elPeer: KNativePointer) => { + return new TextChange(elPeer); + }); + } + readonly fileName: String; + readonly textChanges: TextChange[]; +} + + +export class LspFileTextChanges extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.fileTextChanges = new NativePtrDecoder() + .decode(global.es2panda._getFileTextChanges(peer)) + .map((elPeer: KNativePointer) => { + return new FileTextChanges(elPeer); + }); + } + readonly fileTextChanges: FileTextChanges[]; +} + +export class LspSafeDeleteLocationInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.uri = unpackString(global.es2panda._getSafeDeleteLocationUri(peer)); + this.start = global.es2panda._getSafeDeleteLocationStart(peer); + this.length = global.es2panda._getSafeDeleteLocationLength(peer); + } + readonly uri: String; + readonly start: KInt; + readonly length: KInt; +} + +export class LspSafeDeleteLocation extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.safeDeleteLocationInfos = new NativePtrDecoder() + .decode(global.es2panda._getSafeDeleteLocations(this.peer)) + .map((elPeer: KNativePointer) => { + return new LspSafeDeleteLocationInfo(elPeer); + }); + } + readonly safeDeleteLocationInfos: LspSafeDeleteLocationInfo[]; +} + +export class LspRefactorAction extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.name = unpackString(global.es2panda._getRefactorActionName(peer)); + this.description = unpackString(global.es2panda._getRefactorActionDescription(peer)); + this.kind = unpackString(global.es2panda._getRefactorActionKind(peer)); + } + readonly name: String; + readonly description: String; + readonly kind: String; +} + +export class LspApplicableRefactorInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.name = unpackString(global.es2panda._getApplicableRefactorName(peer)); + this.description = unpackString(global.es2panda._getApplicableRefactorDescription(peer)); + this.action = new LspRefactorAction(global.es2panda._getRefactorAction(peer)); + } + + readonly name: String; + readonly description: String; + readonly action: LspRefactorAction; +} + +export class LspTypeHierarchies extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.fileName = unpackString(global.es2panda._getFileNameFromTypeHierarchies(peer)); + this.name = unpackString(global.es2panda._getNameFromTypeHierarchies(peer)); + this.type = global.es2panda._getTypeFromTypeHierarchies(peer); + this.pos = global.es2panda._getPosFromTypeHierarchies(peer); + this.subOrSuper = new NativePtrDecoder() + .decode(global.es2panda._getSubOrSuper(peer)) + .map((elPeer: KNativePointer) => { + return new LspTypeHierarchies(elPeer); + }); + } + readonly fileName: String; + readonly name: String; + readonly type: HierarchyType; + readonly pos: KInt; + subOrSuper: LspTypeHierarchies[]; +} + +export class LspTypeHierarchiesInfo extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.fileName = unpackString(global.es2panda._getFileNameFromTypeHierarchiesInfo(peer)); + this.name = unpackString(global.es2panda._getNameFromTypeHierarchiesInfo(peer)); + this.type = global.es2panda._getTypeFromTypeHierarchiesInfo(peer); + this.pos = global.es2panda._getPositionFromTypeHierarchiesInfo(peer); + this.superHierarchies = new LspTypeHierarchies(global.es2panda._getSuperFromTypeHierarchiesInfo(peer)); + this.subHierarchies = new LspTypeHierarchies(global.es2panda._getSubFromTypeHierarchiesInfo(peer)); + } + readonly fileName: String; + readonly name: String; + readonly type: HierarchyType; + readonly pos: KInt; + readonly superHierarchies: LspTypeHierarchies; + readonly subHierarchies: LspTypeHierarchies; +} + +enum LspInlayHintKind { + TYPE, + PARAMETER, + ENUM +} + +export class LspInlayHint extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.text = unpackString(global.es2panda._getInlayHintText(peer)); + this.number = global.es2panda._getInlayHintNumber(peer); + this.kind = global.es2panda._getInlayHintKind(peer); + this.whitespaceBefore = global.es2panda._getInlayHintWhitespaceBefore(peer); + this.whitespaceAfter = global.es2panda._getInlayHintWhitespaceAfter(peer); + } + readonly text: string; + readonly number: number; + readonly kind: LspInlayHintKind; + readonly whitespaceBefore: KBoolean; + readonly whitespaceAfter: KBoolean; +} + +export class LspInlayHintList extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.inlayHints = new NativePtrDecoder() + .decode(global.es2panda._getInlayHints(peer)) + .map((elPeer: KNativePointer) => { + return new LspInlayHint(elPeer); + }); + } + readonly inlayHints: LspInlayHint[]; +} + +export class LspSignatureHelpParameter extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.name = unpackString(global.es2panda._getSignatureHelpParameterName(peer)); + this.documentation = new NativePtrDecoder() + .decode(global.es2panda._getSignatureHelpParameterDocumentation(peer)) + .map((elPeer: KNativePointer) => { + return new LspSymbolDisplayPart(elPeer); + }); + this.displayParts = new NativePtrDecoder() + .decode(global.es2panda._getSignatureHelpParameterDisplayParts(peer)) + .map((elPeer: KNativePointer) => { + return new LspSymbolDisplayPart(elPeer); + }); + } + readonly name: string; + readonly documentation: LspSymbolDisplayPart[]; + readonly displayParts: LspSymbolDisplayPart[]; +} + +export class LspSignatureHelpItem extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.prefixDisplayParts = new NativePtrDecoder() + .decode(global.es2panda._getSignatureHelpItemPrefix(peer)) + .map((elPeer: KNativePointer) => { + return new LspSymbolDisplayPart(elPeer); + }); + this.suffixDisplayParts = new NativePtrDecoder() + .decode(global.es2panda._getSignatureHelpItemSuffix(peer)) + .map((elPeer: KNativePointer) => { + return new LspSymbolDisplayPart(elPeer); + }); + this.separatorDisplayParts = new NativePtrDecoder() + .decode(global.es2panda._getSignatureHelpItemSeparator(peer)) + .map((elPeer: KNativePointer) => { + return new LspSymbolDisplayPart(elPeer); + }); + this.parameters = new NativePtrDecoder() + .decode(global.es2panda._getSignatureHelpItemParameter(peer)) + .map((elPeer: KNativePointer) => { + return new LspSignatureHelpParameter(elPeer); + }); + this.documentation = new NativePtrDecoder() + .decode(global.es2panda._getSignatureHelpItemDocumentation(peer)) + .map((elPeer: KNativePointer) => { + return new LspSymbolDisplayPart(elPeer); + }); + } + readonly prefixDisplayParts: LspSymbolDisplayPart[]; + readonly suffixDisplayParts: LspSymbolDisplayPart[]; + readonly separatorDisplayParts: LspSymbolDisplayPart[]; + readonly parameters: LspSignatureHelpParameter[]; + readonly documentation: LspSymbolDisplayPart[]; +} + +export class LspSignatureHelpItems extends LspNode { + constructor(peer: KNativePointer) { + super(peer); + this.items = new NativePtrDecoder() + .decode(global.es2panda._getSignatureHelpItem(peer)) + .map((elPeer: KNativePointer) => { + return new LspSignatureHelpItem(elPeer); + }); + this.applicableSpan = new LspTextSpan(global.es2panda._getApplicableSpan(peer)); + this.selectedItemIndex = global.es2panda._getSelectedItemIndex(peer); + this.argumentIndex = global.es2panda._getArgumentIndex(peer); + this.argumentCount = global.es2panda._getArgumentCount(peer); + } + readonly items: LspSignatureHelpItem[]; + readonly applicableSpan: LspTextSpan; + readonly selectedItemIndex: number; + readonly argumentIndex: number; + readonly argumentCount: number; +} diff --git a/ets2panda/bindings/src/lsp_helper.ts b/ets2panda/bindings/src/lsp_helper.ts index 6e14c70703e0772a182d87125ec2deed2e06826f..b543a2b07ea6fb3041a82eb9e609208085c3fd45 100644 --- a/ets2panda/bindings/src/lsp_helper.ts +++ b/ets2panda/bindings/src/lsp_helper.ts @@ -13,16 +13,46 @@ * limitations under the License. */ -import { LspDriverHelper } from "./driver_helper" -import { global } from "./global" -import { LspDefinitionData, LspDiagsNode, LspReferences, LspQuickInfo, LspDocumentHighlightsReferences, LspCompletionInfo, LspReferenceLocationList, LspLineAndCharacter, LspReferenceData } from "./lspNode" -import { unpackString } from "./private" -import { Es2pandaContextState } from "./generated/Es2pandaEnums" -import { BuildConfig, EtsScript } from './types' -import { PluginDriver, PluginHook } from './ui_plugins_driver' +import { LspDriverHelper } from './driver_helper'; +import { global } from './global'; +import { + LspDefinitionData, + LspDiagsNode, + LspReferences, + LspQuickInfo, + LspClassHierarchy, + LspCompletionEntryKind, + LspClassPropertyInfo, + LspClassHierarchies, + LspDocumentHighlightsReferences, + LspCompletionInfo, + LspReferenceLocationList, + LspLineAndCharacter, + LspReferenceData, + LspClassConstructorInfo, + LspApplicableRefactorInfo, + CompletionEntryDetails, + LspFileTextChanges, + LspSafeDeleteLocationInfo, + LspSafeDeleteLocation, + LspTypeHierarchiesInfo, + LspTextSpan, + LspInlayHint, + LspInlayHintList, + TextSpan, + LspSignatureHelpItems +} from './lspNode'; +import { passStringArray, unpackString } from './private'; +import { Es2pandaContextState } from './generated/Es2pandaEnums'; +import { BuildConfig } from './types'; +import { PluginDriver, PluginHook } from './ui_plugins_driver'; +import { ModuleDescriptor } from './buildConfigGenerate'; +import { generateArkTsConfigByModules } from './arktsConfigGenerate'; -import * as fs from "fs" -import * as path from 'path' +import * as fs from 'fs'; +import * as path from 'path'; + +const ets2pandaCmdPrefix = ['-', '--extension', 'ets', '--arktsconfig']; function initBuildEnv(): void { const currentPath: string | undefined = process.env.PATH; @@ -30,289 +60,668 @@ function initBuildEnv(): void { process.env.PATH = `${currentPath}${path.delimiter}${pandaLibPath}`; } +export interface TextDocumentChangeInfo { + newDoc: string; + rangeStart?: number; + rangeEnd?: number; + updateText?: string; +} + export class Lsp { - private fileNameToArktsconfig: any // Map - private moduleToBuildConfig: any // Map - - constructor(projectPath: string) { - initBuildEnv() - let compileFileInfoPath = path.join(projectPath, '.idea', '.deveco', 'lsp_compileFileInfos.json') - this.fileNameToArktsconfig = JSON.parse(fs.readFileSync(compileFileInfoPath, 'utf-8')) - let buildConfigPath = path.join(projectPath, '.idea', '.deveco', 'lsp_build_config.json') - this.moduleToBuildConfig = JSON.parse(fs.readFileSync(buildConfigPath, 'utf-8')) + private pandaLibPath: string; + private projectPath: string; + private fileNameToArktsconfig: Record; // Map + private moduleToBuildConfig: Record; // Map + private getFileContent: (filePath: string) => string; + private filesMap: Map; // Map + + constructor(projectPath: string, getContentCallback?: (filePath: string) => string) { + initBuildEnv(); + this.pandaLibPath = path.resolve(__dirname, '../../ets2panda/lib'); + this.projectPath = projectPath; + let compileFileInfoPath = path.join(projectPath, '.idea', '.deveco', 'lsp_compileFileInfos.json'); + this.fileNameToArktsconfig = JSON.parse(fs.readFileSync(compileFileInfoPath, 'utf-8')); + let buildConfigPath = path.join(projectPath, '.idea', '.deveco', 'lsp_build_config.json'); + this.moduleToBuildConfig = JSON.parse(fs.readFileSync(buildConfigPath, 'utf-8')); + this.filesMap = new Map(); + this.getFileContent = getContentCallback || ((path: string): string => fs.readFileSync(path, 'utf8')); + } + + modifyFilesMap(fileName: string, fileContent: TextDocumentChangeInfo): void { + this.filesMap.set(fileName, fileContent.newDoc); + } + + deleteFromFilesMap(fileName: string): void { + this.filesMap.delete(fileName); + } + + updateConfig(buildSdkPath: string, modules?: ModuleDescriptor[]): void { + generateArkTsConfigByModules(buildSdkPath, this.projectPath, modules); + let compileFileInfoPath = path.join(this.projectPath, '.idea', '.deveco', 'lsp_compileFileInfos.json'); + this.fileNameToArktsconfig = JSON.parse(fs.readFileSync(compileFileInfoPath, 'utf-8')); + let buildConfigPath = path.join(this.projectPath, '.idea', '.deveco', 'lsp_build_config.json'); + this.moduleToBuildConfig = JSON.parse(fs.readFileSync(buildConfigPath, 'utf-8')); + } + + private getFileSource(filePath: string): string { + const getSource = this.filesMap.get(filePath) || this.getFileContent(filePath); + if (!getSource) { + throw new Error(`File content not found for path: ${filePath}`); + } + return getSource.replace(/\r\n/g, '\n'); } getDefinitionAtPosition(filename: String, offset: number): LspDefinitionData { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getDefinitionAtPosition(localCtx, offset) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getDefinitionAtPosition(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); lspDriverHelper.destroyContext(localCtx); lspDriverHelper.destroyConfig(localCfg); - return new LspDefinitionData(ptr) + return new LspDefinitionData(ptr); } getSemanticDiagnostics(filename: String): LspDiagsNode { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getSemanticDiagnostics(localCtx) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let pandaLibPath: string = path.resolve(__dirname, '../../ets2panda/lib'); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getSemanticDiagnostics(localCtx); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); lspDriverHelper.destroyContext(localCtx); lspDriverHelper.destroyConfig(localCfg); - return new LspDiagsNode(ptr) + return new LspDiagsNode(ptr); } getCurrentTokenValue(filename: String, offset: number): string { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getCurrentTokenValue(localCtx, offset) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getCurrentTokenValue(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); lspDriverHelper.destroyContext(localCtx); lspDriverHelper.destroyConfig(localCfg); - return unpackString(ptr) + return unpackString(ptr); } getImplementationAtPosition(filename: String, offset: number): LspDefinitionData { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getImplementationAtPosition(localCtx, offset) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getImplementationAtPosition(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); lspDriverHelper.destroyContext(localCtx); lspDriverHelper.destroyConfig(localCfg); - return new LspDefinitionData(ptr) + return new LspDefinitionData(ptr); } getFileReferences(filename: String): LspReferenceData[] { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let isPackageModule = global.es2panda._isPackageModule(localCtx) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) + let lspDriverHelper = new LspDriverHelper(); + let searchFilePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[searchFilePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, searchFilePath, this.pandaLibPath); + const source = this.getFileSource(searchFilePath); + let localCtx = lspDriverHelper.createCtx(source, searchFilePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let isPackageModule = global.es2panda._isPackageModule(localCtx); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); lspDriverHelper.destroyContext(localCtx); lspDriverHelper.destroyConfig(localCfg); - let result: LspReferenceData[] = [] - let moduleName = path.basename(path.dirname(arktsconfig)) - let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName] + let result: LspReferenceData[] = []; + let moduleName = path.basename(path.dirname(arktsconfig)); + let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName]; for (let i = 0; i < buildConfig.compileFiles.length; i++) { - let filePath = path.resolve(buildConfig.compileFiles[i]) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getFileReferences(filePath, localCtx, isPackageModule) - let refs = new LspReferences(ptr) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) - lspDriverHelper.destroyContext(localCtx) - lspDriverHelper.destroyConfig(localCfg) + let filePath = path.resolve(buildConfig.compileFiles[i]); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getFileReferences(searchFilePath, localCtx, isPackageModule); + let refs = new LspReferences(ptr); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); for (let j = 0; j < refs.referenceInfos.length; j++) { if (refs.referenceInfos[j].fileName !== '') { - result.push(refs.referenceInfos[j]) + result.push(refs.referenceInfos[j]); } } } - return result + return result; } getReferencesAtPosition(filename: String, offset: number): LspReferenceData[] { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let declInfo = global.es2panda._getDeclInfo(localCtx, offset) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) - lspDriverHelper.destroyContext(localCtx) - lspDriverHelper.destroyConfig(localCfg) - let result: LspReferenceData[] = [] - let moduleName = path.basename(path.dirname(arktsconfig)) - let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName] + let lspDriverHelper = new LspDriverHelper(); + let searchFilePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[searchFilePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, searchFilePath, this.pandaLibPath); + const source = this.getFileSource(searchFilePath); + let localCtx = lspDriverHelper.createCtx(source, searchFilePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let declInfo = global.es2panda._getDeclInfo(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + let result: LspReferenceData[] = []; + let moduleName = path.basename(path.dirname(arktsconfig)); + let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName]; + for (let i = 0; i < buildConfig.compileFiles.length; i++) { + let filePath = path.resolve(buildConfig.compileFiles[i]); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getReferencesAtPosition(localCtx, declInfo); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + let refs = new LspReferences(ptr); + result.push(...refs.referenceInfos); + } + return Array.from(new Set(result)); + } + + getTypeHierarchies(filename: String, offset: number): LspTypeHierarchiesInfo | null { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getTypeHierarchies(localCtx, localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + let ref = new LspTypeHierarchiesInfo(ptr); + if (ref.fileName === '') { + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return null; + } + let result: LspTypeHierarchiesInfo[] = []; + let moduleName = path.basename(path.dirname(arktsconfig)); + let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName]; + for (let i = 0; i < buildConfig.compileFiles.length; i++) { + let filePath = path.resolve(buildConfig.compileFiles[i]); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let searchCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let searchCtx = lspDriverHelper.createCtx(source, filePath, searchCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(searchCtx); + lspDriverHelper.proceedToState(searchCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(searchCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getTypeHierarchies(searchCtx, localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(searchCtx); + lspDriverHelper.destroyConfig(searchCfg); + let refs = new LspTypeHierarchiesInfo(ptr); + if (i > 0) { + result[0].subHierarchies.subOrSuper = result[0].subHierarchies.subOrSuper.concat(refs.subHierarchies.subOrSuper); + } else { + result.push(refs); + } + } + for (let j = 0; j < result[0].subHierarchies.subOrSuper.length; j++) { + let res = this.getTypeHierarchies(result[0].subHierarchies.subOrSuper[j].fileName, result[0].subHierarchies.subOrSuper[j].pos); + if (res !== null) { + let subOrSuperTmp = result[0].subHierarchies.subOrSuper[j].subOrSuper.concat(res.subHierarchies.subOrSuper); + result[0].subHierarchies.subOrSuper[j].subOrSuper = Array.from( + new Map(subOrSuperTmp.map(item => [`${item.fileName}-${item.type}-${item.pos}-${item.name}`, item])).values() + ); + } + } + return result[0]; + } + + getClassHierarchyInfo(filename: String, offset: number): LspClassHierarchy { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileContent(filePath).replace(/\r\n/g, '\n'); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getClassHierarchyInfo(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspClassHierarchy(ptr); + } + + getAliasScriptElementKind(filename: String, offset: number): LspCompletionEntryKind { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileContent(filePath).replace(/\r\n/g, '\n'); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let kind = global.es2panda._getAliasScriptElementKind(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return kind; + } + + getClassHierarchies(filename: String, offset: number): LspClassHierarchies { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileContent(filePath).replace(/\r\n/g, '\n'); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getClassHierarchies(localCtx, filename, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspClassHierarchies(ptr); + } + + getClassPropertyInfo(filename: String, offset: number, shouldCollectInherited: boolean = false): LspClassPropertyInfo { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileContent(filePath).replace(/\r\n/g, '\n'); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getClassPropertyInfo(localCtx, offset, shouldCollectInherited); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspClassPropertyInfo(ptr); + } + + getOrganizeImports(filename: String): LspFileTextChanges { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._organizeImports(localCtx, filename); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspFileTextChanges(ptr); + } + + findSafeDeleteLocation(filename: String, offset: number): LspSafeDeleteLocationInfo[] { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let declInfo = global.es2panda._getDeclInfo(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + let result: LspSafeDeleteLocationInfo[] = []; + let moduleName = path.basename(path.dirname(arktsconfig)); + let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName]; for (let i = 0; i < buildConfig.compileFiles.length; i++) { - let filePath = path.resolve(buildConfig.compileFiles[i]) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getReferencesAtPosition(localCtx, declInfo) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) - lspDriverHelper.destroyContext(localCtx) - lspDriverHelper.destroyConfig(localCfg) - let refs = new LspReferences(ptr) - result.push(...refs.referenceInfos) + let filePath = path.resolve(buildConfig.compileFiles[i]); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._findSafeDeleteLocation(localCtx, declInfo); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + let refs = new LspSafeDeleteLocation(ptr); + result.push(...refs.safeDeleteLocationInfos); } return Array.from(new Set(result)); } + getCompletionEntryDetails(filename: String, offset: number, entryName: String): CompletionEntryDetails { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getCompletionEntryDetails(entryName, filename, localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new CompletionEntryDetails(ptr); + } + + getApplicableRefactors(filename: String, kind: String, offset: number): LspApplicableRefactorInfo { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getApplicableRefactors(localCtx, kind, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspApplicableRefactorInfo(ptr); + } + + getClassConstructorInfo(filename: String, offset: number, properties: string[]): LspClassConstructorInfo { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getClassConstructorInfo(localCtx, offset, passStringArray(properties)); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspClassConstructorInfo(ptr); + } + getSyntacticDiagnostics(filename: String): LspDiagsNode { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getSyntacticDiagnostics(localCtx) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) - lspDriverHelper.destroyContext(localCtx) - lspDriverHelper.destroyConfig(localCfg) - return new LspDiagsNode(ptr) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getSyntacticDiagnostics(localCtx); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspDiagsNode(ptr); } getSuggestionDiagnostics(filename: String): LspDiagsNode { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getSuggestionDiagnostics(localCtx) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) - lspDriverHelper.destroyContext(localCtx) - lspDriverHelper.destroyConfig(localCfg) - return new LspDiagsNode(ptr) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getSuggestionDiagnostics(localCtx); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspDiagsNode(ptr); } getQuickInfoAtPosition(filename: String, offset: number): LspQuickInfo { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getQuickInfoAtPosition(filename, localCtx, offset) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) - lspDriverHelper.destroyContext(localCtx) - lspDriverHelper.destroyConfig(localCfg) - return new LspQuickInfo(ptr) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getQuickInfoAtPosition(filename, localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspQuickInfo(ptr); } getDocumentHighlights(filename: String, offset: number): LspDocumentHighlightsReferences { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getDocumentHighlights(localCtx, offset) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) - lspDriverHelper.destroyContext(localCtx) - lspDriverHelper.destroyConfig(localCfg) - return new LspDocumentHighlightsReferences(ptr) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getDocumentHighlights(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspDocumentHighlightsReferences(ptr); } getCompletionAtPosition(filename: String, offset: number): LspCompletionInfo { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._getCompletionAtPosition(localCtx, offset) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) - lspDriverHelper.destroyContext(localCtx) - lspDriverHelper.destroyConfig(localCfg) - return new LspCompletionInfo(ptr) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + let source = this.getFileSource(filePath); + // This is a temporary solution to support "obj." with wildcard for better solution in internal issue. + if (source[offset - 1] === '.') { + const wildcard = '_WILDCARD'; + if (offset < source.length + 1) { + source = source.slice(0, offset) + wildcard + source.slice(offset); + } else { + source += wildcard; + } + offset += wildcard.length; + } + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getCompletionAtPosition(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspCompletionInfo(ptr); } toLineColumnOffset(filename: String, offset: number): LspLineAndCharacter { - let lspDriverHelper = new LspDriverHelper() - let filePath = path.resolve(filename.valueOf()) - let arktsconfig = this.fileNameToArktsconfig[filePath] - let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', arktsconfig] - let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath) - const source = fs.readFileSync(filePath, 'utf8').toString().replace(/\r\n/g, '\n'); - let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg) - PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED) - PluginDriver.getInstance().runPluginHook(PluginHook.PARSED) - lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED) - let ptr = global.es2panda._toLineColumnOffset(localCtx, offset) - PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN) - lspDriverHelper.destroyContext(localCtx) - lspDriverHelper.destroyConfig(localCfg) - return new LspLineAndCharacter(ptr) + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._toLineColumnOffset(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspLineAndCharacter(ptr); + } + + getSafeDeleteInfo(filename: String, position: number): boolean { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let result = global.es2panda._getSafeDeleteInfo(localCtx, position, path.resolve(__dirname, '../../..')); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return result; + } + + getSpanOfEnclosingComment(filename: String, offset: number, onlyMultiLine: boolean): LspTextSpan { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getSpanOfEnclosingComment(localCtx, offset, onlyMultiLine); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspTextSpan(ptr); + } + + provideInlayHints(filename: String, span: TextSpan): LspInlayHint[] { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + const nativeSpan = global.es2panda._createTextSpan(span.start, span.length); + let ptr = global.es2panda._getInlayHintList(localCtx, nativeSpan); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + const inlayHintList = new LspInlayHintList(ptr); + const inlayHints: LspInlayHint[] = []; + inlayHints.push(...inlayHintList.inlayHints); + return inlayHints; + } + + getSignatureHelpItems(filename: String, offset: number): LspSignatureHelpItems { + let lspDriverHelper = new LspDriverHelper(); + let filePath = path.resolve(filename.valueOf()); + let arktsconfig = this.fileNameToArktsconfig[filePath]; + let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); + let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); + const source = this.getFileSource(filePath); + let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg); + PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); + PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); + lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); + let ptr = global.es2panda._getSignatureHelpItems(localCtx, offset); + PluginDriver.getInstance().runPluginHook(PluginHook.CLEAN); + lspDriverHelper.destroyContext(localCtx); + lspDriverHelper.destroyConfig(localCfg); + return new LspSignatureHelpItems(ptr); } } diff --git a/ets2panda/bindings/src/mainWrapper.ts b/ets2panda/bindings/src/mainWrapper.ts index 2b62690d2e8171260fab6d81be81f8aec8398c73..6d3139b2002585be6ca3f3aaf82ae749f960b5d1 100644 --- a/ets2panda/bindings/src/mainWrapper.ts +++ b/ets2panda/bindings/src/mainWrapper.ts @@ -13,22 +13,22 @@ * limitations under the License. */ -import { KPointer } from "./InteropTypes" -import { ptrToString } from "./Wrapper" -import { className } from "./ts-reflection" +import { KPointer } from './InteropTypes'; +import { ptrToString } from './Wrapper'; +import { className } from './ts-reflection'; /** * An object holding reference to the native pointer. */ export class Wrapper { - ptr: KPointer + ptr: KPointer; constructor(ptr: KPointer) { - if (ptr == null) - throw new Error(`Init <${className(this)}> with null native peer`) - this.ptr = ptr + if (ptr == null) { + throw new Error(`Init <${className(this)}> with null native peer`); + } + this.ptr = ptr; } toString(): string { - return `[native object <${className(this)}> at ${ptrToString(this.ptr)}]` + return `[native object <${className(this)}> at ${ptrToString(this.ptr)}]`; } } - diff --git a/ets2panda/bindings/src/preDefine.ts b/ets2panda/bindings/src/preDefine.ts index 79b1c27022ee539938fc8baafda4064be0241a1d..b0dc4d7f85d7414a5494160cebb02e6b18b62b68 100644 --- a/ets2panda/bindings/src/preDefine.ts +++ b/ets2panda/bindings/src/preDefine.ts @@ -20,8 +20,8 @@ export const ABC_SUFFIX: string = '.abc'; export enum LANGUAGE_VERSION { ARKTS_1_2 = '1.2', ARKTS_1_1 = '1.1', - ARKTS_HYBRID = 'hybrid', -}; + ARKTS_HYBRID = 'hybrid' +} export const PANDA_SDK_PATH_FROM_SDK: string = './build-tools/ets2panda'; export const SYSTEM_SDK_PATH_FROM_SDK: string = './'; diff --git a/ets2panda/bindings/src/private.ts b/ets2panda/bindings/src/private.ts index fa3a1cf5c4c3a0fdd5041352289bc87f6f8917e8..777aad9066bcee2f3e76ede341d48ea2057b884e 100644 --- a/ets2panda/bindings/src/private.ts +++ b/ets2panda/bindings/src/private.ts @@ -13,14 +13,14 @@ * limitations under the License. */ -import { throwError } from "./utils" -import { KNativePointer, nullptr } from "./InteropTypes" -import { withString, withStringArray } from "./arrays" -import { NativePtrDecoder, withStringResult } from "./Platform" -import { LspDiagsNode, LspNode } from "./lspNode"; +import { throwError } from './utils'; +import { KNativePointer, nullptr } from './InteropTypes'; +import { withString, withStringArray } from './arrays'; +import { NativePtrDecoder, withStringResult } from './Platform'; +import { LspDiagsNode, LspNode } from './lspNode'; export function lspData(peer: KNativePointer): LspNode { - return new LspDiagsNode(peer) + return new LspDiagsNode(peer); } export enum VariantTypes { @@ -30,37 +30,36 @@ export enum VariantTypes { export function unpackNonNullableNode(peer: KNativePointer): T { if (peer === nullptr) { - throwError('peer is NULLPTR (maybe you should use unpackNode)') + throwError('peer is NULLPTR (maybe you should use unpackNode)'); } - return lspData(peer) as T + return lspData(peer) as T; } export function unpackNode(peer: KNativePointer): T | undefined { if (peer === nullptr) { - return undefined + return undefined; } + return undefined; } export function unpackNodeArray(nodesPtr: KNativePointer): readonly T[] { if (nodesPtr === nullptr) { - throwError('nodesPtr is NULLPTR (maybe you should use unpackNodeArray)') + throwError('nodesPtr is NULLPTR (maybe you should use unpackNodeArray)'); } - return (new NativePtrDecoder()) - .decode(nodesPtr) - .map((peer: KNativePointer) => unpackNonNullableNode(peer)) + return new NativePtrDecoder().decode(nodesPtr).map((peer: KNativePointer) => unpackNonNullableNode(peer)); } export function unpackString(peer: KNativePointer): string { - return withStringResult(peer) ?? throwError(`failed to unpack (peer shouldn't be NULLPTR)`) + return withStringResult(peer) ?? throwError(`failed to unpack (peer shouldn't be NULLPTR)`); } export function passString(str: string | undefined): string { if (str === undefined) { - return "" + return ''; } - return withString(str, (it: string) => it) + return withString(str, (it: string) => it); } export function passStringArray(strings: string[]): Uint8Array { - return withStringArray(strings) + return withStringArray(strings); } diff --git a/ets2panda/bindings/src/strings.ts b/ets2panda/bindings/src/strings.ts index 0f6cf4ad346d5cd066b550357e0d9d66c142dcc8..ff72c1626e279be2e4e2a098b25fac2aaa3d84f5 100644 --- a/ets2panda/bindings/src/strings.ts +++ b/ets2panda/bindings/src/strings.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { int32 } from "./InteropTypes" +import { int32 } from './InteropTypes'; interface SystemTextEncoder { encode(input?: string): Uint8Array; @@ -25,181 +25,186 @@ interface WithStreamOption { } interface SystemTextDecoder { - decode( - input?: ArrayBuffer | null | Uint8Array, - options?: WithStreamOption - ): string; + decode(input?: ArrayBuffer | null | Uint8Array, options?: WithStreamOption): string; } export class CustomTextEncoder { - static readonly HeaderLen: int32 = Int32Array.BYTES_PER_ELEMENT + static readonly HeaderLen: int32 = Int32Array.BYTES_PER_ELEMENT; - constructor(encoder: SystemTextEncoder | undefined = ((typeof TextEncoder != "undefined") ? new TextEncoder() : undefined)) { - this.encoder = encoder + constructor( + encoder: SystemTextEncoder | undefined = typeof TextEncoder !== 'undefined' ? new TextEncoder() : undefined + ) { + this.encoder = encoder; } - private readonly encoder: SystemTextEncoder | undefined + private readonly encoder: SystemTextEncoder | undefined; public static stringLength(input: string): int32 { - let length = 0 + let length = 0; for (let i = 0; i < input.length; i++) { - length++ - let cp = input.codePointAt(i)! + length++; + let cp = input.codePointAt(i)!; if (cp >= 0x10000) { - i++ + i++; } } - return length + return length; } encodedLength(input: string): int32 { - let length = 0 + let length = 0; for (let i = 0; i < input.length; i++) { - let cp = input.codePointAt(i)! + let cp = input.codePointAt(i)!; if (cp < 0x80) { - length += 1 + length += 1; } else if (cp < 0x800) { - length += 2 + length += 2; } else if (cp < 0x10000) { - length += 3 + length += 3; } else { - length += 4 - i++ + length += 4; + i++; } } - return length + return length; } private addLength(array: Uint8Array, offset: int32, len: int32): void { - array[offset] = (len & 0xff) - array[offset + 1] = ((len >> 8) & 0xff) - array[offset + 2] = ((len >> 16) & 0xff) - array[offset + 3] = ((len >> 24) & 0xff) + array[offset] = len & 0xff; + array[offset + 1] = (len >> 8) & 0xff; + array[offset + 2] = (len >> 16) & 0xff; + array[offset + 3] = (len >> 24) & 0xff; } static getHeaderLength(array: Uint8Array, offset: int32 = 0): int32 { - return (array[offset] | (array[offset + 1] << 8) | (array[offset + 2] << 16) | (array[offset + 3] << 24)) + return array[offset] | (array[offset + 1] << 8) | (array[offset + 2] << 16) | (array[offset + 3] << 24); } // Produces array of bytes with encoded string headed by 4 bytes (little endian) size information: // [s0][s1][s2][s3] [c_0] ... [c_size-1] encode(input: string | undefined, addLength: boolean = true): Uint8Array { - let headerLen = addLength ? CustomTextEncoder.HeaderLen : 0 - let result: Uint8Array + let headerLen = addLength ? CustomTextEncoder.HeaderLen : 0; + let result: Uint8Array; if (!input) { - result = new Uint8Array(headerLen) + result = new Uint8Array(headerLen); } else if (this.encoder !== undefined) { - result = this.encoder!.encode('s'.repeat(headerLen) + input) + result = this.encoder!.encode('s'.repeat(headerLen) + input); } else { - let length = this.encodedLength(input) - result = new Uint8Array(length + headerLen) - this.encodeInto(input, result, headerLen) + let length = this.encodedLength(input); + result = new Uint8Array(length + headerLen); + this.encodeInto(input, result, headerLen); } if (addLength) { - this.addLength(result, 0, result.length - headerLen) + this.addLength(result, 0, result.length - headerLen); } - return result + return result; } // Produces encoded array of strings with size information. encodeArray(strings: Array): Uint8Array { - let totalBytes = CustomTextEncoder.HeaderLen - let lengths = new Int32Array(strings.length) + let totalBytes = CustomTextEncoder.HeaderLen; + let lengths = new Int32Array(strings.length); for (let i = 0; i < lengths.length; i++) { - let len = this.encodedLength(strings[i]) - lengths[i] = len - totalBytes += len + CustomTextEncoder.HeaderLen + let len = this.encodedLength(strings[i]); + lengths[i] = len; + totalBytes += len + CustomTextEncoder.HeaderLen; } - let array = new Uint8Array(totalBytes) - let position = 0 - this.addLength(array, position, lengths.length) - position += CustomTextEncoder.HeaderLen + let array = new Uint8Array(totalBytes); + let position = 0; + this.addLength(array, position, lengths.length); + position += CustomTextEncoder.HeaderLen; for (let i = 0; i < lengths.length; i++) { - this.addLength(array, position, lengths[i]) - position += CustomTextEncoder.HeaderLen - this.encodeInto(strings[i], array, position) - position += lengths[i] + this.addLength(array, position, lengths[i]); + position += CustomTextEncoder.HeaderLen; + this.encodeInto(strings[i], array, position); + position += lengths[i]; } - return array + return array; } encodeInto(input: string, result: Uint8Array, position: int32): Uint8Array { if (this.encoder !== undefined) { - this.encoder!.encodeInto(input, result.subarray(position, result.length)) - return result + this.encoder!.encodeInto(input, result.subarray(position, result.length)); + return result; } - let index = position + let index = position; for (let stringPosition = 0; stringPosition < input.length; stringPosition++) { - let cp = input.codePointAt(stringPosition)! + let cp = input.codePointAt(stringPosition)!; if (cp < 0x80) { - result[index++] = (cp | 0) + result[index++] = cp | 0; } else if (cp < 0x800) { - result[index++] = ((cp >> 6) | 0xc0) - result[index++] = ((cp & 0x3f) | 0x80) + result[index++] = (cp >> 6) | 0xc0; + result[index++] = (cp & 0x3f) | 0x80; } else if (cp < 0x10000) { - result[index++] = ((cp >> 12) | 0xe0) - result[index++] = (((cp >> 6) & 0x3f) | 0x80) - result[index++] = ((cp & 0x3f) | 0x80) + result[index++] = (cp >> 12) | 0xe0; + result[index++] = ((cp >> 6) & 0x3f) | 0x80; + result[index++] = (cp & 0x3f) | 0x80; } else { - result[index++] = ((cp >> 18) | 0xf0) - result[index++] = (((cp >> 12) & 0x3f) | 0x80) - result[index++] = (((cp >> 6) & 0x3f) | 0x80) - result[index++] = ((cp & 0x3f) | 0x80) - stringPosition++ + result[index++] = (cp >> 18) | 0xf0; + result[index++] = ((cp >> 12) & 0x3f) | 0x80; + result[index++] = ((cp >> 6) & 0x3f) | 0x80; + result[index++] = (cp & 0x3f) | 0x80; + stringPosition++; } } - result[index] = 0 - return result + result[index] = 0; + return result; } } export class CustomTextDecoder { - static cpArrayMaxSize = 128 - constructor(decoder: SystemTextDecoder | TextDecoder | undefined = ((typeof TextDecoder != "undefined") ? new TextDecoder() : undefined)) { - this.decoder = decoder + static cpArrayMaxSize = 128; + constructor( + decoder: SystemTextDecoder | TextDecoder | undefined = typeof TextDecoder !== 'undefined' + ? new TextDecoder() + : undefined + ) { + this.decoder = decoder; } - private readonly decoder: SystemTextDecoder | TextDecoder | undefined + private readonly decoder: SystemTextDecoder | TextDecoder | undefined; decode(input: Uint8Array): string { if (this.decoder !== undefined) { - return this.decoder!.decode(input) + return this.decoder!.decode(input); } - const cpSize = Math.min(CustomTextDecoder.cpArrayMaxSize, input.length) - let codePoints = new Int32Array(cpSize) + const cpSize = Math.min(CustomTextDecoder.cpArrayMaxSize, input.length); + let codePoints = new Int32Array(cpSize); let cpIndex = 0; - let index = 0 - let result = "" + let index = 0; + let result = ''; while (index < input.length) { - let elem = input[index] - let lead = elem & 0xff - let count = 0 - let value = 0 + let elem = input[index]; + let lead = elem & 0xff; + let count = 0; + let value = 0; if (lead < 0x80) { - count = 1 - value = elem - } else if ((lead >> 5) == 0x6) { - value = ((elem << 6) & 0x7ff) + (input[index + 1] & 0x3f) - count = 2 - } else if ((lead >> 4) == 0xe) { - value = ((elem << 12) & 0xffff) + ((input[index + 1] << 6) & 0xfff) + - (input[index + 2] & 0x3f) - count = 3 - } else if ((lead >> 3) == 0x1e) { - value = ((elem << 18) & 0x1fffff) + ((input[index + 1] << 12) & 0x3ffff) + - ((input[index + 2] << 6) & 0xfff) + (input[index + 3] & 0x3f) - count = 4 + count = 1; + value = elem; + } else if (lead >> 5 === 0x6) { + value = ((elem << 6) & 0x7ff) + (input[index + 1] & 0x3f); + count = 2; + } else if (lead >> 4 === 0xe) { + value = ((elem << 12) & 0xffff) + ((input[index + 1] << 6) & 0xfff) + (input[index + 2] & 0x3f); + count = 3; + } else if (lead >> 3 === 0x1e) { + value = + ((elem << 18) & 0x1fffff) + + ((input[index + 1] << 12) & 0x3ffff) + + ((input[index + 2] << 6) & 0xfff) + + (input[index + 3] & 0x3f); + count = 4; } - codePoints[cpIndex++] = value - if (cpIndex == cpSize) { - cpIndex = 0 - result += String.fromCodePoint(...codePoints) + codePoints[cpIndex++] = value; + if (cpIndex === cpSize) { + cpIndex = 0; + result += String.fromCodePoint(...codePoints); } - index += count + index += count; } if (cpIndex > 0) { - result += String.fromCodePoint(...codePoints.slice(0, cpIndex)) + result += String.fromCodePoint(...codePoints.slice(0, cpIndex)); } - return result + return result; } } diff --git a/ets2panda/bindings/src/ts-reflection.ts b/ets2panda/bindings/src/ts-reflection.ts index 48a8ed37b5bb67ed9aea2b11fa1c3e8fc8aa8949..b5bca76260e4f1592763e2f590e88de41b9275d2 100644 --- a/ets2panda/bindings/src/ts-reflection.ts +++ b/ets2panda/bindings/src/ts-reflection.ts @@ -14,22 +14,22 @@ */ export function className(object?: Object): string { - return object?.constructor.name ?? "" + return object?.constructor.name ?? ''; } export function isFunction(object?: Object): boolean { - return typeof object === 'function' + return typeof object === 'function'; } // TODO: this is to match arkts counterpart export function functionOverValue(value: Value | (() => Value)): boolean { - return typeof value === 'function' + return typeof value === 'function'; } export function refEqual(a: Value, b: Value): boolean { - return a === b + return a === b; } export function isNotPrimitive(value: Object): boolean { - return true + return true; } diff --git a/ets2panda/bindings/src/types.ts b/ets2panda/bindings/src/types.ts index 182f8bc5eab3174cc6b67f0349dd2a06a5855401..2a34d968b7c5a540cb7d7cfa7f17e0c7622eb623 100644 --- a/ets2panda/bindings/src/types.ts +++ b/ets2panda/bindings/src/types.ts @@ -13,140 +13,101 @@ * limitations under the License. */ -import { KNativePointer as KPtr } from "./InteropTypes" -import { global } from "./global" -import { throwError } from "./utils" -import { passString, passStringArray, unpackString } from "./private" -import { isNullPtr } from "./Wrapper" +import { KNativePointer as KPtr } from './InteropTypes'; +import { global } from './global'; +import { throwError } from './utils'; +import { passString, passStringArray, unpackString } from './private'; +import { isNullPtr } from './Wrapper'; -export const arrayOfNullptr = new BigUint64Array([BigInt(0)]) +export const arrayOfNullptr = new BigUint64Array([BigInt(0)]); export abstract class ArktsObject { protected constructor(peer: KPtr) { - this.peer = peer + this.peer = peer; } - readonly peer: KPtr + readonly peer: KPtr; } export abstract class Node extends ArktsObject { protected constructor(peer: KPtr) { if (isNullPtr(peer)) { - throw new Error('trying to create new Node on NULLPTR') + throw new Error('trying to create new Node on NULLPTR'); } - super(peer) + super(peer); } public get originalPeer(): KPtr { - return global.es2panda._AstNodeOriginalNodeConst(global.context, this.peer) + return global.es2panda._AstNodeOriginalNodeConst(global.context, this.peer); } public set originalPeer(peer: KPtr) { - global.es2panda._AstNodeSetOriginalNode(global.context, this.peer, peer) + global.es2panda._AstNodeSetOriginalNode(global.context, this.peer, peer); } protected dumpMessage(): string { - return `` + return ``; } public dumpJson(): string { - return unpackString(global.es2panda._AstNodeDumpJsonConst(global.context, this.peer)) + return unpackString(global.es2panda._AstNodeDumpJsonConst(global.context, this.peer)); } public dumpSrc(): string { - return unpackString(global.es2panda._AstNodeDumpEtsSrcConst(global.context, this.peer)) + return unpackString(global.es2panda._AstNodeDumpEtsSrcConst(global.context, this.peer)); } } export class Config extends ArktsObject { - readonly path: string + readonly path: string; constructor(peer: KPtr, fpath: string) { - super(peer) + super(peer); // TODO: wait for getter from api - this.path = fpath + this.path = fpath; } public toString(): string { - return `Config (peer = ${this.peer}, path = ${this.path})` + return `Config (peer = ${this.peer}, path = ${this.path})`; } - static create( - input: string[], fpath: string, isEditingMode: boolean = false - ): Config { + static create(input: string[], fpath: string, pandaLibPath: string = '', isEditingMode: boolean = false): Config { if (isEditingMode) { - let cfg = global.es2panda._CreateConfig(input.length, passStringArray(input)) - return new Config(cfg, fpath) + let cfg = global.es2pandaPublic._CreateConfig(input.length, passStringArray(input), pandaLibPath); + return new Config(cfg, fpath); } if (!global.configIsInitialized()) { - let cfg = global.es2panda._CreateConfig(input.length, passStringArray(input)) - global.config = cfg - return new Config( - cfg, fpath - ) + let cfg = global.es2panda._CreateConfig(input.length, passStringArray(input), pandaLibPath); + global.config = cfg; + return new Config(cfg, fpath); } else { - return new Config(global.config, fpath) + return new Config(global.config, fpath); } } } -export class EtsScript extends Node { - constructor(peer: KPtr) { - super(peer) - } - - static fromContext(ctx: Context): EtsScript { - return new EtsScript(global.es2panda._ProgramAst(global.es2panda._ContextProgram(ctx.peer))) - } -} - -export class Program extends ArktsObject { - constructor(peer: KPtr) { - super(peer) - } - - get astNode(): EtsScript { - return new EtsScript(global.es2panda._ProgramAst(this.peer)); - } -} - export class Context extends ArktsObject { constructor(peer: KPtr) { - super(peer) + super(peer); } public toString(): string { - return `Context (peer = ${this.peer})` + return `Context (peer = ${this.peer})`; } - static createFromString( - source: string - ): Context { + static createFromString(source: string): Context { if (!global.configIsInitialized()) { - throwError(`Config not initialized`) + throwError(`Config not initialized`); } return new Context( - global.es2panda._CreateContextFromString( - global.config, - passString(source), - passString(global.filePath) - ) - ) + global.es2panda._CreateContextFromString(global.config, passString(source), passString(global.filePath)) + ); } - static lspCreateFromString( - source: string, filePath: string, cfg: Config - ): KPtr { + static lspCreateFromString(source: string, filePath: string, cfg: Config): KPtr { if (cfg === undefined) { - throwError(`Config not initialized`) + throwError(`Config not initialized`); } - return global.es2panda._CreateContextFromString( - cfg.peer, - passString(source), - passString(filePath) - ) - } - get program(): Program { - return new Program(global.es2panda._ContextProgram(this.peer)); + return global.es2pandaPublic._CreateContextFromString(cfg.peer, passString(source), passString(filePath)); } } @@ -172,10 +133,12 @@ export interface ModuleConfig { export interface PathConfig { loaderOutPath: string; + declgenDtsOutPath: string; + declgenTsOutPath: string; cachePath: string; buildSdkPath: string; - pandaSdkPath?: string; // path to panda sdk lib/bin, for local test - pandaStdlibPath?: string; // path to panda sdk stdlib, for local test + pandaSdkPath?: string; // path to panda sdk lib/bin, for local test + pandaStdlibPath?: string; // path to panda sdk stdlib, for local test abcLinkerPath?: string; } @@ -196,9 +159,9 @@ export interface DependentModuleConfig { modulePath: string; sourceRoots: string[]; entryFile: string; - language: string, - declFilesPath?: string, - dependencies?: string[] + language: string; + declFilesPath?: string; + dependencies?: string[]; } export interface BuildConfig extends BuildBaseConfig, DeclgenConfig, LoggerConfig, ModuleConfig, PathConfig { @@ -209,25 +172,25 @@ export interface BuildConfig extends BuildBaseConfig, DeclgenConfig, LoggerConfi // ProjectConfig ends export interface CompileFileInfo { - filePath: string, - dependentFiles: string[], - abcFilePath: string, - arktsConfigFile: string, - packageName: string, -}; + filePath: string; + dependentFiles: string[]; + abcFilePath: string; + arktsConfigFile: string; + packageName: string; +} export interface ModuleInfo { - isMainModule: boolean, - packageName: string, - moduleRootPath: string, - moduleType: string, - sourceRoots: string[], - entryFile: string, - arktsConfigFile: string, - compileFileInfos: CompileFileInfo[], - declgenV1OutPath: string | undefined, - declgenBridgeCodePath: string | undefined, - dependencies?: string[] + isMainModule: boolean; + packageName: string; + moduleRootPath: string; + moduleType: string; + sourceRoots: string[]; + entryFile: string; + arktsConfigFile: string; + compileFileInfos: CompileFileInfo[]; + declgenV1OutPath: string | undefined; + declgenBridgeCodePath: string | undefined; + dependencies?: string[]; staticDepModuleInfos: Map; dynamicDepModuleInfos: Map; language?: string; diff --git a/ets2panda/bindings/src/ui_plugins_driver.ts b/ets2panda/bindings/src/ui_plugins_driver.ts index b880392f7edf5b80b418b1266a49a1318c7796d3..1d30fb980313a62dfab333d979f6b776ca207725 100644 --- a/ets2panda/bindings/src/ui_plugins_driver.ts +++ b/ets2panda/bindings/src/ui_plugins_driver.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { KNativePointer } from "./InteropTypes"; -import { BuildConfig } from "./types"; +import { KNativePointer } from './InteropTypes'; +import { BuildConfig } from './types'; export enum PluginHook { NEW = 'afterNew', @@ -24,40 +24,40 @@ export enum PluginHook { LOWERED = 'lowered', ASM_GENERATED = 'asmGenerated', BIN_GENERATED = 'binGenerated', - CLEAN = 'clean', -}; + CLEAN = 'clean' +} type PluginHandlerFunction = () => void; type PluginHandlerObject = { - order: 'pre' | 'post' | undefined - handler: PluginHandlerFunction + order: 'pre' | 'post' | undefined; + handler: PluginHandlerFunction; }; type PluginHandler = PluginHandlerFunction | PluginHandlerObject; interface Plugins { - name: string, - afterNew?: PluginHandler, - parsed?: PluginHandler, - scopeInited?: PluginHandler, - checked?: PluginHandler, - lowered?: PluginHandler, - asmGenerated?: PluginHandler, - binGenerated?: PluginHandler, - clean?: PluginHandler, + name: string; + afterNew?: PluginHandler; + parsed?: PluginHandler; + scopeInited?: PluginHandler; + checked?: PluginHandler; + lowered?: PluginHandler; + asmGenerated?: PluginHandler; + binGenerated?: PluginHandler; + clean?: PluginHandler; } type PluginExecutor = { - name: string - handler: PluginHandler + name: string; + handler: PluginHandler; }; type PluginInitFunction = () => Plugins; type RawPlugins = { - name: string, - init: PluginInitFunction | undefined + name: string; + init: PluginInitFunction | undefined; }; class PluginContext { @@ -98,11 +98,11 @@ class PluginContext { } public setContextPtr(ptr: KNativePointer): void { - this.contextPtr = ptr + this.contextPtr = ptr; } public getContextPtr(): KNativePointer | undefined { - return this.contextPtr + return this.contextPtr; } } @@ -167,7 +167,7 @@ export class PluginDriver { let post: PluginExecutor[] = []; this.allPlugins.forEach((pluginObject: Plugins, name: string) => { - if (!(pluginObject[hook])) { + if (!pluginObject[hook]) { return; } diff --git a/ets2panda/bindings/src/utils.ts b/ets2panda/bindings/src/utils.ts index b767be2e7a70cb97ccd8c1e0bd7ae0fdb45fe1bf..5e21866cc6fe8a7bfe6763bde7ce076f6abf8ea2 100644 --- a/ets2panda/bindings/src/utils.ts +++ b/ets2panda/bindings/src/utils.ts @@ -17,12 +17,12 @@ import * as fs from 'fs'; import * as path from 'path'; export function throwError(error: string): never { - throw new Error(error) + throw new Error(error); } export function withWarning(value: T, message: string): T { - console.warn(message) - return value + console.warn(message); + return value; } export function changeFileExtension(file: string, targetExt: string, originExt = ''): string { diff --git a/ets2panda/bindings/test/README.md b/ets2panda/bindings/test/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0a6e5478bf6157e1439a310cb6c55474b87aa6f0 --- /dev/null +++ b/ets2panda/bindings/test/README.md @@ -0,0 +1,61 @@ +### How to run bindings test? + +```Bash +cd /path/to/bindings + +### check environment +# if you are using Linux shell +bash test/prepare.sh +# or if you are using Windows shell +powershell -f test/prepare.ps1 + +### run test +npm install +npm run test + +### restore the path to the original state +bash test/prepare.sh --restore +# or +powershell -f test/prepare.ps1 --restore +``` + +#### tips +1. If you want to update a lot of expected results, you can use `node dist-test/test/run_tests.js ./test --update` + +### testcase directory structure +. +├── cases.ts +├── run_tests.ts +├── expected +│   ├── exampleFuncName.json +└── testcases +    ├── .idea +    │   └── .deveco +    │   ├── exampleFuncName +    │   │   └── arktsconfig.json +    │   ├── lsp_build_config.json +    │   └── lsp_compileFileInfos.json +    └── exampleFuncName +       └── exampleFuncName1.ets + +case.ts: +```typescript +{ + testName: { + "expectedFilePath": "/path/to/expected.json", + "1": [ "param1", "param2" ], // lsp will call lsp.testName(param1, param2) + "2": [ "param1", "param2" ] + } +} +``` + +#### How to add a new test case? +1. add exampleFuncName2.ets file in `testcases/exampleFuncName` directory +2. add parameters in `cases.ts` file +3. add expected result in `expected/exampleFuncName.json` file + +#### How to add a new test function? +1. add exampleFuncName2 directory in `testcases` directory +2. add exampleFuncName2 field in `cases.ts` file +3. add exampleFuncName2.json in `expected` directory +4. add a new test case according to the above steps diff --git a/ets2panda/bindings/test/cases.ts b/ets2panda/bindings/test/cases.ts new file mode 100644 index 0000000000000000000000000000000000000000..87a87dc23edfadbc4ea23f8aae2bb3eec115032d --- /dev/null +++ b/ets2panda/bindings/test/cases.ts @@ -0,0 +1,139 @@ +/* + * 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 path from 'path'; +import { TextSpan } from '../src/lspNode'; + +export interface TestConfig { + expectedFilePath: string; + // CC-OFFNXT(no_explicit_any) project code style + [key: string]: Array | string; +} + +export interface TestCases { + [testName: string]: TestConfig; +} + +const PROJECT_ROOT = path.resolve(__dirname, '../../'); + +function resolveTestPath(relativePath: string): string { + return path.join(PROJECT_ROOT, relativePath); +} + +export const testCases: TestCases = { + getDefinitionAtPosition: { + expectedFilePath: resolveTestPath('test/expected/getDefinitionAtPosition.json'), + '1': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition2.ets'), 655], + '2': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition3.ets'), 662], + '3': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition5.ets'), 664], + '4': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition7.ets'), 683], + '5': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition9.ets'), 666], + '6': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition11.ets'), 675], + '7': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition13.ets'), 664], + '8': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition15.ets'), 617], + '9': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition17.ets'), 677], + '10': [resolveTestPath('test/testcases/getDefinitionAtPosition/getDefinitionAtPosition18.ets'), 930] + }, + getSemanticDiagnostics: { + expectedFilePath: resolveTestPath('test/expected/getSemanticDiagnostics.json'), + '1': [resolveTestPath('test/testcases/getSemanticDiagnostics/getSemanticDiagnostics1.ets')], + '2': [resolveTestPath('test/testcases/getSemanticDiagnostics/getSemanticDiagnostics2.ets')] + }, + getCurrentTokenValue: { + expectedFilePath: resolveTestPath('test/expected/getCurrentTokenValue.json'), + '1': [resolveTestPath('test/testcases/getCurrentTokenValue/getCurrentTokenValue1.ets'), 611], + '2': [resolveTestPath('test/testcases/getCurrentTokenValue/getCurrentTokenValue2.ets'), 612], + '3': [resolveTestPath('test/testcases/getCurrentTokenValue/getCurrentTokenValue3.ets'), 612], + '4': [resolveTestPath('test/testcases/getCurrentTokenValue/getCurrentTokenValue4.ets'), 611] + }, + getFileReferences: { + expectedFilePath: resolveTestPath('test/expected/getFileReferences.json'), + '1': [resolveTestPath('test/testcases/getFileReferences/getFileReferences1_export.ets')] + }, + getReferencesAtPosition: { + expectedFilePath: resolveTestPath('test/expected/getReferencesAtPosition.json'), + '1': [resolveTestPath('test/testcases/getReferencesAtPosition/getReferencesAtPosition1.ets'), 613], + '2': [resolveTestPath('test/testcases/getReferencesAtPosition/getReferencesAtPosition2.ets'), 635], + '3': [resolveTestPath('test/testcases/getReferencesAtPosition/getReferencesAtPosition4.ets'), 625] + }, + getSyntacticDiagnostics: { + expectedFilePath: resolveTestPath('test/expected/getSyntacticDiagnostics.json'), + '1': [resolveTestPath('test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics1.ets')], + '2': [resolveTestPath('test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics2.ets')] + }, + getSuggestionDiagnostics: { + expectedFilePath: resolveTestPath('test/expected/getSuggestionDiagnostics.json'), + '1': [resolveTestPath('test/testcases/getSuggestionDiagnostics/getSuggestionDiagnostics1.ets')] + }, + getQuickInfoAtPosition: { + expectedFilePath: resolveTestPath('test/expected/getQuickInfoAtPosition.json'), + '1': [resolveTestPath('test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition1.ets'), 626], + '2': [resolveTestPath('test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition2.ets'), 618], + '3': [resolveTestPath('test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition3.ets'), 663] + }, + getDocumentHighlights: { + expectedFilePath: resolveTestPath('test/expected/getDocumentHighlights.json'), + '1': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights1.ets'), 614], + '2': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights2.ets'), 717], + '3': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights3.ets'), 616], + '4': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights4.ets'), 626], + '5': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights5.ets'), 619], + '6': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights6.ets'), 657], + '7': [resolveTestPath('test/testcases/getDocumentHighlights/getDocumentHighlights7.ets'), 733] + }, + getCompletionAtPosition: { + expectedFilePath: resolveTestPath('test/expected/getCompletionAtPosition.json'), + '1': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition1.ets'), 705], + '2': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition2.ets'), 735], + '3': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition3.ets'), 789], + '4': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition4.ets'), 767], + '5': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition5.ets'), 728], + '6': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition6.ets'), 718], + '7': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition7.ets'), 683], + '8': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition8.ets'), 614], + '9': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition9.ets'), 619], + '10': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition10.ets'), 712], + '11': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition11.ets'), 682], + '12': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition12.ets'), 720], + '13': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition13.ets'), 658], + '14': [resolveTestPath('test/testcases/getCompletionAtPosition/getCompletionsAtPosition14.ets'), 659] + }, + toLineColumnOffset: { + expectedFilePath: resolveTestPath('test/expected/toLineColumnOffset.json'), + '1': [resolveTestPath('test/testcases/toLineColumnOffset/toLineColumnOffset1.ets'), 0], + '2': [resolveTestPath('test/testcases/toLineColumnOffset/toLineColumnOffset1.ets'), 642] + }, + getSpanOfEnclosingComment: { + expectedFilePath: resolveTestPath('test/expected/getSpanOfEnclosingComment.json'), + '1': [resolveTestPath('test/testcases/getSpanOfEnclosingComment/getSpanOfEnclosingComment1.ets'), 669, false], + '2': [resolveTestPath('test/testcases/getSpanOfEnclosingComment/getSpanOfEnclosingComment1.ets'), 663, false], + '3': [resolveTestPath('test/testcases/getSpanOfEnclosingComment/getSpanOfEnclosingComment2.ets'), 663, false] + }, + provideInlayHints: { + expectedFilePath: resolveTestPath('test/expected/provideInlayHints.json'), + '1': [ + resolveTestPath('test/testcases/provideInlayHints/provideInlayHints1.ets'), + { start: 712, length: 11 } as TextSpan + ] + }, + getSignatureHelpItems: { + expectedFilePath: resolveTestPath('test/expected/getSignatureHelpItems.json'), + '1': [resolveTestPath('test/testcases/getSignatureHelpItems/getSignatureHelpItems1.ets'), 613], + '2': [resolveTestPath('test/testcases/getSignatureHelpItems/getSignatureHelpItems1.ets'), 620], + '3': [resolveTestPath('test/testcases/getSignatureHelpItems/getSignatureHelpItems1.ets'), 678] + } +}; + +export const getSpanOfEnclosingCommentTests = testCases.getSpanOfEnclosingComment; diff --git a/ets2panda/bindings/test/expected/getCompletionAtPosition.json b/ets2panda/bindings/test/expected/getCompletionAtPosition.json new file mode 100644 index 0000000000000000000000000000000000000000..043a9b5580a8653f7583d0d812e8b37f900d3ed4 --- /dev/null +++ b/ets2panda/bindings/test/expected/getCompletionAtPosition.json @@ -0,0 +1,190 @@ +{ + "1": [ + { + "name": "num1", + "sortText": "15", + "insertText": "", + "kind": 3, + "data": null + }, + { + "name": "num2", + "sortText": "15", + "insertText": "", + "kind": 3, + "data": null + } + ], + "2": [ + { + "name": "aaa", + "sortText": "15", + "insertText": "", + "kind": 6, + "data": null + }, + { + "name": "abb", + "sortText": "15", + "insertText": "", + "kind": 21, + "data": null + }, + { + "name": "axx", + "sortText": "15", + "insertText": "", + "kind": 3, + "data": null + } + ], + "3": [ + { + "name": "baa", + "sortText": "15", + "insertText": "", + "kind": 6, + "data": null + }, + { + "name": "bbb", + "sortText": "15", + "insertText": "", + "kind": 6, + "data": null + }, + { + "name": "bcc", + "sortText": "15", + "insertText": "", + "kind": 6, + "data": null + }, + { + "name": "bxx", + "sortText": "15", + "insertText": "", + "kind": 3, + "data": null + } + ], + "4": [ + { + "name": "baa", + "sortText": "15", + "insertText": "", + "kind": 6, + "data": null + }, + { + "name": "bbb", + "sortText": "15", + "insertText": "", + "kind": 6, + "data": null + }, + { + "name": "bxx", + "sortText": "15", + "insertText": "", + "kind": 3, + "data": null + } + ], + "5": [ + { + "name": "myProp", + "sortText": "14", + "insertText": "", + "kind": 10, + "data": null + } + ], + "6": [ + { + "name": "classInSpace", + "sortText": "13", + "insertText": "", + "kind": 7, + "data": null + } + ], + "7": [ + { + "name": "Red", + "sortText": "13", + "insertText": "", + "kind": 20, + "data": null + } + ], + "8": [], + "9": [ + { + "name": "number", + "sortText": "15", + "insertText": "", + "kind": 14, + "data": null + } + ], + "10": [ + { + "name": "classInSpace", + "sortText": "13", + "insertText": "", + "kind": 7, + "data": null + } + ], + "11": [ + { + "name": "Blue", + "sortText": "13", + "insertText": "", + "kind": 20, + "data": null + }, + { + "name": "Red", + "sortText": "13", + "insertText": "", + "kind": 20, + "data": null + } + ], + "12": [ + { + "name": "myProp", + "sortText": "14", + "insertText": "", + "kind": 10, + "data": null + }, + { + "name": "prop", + "sortText": "14", + "insertText": "", + "kind": 10, + "data": null + } + ], + "13": [ + { + "name": "key", + "sortText": "17", + "insertText": "", + "kind": 2, + "data": null + } + ], + "14": [ + { + "name": "key", + "sortText": "17", + "insertText": "", + "kind": 2, + "data": null + } + ] +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getCurrentTokenValue.json b/ets2panda/bindings/test/expected/getCurrentTokenValue.json new file mode 100644 index 0000000000000000000000000000000000000000..2efc1c7dcc7425280098742dee114aaf29f47d4e --- /dev/null +++ b/ets2panda/bindings/test/expected/getCurrentTokenValue.json @@ -0,0 +1,6 @@ +{ + "1": "ab", + "2": "ab", + "3": "ab", + "4": "ab" +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getDefinitionAtPosition.json b/ets2panda/bindings/test/expected/getDefinitionAtPosition.json new file mode 100644 index 0000000000000000000000000000000000000000..74bd51b3c26f3f49e8838394eed310a2e59b72d1 --- /dev/null +++ b/ets2panda/bindings/test/expected/getDefinitionAtPosition.json @@ -0,0 +1,52 @@ +{ + "1": { + "fileName": "getDefinitionAtPosition1.ets", + "start": 625, + "length": 1 + }, + "2": { + "fileName": "getDefinitionAtPosition3.ets", + "start": 618, + "length": 1 + }, + "3": { + "fileName": "getDefinitionAtPosition4.ets", + "start": 625, + "length": 1 + }, + "4": { + "fileName": "getDefinitionAtPosition6.ets", + "start": 626, + "length": 3 + }, + "5": { + "fileName": "getDefinitionAtPosition8.ets", + "start": 625, + "length": 1 + }, + "6": { + "fileName": "getDefinitionAtPosition10.ets", + "start": 626, + "length": 3 + }, + "7": { + "fileName": "getDefinitionAtPosition12.ets", + "start": 620, + "length": 1 + }, + "8": { + "fileName": "getDefinitionAtPosition14.ets", + "start": 626, + "length": 1 + }, + "9": { + "fileName": "getDefinitionAtPosition16.ets", + "start": 622, + "length": 3 + }, + "10": { + "fileName": "text.d.ets", + "start": 7586, + "length": 4 + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getDocumentHighlights.json b/ets2panda/bindings/test/expected/getDocumentHighlights.json new file mode 100644 index 0000000000000000000000000000000000000000..49190c9ce2c7e36b26677db053333613d4eb04fc --- /dev/null +++ b/ets2panda/bindings/test/expected/getDocumentHighlights.json @@ -0,0 +1,317 @@ +{ + "1": { + "documentHighlights": [ + { + "fileName": "getDocumentHighlights1.ets", + "highlightSpans": [ + { + "fileName": "getDocumentHighlights1.ets", + "textSpan": { + "start": 613, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 3 + }, + { + "fileName": "getDocumentHighlights1.ets", + "textSpan": { + "start": 634, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + }, + { + "fileName": "getDocumentHighlights1.ets", + "textSpan": { + "start": 661, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + } + ] + } + ] + }, + "2": { + "documentHighlights": [ + { + "fileName": "getDocumentHighlights2.ets", + "highlightSpans": [ + { + "fileName": "getDocumentHighlights2.ets", + "textSpan": { + "start": 628, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 3 + }, + { + "fileName": "getDocumentHighlights2.ets", + "textSpan": { + "start": 655, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + }, + { + "fileName": "getDocumentHighlights2.ets", + "textSpan": { + "start": 716, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + } + ] + } + ] + }, + "3": { + "documentHighlights": [ + { + "fileName": "getDocumentHighlights3.ets", + "highlightSpans": [ + { + "fileName": "getDocumentHighlights3.ets", + "textSpan": { + "start": 615, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 3 + }, + { + "fileName": "getDocumentHighlights3.ets", + "textSpan": { + "start": 660, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + }, + { + "fileName": "getDocumentHighlights3.ets", + "textSpan": { + "start": 718, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + } + ] + } + ] + }, + "4": { + "documentHighlights": [ + { + "fileName": "getDocumentHighlights4.ets", + "highlightSpans": [ + { + "fileName": "getDocumentHighlights4.ets", + "textSpan": { + "start": 625, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 3 + }, + { + "fileName": "getDocumentHighlights4.ets", + "textSpan": { + "start": 672, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + }, + { + "fileName": "getDocumentHighlights4.ets", + "textSpan": { + "start": 741, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + }, + { + "fileName": "getDocumentHighlights4.ets", + "textSpan": { + "start": 752, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + } + ] + } + ] + }, + "5": { + "documentHighlights": [ + { + "fileName": "getDocumentHighlights5.ets", + "highlightSpans": [ + { + "fileName": "getDocumentHighlights5.ets", + "textSpan": { + "start": 618, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 3 + }, + { + "fileName": "getDocumentHighlights5.ets", + "textSpan": { + "start": 696, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + }, + { + "fileName": "getDocumentHighlights5.ets", + "textSpan": { + "start": 740, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + } + ] + } + ] + }, + "6": { + "documentHighlights": [ + { + "fileName": "getDocumentHighlights6.ets", + "highlightSpans": [ + { + "fileName": "getDocumentHighlights6.ets", + "textSpan": { + "start": 615, + "length": 8 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 3 + }, + { + "fileName": "getDocumentHighlights6.ets", + "textSpan": { + "start": 653, + "length": 8 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + } + ] + } + ] + }, + "7": { + "documentHighlights": [ + { + "fileName": "getDocumentHighlights7.ets", + "highlightSpans": [ + { + "fileName": "getDocumentHighlights7.ets", + "textSpan": { + "start": 618, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 3 + }, + { + "fileName": "getDocumentHighlights7.ets", + "textSpan": { + "start": 732, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + }, + { + "fileName": "getDocumentHighlights7.ets", + "textSpan": { + "start": 745, + "length": 3 + }, + "contextSpan": { + "start": 0, + "length": 0 + }, + "kind": 2 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getFileReferences.json b/ets2panda/bindings/test/expected/getFileReferences.json new file mode 100644 index 0000000000000000000000000000000000000000..270729c437bc25ccff94f07becd5a81f684b8ba2 --- /dev/null +++ b/ets2panda/bindings/test/expected/getFileReferences.json @@ -0,0 +1,26 @@ +{ + "1": [ + { + "fileName": "getFileReferences1.ets", + "start": 625, + "length": 29 + }, + { + "fileName": "getFileReferences1.ets", + "start": 672, + "length": 29 + } + ], + "2": [ + { + "fileName": "getFileReferences2.ets", + "start": 625, + "length": 29 + }, + { + "fileName": "getFileReferences2.ets", + "start": 672, + "length": 29 + } + ] +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getQuickInfoAtPosition.json b/ets2panda/bindings/test/expected/getQuickInfoAtPosition.json new file mode 100644 index 0000000000000000000000000000000000000000..d8dd45871470028b82e634b66b599d7087f65e11 --- /dev/null +++ b/ets2panda/bindings/test/expected/getQuickInfoAtPosition.json @@ -0,0 +1,107 @@ +{ + "1": { + "kind": "", + "kindModifier": "static public readonly", + "textSpan": { + "start": 626, + "length": 1 + }, + "fileName": "getQuickInfoAtPosition1.ets", + "displayParts": [ + { + "text": "MyStrings", + "kind": "enumName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "A", + "kind": "enumMember" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "\"", + "kind": "punctuation" + }, + { + "text": "hello", + "kind": "text" + }, + { + "text": "\"", + "kind": "punctuation" + } + ] + }, + "2": { + "kind": "class", + "kindModifier": "", + "textSpan": { + "start": 615, + "length": 7 + }, + "fileName": "getQuickInfoAtPosition2.ets", + "displayParts": [ + { + "text": "class", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "MyClass", + "kind": "className" + } + ] + }, + "3": { + "kind": "property", + "kindModifier": "public abstract", + "textSpan": { + "start": 661, + "length": 3 + }, + "fileName": "getQuickInfoAtPosition3.ets", + "displayParts": [ + { + "text": "objI", + "kind": "interface" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "key", + "kind": "property" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "returnType" + } + ] + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getReferencesAtPosition.json b/ets2panda/bindings/test/expected/getReferencesAtPosition.json new file mode 100644 index 0000000000000000000000000000000000000000..526e1ac25619fc3bbc93bf40deaacb4d251492c5 --- /dev/null +++ b/ets2panda/bindings/test/expected/getReferencesAtPosition.json @@ -0,0 +1,53 @@ +{ + "1": [ + { + "fileName": "getReferencesAtPosition1.ets", + "start": 613, + "length": 1 + } + ], + "2": [ + { + "fileName": "getReferencesAtPosition2.ets", + "start": 620, + "length": 1 + }, + { + "fileName": "getReferencesAtPosition2.ets", + "start": 635, + "length": 1 + }, + { + "fileName": "getReferencesAtPosition2.ets", + "start": 665, + "length": 1 + }, + { + "fileName": "getReferencesAtPosition3.ets", + "start": 617, + "length": 1 + }, + { + "fileName": "getReferencesAtPosition3.ets", + "start": 667, + "length": 1 + } + ], + "3": [ + { + "fileName": "getReferencesAtPosition4.ets", + "start": 625, + "length": 1 + }, + { + "fileName": "getReferencesAtPosition5.ets", + "start": 617, + "length": 1 + }, + { + "fileName": "getReferencesAtPosition5.ets", + "start": 655, + "length": 1 + } + ] +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getSemanticDiagnostics.json b/ets2panda/bindings/test/expected/getSemanticDiagnostics.json new file mode 100644 index 0000000000000000000000000000000000000000..679a81c0565df7ffcaec412a54ad8a473b295304 --- /dev/null +++ b/ets2panda/bindings/test/expected/getSemanticDiagnostics.json @@ -0,0 +1,75 @@ +{ + "1": { + "diagnostics": [] + }, + "2": { + "diagnostics": [ + { + "message": "Type '\"1\"' is not compatible with type 'double' at index 1", + "source": "\"1\"", + "range": { + "start": { + "line": 20, + "character": 5 + }, + "end": { + "line": 20, + "character": 8 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "No matching call signature for add(\"1\", int)", + "source": "add", + "range": { + "start": { + "line": 20, + "character": 1 + }, + "end": { + "line": 20, + "character": 4 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Type '\"hello\"' cannot be assigned to type 'double'", + "source": "\"hello\"", + "range": { + "start": { + "line": 16, + "character": 19 + }, + "end": { + "line": 16, + "character": 26 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + } + ] + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getSignatureHelpItems.json b/ets2panda/bindings/test/expected/getSignatureHelpItems.json new file mode 100644 index 0000000000000000000000000000000000000000..51881ad082d114fead94544196db25c846c52d88 --- /dev/null +++ b/ets2panda/bindings/test/expected/getSignatureHelpItems.json @@ -0,0 +1,299 @@ +{ + "1": { + "items": [ + { + "prefixDisplayParts": [ + { + "text": "(", + "kind": "punctuation" + } + ], + "suffixDisplayParts": [ + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "void", + "kind": "typeName" + } + ], + "separatorDisplayParts": [], + "parameters": [ + { + "name": "a", + "documentation": [], + "displayParts": [ + { + "text": "a", + "kind": "paramName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "double", + "kind": "typeName" + }, + { + "text": ",", + "kind": "punctuation" + } + ] + }, + { + "name": "b", + "documentation": [], + "displayParts": [ + { + "text": "b", + "kind": "paramName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "String", + "kind": "typeName" + } + ] + } + ], + "documentation": [] + } + ], + "applicableSpan": { + "start": 609, + "length": 65 + }, + "selectedItemIndex": 0, + "argumentIndex": 1, + "argumentCount": 1 + }, + "2": { + "items": [ + { + "prefixDisplayParts": [ + { + "text": "(", + "kind": "punctuation" + } + ], + "suffixDisplayParts": [ + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "void", + "kind": "typeName" + } + ], + "separatorDisplayParts": [], + "parameters": [ + { + "name": "a", + "documentation": [], + "displayParts": [ + { + "text": "a", + "kind": "paramName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "double", + "kind": "typeName" + }, + { + "text": ",", + "kind": "punctuation" + } + ] + }, + { + "name": "b", + "documentation": [], + "displayParts": [ + { + "text": "b", + "kind": "paramName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "String", + "kind": "typeName" + } + ] + } + ], + "documentation": [] + } + ], + "applicableSpan": { + "start": 609, + "length": 65 + }, + "selectedItemIndex": 0, + "argumentIndex": 1, + "argumentCount": 1 + }, + "3": { + "items": [ + { + "prefixDisplayParts": [ + { + "text": "(", + "kind": "punctuation" + } + ], + "suffixDisplayParts": [ + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "void", + "kind": "typeName" + } + ], + "separatorDisplayParts": [], + "parameters": [ + { + "name": "a", + "documentation": [], + "displayParts": [ + { + "text": "a", + "kind": "paramName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "double", + "kind": "typeName" + }, + { + "text": ",", + "kind": "punctuation" + } + ] + }, + { + "name": "b", + "documentation": [], + "displayParts": [ + { + "text": "b", + "kind": "paramName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "String", + "kind": "typeName" + } + ] + } + ], + "documentation": [] + }, + { + "prefixDisplayParts": [ + { + "text": "(", + "kind": "punctuation" + } + ], + "suffixDisplayParts": [ + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "void", + "kind": "typeName" + } + ], + "separatorDisplayParts": [], + "parameters": [ + { + "name": "a", + "documentation": [], + "displayParts": [ + { + "text": "a", + "kind": "paramName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "double", + "kind": "typeName" + }, + { + "text": ",", + "kind": "punctuation" + } + ] + }, + { + "name": "b", + "documentation": [], + "displayParts": [ + { + "text": "b", + "kind": "paramName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": "String", + "kind": "typeName" + } + ] + } + ], + "documentation": [] + } + ], + "applicableSpan": { + "start": 675, + "length": 15 + }, + "selectedItemIndex": 0, + "argumentIndex": 1, + "argumentCount": 0 + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getSpanOfEnclosingComment.json b/ets2panda/bindings/test/expected/getSpanOfEnclosingComment.json new file mode 100644 index 0000000000000000000000000000000000000000..10e44761c4c7f610708c88334bab57ec50979c4f --- /dev/null +++ b/ets2panda/bindings/test/expected/getSpanOfEnclosingComment.json @@ -0,0 +1,14 @@ +{ + "1": { + "start": 0, + "length": 0 + }, + "2": { + "start": 659, + "length": 6 + }, + "3": { + "start": 659, + "length": 9 + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getSuggestionDiagnostics.json b/ets2panda/bindings/test/expected/getSuggestionDiagnostics.json new file mode 100644 index 0000000000000000000000000000000000000000..cd3d78acf8f1199d3918b328ceab6e0403ffaafe --- /dev/null +++ b/ets2panda/bindings/test/expected/getSuggestionDiagnostics.json @@ -0,0 +1,534 @@ +{ + "1": { + "diagnostics": [ + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 609 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 609 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 609 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 609 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 618 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 618 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 618 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 618 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 618 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 618 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 618 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 15, + "character": 618 + }, + "end": { + "line": 17, + "character": 661 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 662 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 662 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 662 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 662 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 671 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 671 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 671 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 671 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 671 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 671 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 671 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + }, + { + "message": "This_may_be_converted_to_an_async_function", + "source": "", + "range": { + "start": { + "line": 18, + "character": 671 + }, + "end": { + "line": 20, + "character": 717 + } + }, + "tags": [], + "relatedInfo": [], + "code": 0, + "data": 0, + "severity": 4, + "codeDescription": { + "href": "" + } + } + ] + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json b/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json new file mode 100644 index 0000000000000000000000000000000000000000..2ed128d561f1f5ac1426fe6fbeabf5752a076545 --- /dev/null +++ b/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json @@ -0,0 +1,295 @@ +{ + "1": { + "diagnostics": [] + }, + "2": { + "diagnostics": [ + { + "message": "Unexpected token 'add'.", + "source": "add", + "range": { + "start": { + "line": 16, + "character": 9 + }, + "end": { + "line": 16, + "character": 12 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token, expected ',' or ')'.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 14 + }, + "end": { + "line": 16, + "character": 15 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token ':'.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 14 + }, + "end": { + "line": 16, + "character": 15 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token ':'.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 14 + }, + "end": { + "line": 16, + "character": 15 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token ':'.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 14 + }, + "end": { + "line": 16, + "character": 15 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token ','.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 22 + }, + "end": { + "line": 16, + "character": 23 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token ','.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 22 + }, + "end": { + "line": 16, + "character": 23 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token ','.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 22 + }, + "end": { + "line": 16, + "character": 23 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Label must be followed by a loop statement.", + "source": "", + "range": { + "start": { + "line": 16, + "character": 27 + }, + "end": { + "line": 16, + "character": 33 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token ')'.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 33 + }, + "end": { + "line": 16, + "character": 34 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token ')'.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 33 + }, + "end": { + "line": 16, + "character": 34 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "Unexpected token ')'.", + "source": "*ERROR_LITERAL*", + "range": { + "start": { + "line": 16, + "character": 33 + }, + "end": { + "line": 16, + "character": 34 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + }, + { + "message": "return keyword should be used in function body.", + "source": "return ((a) + (b));", + "range": { + "start": { + "line": 17, + "character": 5 + }, + "end": { + "line": 17, + "character": 18 + } + }, + "tags": [], + "relatedInfo": [], + "code": 1, + "data": 0, + "severity": 1, + "codeDescription": { + "href": "test code description" + } + } + ] + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/provideInlayHints.json b/ets2panda/bindings/test/expected/provideInlayHints.json new file mode 100644 index 0000000000000000000000000000000000000000..2fcb8921af2f206fc19a95241126550f0e14bd1a --- /dev/null +++ b/ets2panda/bindings/test/expected/provideInlayHints.json @@ -0,0 +1,18 @@ +{ + "1": [ + { + "text": "param1", + "number": 716, + "kind": 1, + "whitespaceBefore": false, + "whitespaceAfter": true + }, + { + "text": "param2", + "number": 720, + "kind": 1, + "whitespaceBefore": false, + "whitespaceAfter": true + } + ] +} \ No newline at end of file diff --git a/ets2panda/bindings/test/expected/toLineColumnOffset.json b/ets2panda/bindings/test/expected/toLineColumnOffset.json new file mode 100644 index 0000000000000000000000000000000000000000..df135e00843c85304cca7f3dea794ca01f3d70c5 --- /dev/null +++ b/ets2panda/bindings/test/expected/toLineColumnOffset.json @@ -0,0 +1,10 @@ +{ + "1": { + "line": 0, + "character": 0 + }, + "2": { + "line": 17, + "character": 642 + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/prepare.ps1 b/ets2panda/bindings/test/prepare.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..ac679d55c1f18c078c27a0b1b28069f20234cdc6 --- /dev/null +++ b/ets2panda/bindings/test/prepare.ps1 @@ -0,0 +1,65 @@ +# 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. + +# This script will replace the old paths with the new ones in all files within the testcases directory. + +$ErrorActionPreference = "Stop" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path + +# Check if the 'ets' directory exists in ScriptDir +if (-not (Test-Path -Path "$ScriptDir\ets" -PathType Container)) { + Write-Error "Error: 'ets' directory not found in $ScriptDir." + Write-Error "Please make sure the 'ets' directory exists before running bindings test." + exit 1 +} + +$RestoreMode = 0 +if ($args.Count -gt 0 -and $args[0] -eq "--restore") { + $RestoreMode = 1 +} + +if ($RestoreMode -eq 1) { + if (Test-Path -Path "$ScriptDir\..\ets2panda") { + Remove-Item -Path "$ScriptDir\..\ets2panda" -Recurse -Force + Write-Host "Removed '$ScriptDir\..\ets2panda' directory." + } +} +else { + $sourceDir = "$ScriptDir\ets\ets1.2\build-tools\ets2panda" + $destinationDir = "$ScriptDir\..\ets2panda" + + # Check if source directory exists + if (-not (Test-Path -Path $sourceDir -PathType Container)) { + Write-Error "Source directory '$sourceDir' does not exist." + exit 1 + } + + # Remove destination directory if it exists + if (Test-Path -Path $destinationDir) { + Remove-Item -Path $destinationDir -Recurse -Force + } + + # Copy directory + try { + Copy-Item -Path $sourceDir -Destination $destinationDir -Recurse -Force + Write-Host "Directory copied successfully from '$sourceDir' to '$destinationDir'." + } + catch { + Write-Error "Failed to copy directory." + Write-Error $_.Exception.Message + exit 1 + } +} + +exit 0 \ No newline at end of file diff --git a/ets2panda/bindings/test/prepare.sh b/ets2panda/bindings/test/prepare.sh new file mode 100755 index 0000000000000000000000000000000000000000..c56f56120a7221614e61fa64ebd00173abc8f024 --- /dev/null +++ b/ets2panda/bindings/test/prepare.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env 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. + +# This script will replace the old paths with the new ones in all files within the testcases directory. + +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Check if the 'ets' directory exists in SCRIPT_DIR +if [ ! -d "${SCRIPT_DIR}/ets" ]; then + echo "Error: 'ets' directory not found in ${SCRIPT_DIR}." + echo "Please make sure the 'ets' directory exists before running bindings test." + exit 1 +fi + +RESTORE_MODE=0 +if [ "$1" == "--restore" ]; then + RESTORE_MODE=1 +fi + +if [ $RESTORE_MODE -eq 1 ]; then + rm "${SCRIPT_DIR}/../ets2panda" + echo 'Remove the symbolic link to ets2panda' +else + ln -s "${SCRIPT_DIR}/ets/ets1.2/build-tools/ets2panda" "${SCRIPT_DIR}/../ets2panda" + echo 'Create a symbolic link to ets2panda' +fi + +exit 0 diff --git a/ets2panda/bindings/test/run_tests.ts b/ets2panda/bindings/test/run_tests.ts new file mode 100644 index 0000000000000000000000000000000000000000..ecb0adaa1651af5c538924461a4f880994f960d2 --- /dev/null +++ b/ets2panda/bindings/test/run_tests.ts @@ -0,0 +1,348 @@ +/* + * 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 path from 'path'; +import fs from 'fs'; +import { + Lsp, + LspDefinitionData, + LspCompletionInfo, + LspDiagsNode, + ModuleDescriptor, + generateArkTsConfigByModules +} from '../src/index'; +import { testCases } from './cases'; +import { LspCompletionEntry } from '../src/lspNode'; + +interface ComparisonOptions { + subMatch?: boolean; +} + +interface ComparisonOutcome { + passed: boolean; + expectedJSON?: string; + actualJSON?: string; +} + +let updateMode = false; + +function getModules(projectRoot: string): ModuleDescriptor[] { + return Object.keys(testCases).map((name) => { + const modulePath = path.join(projectRoot, name); + return { + arktsversion: '1.2', + name, + moduleType: 'har', + srcPath: modulePath + } as ModuleDescriptor; + }); +} + +// CC-OFFNXT(no_explicit_any) project code style +function getExpectedResult(filePath: string): any { + try { + return JSON.parse(fs.readFileSync(filePath, 'utf-8')); + } catch (err) { + console.error(`Failed to read expected result from ${filePath}: ${err}`); + return null; + } +} + +function sortCompletions(completionResult: LspCompletionInfo): LspCompletionInfo { + if (!completionResult || !completionResult.entries || !Array.isArray(completionResult.entries)) { + return completionResult; + } + + // Sort entries by name + completionResult.entries.sort((a, b) => { + const nameA = a.name.toString().toLowerCase(); + const nameB = b.name.toString().toLowerCase(); + return nameA.localeCompare(nameB); + }); + + return completionResult; +} + +function sortDiagnostics(diags: LspDiagsNode): LspDiagsNode { + if (!diags || !diags.diagnostics || !Array.isArray(diags.diagnostics)) { + return diags; + } + + diags.diagnostics.sort((a, b) => { + if (a.range.start.line !== b.range.start.line) { + return a.range.start.line - b.range.start.line; + } + + if (a.range.start.character !== b.range.start.character) { + return a.range.start.character - b.range.start.character; + } + + if (a.range.end.line !== b.range.end.line) { + return a.range.end.line - b.range.end.line; + } + + return a.range.end.character - b.range.end.character; + }); + + return diags; +} + +// CC-OFFNXT(no_explicit_any) project code style +function sortActualResult(testName: string, res: any): any { + if (testName === 'getCompletionAtPosition') { + return sortCompletions(res as LspCompletionInfo); + } + if (testName === 'getSuggestionDiagnostics') { + return sortDiagnostics(res as LspDiagsNode); + } + return res; +} + +// CC-OFFNXT(no_explicit_any) project code style +function normalizeData(obj: any): any { + if (Array.isArray(obj)) { + return obj.map(normalizeData); + } else if (obj && typeof obj === 'object') { + const newObj = { ...obj }; + if ('peer' in newObj) { + delete newObj.peer; // do not compare peer + } + if (newObj.fileName) { + newObj.fileName = path.basename(newObj.fileName); + } + for (const key of Object.keys(newObj)) { + newObj[key] = normalizeData(newObj[key]); + } + return newObj; + } + return obj; +} + +// CC-OFFNXT(no_explicit_any) project code style +function isSubObject(actual: any, expected: any): boolean { + if (typeof expected !== 'object' || expected === null) { + return actual === expected; + } + + if (typeof actual !== 'object' || actual === null) { + return false; + } + + if (Array.isArray(expected)) { + if (!Array.isArray(actual)) { + return false; + } + return expected.every((expectedItem) => actual.some((actualItem) => isSubObject(actualItem, expectedItem))); + } + + for (const key in expected) { + if (Object.prototype.hasOwnProperty.call(expected, key)) { + if (!Object.prototype.hasOwnProperty.call(actual, key)) { + return false; + } + if (!isSubObject(actual[key], expected[key])) { + return false; + } + } + } + + return true; +} + +function performComparison( + normalizedActual: unknown, + expected: unknown, + options: ComparisonOptions = {} +): ComparisonOutcome { + const { subMatch = false } = options; + if (subMatch) { + if (isSubObject(normalizedActual, expected)) { + return { passed: true }; + } + return { + passed: false, + expectedJSON: JSON.stringify(expected, null, 2), + actualJSON: JSON.stringify(normalizedActual, null, 2) + }; + } + + const actualJSON = JSON.stringify(normalizedActual, null, 2); + const expectedJSON = JSON.stringify(expected, null, 2); + + if (actualJSON === expectedJSON) { + return { passed: true }; + } + + return { + passed: false, + expectedJSON: expectedJSON, + actualJSON: actualJSON + }; +} + +function compareResultsHelper( + testName: string, + normalizedActual: unknown, + expected: unknown, + options: ComparisonOptions = {} +): boolean { + const comparison = performComparison(normalizedActual, expected, options); + + if (comparison.passed) { + console.log(`[${testName}] ✅ Passed`); + return true; + } + + console.log(`[${testName}] ❌ Failed`); + console.log(`Expected: ${comparison.expectedJSON}`); + console.log(`Actual: ${comparison.actualJSON}`); + return false; +} + +function compareGetCompletionResult(testName: string, actual: unknown, expected: unknown): boolean { + const completionResult = actual as LspCompletionInfo; + const actualEntries = completionResult.entries as LspCompletionEntry[]; + const expectedEntries = expected as { + name: string; + sortText: string; + insertText: string; + kind: number; + data: null; + }[]; + + return compareResultsHelper(testName, normalizeData(actualEntries), expectedEntries, { + subMatch: true + } as ComparisonOptions); +} + +function findTextDefinitionPosition(sourceCode: string): number { + const textDefinitionPattern = /export\s+declare\s+function\s+Text\(/; + const match = textDefinitionPattern.exec(sourceCode); + if (match) { + const functionTextPattern = /function\s+Text\(/; + const subMatch = functionTextPattern.exec(sourceCode.substring(match.index)); + if (subMatch) { + const positionOfT = match.index + subMatch.index + 'function '.length; + return positionOfT; + } + } + throw new Error('Could not find Text definition in source code'); +} + +function compareGetDefinitionResult(testName: string, actual: any, expected: Record): boolean { + // This is the definition info for the UI component. + // File in the SDK might changed, so the offset needs to be checked dynamically. + if (expected['fileName'] === 'text.d.ets') { + const actualDef = actual as LspDefinitionData; + const fileName = actualDef.fileName as string; + const fileContent = fs.readFileSync(fileName, 'utf8'); + const expectedStart = findTextDefinitionPosition(fileContent); + const expectedResult = { + ...expected, + start: expectedStart + }; + return compareResultsHelper(testName, normalizeData(actual), expectedResult); + } + return compareResultsHelper(testName, normalizeData(actual), expected); +} + +// CC-OFFNXT(no_explicit_any) project code style +function compareResults(testName: string, index: string, actual: unknown, expected: unknown): boolean { + const name = `${testName}:${index}`; + if (testName === 'getDefinitionAtPosition') { + return compareGetDefinitionResult(name, actual, expected as Record); + } + if (testName === 'getCompletionAtPosition') { + return compareGetCompletionResult(name, actual, expected); + } + + return compareResultsHelper(name, normalizeData(actual), expected); +} + +function runTests(testDir: string, lsp: Lsp) { + console.log('Running tests...'); + if (!testCases) { + console.error('Failed to load test cases'); + return; + } + + let failedList: string[] = []; + for (const [testName, testConfig] of Object.entries(testCases)) { + const { expectedFilePath, ...testCaseVariants } = testConfig; + const expectedResult = getExpectedResult(expectedFilePath); + if (expectedResult === null) { + console.error(`[${testName}] Skipped (expected result not found)`); + continue; + } + // CC-OFFNXT(no_explicit_any) project code style + if (typeof (lsp as any)[testName] !== 'function') { + console.error(`[${testName}] ❌ Error: Method "${testName}" not found on Lsp object`); + continue; + } + + for (const [index, params] of Object.entries(testCaseVariants)) { + let pass = false; + let actualResult = null; + try { + // CC-OFFNXT(no_explicit_any) project code style + actualResult = (lsp as any)[testName](...params); + actualResult = sortActualResult(testName, actualResult); + pass = compareResults(testName, index, actualResult, expectedResult[index]); + } catch (error) { + console.error(`[${testName}:${index}] ❌ Error: ${error}`); + } + if (!pass) { + failedList.push(`${testName}:${index}`); + } + if (!pass && updateMode) { + console.log(`Updating expected result for ${testName}:${index}`); + expectedResult[index] = normalizeData(actualResult); + } + } + if (updateMode) { + fs.writeFileSync(expectedFilePath, JSON.stringify(expectedResult, null, 2)); + } + console.log(`Finished test: ${testName}`); + console.log('-----------------------------------'); + } + console.log('Tests completed.'); + if (failedList.length > 0) { + console.log('❌ Failed tests:'); + failedList.forEach((failedCase) => { + console.log(`- ${failedCase}`); + }); + } +} + +if (require.main === module) { + if (process.argv.length < 3) { + console.error('Usage: node run_tests.js '); + process.exit(1); + } + // If update flag is passed, update the expected result files + if (process.argv[3] && process.argv[3] === '--update') { + updateMode = true; + } + const testDir = path.resolve(process.argv[2]); + const buildSdkPath = path.join(testDir, 'ets', 'ets1.2'); + const projectRoot = path.join(testDir, 'testcases'); + const modules = getModules(projectRoot); + + generateArkTsConfigByModules(buildSdkPath, projectRoot, modules); + const lsp = new Lsp(projectRoot); + + process.env.BINDINGS_PATH = path.join(buildSdkPath, 'build-tools', 'bindings'); + runTests(testDir, lsp); +} diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition1.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition1.ets new file mode 100644 index 0000000000000000000000000000000000000000..1d4247831e5b95a154961c0d129de80797fa4f9e --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition1.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. + */ + +function num1() { + return 1; +} + +function num2() { + return 2; +} + +console.log(1); + +let a = n \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition10.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition10.ets new file mode 100644 index 0000000000000000000000000000000000000000..b563112f61b9c0098169d19e5b620a6363d2e34c --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition10.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. + */ + +namespace space { + export class classInSpace { + public c: number = 2; + } +} +let numOfSpace: space. diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition11.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition11.ets new file mode 100644 index 0000000000000000000000000000000000000000..d5f9f2ac624b4ddb697c0b511dd9a80c7978b57b --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition11.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. + */ + +enum Color { + Red = "red", + Blue = "blue" +} +let myColor: Color = Color. \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition12.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition12.ets new file mode 100644 index 0000000000000000000000000000000000000000..87e6b926de9b4783b4878c9bb71c1032668c67a6 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition12.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. + */ + +class MyClass { + public myProp: number = 0; + public prop: number = 0; +} +let obj = new MyClass(); +let p = obj. +let a = 1; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition13.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition13.ets new file mode 100644 index 0000000000000000000000000000000000000000..47153d45763a22a3e2cd68c593f1965aca297b1e --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition13.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. + */ + +interface Inner { key : string; } +let i: Inner +i. +let a = 1; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition14.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition14.ets new file mode 100644 index 0000000000000000000000000000000000000000..e69f51bc2beadb667d8693077c3c6205e1b42574 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition14.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. + */ + +interface Inner { key : string; } +let i: Inner +i.k +let a = 1; \ No newline at end of file diff --git a/ets2panda/linter/test/interop/oh_modules/reflect_export_safe.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition2.ets similarity index 80% rename from ets2panda/linter/test/interop/oh_modules/reflect_export_safe.ets rename to ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition2.ets index 64ac6ea76a5f674eb375505d74e6a7f8f19c2322..740efcba7c4fd482148d459f05911c9f104edaa1 100644 --- a/ets2panda/linter/test/interop/oh_modules/reflect_export_safe.ets +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition2.ets @@ -13,8 +13,15 @@ * limitations under the License. */ -export function safeVersion(prx: Object) { - Reflect.get(prx, 'a') // 'hello' - Reflect.set(prx, 'a', 'world') // true - Reflect.ownKeys(prx) // ['a'] +let aaa = 123; +const abb = 333; + +function axx() { + return 444; +} + +function foo() { + let bbb = 222; + let ccc = bbb + a + return bbb + ccc; } \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition3.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition3.ets new file mode 100644 index 0000000000000000000000000000000000000000..e1b6f9cd79e7432c5ff06a9ab17046c082948b99 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition3.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Foo { + bar: number = 1; +} + +let foo = new Foo(); +foo.bar = 2; +let baa = 3; +let bbb = 4; + +function bxx() { + return 5; +} + +function fxx() { + let bcc = 6; + let axx = b +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition4.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition4.ets new file mode 100644 index 0000000000000000000000000000000000000000..36b649df574e6fcdecb87c391b02439d1cf53a92 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition4.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 Foo { + bar: number = 1; +} + +let foo = new Foo(); +foo.bar = 2; +let baa = 3; +let bbb = 4; + +function bxx() { + let bcc = 6; + return 5; +} +let axx = b \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition5.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition5.ets new file mode 100644 index 0000000000000000000000000000000000000000..a73540ca9db758a2ad0ebaa065594938b5527f2b --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition5.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. + */ + +class MyClass1 { + public myProp: number = 0; + public prop: number = 1; +} +let obj1 = new MyClass1() +let prop = obj1.yp \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition6.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition6.ets new file mode 100644 index 0000000000000000000000000000000000000000..8cf5346413a451e1fe3a2c87d32c40e5955e206c --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition6.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. + */ + +namespace space { + export class classInSpace { + public c: number = 2; + } +} +let numOfSpace: space.classi \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition7.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition7.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53589f4f374587839f6ccfcb729789646fd0f1b --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition7.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. + */ + +enum Color { + Red = "red", + Blue = "blue" +} +let myColor: Color = Color.R \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ts b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition8.ets similarity index 92% rename from ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ts rename to ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition8.ets index ed88cb6a2d9e247828708e561d02b06e512603ae..3409ce460c45ce30e9931e06854c621f0bed9ff4 100644 --- a/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ts +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition8.ets @@ -13,4 +13,4 @@ * limitations under the License. */ -export { worker } from '../oh_modules/@ohos.worker'; \ No newline at end of file +class \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition9.ets b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition9.ets new file mode 100644 index 0000000000000000000000000000000000000000..a0e0c15f46163ee4b3f71aa31f345587b83bfed8 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCompletionAtPosition/getCompletionsAtPosition9.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: num \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue1.ets b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue1.ets new file mode 100644 index 0000000000000000000000000000000000000000..e1b4fa850d1f6d701415d2690eb970405b429c0c --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue1.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. + */ + +ab \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue2.ets b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue2.ets new file mode 100644 index 0000000000000000000000000000000000000000..b3752d9f81967f9e0c3664608fa6d75be6167bda --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue2.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. + */ + +"ab" \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue3.ets b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue3.ets new file mode 100644 index 0000000000000000000000000000000000000000..884bb23fd4c8ee5c35ad86486eb91ae15ae7444d --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue3.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. + */ + +'ab' \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue4.ets b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue4.ets new file mode 100644 index 0000000000000000000000000000000000000000..d6df2324cfbcd221bd36202b55a88267246411c1 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getCurrentTokenValue/getCurrentTokenValue4.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. + */ + +abc \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition1.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition1.ets new file mode 100644 index 0000000000000000000000000000000000000000..15c179144e7fcc06e81e081b2c213d1526e5d071 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition1.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 function A(a:number, b:number): number { + return a + b; +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition10.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition10.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd50405e8cb4bab936ad01b451de02f9a6e45499 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition10.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. + */ + +export class A { +Foo(a:number, b:number): number { + return a + b; +}}; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition11.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition11.ets new file mode 100644 index 0000000000000000000000000000000000000000..09e0ac8b85cea3b6722c624ac2504b037963a7c1 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition11.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. + */ + +import {A} from './getDefinitionAtPosition10'; +let a = new A(); +a.Foo(1, 2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition12.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition12.ets new file mode 100644 index 0000000000000000000000000000000000000000..c527ffc7238e7ee58f4edbc288f4d51c9a975160 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition12.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. + */ + +export let a = 1; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition13.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition13.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b7fd8781445b8b13fc78ba3fec1a6be414ce222 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition13.ets @@ -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. + */ + +import {a} from './getDefinitionAtPosition12'; +let b = a; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition14.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition14.ets new file mode 100644 index 0000000000000000000000000000000000000000..be0a8b16016326df03860de7bebf09114c85d5ad --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition14.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. + */ + +export interface I {} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition15.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition15.ets new file mode 100644 index 0000000000000000000000000000000000000000..179cd69d8b84e178a48952cb3e60b6191d10857c --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition15.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. + */ + +import {I} from './getDefinitionAtPosition14'; +import * as All from './getDefinitionAtPosition14'; +class A implements All.I {}; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition16.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition16.ets new file mode 100644 index 0000000000000000000000000000000000000000..e0aea4f53a7dc35ee22fa89915915e458ffc2a4b --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition16.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. + */ + +export class Foo { +Foo(a:number, b:number): number { + return a + b; +}} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition17.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition17.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc857dfeb21465336ebd095481cd941e5a67118d --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition17.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. + */ + +import * as All from './getDefinitionAtPosition16'; +let a = new All.Foo(); +a.Foo(1, 2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition18.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition18.ets new file mode 100644 index 0000000000000000000000000000000000000000..c54a0d1535beb24b839528d630e01201cd4010fa --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition18.ets @@ -0,0 +1,47 @@ +/* + * 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 { memo, __memo_context_type, __memo_id_type } from "@ohos.arkui.stateManagement"; +import { Text, Column, Component, Button, ClickEvent } from "@ohos.arkui.component"; + +import hilog from '@ohos.hilog'; + +@Component +export struct MyStateSample { + message: string = "Click"; + + build() { + Column(undefined) { + Text("Hello World") + .fontSize(20) + Button(this.message) + .backgroundColor("#FFFF00FF") + .onClick((e: ClickEvent) => { + hilog.info(0x0000, 'testTag', 'On Click'); + }) + Child() + } + } +} + +@Component +export struct Child { + stateVar: string = "Child"; + + build() { + Text(this.stateVar) + .fontSize(50) + } +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition2.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition2.ets new file mode 100644 index 0000000000000000000000000000000000000000..ff644354c7b56be43105f65185cb829d86d82657 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition2.ets @@ -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. + */ + +import {A} from './getDefinitionAtPosition1'; +A(1, 2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition3.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition3.ets new file mode 100644 index 0000000000000000000000000000000000000000..dbe14c69b85f9b3f47a6f9b4d78246ed2827d099 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition3.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. + */ + +function A(a:number, b:number) { + return a + b; +} +A(1, 2); +function A(a:number) { + return a; +} +A(1); diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition4.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition4.ets new file mode 100644 index 0000000000000000000000000000000000000000..15c179144e7fcc06e81e081b2c213d1526e5d071 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition4.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 function A(a:number, b:number): number { + return a + b; +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition5.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition5.ets new file mode 100644 index 0000000000000000000000000000000000000000..1598eef8a4db9c5cc0b9060f856c7ccba56352c3 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition5.ets @@ -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. + */ + +import * as All from './getDefinitionAtPosition4'; +All.A(1, 2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition6.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition6.ets new file mode 100644 index 0000000000000000000000000000000000000000..ef8ffe33f4d5cd7bbc2048036a12c88d9ca8fe51 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition6.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. + */ + +export class A { +Foo(a:number, b:number): number { + return a + b; +}} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition7.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition7.ets new file mode 100644 index 0000000000000000000000000000000000000000..a49397300d2cff32402da00a492279132fb493ef --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition7.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. + */ + +import * as All from './getDefinitionAtPosition6'; +let a = new All.A(); +a.Foo(1, 2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition8.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition8.ets new file mode 100644 index 0000000000000000000000000000000000000000..b414cf820fe50e1ff84cc3377884351564128dd6 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition8.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 enum A { +a, +b} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition9.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition9.ets new file mode 100644 index 0000000000000000000000000000000000000000..45f00993e7c446b77b8e21f33bd4a331eddc073c --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition9.ets @@ -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. + */ + +import * as All from './getDefinitionAtPosition8'; +All.A.a; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights1.ets b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights1.ets new file mode 100644 index 0000000000000000000000000000000000000000..76a3f0cf46865aca4a27d40ace111e496cfc2be5 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights1.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. + */ + +let aaa = 123; +let bbb = aaa + 111; +let ccc = bbb + aaa + 234; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights2.ets b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights2.ets new file mode 100644 index 0000000000000000000000000000000000000000..ded0ce54046dfc75eb6777b12605ca961bfde1c9 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights2.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. + */ + +let aaa = 123; +let bbb = aaa + 111; +let ccc = bbb + aaa + 234; +function f1(aaa: number) { + return aaa + bbb; +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights3.ets b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights3.ets new file mode 100644 index 0000000000000000000000000000000000000000..ce627f2bb7bc9a3c8c4d164eb5c627a24be61a3e --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights3.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. + */ + +class Foo { + aaa: number = 0; +} + +let foo1 = new Foo(); +foo1.aaa = 222 + +function f2() { + let foo2 = new Foo(); + return foo2.aaa + foo1.aaa; +} diff --git a/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights4.ets b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights4.ets new file mode 100644 index 0000000000000000000000000000000000000000..ce627f2bb7bc9a3c8c4d164eb5c627a24be61a3e --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights4.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. + */ + +class Foo { + aaa: number = 0; +} + +let foo1 = new Foo(); +foo1.aaa = 222 + +function f2() { + let foo2 = new Foo(); + return foo2.aaa + foo1.aaa; +} diff --git a/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights5.ets b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights5.ets new file mode 100644 index 0000000000000000000000000000000000000000..a287d390a92c7c68a91862c38f53e1a434c4ef62 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights5.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. + */ + +function add(x: number, y: number) { + return x + y; +} + +function five() { + return add(2, 3); +} + +class Bar { + six: number = add(2, 4); +} diff --git a/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights6.ets b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights6.ets new file mode 100644 index 0000000000000000000000000000000000000000..f90546953c572d5ee3ffd934f20a8f9f41f24e9c --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights6.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 ListNode { + value: T; + next: ListNode | null = null; + + constructor(value: T) { + this.value = value; + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights7.ets b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights7.ets new file mode 100644 index 0000000000000000000000000000000000000000..978e4efd6d2df862dc513be7b527e92fcd5f8c41 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDocumentHighlights/getDocumentHighlights7.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. + */ + +function fib(n: number) { + if (n === 0) { + return 0; + } + if (n === 1) { + return 1; + } + return fib(n - 1) + fib(n - 2); +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getFileReferences/getFileReferences1.ets b/ets2panda/bindings/test/testcases/getFileReferences/getFileReferences1.ets new file mode 100644 index 0000000000000000000000000000000000000000..45206d98aa97f45aaebb6947257ae72f2b678039 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getFileReferences/getFileReferences1.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. + */ + +import {A} from "./getFileReferences1_export"; +import {B} from "./getFileReferences1_export"; +A(1, 2); +B(1, 2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getFileReferences/getFileReferences1_export.ets b/ets2panda/bindings/test/testcases/getFileReferences/getFileReferences1_export.ets new file mode 100644 index 0000000000000000000000000000000000000000..77c482b8ce8d6a4876a6eb38a9abd9d1ba62e588 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getFileReferences/getFileReferences1_export.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. + */ + +export function A(a:number, b:number): number { + return a + b; +} +export function B(a:number, b:number): number { + return a + b; +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition1.ets b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition1.ets new file mode 100644 index 0000000000000000000000000000000000000000..f50e4bfbd5dd67a67dd3cff24ba514a3067e0c03 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition1.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. + */ + +enum MyStrings { A = 'hello' }; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition2.ets b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition2.ets new file mode 100644 index 0000000000000000000000000000000000000000..a7889745470909f675847a714ba2ebbfbf725626 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition2.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. + */ + +class MyClass { + public myProp: number = 0; +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition3.ets b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition3.ets new file mode 100644 index 0000000000000000000000000000000000000000..ab0913585dd0a72aa53f9106e9508e1584a8bc88 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getQuickInfoAtPosition/getQuickInfoAtPosition3.ets @@ -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. + */ + +interface objI { key : string; } +let obj : objI = { key:"valueaaaaaaaaa," } \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition1.ets b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition1.ets new file mode 100644 index 0000000000000000000000000000000000000000..3a56d3e05d8760e8d98ebbd264c69684f183a545 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition1.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 diff --git a/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition2.ets b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition2.ets new file mode 100644 index 0000000000000000000000000000000000000000..1ae5e4a07626e6ccdd0ac9237893d731ad23e925 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition2.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. + */ + +export let a = 1; +let b = a; +function C() { + let c = a; +}; +function D() { + let a = 1; +}; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition3.ets b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition3.ets new file mode 100644 index 0000000000000000000000000000000000000000..e0a302229e25c9f7f7d6995db95441b38d3f2c72 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition3.ets @@ -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. + */ + +import {a} from './getReferencesAtPosition2'; +console.log(a); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition4.ets b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition4.ets new file mode 100644 index 0000000000000000000000000000000000000000..494046b0c39f525bb79f20b669869c3d23f82d7d --- /dev/null +++ b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition4.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. + */ + +export function A(){}; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition5.ets b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition5.ets new file mode 100644 index 0000000000000000000000000000000000000000..55b0a4e86a2440f7a1f3dcb0ec20953530c797fd --- /dev/null +++ b/ets2panda/bindings/test/testcases/getReferencesAtPosition/getReferencesAtPosition5.ets @@ -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. + */ + +import {A} from './getReferencesAtPosition4'; +A(); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics1.ets b/ets2panda/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics1.ets new file mode 100644 index 0000000000000000000000000000000000000000..7f2a3720c40450e024f050070a6a3ec706dfa0ee --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics1.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. + */ + +function add(a: number, b: number) { + return a + b; +} +let n = 333; +let res = add(n, n); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics2.ets b/ets2panda/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics2.ets new file mode 100644 index 0000000000000000000000000000000000000000..859d052f4d44d353ceeb5c0ee7c709fb5b75b5cf --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSemanticDiagnostics/getSemanticDiagnostics2.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. + */ + +const a: number = "hello"; +function add(a: number, b: number): number { + return a + b; +} +add("1", 2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getSignatureHelpItems/getSignatureHelpItems1.ets b/ets2panda/bindings/test/testcases/getSignatureHelpItems/getSignatureHelpItems1.ets new file mode 100644 index 0000000000000000000000000000000000000000..fc4ebb691ae3db8f38eff3d873346482cc815b1c --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSignatureHelpItems/getSignatureHelpItems1.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. + */ + +function test(a: number, b: string): void { + console.log(a); +} +test(1, "test"); diff --git a/ets2panda/bindings/test/testcases/getSpanOfEnclosingComment/getSpanOfEnclosingComment1.ets b/ets2panda/bindings/test/testcases/getSpanOfEnclosingComment/getSpanOfEnclosingComment1.ets new file mode 100644 index 0000000000000000000000000000000000000000..447a4e414d153dd89d8844e588a1f5510c022bb5 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSpanOfEnclosingComment/getSpanOfEnclosingComment1.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. + */ + +function A(a:number, b:number) { + return a + b; // add +} +A(1, 2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getSpanOfEnclosingComment/getSpanOfEnclosingComment2.ets b/ets2panda/bindings/test/testcases/getSpanOfEnclosingComment/getSpanOfEnclosingComment2.ets new file mode 100644 index 0000000000000000000000000000000000000000..eb6f8ca23d70ac31df3a714f42b6b45f0699038d --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSpanOfEnclosingComment/getSpanOfEnclosingComment2.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. + */ + +function A(a:number, b:number) { + return a + b; /* add */ +} +A(1, 2); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getSuggestionDiagnostics/getSuggestionDiagnostics1.ets b/ets2panda/bindings/test/testcases/getSuggestionDiagnostics/getSuggestionDiagnostics1.ets new file mode 100644 index 0000000000000000000000000000000000000000..cc976ab41fb0111a4f94e13514dd0886d2b187ba --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSuggestionDiagnostics/getSuggestionDiagnostics1.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 fetchData(){ +return Promise.resolve("h") +;} +function processData(){ +return fetchData().finally(); +}; +processData(); diff --git a/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics1.ets b/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics1.ets new file mode 100644 index 0000000000000000000000000000000000000000..7f2a3720c40450e024f050070a6a3ec706dfa0ee --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics1.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. + */ + +function add(a: number, b: number) { + return a + b; +} +let n = 333; +let res = add(n, n); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics2.ets b/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics2.ets new file mode 100644 index 0000000000000000000000000000000000000000..6131061452c61cf2d77ef9c4303a541d29fa6469 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getSyntacticDiagnostics/getSyntacticDiagnostics2.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. + */ + +functon add(a: number, b: number) { + return a + b; +} +let n = 333; +let res = add(n, n); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/provideInlayHints/provideInlayHints1.ets b/ets2panda/bindings/test/testcases/provideInlayHints/provideInlayHints1.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d4264b1877f0d48759208ae8183884e63abb803 --- /dev/null +++ b/ets2panda/bindings/test/testcases/provideInlayHints/provideInlayHints1.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(param1: number, param2: number) { + } + + function bar() { + foo(10, 20); // Call expression + } diff --git a/ets2panda/bindings/test/testcases/toLineColumnOffset/toLineColumnOffset1.ets b/ets2panda/bindings/test/testcases/toLineColumnOffset/toLineColumnOffset1.ets new file mode 100644 index 0000000000000000000000000000000000000000..e7cfca2ae5107658fda5d5a6e7ac06ea85ed44c5 --- /dev/null +++ b/ets2panda/bindings/test/testcases/toLineColumnOffset/toLineColumnOffset1.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. + */ + +interface X +{ name: string}; +let variable: X = { name: 'Test' }; diff --git a/ets2panda/bindings/test/tsconfig.json b/ets2panda/bindings/test/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..72faeb9bec1b595501ad8d3ae29043ff0d5ab6d3 --- /dev/null +++ b/ets2panda/bindings/test/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "..", + "outDir": "../dist-test", + "types": [ + "node" + ] + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ], + "exclude": [ + "../node_modules", + "../dist", + "../dist-test", + "./ets", + "./testcases", + ] +} \ No newline at end of file diff --git a/ets2panda/checker/ASchecker.cpp b/ets2panda/checker/ASchecker.cpp index 3a3cb8e6919aafd41329ac9b4fa2d6880ee55fff..ee3cd234f8fcdb5e5d20957c1ff19f7d17086b66 100644 --- a/ets2panda/checker/ASchecker.cpp +++ b/ets2panda/checker/ASchecker.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 @@ -21,8 +21,6 @@ namespace ark::es2panda::checker { bool ASChecker::StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const util::Options &options) { - Initialize(varbinder); - if (options.IsDumpAst()) { std::cout << Program()->Dump() << std::endl; } diff --git a/ets2panda/checker/ASchecker.h b/ets2panda/checker/ASchecker.h index 399d423630223822cbbc6dd951964f5765c8b170..84ba809e5b0d673bdfc99f006a9ea7a649a2b281 100644 --- a/ets2panda/checker/ASchecker.h +++ b/ets2panda/checker/ASchecker.h @@ -23,7 +23,11 @@ namespace ark::es2panda::checker { class ASChecker : public Checker { public: // NOLINTNEXTLINE(readability-redundant-member-init) - explicit ASChecker(util::DiagnosticEngine &diagnosticEngine) : Checker(diagnosticEngine) {} + explicit ASChecker([[maybe_unused]] ThreadSafeArenaAllocator *allocator, util::DiagnosticEngine &diagnosticEngine, + [[maybe_unused]] ArenaAllocator *programAllocator) + : Checker(allocator, diagnosticEngine) + { + } bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, [[maybe_unused]] const util::Options &options) override; diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 3a5061934cd80fad1096e3b4210826e35f19eaac..cc87b76f3415a275a203b6ca591e1364e7951a92 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -15,6 +15,7 @@ #include "ETSAnalyzer.h" +#include "checker/ETSchecker.h" #include "generated/diagnostic.h" #include "checker/types/globalTypesHolder.h" #include "checker/types/ets/etsTupleType.h" @@ -22,6 +23,10 @@ #include "types/signature.h" #include "compiler/lowering/ets/setJumpTarget.h" #include "checker/types/ets/etsAsyncFuncReturnType.h" +#include "util/es2pandaMacros.h" + +#include + namespace ark::es2panda::checker { ETSChecker *ETSAnalyzer::GetETSChecker() const @@ -53,8 +58,19 @@ checker::Type *ETSAnalyzer::Check(ir::CatchClause *st) const ES2PANDA_ASSERT(checker->IsAnyError()); } + const varbinder::Variable *catchVar = nullptr; + if (st->Param() != nullptr && st->Param()->IsIdentifier()) { + catchVar = st->Param()->AsIdentifier()->Variable(); + ES2PANDA_ASSERT(catchVar != nullptr); + catchParamStack_.push_back(catchVar); + } + st->Body()->Check(checker); + if (catchVar != nullptr) { + catchParamStack_.pop_back(); + } + return st->SetTsType(exceptionType); } @@ -93,6 +109,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const if (st->TypeAnnotation() != nullptr) { st->TypeAnnotation()->Check(checker); } + checker::SavedCheckerContext savedContext(checker, checker->Context().Status(), checker->Context().ContainingClass(), checker->Context().ContainingSignature()); @@ -104,7 +121,13 @@ checker::Type *ETSAnalyzer::Check(ir::ClassProperty *st) const checker::Type *propertyType = checker->CheckVariableDeclaration(st->Id(), st->TypeAnnotation(), st->Value(), st->Modifiers()); - return st->SetTsType(propertyType != nullptr ? propertyType : checker->GlobalTypeError()); + propertyType = propertyType != nullptr ? propertyType : checker->GlobalTypeError(); + st->SetTsType(propertyType); + if (st->IsDefinite() && st->TsType()->PossiblyETSNullish()) { + checker->LogError(diagnostic::LATE_INITIALIZATION_FIELD_HAS_INVALID_TYPE, st->TypeAnnotation()->Start()); + } + + return propertyType; } checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const @@ -174,6 +197,12 @@ static checker::Type *CheckMethodDefinitionHelper(ETSChecker *checker, ir::Metho return node->TsType(); } +static bool IsInitializerBlockTransfer(std::string_view str) +{ + auto prefix = compiler::Signatures::INITIALIZER_BLOCK_INIT; + return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0; +} + checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const { ETSChecker *checker = GetETSChecker(); @@ -219,6 +248,10 @@ checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const node->SetTsType(checker->BuildMethodSignature(node)); } + if (IsInitializerBlockTransfer(scriptFunc->Id()->Name().Utf8())) { + checker->AddStatus(CheckerStatus::IN_STATIC_BLOCK); + } + this->CheckMethodModifiers(node); HandleNativeAndAsyncMethods(checker, node); DoBodyTypeChecking(checker, node, scriptFunc); @@ -278,22 +311,26 @@ checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::Property *expr) const checker::Type *ETSAnalyzer::Check(ir::SpreadElement *expr) const { + if (expr->TsType() != nullptr) { + return expr->TsType(); + } + ETSChecker *checker = GetETSChecker(); Type *exprType = expr->AsSpreadElement()->Argument()->Check(checker); if (exprType->IsETSResizableArrayType()) { return expr->SetTsType(exprType->AsETSObjectType()->TypeArguments().front()); } + if (!exprType->IsETSArrayType() && !exprType->IsETSTupleType()) { if (!exprType->IsTypeError()) { // Don't duplicate error messages for the same error checker->LogError(diagnostic::SPREAD_OF_INVALID_TYPE, {exprType}, expr->Start()); } - return expr->SetTsType(checker->GlobalTypeError()); + return checker->InvalidateType(expr); } - checker::Type *const elementType = exprType->IsETSTupleType() ? exprType->AsETSTupleType()->GetLubType() - : exprType->AsETSArrayType()->ElementType(); + checker::Type *const elementType = exprType->IsETSTupleType() ? exprType : checker->GetElementTypeOfArray(exprType); return expr->SetTsType(elementType); } @@ -320,7 +357,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSClassLiteral *expr) const return expr->TsType(); } - ArenaVector typeArgTypes(checker->Allocator()->Adapter()); + ArenaVector typeArgTypes(checker->ProgramAllocator()->Adapter()); typeArgTypes.push_back(exprType); // NOTE: Box it if it's a primitive type checker::InstantiationContext ctx(checker, checker->GlobalBuiltinTypeType(), std::move(typeArgTypes), @@ -353,26 +390,6 @@ checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const return node->SetTsType(checker->CreateETSArrowType(signature)); } -checker::Type *ETSAnalyzer::Check(ir::ETSLaunchExpression *expr) const -{ - ETSChecker *checker = GetETSChecker(); - expr->expr_->Check(checker); - - // Launch expression returns a Promise type, so we need to insert the expression's type - // as type parameter for the Promise class. - - auto exprType = [&checker](auto *tsType) { - if (tsType->IsETSPrimitiveType()) { - return checker->MaybeBoxInRelation(tsType); - } - - return tsType; - }(expr->expr_->TsType()); - - expr->SetTsType(checker->CreatePromiseOf(exprType)); - return expr->TsType(); -} - template >> static bool CheckArrayElementType(ETSChecker *checker, T *newArrayInstanceExpr) { @@ -391,7 +408,7 @@ static bool CheckArrayElementType(ETSChecker *checker, T *newArrayInstanceExpr) // A workaround check for new Interface[...] in test cases newArrayInstanceExpr->SetSignature(checker->CollectParameterlessConstructor( calleeObj->ConstructSignatures(), newArrayInstanceExpr->Start())); - checker->ValidateSignatureAccessibility(calleeObj, nullptr, newArrayInstanceExpr->Signature(), + checker->ValidateSignatureAccessibility(calleeObj, newArrayInstanceExpr->Signature(), newArrayInstanceExpr->Start()); } else { checker->LogError(diagnostic::ABSTRACT_CLASS_AS_ARRAY_ELEMENT_TYPE, {}, newArrayInstanceExpr->Start()); @@ -412,6 +429,12 @@ static bool CheckArrayElementType(ETSChecker *checker, T *newArrayInstanceExpr) return true; } +static bool NeedCreateETSResizableArrayType(ETSChecker *checker, Type *type) +{ + return type == nullptr || + checker->Relation()->IsSupertypeOf(type, checker->GetGlobalTypesHolder()->GlobalArrayBuiltinType()); +} + checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const { ETSChecker *checker = GetETSChecker(); @@ -420,8 +443,19 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewArrayInstanceExpression *expr) const checker->ValidateArrayIndex(expr->Dimension(), true); CheckArrayElementType(checker, expr); - expr->SetTsType(checker->CreateETSArrayType(elementType)); - checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); + GetUnionPreferredType(expr, expr->GetPreferredType()); + + auto *preferredType = expr->GetPreferredType(); + + if (NeedCreateETSResizableArrayType(checker, expr->GetPreferredType()) || + preferredType->IsETSResizableArrayType()) { + expr->SetTsType(checker->CreateETSResizableArrayType(elementType)); + } else { + expr->SetTsType(checker->CreateETSArrayType(elementType)); + } + if (expr->TsType()->IsETSArrayType()) { + checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), 1); + } return expr->TsType(); } @@ -433,13 +467,13 @@ static checker::Type *CheckInstantiatedNewType(ETSChecker *checker, ir::ETSNewCl return checker->InvalidateType(expr->GetTypeRef()); } if (calleeType->IsETSUnionType()) { - return checker->TypeError(expr->GetTypeRef(), "The union type is not constructible.", expr->Start()); + return checker->TypeError(expr->GetTypeRef(), diagnostic::UNION_NONCONSTRUCTIBLE, expr->Start()); } if (!ir::ETSNewClassInstanceExpression::TypeIsAllowedForInstantiation(calleeType)) { - return checker->TypeError(expr->GetTypeRef(), {"Type '", calleeType, "' is not constructible."}, expr->Start()); + return checker->TypeError(expr->GetTypeRef(), diagnostic::CALLEE_NONCONSTRUCTIBLE, {calleeType}, expr->Start()); } if (!calleeType->IsETSObjectType()) { - return checker->TypeError(expr->GetTypeRef(), "This expression is not constructible.", expr->Start()); + return checker->TypeError(expr->GetTypeRef(), diagnostic::EXPR_NONCONSTRUCTIBLE, {}, expr->Start()); } auto calleeObj = calleeType->AsETSObjectType(); @@ -487,7 +521,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewClassInstanceExpression *expr) const checker->CheckObjectLiteralArguments(signature, expr->GetArguments()); - checker->ValidateSignatureAccessibility(calleeObj, nullptr, signature, expr->Start()); + checker->ValidateSignatureAccessibility(calleeObj, signature, expr->Start()); if (calleeType->IsETSDynamicType()) { ES2PANDA_ASSERT(signature->Function()->IsDynamic()); @@ -509,13 +543,25 @@ checker::Type *ETSAnalyzer::Check(ir::ETSNewMultiDimArrayInstanceExpression *exp CheckArrayElementType(checker, expr); auto *elementType = expr->TypeReference()->GetType(checker); + auto *fixedArrayType = elementType; for (auto *dim : expr->Dimensions()) { checker->ValidateArrayIndex(dim, true); - elementType = checker->CreateETSArrayType(elementType); + fixedArrayType = checker->CreateETSArrayType(fixedArrayType); + } + GetUnionPreferredType(expr, expr->GetPreferredType()); + + auto *preferredType = expr->GetPreferredType(); + if (NeedCreateETSResizableArrayType(checker, expr->GetPreferredType()) || + preferredType->IsETSResizableArrayType()) { + expr->SetTsType(checker->CreateETSMultiDimResizableArrayType(elementType, expr->Dimensions().size())); + } else { + expr->SetTsType(fixedArrayType); } - expr->SetTsType(elementType); - expr->SetSignature(checker->CreateBuiltinArraySignature(elementType->AsETSArrayType(), expr->Dimensions().size())); + if (expr->TsType()->IsETSArrayType()) { + expr->SetSignature( + checker->CreateBuiltinArraySignature(expr->TsType()->AsETSArrayType(), expr->Dimensions().size())); + } return expr->TsType(); } @@ -571,18 +617,31 @@ checker::Type *ETSAnalyzer::Check(ir::ETSTypeReferencePart *node) const return node->GetType(checker); } +checker::Type *ETSAnalyzer::Check(ir::ETSNonNullishTypeNode *node) const +{ + if (node->TsType() != nullptr) { + return node->TsType(); + } + ETSChecker *checker = GetETSChecker(); + checker::Type *originalType = node->GetTypeNode()->Check(checker); + if (!originalType->IsETSTypeParameter()) { + checker->LogError(diagnostic::ILLEGAL_NON_NULLISH_TYPE, {}, node->GetTypeNode()->Start()); + } + return node->SetTsType(checker->GetNonNullishType(originalType)); +} + checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const { ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); - return checker->GlobalETSNullType(); + return node->SetTsType(checker->GlobalETSNullType()); } checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSUndefinedType *node) const { ETSChecker *checker = GetETSChecker(); checker->CheckAnnotations(node->Annotations()); - return checker->GlobalETSUndefinedType(); + return node->SetTsType(checker->GlobalETSUndefinedType()); } checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::ETSNeverType *node) const @@ -611,104 +670,68 @@ checker::Type *ETSAnalyzer::GetPreferredType(ir::ArrayExpression *expr) const return expr->preferredType_; } -struct ArrayTargetTypes { - checker::Type *arrayType; - checker::Type *possibleTupleType; -}; - -static bool CheckArrayElementForTupleAssignment(ETSChecker *checker, checker::Type *elementType, - ArrayTargetTypes &targetElementTypes, - ir::Expression *const currentElement) +static void AddSpreadElementTypes(ETSChecker *checker, ir::SpreadElement *const element, + ArenaVector> &elementTypes) { - // NOTE (mmartin): Need to find out the semantics behind this function, and refactor it even more in the future or - // remove it - const bool isTargetArray = targetElementTypes.arrayType->IsETSArrayType(); - const bool arrayExpressionAssignedToArrayType = isTargetArray && currentElement->IsArrayExpression(); - const Type *const targetArrayElementType = - isTargetArray ? targetElementTypes.arrayType->AsETSArrayType()->ElementType() : nullptr; + Type *const spreadType = element->Check(checker); - const bool hasTupleTargetType = targetElementTypes.possibleTupleType != nullptr; - bool needElementTypecheck = (isTargetArray && targetArrayElementType->IsETSArrayType() && hasTupleTargetType); - if (!needElementTypecheck) { - needElementTypecheck = - !arrayExpressionAssignedToArrayType && - !checker::AssignmentContext(checker->Relation(), currentElement, elementType, targetElementTypes.arrayType, - currentElement->Start(), {}, TypeRelationFlag::NO_THROW) - .IsAssignable(); + if (spreadType->IsTypeError()) { + // error recovery + return; } - if (needElementTypecheck) { - auto *const targetType = - hasTupleTargetType ? targetElementTypes.possibleTupleType : targetElementTypes.arrayType; + Type *const spreadArgumentType = element->Argument()->TsType(); - bool isNodeErroneous = !hasTupleTargetType; - if (hasTupleTargetType) { - isNodeErroneous = !arrayExpressionAssignedToArrayType && - !checker::AssignmentContext(checker->Relation(), currentElement, elementType, targetType, - currentElement->Start(), {}, TypeRelationFlag::NO_THROW) - .IsAssignable(); - } - - if (isNodeErroneous) { - checker->LogError(diagnostic::ARRAY_ELEMENT_UNASSIGNABLE, {elementType, targetType}, - currentElement->Start()); - - return false; + if (spreadArgumentType->IsETSTupleType()) { + for (Type *type : spreadArgumentType->AsETSTupleType()->GetTupleTypesList()) { + elementTypes.emplace_back(type, element); } + } else if (spreadArgumentType->IsETSArrayType()) { + elementTypes.emplace_back(spreadArgumentType->AsETSArrayType()->ElementType(), element); + } else { + ES2PANDA_ASSERT(spreadArgumentType->IsETSResizableArrayType()); + elementTypes.emplace_back(spreadArgumentType->AsETSObjectType()->TypeArguments().front(), element); } - - return true; } -static bool AddSpreadElementTypes(ETSChecker *checker, ir::Expression *const element, - ArenaVector> &elementTypes, bool isPreferredTuple) +static bool ValidArrayExprSizeForTupleSize(ETSChecker *checker, Type *possibleTupleType, + ir::Expression *possibleArrayExpr) { - Type *elementType = element->Check(checker); - Type *argumentType = element->AsSpreadElement()->Argument()->Check(checker); - - if (argumentType->IsETSTupleType()) { - for (Type *type : argumentType->AsETSTupleType()->GetTupleTypesList()) { - elementTypes.emplace_back(type, element); - } + if (!possibleArrayExpr->IsArrayExpression() || !possibleTupleType->IsETSTupleType()) { return true; } - if (!argumentType->IsETSTupleType() && isPreferredTuple) { - checker->LogError(diagnostic::INVALID_SPREAD_IN_TUPLE, {argumentType}, element->Start()); - elementTypes.emplace_back(elementType, element); - return false; - } - - elementTypes.emplace_back(elementType, element); - return true; + return checker->IsArrayExprSizeValidForTuple(possibleArrayExpr->AsArrayExpression(), + possibleTupleType->AsETSTupleType()); } -static ArenaVector> GetElementTypes(ir::ArrayExpression *expr, ETSChecker *checker, - const bool isPreferredTuple, bool &checkResult) +static ArenaVector> GetElementTypes(ETSChecker *checker, ir::ArrayExpression *expr) { - ArenaVector> elementTypes(checker->Allocator()->Adapter()); + ArenaVector> elementTypes(checker->ProgramAllocator()->Adapter()); for (std::size_t idx = 0; idx < expr->Elements().size(); ++idx) { ir::Expression *const element = expr->Elements()[idx]; - if (element->IsArrayExpression() && - !expr->TrySetPreferredTypeForNestedArrayExpr(checker, element->AsArrayExpression(), idx)) { - elementTypes.emplace_back(checker->GlobalTypeError(), element); + if (element->IsSpreadElement()) { + AddSpreadElementTypes(checker, element->AsSpreadElement(), elementTypes); continue; } - if (element->IsSpreadElement()) { - if (!AddSpreadElementTypes(checker, element, elementTypes, isPreferredTuple)) { - checkResult = false; - } + auto *const exprPreferredType = expr->GetPreferredType(); + + if (expr->GetPreferredType()->IsETSTupleType() && + idx < expr->GetPreferredType()->AsETSTupleType()->GetTupleSize() && + !ValidArrayExprSizeForTupleSize(checker, exprPreferredType->AsETSTupleType()->GetTypeAtIndex(idx), + element)) { + elementTypes.emplace_back(checker->GlobalTypeError(), element); continue; } - if (element->IsObjectExpression()) { - auto *const exprPreferredType = expr->GetPreferredType(); - checker->SetPreferredTypeIfPossible(element, exprPreferredType->IsETSTupleType() - ? exprPreferredType->AsETSTupleType()->GetTypeAtIndex(idx) - : exprPreferredType->AsETSArrayType()->ElementType()); + if (element->IsArrayExpression() || element->IsObjectExpression()) { + auto *const targetPreferredType = exprPreferredType->IsETSTupleType() + ? exprPreferredType->AsETSTupleType()->GetTypeAtIndex(idx) + : checker->GetElementTypeOfArray(exprPreferredType); + ETSChecker::SetPreferredTypeIfPossible(element, targetPreferredType); } elementTypes.emplace_back(element->Check(checker), element); @@ -717,9 +740,17 @@ static ArenaVector> GetElementTypes(ir::Arra return elementTypes; } -static bool CheckElement(ETSChecker *checker, const ir::ArrayExpression *const arrayExpr, - ArenaVector> arrayExprElementTypes, - ArrayTargetTypes &targetElementTypes, std::size_t idx) +static Type *GetArrayElementType(ETSChecker *checker, Type *preferredType) +{ + if (preferredType->IsETSArrayType()) { + return checker->GetNonConstantType(checker->GetElementTypeOfArray(preferredType)); + } + ES2PANDA_ASSERT(preferredType->IsETSResizableArrayType()); + return preferredType->AsETSResizableArrayType()->ElementType(); +} + +static bool CheckElement(ETSChecker *checker, Type *const preferredType, + ArenaVector> arrayExprElementTypes, std::size_t idx) { auto [elementType, currentElement] = arrayExprElementTypes[idx]; @@ -727,8 +758,10 @@ static bool CheckElement(ETSChecker *checker, const ir::ArrayExpression *const a return true; } - if (!elementType->IsETSArrayType() && arrayExpr->GetPreferredType()->IsETSTupleType()) { - const auto *const tupleType = arrayExpr->GetPreferredType()->AsETSTupleType(); + Type *targetType = nullptr; + + if (preferredType->IsETSTupleType()) { + const auto *const tupleType = preferredType->AsETSTupleType(); if (tupleType->GetTupleSize() != arrayExprElementTypes.size()) { return false; } @@ -740,44 +773,90 @@ static bool CheckElement(ETSChecker *checker, const ir::ArrayExpression *const a } auto ctx = AssignmentContext(checker->Relation(), currentElement, elementType, compareType, - currentElement->Start(), {}, TypeRelationFlag::NO_THROW); + currentElement->Start(), std::nullopt, TypeRelationFlag::NO_THROW); if (!ctx.IsAssignable()) { checker->LogError(diagnostic::TUPLE_UNASSIGNABLE_ARRAY, {idx}, currentElement->Start()); return false; } - elementType = compareType; + const CastingContext castCtx( + checker->Relation(), diagnostic::CAST_FAIL_UNREACHABLE, {}, + CastingContext::ConstructorData {currentElement, compareType, checker->MaybeBoxType(compareType), + currentElement->Start(), TypeRelationFlag::NO_THROW}); + + targetType = compareType; + } else { + targetType = GetArrayElementType(checker, preferredType); } - if (targetElementTypes.arrayType == elementType) { - return true; + auto ctx = AssignmentContext(checker->Relation(), currentElement, elementType, targetType, currentElement->Start(), + {}, TypeRelationFlag::NO_THROW); + if (!ctx.IsAssignable()) { + checker->LogError(diagnostic::ARRAY_ELEMENT_INIT_TYPE_INCOMPAT, {idx, elementType, targetType}, + currentElement->Start()); + return false; } - return CheckArrayElementForTupleAssignment(checker, elementType, targetElementTypes, currentElement); + return true; } -// CC-OFFNXT(huge_depth[C++]) solid logic -static bool CheckArrayExpressionElements(ir::ArrayExpression *arrayExpr, ETSChecker *checker, - ArrayTargetTypes &targetElementTypes, bool isPreferredTuple) +static Type *InferPreferredTypeFromElements(ETSChecker *checker, ir::ArrayExpression *arrayExpr) { - bool checkResult = true; + ArenaVector arrayExpressionElementTypes(checker->ProgramAllocator()->Adapter()); + for (auto *const element : arrayExpr->Elements()) { + auto *elementType = *element->Check(checker); + if (element->IsSpreadElement() && elementType->IsETSTupleType()) { + for (auto *typeFromTuple : elementType->AsETSTupleType()->GetTupleTypesList()) { + arrayExpressionElementTypes.emplace_back(typeFromTuple); + } - const ArenaVector> arrayExprElementTypes = - GetElementTypes(arrayExpr, checker, isPreferredTuple, checkResult); + continue; + } + + if (element->IsSpreadElement() && elementType->IsETSArrayType()) { + elementType = elementType->AsETSArrayType()->ElementType(); + } + + arrayExpressionElementTypes.emplace_back(elementType); + } + + // NOTE (smartin): fix union type normalization. Currently for primitive types like a 'char | char' type, it will be + // normalized to 'Char'. However it shouldn't be boxed, and be kept as 'char'. For a quick fix, if all types are + // primitive, then after making the union type, explicitly unbox it. + if (std::all_of(arrayExpressionElementTypes.begin(), arrayExpressionElementTypes.end(), + [](Type *const typeOfElement) { return typeOfElement->IsETSPrimitiveType(); })) { + return checker->CreateETSResizableArrayType(checker->GetNonConstantType( + checker->MaybeUnboxType(checker->CreateETSUnionType(std::move(arrayExpressionElementTypes))))); + } + + // NOTE (smartin): optimize element access on constant array expressions (note is here, because the constant value + // will be present on the type) + return checker->CreateETSResizableArrayType( + checker->GetNonConstantType(checker->CreateETSUnionType(std::move(arrayExpressionElementTypes)))); +} + +static bool CheckArrayExpressionElements(ETSChecker *checker, ir::ArrayExpression *arrayExpr) +{ + const ArenaVector> arrayExprElementTypes = GetElementTypes(checker, arrayExpr); + + bool allElementsAssignable = !std::any_of(arrayExprElementTypes.begin(), arrayExprElementTypes.end(), + [](auto &pair) { return pair.first->IsTypeError(); }); for (std::size_t idx = 0; idx < arrayExprElementTypes.size(); ++idx) { - checkResult &= CheckElement(checker, arrayExpr, arrayExprElementTypes, targetElementTypes, idx); + allElementsAssignable &= CheckElement(checker, arrayExpr->GetPreferredType(), arrayExprElementTypes, idx); } - return checkResult; + return allElementsAssignable; } -void ETSAnalyzer::GetUnionPreferredType(ir::ArrayExpression *expr) const +void ETSAnalyzer::GetUnionPreferredType(ir::Expression *expr, Type *originalType) const { - ES2PANDA_ASSERT(expr->preferredType_->IsETSUnionType()); + if (originalType == nullptr || !originalType->IsETSUnionType()) { + return; + } checker::Type *preferredType = nullptr; - for (auto &type : expr->preferredType_->AsETSUnionType()->ConstituentTypes()) { - if (type->IsETSArrayType() || type->IsETSTupleType()) { + for (auto &type : originalType->AsETSUnionType()->ConstituentTypes()) { + if (type->IsETSArrayType() || type->IsETSTupleType() || type->IsETSResizableArrayType()) { if (preferredType != nullptr) { preferredType = nullptr; break; @@ -785,8 +864,15 @@ void ETSAnalyzer::GetUnionPreferredType(ir::ArrayExpression *expr) const preferredType = type; } } - - expr->preferredType_ = preferredType; + if (expr->IsArrayExpression()) { + expr->AsArrayExpression()->SetPreferredType(preferredType); + } else if (expr->IsETSNewArrayInstanceExpression()) { + expr->AsETSNewArrayInstanceExpression()->SetPreferredType(preferredType); + } else if (expr->IsETSNewMultiDimArrayInstanceExpression()) { + expr->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredType(preferredType); + } else { + ES2PANDA_UNREACHABLE(); + } } checker::Type *ETSAnalyzer::Check(ir::ArrayExpression *expr) const @@ -802,58 +888,61 @@ checker::Type *ETSAnalyzer::Check(ir::ArrayExpression *expr) const } if (expr->GetPreferredType()->IsETSUnionType()) { - GetUnionPreferredType(expr); + GetUnionPreferredType(expr, expr->GetPreferredType()); } } - if (expr->GetPreferredType() != nullptr && !expr->GetPreferredType()->IsETSArrayType() && - !expr->GetPreferredType()->IsETSTupleType() && - !checker->Relation()->IsSupertypeOf(expr->preferredType_, checker->GlobalETSObjectType())) { - checker->LogError(diagnostic::UNEXPECTED_ARRAY, {expr->preferredType_}, expr->Start()); + if (!IsArrayExpressionValidInitializerForType(checker, expr->GetPreferredType())) { + checker->LogError(diagnostic::UNEXPECTED_ARRAY, {expr->GetPreferredType()}, expr->Start()); return checker->InvalidateType(expr); } if (!expr->Elements().empty()) { if (expr->GetPreferredType() == nullptr || expr->GetPreferredType() == checker->GlobalETSObjectType()) { - /* - * NOTE(SM): If elements has different types - * should calculated as union of types from each element, - * otherwise don't properly work with array from union type - */ - expr->SetPreferredType( - checker->CreateETSArrayType(checker->GetNonConstantType(expr->Elements().front()->Check(checker)))); + expr->SetPreferredType(InferPreferredTypeFromElements(checker, expr)); } - auto *const preferredType = expr->GetPreferredType(); - - // NOTE(aakmaev): Need to rework type inference of array literal (#19096 internal issue) - const bool isPreferredTuple = preferredType->IsETSTupleType(); - - Type *const arrayTargetElementType = - isPreferredTuple ? preferredType->AsETSTupleType()->GetLubType() - : checker->GetNonConstantType(preferredType->AsETSArrayType()->ElementType()); - - Type *const possibleTupleTargetType = - isPreferredTuple ? preferredType->AsETSTupleType()->GetLubType() : nullptr; - - ArrayTargetTypes targetElementTypes {arrayTargetElementType, possibleTupleTargetType}; - if (!CheckArrayExpressionElements(expr, checker, targetElementTypes, isPreferredTuple)) { + if (!CheckArrayExpressionElements(checker, expr)) { return checker->InvalidateType(expr); } } if (expr->GetPreferredType() == nullptr) { - return checker->TypeError(expr, "Can't resolve array type", expr->Start()); + return checker->TypeError(expr, diagnostic::UNRESOLVABLE_ARRAY, expr->Start()); } expr->SetTsType(expr->GetPreferredType()); - const auto *const arrayType = expr->TsType()->IsETSTupleType() - ? expr->TsType()->AsETSTupleType()->GetHolderArrayType() - : expr->TsType()->AsETSArrayType(); - checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); + if (!expr->GetPreferredType()->IsETSResizableArrayType() && !expr->TsType()->IsETSTupleType()) { + ES2PANDA_ASSERT(expr->TsType()->IsETSArrayType()); + const auto *const arrayType = expr->TsType()->AsETSArrayType(); + checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); + } return expr->TsType(); } +void TryInferPreferredType(ir::ArrowFunctionExpression *expr, checker::Type *preferredType, ETSChecker *checker) +{ + if (!preferredType->IsETSUnionType()) { + if (preferredType->IsETSArrowType() && + !preferredType->AsETSFunctionType()->CallSignaturesOfMethodOrArrow().empty()) { + checker->TryInferTypeForLambdaTypeAlias(expr, preferredType->AsETSFunctionType()); + checker->BuildFunctionSignature(expr->Function(), false); + } + return; + } + + for (auto &ct : preferredType->AsETSUnionType()->ConstituentTypes()) { + if (!ct->IsETSArrowType() || ct->AsETSFunctionType()->CallSignaturesOfMethodOrArrow().empty()) { + continue; + } + checker->TryInferTypeForLambdaTypeAlias(expr, ct->AsETSFunctionType()); + checker->BuildFunctionSignature(expr->Function(), false); + if (expr->Function()->Signature() != nullptr) { + return; + } + } +} + checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const { ETSChecker *checker = GetETSChecker(); @@ -893,7 +982,13 @@ checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const checker->AddStatus(checker::CheckerStatus::IN_LAMBDA); checker->Context().SetContainingLambda(expr); - checker->BuildFunctionSignature(expr->Function(), false); + auto preferredType = expr->GetPreferredType(); + if (preferredType != nullptr) { + TryInferPreferredType(expr, preferredType, checker); + } else { + checker->BuildFunctionSignature(expr->Function(), false); + } + if (expr->Function()->Signature() == nullptr) { return checker->InvalidateType(expr); } @@ -989,7 +1084,7 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const checker->WarnForEndlessLoopInGetterSetter(expr->Left()->AsMemberExpression()); } - auto const leftType = expr->Left()->Check(checker); + const auto leftType = expr->Left()->Check(checker); if (IsInvalidArrayMemberAssignment(expr, checker)) { expr->SetTsType(checker->GlobalTypeError()); @@ -999,6 +1094,10 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const if (expr->Left()->IsIdentifier()) { expr->target_ = expr->Left()->AsIdentifier()->Variable(); } else if (expr->Left()->IsMemberExpression()) { + if (!expr->IsIgnoreConstAssign() && + expr->Left()->AsMemberExpression()->Object()->TsType()->HasTypeFlag(TypeFlag::READONLY)) { + checker->LogError(diagnostic::READONLY_PROPERTY_REASSIGN, {}, expr->Left()->Start()); + } expr->target_ = expr->Left()->AsMemberExpression()->PropVar(); } else { checker->LogError(diagnostic::ASSIGNMENT_INVALID_LHS, {}, expr->Left()->Start()); @@ -1012,26 +1111,51 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const auto [rightType, relationNode] = CheckAssignmentExprOperatorType(expr, leftType); if (rightType->IsTypeError()) { - return expr->SetTsType(checker->GlobalTypeError()); + return expr->SetTsType(leftType); } - checker::Type *smartType = leftType; + CastPossibleTupleOnRHS(checker, expr); + + checker::Type *smartType = rightType; if (!leftType->IsTypeError()) { - if (auto ctx = checker::AssignmentContext( - // CC-OFFNXT(G.FMT.06-CPP) project code style - checker->Relation(), relationNode, rightType, leftType, expr->Right()->Start(), - // CC-OFFNXT(G.FMT.06-CPP) project code style - {"Type '", rightType, "' cannot be assigned to type '", leftType, "'"}); + if (const auto ctx = checker::AssignmentContext(checker->Relation(), relationNode, rightType, leftType, + expr->Right()->Start(), + {{diagnostic::INVALID_ASSIGNMNENT, {rightType, leftType}}}); ctx.IsAssignable()) { smartType = GetSmartType(expr, leftType, rightType); } - } else { - smartType = rightType; } return expr->SetTsType(smartType); } +static checker::Type *HandleSubstitution(ETSChecker *checker, ir::AssignmentExpression *expr, Type *const leftType) +{ + bool possibleInferredTypeOfArray = leftType->IsETSArrayType() || leftType->IsETSResizableArrayType() || + leftType->IsETSTupleType() || leftType->IsETSUnionType(); + if (expr->Right()->IsArrayExpression() && possibleInferredTypeOfArray) { + checker->ModifyPreferredType(expr->Right()->AsArrayExpression(), leftType); + } + + if (expr->Right()->IsETSNewArrayInstanceExpression()) { + expr->Right()->AsETSNewArrayInstanceExpression()->SetPreferredType(leftType); + } + + if (expr->Right()->IsETSNewMultiDimArrayInstanceExpression()) { + expr->Right()->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredType(leftType); + } + + if (expr->Right()->IsObjectExpression()) { + expr->Right()->AsObjectExpression()->SetPreferredType(leftType); + } + + if (expr->Right()->IsArrowFunctionExpression() && (leftType->IsETSArrowType() || leftType->IsETSUnionType())) { + expr->Right()->AsArrowFunctionExpression()->SetPreferredType(leftType); + } + + return expr->Right()->Check(checker); +} + std::tuple ETSAnalyzer::CheckAssignmentExprOperatorType(ir::AssignmentExpression *expr, Type *const leftType) const { @@ -1061,24 +1185,7 @@ std::tuple ETSAnalyzer::CheckAssignmentExprOperatorTyp break; } case lexer::TokenType::PUNCTUATOR_SUBSTITUTION: { - if (leftType->IsETSArrayType() && expr->Right()->IsArrayExpression()) { - checker->ModifyPreferredType(expr->Right()->AsArrayExpression(), leftType); - } - - if (leftType->IsETSTupleType() && expr->Right()->IsArrayExpression()) { - checker->ModifyPreferredType(expr->Right()->AsArrayExpression(), leftType); - } - - if (expr->Right()->IsObjectExpression()) { - expr->Right()->AsObjectExpression()->SetPreferredType(leftType); - } - - if (expr->Right()->IsArrowFunctionExpression() && leftType->IsETSArrowType() && - !leftType->AsETSFunctionType()->CallSignaturesOfMethodOrArrow().empty()) { - checker->TryInferTypeForLambdaTypeAlias(expr, leftType->AsETSFunctionType()); - } - - sourceType = expr->Right()->Check(checker); + sourceType = HandleSubstitution(checker, expr, leftType); break; } default: { @@ -1090,6 +1197,12 @@ std::tuple ETSAnalyzer::CheckAssignmentExprOperatorTyp return {sourceType, relationNode}; } +static bool IsPromiseType(checker::Type *type, ETSChecker *checker) +{ + return type->IsETSObjectType() && + type->AsETSObjectType()->GetOriginalBaseType() == checker->GlobalBuiltinPromiseType(); +} + checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const { ETSChecker *checker = GetETSChecker(); @@ -1098,15 +1211,27 @@ checker::Type *ETSAnalyzer::Check(ir::AwaitExpression *expr) const } checker::Type *argType = checker->GetApparentType(expr->argument_->Check(checker)); - // Check the argument type of await expression - if (!argType->IsETSObjectType() || - (argType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType())) { - return checker->TypeError(expr, "'await' expressions require Promise object as argument.", - expr->Argument()->Start()); + ArenaVector awaitedTypes(checker->ProgramAllocator()->Adapter()); + + if (argType->IsETSUnionType()) { + for (Type *type : argType->AsETSUnionType()->ConstituentTypes()) { + if (!IsPromiseType(type, checker)) { + return checker->TypeError(expr, diagnostic::AWAITED_NOT_PROMISE, expr->Argument()->Start()); + } + + Type *typeArg = type->AsETSObjectType()->TypeArguments().at(0); + awaitedTypes.push_back(UnwrapPromiseType(typeArg)); + } + } else { + if (!IsPromiseType(argType, checker)) { + return checker->TypeError(expr, diagnostic::AWAITED_NOT_PROMISE, expr->Argument()->Start()); + } + + Type *typeArg = argType->AsETSObjectType()->TypeArguments().at(0); + awaitedTypes.push_back(UnwrapPromiseType(typeArg)); } - Type *type = argType->AsETSObjectType()->TypeArguments().at(0); - expr->SetTsType(UnwrapPromiseType(type)); + expr->SetTsType(argType->IsETSUnionType() ? checker->CreateETSUnionType(std::move(awaitedTypes)) : awaitedTypes[0]); return expr->TsType(); } @@ -1146,6 +1271,26 @@ checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const } ETSChecker *checker = GetETSChecker(); + + bool inSmartExpr = false; + if (!checker->Context().IsInTestExpression()) { + switch (expr->OperatorType()) { + case lexer::TokenType::KEYW_INSTANCEOF: + case lexer::TokenType::PUNCTUATOR_EQUAL: + case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: + case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: + case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: + case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: + case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { + inSmartExpr = true; + SmartCastArray smartCasts = checker->Context().EnterTestExpression(); + break; + } + default: + break; + } + } + checker::Type *newTsType {nullptr}; std::tie(newTsType, expr->operationType_) = checker->CheckBinaryOperator(expr->Left(), expr->Right(), expr, expr->OperatorType(), expr->Start()); @@ -1153,6 +1298,10 @@ checker::Type *ETSAnalyzer::Check(ir::BinaryExpression *expr) const checker->Context().CheckBinarySmartCastCondition(expr); + if (inSmartExpr) { + checker->Context().ExitTestExpression(); + } + return expr->TsType(); } @@ -1176,6 +1325,15 @@ checker::Type *ETSAnalyzer::Check(ir::BlockExpression *st) const return st->TsType(); } +static bool LambdaIsField(ir::CallExpression *expr) +{ + if (!expr->Callee()->IsMemberExpression()) { + return false; + } + auto *me = expr->Callee()->AsMemberExpression(); + return me->PropVar() != nullptr; +} + checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, checker::Type *calleeType) const { @@ -1183,8 +1341,7 @@ checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallE expr->Signature() != nullptr) { // Note: Only works when rechecking in DeclareOveloadLowering phase auto *helperSignature = calleeType->AsETSFunctionType()->GetHelperSignature(); - checker->ReportWarning({"Detect duplicate signatures, use '", helperSignature->Function()->Id()->Name(), - helperSignature, "' to replace"}, + checker->LogDiagnostic(diagnostic::DUPLICATE_SIGS, {helperSignature->Function()->Id()->Name(), helperSignature}, expr->Start()); checker->CreateOverloadSigContainer(helperSignature); return checker->ResolveCallExpressionAndTrailingLambda(checker->GetOverloadSigContainer(), expr, expr->Start()); @@ -1197,7 +1354,9 @@ checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallE return signature; } - if (checker->IsExtensionETSFunctionType(calleeType)) { + // when a lambda with receiver is a class field or interface property, + // then it can only be called like a lambda without receiver. + if (checker->IsExtensionETSFunctionType(calleeType) && !LambdaIsField(expr)) { auto *signature = ResolveCallExtensionFunction(calleeType, checker, expr); if (signature != nullptr && signature->IsExtensionAccessor() && !checker->HasStatus(CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK)) { @@ -1248,7 +1407,7 @@ Type *ETSAnalyzer::GetReturnType(ir::CallExpression *expr, Type *calleeType) con if (calleeType->IsETSMethodType()) { ETSObjectType *calleeObj = GetCallExpressionCalleeObject(checker, expr, calleeType); - checker->ValidateSignatureAccessibility(calleeObj, expr, signature, expr->Start()); + checker->ValidateSignatureAccessibility(calleeObj, signature, expr->Start()); } if (calleeType->IsETSMethodType() && signature->Function()->IsDynamic()) { @@ -1315,7 +1474,7 @@ checker::Type *ETSAnalyzer::GetCallExpressionReturnType(ir::CallExpression *expr { ETSChecker *checker = GetETSChecker(); checker::Type *returnType = nullptr; - if (calleeType->IsETSDynamicType() && !calleeType->AsETSDynamicType()->HasDecl()) { + if (UNLIKELY(calleeType->IsETSDynamicType() && !calleeType->AsETSDynamicType()->HasDecl())) { // Trailing lambda for js function call is not supported, check the correctness of `foo() {}` checker->EnsureValidCurlyBrace(expr); auto lang = calleeType->AsETSDynamicType()->Language(); @@ -1332,9 +1491,6 @@ checker::Type *ETSAnalyzer::GetCallExpressionReturnType(ir::CallExpression *expr auto *const signature = expr->Signature(); if (signature->RestVar() != nullptr && signature->RestVar()->TsType()->IsETSArrayType()) { auto *elementType = signature->RestVar()->TsType()->AsETSArrayType()->ElementType(); - if (elementType->IsETSTupleType()) { - elementType = elementType->AsETSTupleType()->GetLubType(); - } auto *const arrayType = checker->CreateETSArrayType(elementType)->AsETSArrayType(); checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); } @@ -1402,6 +1558,7 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const } else { expr->SetUncheckedType(checker->GuaranteedTypeForUncheckedCallReturn(expr->Signature())); } + if (expr->UncheckedType() != nullptr) { ES2PANDA_ASSERT(expr->UncheckedType()->IsETSReferenceType()); checker->ComputeApparentType(returnType); @@ -1471,6 +1628,9 @@ checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const } } + // Restore smart casts to initial state. + checker->Context().RestoreSmartCasts(smartCasts); + return expr->TsType(); } @@ -1494,12 +1654,12 @@ static Type *TransformTypeForMethodReference(ETSChecker *checker, ir::Expression } if (type->AsETSFunctionType()->CallSignatures().at(0)->HasSignatureFlag(SignatureFlags::PRIVATE)) { - checker->LogTypeError("Private method is used as value", getUseSite()); + checker->LogError(diagnostic::PRIVATE_METHOD_AS_VALUE, getUseSite()); return checker->GlobalTypeError(); } if (type->AsETSFunctionType()->CallSignatures().size() > 1) { - checker->LogTypeError("Overloaded method is used as value", getUseSite()); + checker->LogError(diagnostic::OVERLOADED_METHOD_AS_VALUE, getUseSite()); return checker->GlobalTypeError(); } return type->AsETSFunctionType()->MethodToArrow(checker); @@ -1532,7 +1692,7 @@ checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const } std::pair SearchReExportsType(ETSObjectType *baseType, ir::MemberExpression *expr, - util::StringView &aliasName, ETSChecker *checker) + util::StringView const &aliasName, ETSChecker *checker) { std::pair ret {}; @@ -1562,9 +1722,8 @@ std::pair SearchReExportsType(ETSObjectType * static void TypeErrorOnMissingProperty(ir::MemberExpression *expr, checker::Type *baseType, checker::ETSChecker *checker) { - std::ignore = checker->TypeError( - expr, {"Property '", expr->Property()->AsIdentifier()->Name(), "' does not exist on type '", baseType, "'"}, - expr->Object()->Start()); + std::ignore = checker->TypeError(expr, diagnostic::PROPERTY_NONEXISTENT, + {expr->Property()->AsIdentifier()->Name(), baseType}, expr->Object()->Start()); } checker::Type *ETSAnalyzer::ResolveMemberExpressionByBaseType(ETSChecker *checker, checker::Type *baseType, @@ -1582,10 +1741,14 @@ checker::Type *ETSAnalyzer::ResolveMemberExpressionByBaseType(ETSChecker *checke return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); } - if (baseType->IsETSFunctionType() || baseType->IsETSTupleType()) { + if (baseType->IsETSTupleType()) { return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); } + if (baseType->IsETSFunctionType()) { + return expr->SetAndAdjustType(checker, checker->GlobalBuiltinFunctionType()); + } + if (baseType->IsETSObjectType()) { checker->ETSObjectTypeDeclNode(checker, baseType->AsETSObjectType()); return expr->SetTsType(TransformTypeForMethodReference( @@ -1595,6 +1758,30 @@ checker::Type *ETSAnalyzer::ResolveMemberExpressionByBaseType(ETSChecker *checke if (baseType->IsETSUnionType()) { return expr->AdjustType(checker, expr->CheckUnionMember(checker, baseType)); } + + // NOTE(mshimenkov): temporary workaround to deliver 'primitives refactoring' patch + // To be removed after complete refactoring + if (baseType->IsETSPrimitiveType()) { + static std::array castMethods {{ + "toChar", + "toByte", + "toShort", + "toInt", + "toLong", + "toFloat", + "toDouble", + }}; + auto method = expr->Property()->AsIdentifier()->Name().Utf8(); + auto res = std::find(castMethods.begin(), castMethods.end(), method); + if (res != castMethods.end()) { + auto type = checker->MaybeBoxType(baseType); + expr->SetAstNodeFlags(ir::AstNodeFlags::TMP_CONVERT_PRIMITIVE_CAST_METHOD_CALL); + checker->ETSObjectTypeDeclNode(checker, type->AsETSObjectType()); + return expr->SetTsType(TransformTypeForMethodReference( + checker, expr, expr->SetAndAdjustType(checker, type->AsETSObjectType()))); + } + } + TypeErrorOnMissingProperty(expr, baseType, checker); return expr->TsType(); } @@ -1658,7 +1845,7 @@ checker::Type *ETSAnalyzer::CheckDynamic(ir::ObjectExpression *expr) const return expr->PreferredType(); } -static bool ValidatePreferredType(ir::ObjectExpression *expr, ETSChecker *checker) +static bool ValidatePreferredType(ETSChecker *checker, ir::ObjectExpression *expr) { auto preferredType = expr->PreferredType(); if (preferredType == nullptr) { @@ -1672,7 +1859,7 @@ static bool ValidatePreferredType(ir::ObjectExpression *expr, ETSChecker *checke } if (!preferredType->IsETSObjectType()) { - checker->LogError(diagnostic::CKASS_COMPOSITE_INVALID_TARGET, {preferredType}, expr->Start()); + checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_TARGET, {preferredType}, expr->Start()); return false; } @@ -1693,6 +1880,359 @@ static void SetTypeforRecordProperties(const ir::ObjectExpression *expr, checker } } +// Helper to check for parameterless constructor +static bool HasParameterlessConstructor(checker::ETSObjectType *objType, ETSChecker *checker, + const lexer::SourcePosition &pos) +{ + for (checker::Signature *sig : objType->ConstructSignatures()) { + if (sig->Params().empty()) { + checker->ValidateSignatureAccessibility(objType, sig, pos); + return true; + } + } + return false; +} + +// Helper to resolve property name from key expression +static std::optional GetPropertyNameFromKey(ir::Expression *key) +{ + if (key->IsStringLiteral()) { + return key->AsStringLiteral()->Str(); + } + if (key->IsIdentifier()) { + return key->AsIdentifier()->Name(); + } + return std::nullopt; // Indicates invalid key type +} + +// Helper to determine property search flags based on object type +static checker::PropertySearchFlags DetermineSearchFlagsForLiteral(checker::ETSObjectType *potentialObjType) +{ + if (potentialObjType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) { + return checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | + checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | + checker::PropertySearchFlags::SEARCH_INSTANCE_DECL | checker::PropertySearchFlags::SEARCH_IN_INTERFACES; + } + return checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | checker::PropertySearchFlags::SEARCH_IN_BASE | + checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD; +} + +static bool CheckSinglePropertyCompatibility(ir::Expression *propExpr, checker::ETSObjectType *potentialObjType) +{ + if (!propExpr->IsProperty()) { + return false; // Not a key-value property + } + ir::Expression *key = propExpr->AsProperty()->Key(); + + std::optional optPname = GetPropertyNameFromKey(key); + if (!optPname.has_value()) { + return false; // Invalid key type in literal + } + util::StringView pname = optPname.value(); + + checker::PropertySearchFlags searchFlags = DetermineSearchFlagsForLiteral(potentialObjType); + + return potentialObjType->GetProperty(pname, searchFlags) != nullptr; +} + +static bool CheckObjectLiteralCompatibility(ir::ObjectExpression *expr, checker::ETSObjectType *potentialObjType) +{ + for (ir::Expression *propExpr : expr->Properties()) { + if (!CheckSinglePropertyCompatibility(propExpr, potentialObjType)) { + return false; + } + } + return true; // All properties found +} + +// Helper to check if a property type indicates optionality (union with undefined) +static bool IsPropertyTypeOptional(checker::Type *propertyType) +{ + if (!propertyType->IsETSUnionType()) { + return false; + } + + auto *unionType = propertyType->AsETSUnionType(); + for (auto *constituentType : unionType->ConstituentTypes()) { + if (constituentType->IsETSUndefinedType()) { + return true; + } + } + return false; +} + +// Helper to check if a property has a default value in its declaration +static bool HasPropertyDefaultValue(varbinder::LocalVariable *property) +{ + auto *decl = property->Declaration(); + if (decl == nullptr || decl->Node() == nullptr || !decl->Node()->IsClassProperty()) { + return false; + } + + auto *classProp = decl->Node()->AsClassProperty(); + return classProp->Value() != nullptr; +} + +// Helper to check if a property is optional (flag or declaration) +static bool IsPropertyOptional(varbinder::LocalVariable *property, checker::Type *propertyType) +{ + // Check if property is marked as optional + if (property->HasFlag(varbinder::VariableFlags::OPTIONAL)) { + return true; + } + + // Check if property type includes undefined (indicating optional) + if (IsPropertyTypeOptional(propertyType)) { + return true; + } + + // Check if declaration has optional modifier + auto *decl = property->Declaration(); + if (decl != nullptr && decl->Node() != nullptr && decl->Node()->IsClassProperty()) { + auto *classProp = decl->Node()->AsClassProperty(); + if (classProp->IsOptionalDeclaration()) { + return true; + } + } + + return false; +} + +// Helper to check if a method property is only getters/setters +static bool IsMethodOnlyAccessors(checker::Type *propertyType) +{ + if (!propertyType->IsETSMethodType()) { + return false; + } + + auto methodType = propertyType->AsETSFunctionType(); + for (auto *sig : methodType->CallSignatures()) { + if (!sig->HasSignatureFlag(checker::SignatureFlags::GETTER) && + !sig->HasSignatureFlag(checker::SignatureFlags::SETTER)) { + // Regular method found + return false; + } + } + return true; +} + +// Helper to check if an interface property is compatible with object literal property +static bool IsInterfacePropertyCompatible(ir::Expression *propExpr, checker::ETSObjectType *interfaceType, + ETSChecker *checker) +{ + if (!propExpr->IsProperty()) { + return false; + } + + ir::Expression *key = propExpr->AsProperty()->Key(); + std::optional optPname = GetPropertyNameFromKey(key); + if (!optPname.has_value()) { + return false; + } + util::StringView pname = optPname.value(); + + // Check if property exists in interface + varbinder::LocalVariable *property = + interfaceType->GetProperty(pname, checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | + checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | + checker::PropertySearchFlags::SEARCH_INSTANCE_DECL | + checker::PropertySearchFlags::SEARCH_IN_INTERFACES); + + if (property == nullptr) { + return false; + } + + auto *propertyType = checker->GetTypeOfVariable(property); + + // If it's a method type, it should only be getter/setter, not regular methods + if (propertyType->IsETSMethodType()) { + return IsMethodOnlyAccessors(propertyType); + } + + return true; +} + +// Helper to check if all required interface properties are satisfied +static bool AreAllRequiredInterfacePropertiesSatisfied(ir::ObjectExpression *expr, + checker::ETSObjectType *interfaceType, ETSChecker *checker) +{ + // Get all properties of the interface using GetAllProperties + auto allProperties = interfaceType->GetAllProperties(); + + // Create a set of property names provided in the object literal + std::unordered_set literalProperties; + for (ir::Expression *propExpr : expr->Properties()) { + if (propExpr->IsProperty()) { + ir::Expression *key = propExpr->AsProperty()->Key(); + if (auto optPname = GetPropertyNameFromKey(key); optPname.has_value()) { + literalProperties.insert(std::string(optPname.value().Utf8())); + } + } + } + + // Check if all literal properties exist in this interface + for (const auto &litPropName : literalProperties) { + bool found = false; + for (auto *property : allProperties) { + if (property->Name().Utf8() == litPropName) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + + // Check that all required interface properties are satisfied + for (auto *property : allProperties) { + std::string propName(property->Name().Utf8()); + auto *propertyType = checker->GetTypeOfVariable(property); + + // Skip method types that aren't getters/setters (they make interface incompatible anyway) + if (propertyType->IsETSMethodType()) { + if (!IsMethodOnlyAccessors(propertyType)) { + // Regular methods not allowed + return false; + } + } + // Check if this property is provided in the literal + bool isInLiteral = literalProperties.find(propName) != literalProperties.end(); + if (!isInLiteral) { + // Property not in literal - check if it's optional or has default value + bool isOptional = IsPropertyOptional(property, propertyType); + bool hasDefaultValue = HasPropertyDefaultValue(property); + if (!isOptional && !hasDefaultValue) { + return false; + } + } + } + + return true; // All required properties are satisfied +} + +static bool IsObjectTypeCompatibleWithLiteral(ETSChecker *checker, ir::ObjectExpression *expr, + checker::ETSObjectType *potentialObjType) +{ + // Split record/map types, class types and interfaces as requested by reviewer + + checker::ETSObjectType *originalBaseType = potentialObjType->GetOriginalBaseType(); + checker::GlobalTypesHolder *globalTypes = checker->GetGlobalTypesHolder(); + + // Handle Record/Map types + if (checker->IsTypeIdenticalTo(originalBaseType, globalTypes->GlobalMapBuiltinType()) || + checker->IsTypeIdenticalTo(originalBaseType, globalTypes->GlobalRecordBuiltinType())) { + // Maps and Records are always compatible with object literals + return true; + } + + // Handle interface types + if (potentialObjType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) { + // For interface types, check that all literal properties exist in the interface + // and that interface has no regular methods (only getters/setters allowed) + + // For non-empty literals, check that all literal properties exist in interface + // and all required interface properties are satisfied + for (ir::Expression *propExpr : expr->Properties()) { + if (!IsInterfacePropertyCompatible(propExpr, potentialObjType, checker)) { + return false; + } + } + + // Check all required interface properties are satisfied + return AreAllRequiredInterfacePropertiesSatisfied(expr, potentialObjType, checker); + } + + // Handle class types + // For class types, you need to check: + // - that there is a parameterless constructor, and + // - that all fields/properties set in the object literal are present in the class + + if (!HasParameterlessConstructor(potentialObjType, checker, expr->Start())) { + return false; + } + + // Check that all properties in literal exist in class + return CheckObjectLiteralCompatibility(expr, potentialObjType); +} + +checker::ETSObjectType *ResolveUnionObjectTypeForObjectLiteral(ETSChecker *checker, ir::ObjectExpression *expr, + checker::ETSUnionType *unionType) +{ + std::vector candidateObjectTypes; + // Phase 1: Gather all ETSObjectTypes from the union + for (auto *constituentType : unionType->ConstituentTypes()) { + if (constituentType->IsETSObjectType()) { + candidateObjectTypes.push_back(constituentType->AsETSObjectType()); + } + } + + if (candidateObjectTypes.empty()) { + // No ETSObjectTypes in the union at all + checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_TARGET, {expr->PreferredType()}, expr->Start()); + return nullptr; + } + + std::vector matchingObjectTypes; + // Phase 2: Filter candidates using the helper function + for (auto *potentialObjType : candidateObjectTypes) { + if (IsObjectTypeCompatibleWithLiteral(checker, expr, potentialObjType)) { + matchingObjectTypes.push_back(potentialObjType); + } + } + + // Phase 3: Decide based on number of matches + if (matchingObjectTypes.size() == 1) { + return matchingObjectTypes.front(); + } + if (matchingObjectTypes.empty()) { + // No candidate ETSObjectType from the union matched all properties + checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_TARGET, {expr->PreferredType()}, expr->Start()); + return nullptr; + } + // Ambiguous + checker->LogError(diagnostic::AMBIGUOUS_REFERENCE, {expr->PreferredType()->ToString()}, expr->Start()); + return nullptr; +} + +static checker::ETSObjectType *ResolveObjectTypeFromPreferredType(ETSChecker *checker, ir::ObjectExpression *expr) +{ + // Assume not null, checked by caller in Check() + checker::Type *preferredType = expr->PreferredType(); + + if (preferredType->IsETSUnionType()) { + return ResolveUnionObjectTypeForObjectLiteral(checker, expr, preferredType->AsETSUnionType()); + } + + if (preferredType->IsETSObjectType()) { + return preferredType->AsETSObjectType(); + } + + return nullptr; +} + +// Helper to handle interface type objects +static checker::Type *HandleInterfaceType(ETSChecker *checker, ir::ObjectExpression *expr, + checker::ETSObjectType *objType) +{ + auto *analyzer = static_cast(checker->GetAnalyzer()); + analyzer->CheckObjectExprProps( + expr, objType, + checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | + checker::PropertySearchFlags::SEARCH_INSTANCE_DECL | checker::PropertySearchFlags::SEARCH_IN_INTERFACES); + expr->SetTsType(objType); + return objType; +} + +// Helper to handle Record/Map types +static checker::Type *HandleRecordOrMapType(ETSChecker *checker, ir::ObjectExpression *expr, + checker::ETSObjectType *objType) +{ + expr->SetTsType(objType); + SetTypeforRecordProperties(expr, objType, checker); + return objType; +} + checker::Type *ETSAnalyzer::Check(ir::ObjectExpression *expr) const { ETSChecker *checker = GetETSChecker(); @@ -1700,62 +2240,64 @@ checker::Type *ETSAnalyzer::Check(ir::ObjectExpression *expr) const return expr->TsType(); } - if (!ValidatePreferredType(expr, checker)) { + if (expr->PreferredType() == nullptr) { + checker->LogError(diagnostic::CLASS_COMPOSITE_UNKNOWN_TYPE, {}, expr->Start()); + expr->SetTsType(checker->GlobalTypeError()); + return expr->TsType(); + } + + if (!expr->PreferredType()->IsETSUnionType() && !expr->PreferredType()->IsETSDynamicType() && + !ValidatePreferredType(checker, expr)) { expr->SetTsType(checker->GlobalTypeError()); return expr->TsType(); } - if (expr->PreferredType()->IsETSDynamicType()) { + if (expr->PreferredType()->IsETSDynamicType() && !expr->PreferredType()->AsETSDynamicType()->HasDecl()) { return CheckDynamic(expr); } - checker::ETSObjectType *objType = expr->PreferredType()->AsETSObjectType(); - if (objType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) { - // Object literal of interface tpye - // Further interfaceObjectLiteralLowering phase will resolve interface type - // and create corresponding anonymous class and class type - // Here we just set the type to pass the checker - CheckObjectExprProps(expr, checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | - checker::PropertySearchFlags::SEARCH_IN_INTERFACES); - expr->SetTsType(objType); - return objType; - } - - if (expr->PreferredType()->ToAssemblerName().str() == "escompat.Record" || - expr->PreferredType()->ToAssemblerName().str() == "escompat.Map") { - // 7.6.3 Object Literal of Record Type - // Record is an alias to Map - // Here we just set the type to pass the checker - // See Record Lowering for details - expr->SetTsType(objType); - SetTypeforRecordProperties(expr, objType, checker); - return objType; - } - - bool haveEmptyConstructor = false; - for (checker::Signature *sig : objType->ConstructSignatures()) { - if (sig->Params().empty()) { - haveEmptyConstructor = true; - checker->ValidateSignatureAccessibility(objType, nullptr, sig, expr->Start()); - break; + checker::ETSObjectType *objType = ResolveObjectTypeFromPreferredType(checker, expr); + + if (objType == nullptr) { + if (!expr->PreferredType()->IsETSUnionType()) { + checker->LogError(diagnostic::CLASS_COMPOSITE_INVALID_TARGET, {expr->PreferredType()}, expr->Start()); } + expr->SetTsType(checker->GlobalTypeError()); + return expr->TsType(); } - if (!haveEmptyConstructor) { - return checker->TypeError(expr, {"type ", objType->Name(), " has no parameterless constructor"}, expr->Start()); + + if (objType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE)) { + return HandleInterfaceType(checker, expr, objType); + } + + checker::ETSObjectType *originalBaseObjType = objType->GetOriginalBaseType(); + checker::GlobalTypesHolder *globalTypes = checker->GetGlobalTypesHolder(); + if (checker->IsTypeIdenticalTo(originalBaseObjType, globalTypes->GlobalMapBuiltinType()) || + checker->IsTypeIdenticalTo(originalBaseObjType, globalTypes->GlobalRecordBuiltinType())) { + return HandleRecordOrMapType(checker, expr, objType); + } + + // If we reach here, objType is a class. It must have a parameterless constructor + if (!HasParameterlessConstructor(objType, checker, expr->Start())) { + expr->SetTsType(checker->TypeError(expr, diagnostic::NO_PARAMLESS_CTOR, {objType->Name()}, expr->Start())); + return expr->TsType(); } - CheckObjectExprProps(expr, checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | - checker::PropertySearchFlags::SEARCH_IN_BASE | - checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD); + CheckObjectExprProps(expr, objType, + checker::PropertySearchFlags::SEARCH_INSTANCE_FIELD | + checker::PropertySearchFlags::SEARCH_IN_BASE | + checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD); expr->SetTsType(objType); return objType; } -void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr, checker::PropertySearchFlags searchFlags) const +void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr, + checker::ETSObjectType *objectTypeForProperties, + checker::PropertySearchFlags searchFlags) const { ETSChecker *checker = GetETSChecker(); - checker::ETSObjectType *objType = expr->PreferredType()->AsETSObjectType(); + checker::ETSObjectType *objType = objectTypeForProperties; for (ir::Expression *propExpr : expr->Properties()) { if (!propExpr->IsProperty()) { @@ -1795,9 +2337,8 @@ void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr, checker key->SetTsType(propType); value->SetTsType(value->Check(checker)); - checker::AssignmentContext( - checker->Relation(), value, value->TsType(), propType, value->Start(), - {"Type '", value->TsType(), "' is not compatible with type '", propType, "' at property '", pname, "'"}); + checker::AssignmentContext(checker->Relation(), value, value->TsType(), propType, value->Start(), + {{diagnostic::PROP_INCOMPAT, {value->TsType(), propType, pname}}}); } if (objType->HasObjectFlag(ETSObjectFlags::REQUIRED)) { @@ -1927,7 +2468,7 @@ static checker::Type *GetTypeOfStringType(checker::Type *argType, ETSChecker *ch if (argType->IsETSUndefinedType()) { return checker->CreateETSStringLiteralType("undefined"); } - if (argType->IsETSArrayType() || argType->IsETSNullType()) { + if (argType->IsETSArrayType() || argType->IsETSNullType() || argType->IsETSResizableArrayType()) { return checker->CreateETSStringLiteralType("object"); } if (argType->IsETSStringType()) { @@ -1951,7 +2492,7 @@ static checker::Type *GetTypeOfStringType(checker::Type *argType, ETSChecker *ch static checker::Type *ComputeTypeOfType(ETSChecker *checker, checker::Type *argType) { checker::Type *ret = nullptr; - ArenaVector types(checker->Allocator()->Adapter()); + ArenaVector types(checker->ProgramAllocator()->Adapter()); if (argType->IsETSUnionType()) { for (auto *it : argType->AsETSUnionType()->ConstituentTypes()) { checker::Type *elType = ComputeTypeOfType(checker, it); @@ -2021,13 +2562,13 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const } } - SetTsTypeForUnaryExpression(checker, expr, operandType); - if ((argType != nullptr) && argType->IsETSObjectType() && (unboxedOperandType != nullptr) && unboxedOperandType->IsETSPrimitiveType()) { expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedOperandType)); } + SetTsTypeForUnaryExpression(checker, expr, operandType); + checker->Context().CheckUnarySmartCastCondition(expr); return expr->TsType(); @@ -2106,7 +2647,7 @@ checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const { ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { - expr->SetTsType(checker->Allocator()->New(expr->Char())); + expr->SetTsType(checker->ProgramAllocator()->New(expr->Char())); } return expr->TsType(); } @@ -2175,7 +2716,14 @@ checker::Type *ETSAnalyzer::Check(ir::ImportNamespaceSpecifier *st) const return st->Local()->TsType(); } - auto *importDecl = st->Parent()->AsETSImportDeclaration(); + ir::ETSImportDeclaration *importDecl = nullptr; + if (st->Parent()->IsETSImportDeclaration()) { + importDecl = st->Parent()->AsETSImportDeclaration(); + } else if (st->Parent()->IsETSReExportDeclaration()) { + importDecl = st->Parent()->AsETSReExportDeclaration()->GetETSImportDeclarations(); + } else { + ES2PANDA_UNREACHABLE(); + } if (importDecl->IsPureDynamic()) { auto *type = checker->GlobalBuiltinDynamicType(importDecl->Language()); @@ -2205,10 +2753,9 @@ checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const stmt->Check(checker); // NOTE! Processing of trailing blocks was moved here so that smart casts could be applied correctly - if (auto const tb = st->trailingBlocks_.find(stmt); tb != st->trailingBlocks_.end()) { - auto *const trailingBlock = tb->second; + if (auto *const trailingBlock = st->SearchStatementInTrailingBlock(stmt); trailingBlock != nullptr) { trailingBlock->Check(checker); - st->Statements().emplace(std::next(st->Statements().begin() + idx), trailingBlock); + st->AddStatement(idx, trailingBlock); ++idx; } } @@ -2236,6 +2783,11 @@ checker::Type *ETSAnalyzer::Check(ir::BlockStatement *st) const } } + // Note: Guarantee all the const property need to be initialized in initializer block is initialized. + if (st->IsETSModule() && st->AsETSModule()->Program()->IsPackage() && + (checker->Context().Status() & checker::CheckerStatus::IN_EXTERNAL) == 0) { + CheckAllConstPropertyInitialized(checker, st->AsETSModule()); + } return ReturnTypeForStatement(st); } @@ -2300,7 +2852,8 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const ETSChecker *checker = GetETSChecker(); st->Expr()->Check(checker); - if (!st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { + if (st->GetBaseName()->Variable() == nullptr || + !st->GetBaseName()->Variable()->Declaration()->Node()->IsAnnotationDeclaration()) { checker->LogError(diagnostic::NOT_AN_ANNOTATION, {st->GetBaseName()->Name()}, st->GetBaseName()->Start()); return ReturnTypeForStatement(st); } @@ -2308,7 +2861,7 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const auto *annoDecl = st->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration(); annoDecl->Check(checker); - ArenaUnorderedMap fieldMap {checker->Allocator()->Adapter()}; + ArenaUnorderedMap fieldMap {checker->ProgramAllocator()->Adapter()}; for (auto *it : annoDecl->Properties()) { auto *field = it->AsClassProperty(); fieldMap.insert(std::make_pair(field->Id()->Name(), field)); @@ -2387,8 +2940,9 @@ static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, auto *const relation = checker->Relation(); relation->SetFlags(checker::TypeRelationFlag::ASSIGNMENT_CONTEXT); relation->SetNode(ident); - - if (!relation->IsAssignableTo(elemType, iterType)) { + if (auto ctx = checker::AssignmentContext(checker->Relation(), ident, elemType, iterType, ident->Start(), + std::nullopt, TypeRelationFlag::NO_THROW); + !ctx.IsAssignable()) { checker->LogError(diagnostic::ITERATOR_ELEMENT_TYPE_MISMATCH, {elemType, iterType}, st->Start()); return false; } @@ -2424,8 +2978,8 @@ checker::Type *ETSAnalyzer::Check(ir::ForOfStatement *const st) const if (exprType->IsETSStringType()) { elemType = checker->GetGlobalTypesHolder()->GlobalCharType(); - } else if (exprType->IsETSArrayType()) { - elemType = exprType->AsETSArrayType()->ElementType(); + } else if (exprType->IsETSArrayType() || exprType->IsETSResizableArrayType()) { + elemType = checker->GetElementTypeOfArray(exprType); } else if (exprType->IsETSObjectType() || exprType->IsETSUnionType() || exprType->IsETSTypeParameter()) { elemType = st->CheckIteratorMethod(checker); } @@ -2537,7 +3091,8 @@ static bool CheckIsValidReturnTypeAnnotation(ir::ReturnStatement *st, ir::Script ir::TypeNode *returnTypeAnnotation, ETSChecker *checker) { // check valid `this` type as return type - if (containingFunc->GetPreferredReturnType() != nullptr || !returnTypeAnnotation->IsTSThisType()) { + if (containingFunc->GetPreferredReturnType() != nullptr || + (returnTypeAnnotation != nullptr && !returnTypeAnnotation->IsTSThisType())) { return true; } @@ -2603,6 +3158,14 @@ bool ETSAnalyzer::CheckInferredFunctionReturnType(ir::ReturnStatement *st, ir::S st->argument_->AsArrayExpression()->SetPreferredType(funcReturnType); } + if (st->argument_->IsETSNewArrayInstanceExpression()) { + st->argument_->AsETSNewArrayInstanceExpression()->SetPreferredType(funcReturnType); + } + + if (st->argument_->IsETSNewMultiDimArrayInstanceExpression()) { + st->argument_->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredType(funcReturnType); + } + checker::Type *argumentType = st->argument_->Check(checker); return CheckReturnType(checker, funcReturnType, argumentType, st->argument_, containingFunc); } @@ -2729,8 +3292,18 @@ checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const checker::Type *ETSAnalyzer::Check(ir::ThrowStatement *st) const { ETSChecker *checker = GetETSChecker(); + const auto *arg = st->argument_; + checker::Type *argType = st->argument_->Check(checker); - if (checker::Type *argType = st->argument_->Check(checker); !argType->IsTypeError()) { + bool isRethrow = false; + if (arg->IsIdentifier() && !catchParamStack_.empty()) { + const varbinder::Variable *sym = arg->AsIdentifier()->Variable(); + ES2PANDA_ASSERT(sym != nullptr); + if (!catchParamStack_.empty() && sym == catchParamStack_.back()) { + isRethrow = true; + } + } + if (!isRethrow && !argType->IsTypeError()) { checker->CheckExceptionOrErrorType(argType, st->Start()); } @@ -2801,12 +3374,11 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const flags |= ir::ModifierFlags::OPTIONAL; } - auto *const variableType = checker->CheckVariableDeclaration(ident, ident->TypeAnnotation(), st->Init(), flags); - // Processing possible parser errors if (ident->Variable() == nullptr) { ident->Check(checker); } + auto *const variableType = checker->CheckVariableDeclaration(ident, ident->TypeAnnotation(), st->Init(), flags); // Now try to define the actual type of Identifier so that smart cast can be used in further checker processing // NOTE: T_S and K_o_t_l_i_n don't act in such way, but we can try - why not? :) @@ -2871,9 +3443,6 @@ checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const node->SetTsType(node->GetType(checker)); const auto *arrayType = node->TsType()->AsETSArrayType(); - if (arrayType->IsETSTupleType()) { - arrayType = arrayType->AsETSTupleType()->GetHolderArrayType(); - } checker->CreateBuiltinArraySignature(arrayType, arrayType->Rank()); return node->TsType(); } @@ -2908,11 +3477,11 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const } if (sourceType->DefinitelyETSNullish() && !targetType->PossiblyETSNullish()) { - return checker->TypeError(expr, "Cannot cast 'null' or 'undefined' to non-nullish type.", expr->Start()); + return checker->TypeError(expr, diagnostic::NULLISH_CAST_TO_NONNULLISH, expr->Start()); } const checker::CastingContext ctx( - checker->Relation(), {"Cannot cast type '", sourceType, "' to '", targetType, "'"}, + checker->Relation(), diagnostic::INVALID_CAST, {sourceType, targetType}, checker::CastingContext::ConstructorData {expr->Expr(), sourceType, targetType, expr->Expr()->Start()}); if (sourceType->IsETSDynamicType() && targetType->IsLambdaObject()) { @@ -2925,15 +3494,13 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const // Make sure the array type symbol gets created for the assembler to be able to emit checkcast. // Because it might not exist, if this particular array type was never created explicitly. - if (!expr->isUncheckedCast_ && (targetType->IsETSArrayType() || targetType->IsETSTupleType())) { - const auto *const targetArrayType = targetType->IsETSTupleType() - ? targetType->AsETSTupleType()->GetHolderArrayType() - : targetType->AsETSArrayType(); + if (!expr->isUncheckedCast_ && targetType->IsETSArrayType()) { + const auto *const targetArrayType = targetType->AsETSArrayType(); checker->CreateBuiltinArraySignature(targetArrayType, targetArrayType->Rank()); } if (targetType == checker->GetGlobalTypesHolder()->GlobalETSNeverType()) { - return checker->TypeError(expr, "Cast to 'never' is prohibited", expr->Start()); + return checker->TypeError(expr, diagnostic::CAST_TO_NEVER, expr->Start()); } checker->ComputeApparentType(targetType); @@ -2988,11 +3555,20 @@ checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const // If the actual [smart] type is definitely 'null' or 'undefined' then probably CTE should be thrown. // Anyway we'll definitely obtain NullPointerError at runtime. if (exprType->DefinitelyETSNullish()) { - checker->ReportWarning( - {"Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'."}, - expr->Expr()->Start()); + checker->LogDiagnostic(diagnostic::NULLISH_OPERAND, expr->Expr()->Start()); + + if (expr->expr_->IsIdentifier()) { + ES2PANDA_ASSERT(expr->expr_->AsIdentifier()->Variable() != nullptr); + auto originalType = expr->expr_->AsIdentifier()->Variable()->TsType(); + if (originalType != nullptr) { + expr->SetTsType(checker->GetNonNullishType(originalType)); + } + } + } + + if (expr->TsType() == nullptr) { + expr->SetTsType(checker->GetNonNullishType(exprType)); } - expr->SetTsType(checker->GetNonNullishType(exprType)); expr->SetOriginalType(expr->TsType()); return expr->TsType(); } diff --git a/ets2panda/checker/ETSAnalyzer.h b/ets2panda/checker/ETSAnalyzer.h index 28e145066b5aa0515e12f162f3b226d40a28121e..c9a398b319b807b28c697498308e787f9103af69 100644 --- a/ets2panda/checker/ETSAnalyzer.h +++ b/ets2panda/checker/ETSAnalyzer.h @@ -39,8 +39,9 @@ public: checker::Type *PreferredType(ir::ObjectExpression *expr) const; checker::Type *CheckDynamic(ir::ObjectExpression *expr) const; checker::Type *GetPreferredType(ir::ArrayExpression *expr) const; - void GetUnionPreferredType(ir::ArrayExpression *expr) const; - void CheckObjectExprProps(const ir::ObjectExpression *expr, checker::PropertySearchFlags searchFlags) const; + void GetUnionPreferredType(ir::Expression *expr, Type *originalType) const; + void CheckObjectExprProps(const ir::ObjectExpression *expr, checker::ETSObjectType *objectTypeForProperties, + checker::PropertySearchFlags searchFlags) const; std::tuple CheckAssignmentExprOperatorType(ir::AssignmentExpression *expr, Type *leftType) const; [[nodiscard]] checker::Type *ReturnTypeForStatement([[maybe_unused]] const ir::Statement *const st) const; @@ -78,12 +79,12 @@ private: return; } } - bool acceptVoid = - parent->IsExpressionStatement() || parent->IsReturnStatement() || parent->IsETSLaunchExpression(); + bool acceptVoid = parent->IsExpressionStatement() || parent->IsReturnStatement(); if (!acceptVoid) { checker->LogError(diagnostic::VOID_VALUE, {}, expr->Start()); } } + mutable std::vector catchParamStack_ {}; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index d7043742daf968a74ece5f62488c4a2a8f0c8b01..ff4be3487e2d1f5ac6cd8e4aa1a8b2ba08f0120c 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -70,8 +70,7 @@ void CheckExtensionIsShadowedInCurrentClassOrInterface(checker::ETSChecker *chec checker->LogError(diagnostic::EXTENSION_FUNC_NAME_CONFLICT_WITH_METH, {funcType->Name(), objType->Name()}, extensionFunc->Body()->Start()); } else { - checker->ReportWarning({"The extension function '", funcType->Name(), - "' has the same name with non-public method in class ", objType->Name()}, + checker->LogDiagnostic(diagnostic::EXTENSION_NONPUBLIC_COLLISION, {funcType->Name(), objType->Name()}, extensionFunc->Body()->Start()); } return; @@ -110,15 +109,15 @@ static void ReplaceThisInExtensionMethod(checker::ETSChecker *checker, ir::Scrip auto *const thisTypeAnnotation = extensionFunc->Params()[0]->AsETSParameterExpression()->Ident()->TypeAnnotation(); extensionFunc->Signature()->SetReturnType(thisType); - extensionFunc->SetReturnTypeAnnotation(thisTypeAnnotation->Clone(checker->Allocator(), extensionFunc)); + extensionFunc->SetReturnTypeAnnotation(thisTypeAnnotation->Clone(checker->ProgramAllocator(), extensionFunc)); } auto thisVariable = extensionFunc->Params()[0]->Variable(); extensionFunc->Body()->TransformChildrenRecursively( [=](ir::AstNode *ast) { if (ast->IsThisExpression()) { - auto *thisParam = checker->Allocator()->New( - varbinder::TypedBinder::MANDATORY_PARAM_THIS, checker->Allocator()); + auto *thisParam = checker->ProgramAllocator()->New( + varbinder::TypedBinder::MANDATORY_PARAM_THIS, checker->ProgramAllocator()); thisParam->SetRange(ast->Range()); thisParam->SetParent(ast->Parent()); thisParam->SetVariable(thisVariable); @@ -148,8 +147,8 @@ void CheckExtensionMethod(checker::ETSChecker *checker, ir::ScriptFunction *exte return; } - checker::SignatureInfo *originalExtensionSigInfo = checker->Allocator()->New( - extensionFunc->Signature()->GetSignatureInfo(), checker->Allocator()); + checker::SignatureInfo *originalExtensionSigInfo = checker->ProgramAllocator()->New( + extensionFunc->Signature()->GetSignatureInfo(), checker->ProgramAllocator()); originalExtensionSigInfo->minArgCount -= 1U; originalExtensionSigInfo->params.erase(originalExtensionSigInfo->params.begin()); checker::Signature *originalExtensionSignature = @@ -243,16 +242,16 @@ void ComposeAsyncImplFuncReturnType(ETSChecker *checker, ir::ScriptFunction *scr { auto const promiseType = checker->CreatePromiseOf(checker->MaybeBoxType(scriptFunc->Signature()->ReturnType())); - auto *objectId = - checker->AllocNode(compiler::Signatures::BUILTIN_OBJECT_CLASS, checker->Allocator()); + auto *objectId = checker->ProgramAllocNode(compiler::Signatures::BUILTIN_OBJECT_CLASS, + checker->ProgramAllocator()); checker->VarBinder()->AsETSBinder()->LookupTypeReference(objectId, false); - auto *returnType = checker->AllocNode( - checker->AllocNode(objectId, nullptr, nullptr, checker->Allocator()), - checker->Allocator()); + auto *returnType = checker->ProgramAllocNode( + checker->ProgramAllocNode(objectId, nullptr, nullptr, checker->ProgramAllocator()), + checker->ProgramAllocator()); objectId->SetParent(returnType->Part()); returnType->Part()->SetParent(returnType); - returnType->SetTsType( - checker->Allocator()->New(checker->Allocator(), checker->Relation(), promiseType)); + returnType->SetTsType(checker->ProgramAllocator()->New(checker->ProgramAllocator(), + checker->Relation(), promiseType)); returnType->Check(checker); scriptFunc->Signature()->SetReturnType(returnType->TsType()); } @@ -405,7 +404,7 @@ checker::Signature *GetMostSpecificSigFromExtensionFuncAndClassMethod(checker::E // So we temporarily transfer expr node from `a.foo(...)` to `a.foo(a, ...)`. // For allCallSignatures in ClassMethodType, temporarily insert the dummyReceiver into their signatureInfo, // otherwise we can't get the most suitable classMethod signature if all the extensionFunction signature mismatched. - ArenaVector signatures(checker->Allocator()->Adapter()); + ArenaVector signatures(checker->ProgramAllocator()->Adapter()); signatures.insert(signatures.end(), type->ClassMethodType()->CallSignatures().begin(), type->ClassMethodType()->CallSignatures().end()); signatures.insert(signatures.end(), type->ExtensionMethodType()->CallSignatures().begin(), @@ -421,7 +420,7 @@ checker::Signature *GetMostSpecificSigFromExtensionFuncAndClassMethod(checker::E methodCallSig->GetSignatureInfo()->minArgCount++; auto ¶msVar = methodCallSig->Params(); paramsVar.insert(paramsVar.begin(), dummyReceiverVar); - auto ¶ms = methodCallSig->Function()->Params(); + auto ¶ms = methodCallSig->Function()->ParamsForUpdate(); params.insert(params.begin(), dummyReceiver); if (typeParamsNeeded) { auto &typeParams = methodCallSig->TypeParams(); @@ -437,7 +436,7 @@ checker::Signature *GetMostSpecificSigFromExtensionFuncAndClassMethod(checker::E methodCallSig->GetSignatureInfo()->minArgCount--; auto ¶msVar = methodCallSig->Params(); paramsVar.erase(paramsVar.begin()); - auto ¶ms = methodCallSig->Function()->Params(); + auto ¶ms = methodCallSig->Function()->ParamsForUpdate(); params.erase(params.begin()); if (typeParamsNeeded) { auto &typeParams = methodCallSig->TypeParams(); @@ -448,7 +447,8 @@ checker::Signature *GetMostSpecificSigFromExtensionFuncAndClassMethod(checker::E expr->Arguments().erase(expr->Arguments().begin()); if (signature != nullptr) { - if (signature->Owner()->Name() == compiler::Signatures::ETS_GLOBAL) { + if (signature->Owner()->GetDeclNode()->IsClassDefinition() && + signature->Owner()->GetDeclNode()->AsClassDefinition()->IsGlobal()) { SwitchMethodCallToFunctionCall(checker, expr, signature); } else { auto *var = type->ClassMethodType()->Variable(); @@ -463,8 +463,8 @@ checker::Signature *ResolveCallForETSExtensionFuncHelperType(checker::ETSExtensi { ES2PANDA_ASSERT(expr->Callee()->IsMemberExpression()); auto *calleeObj = expr->Callee()->AsMemberExpression()->Object(); - bool isCalleeObjETSGlobal = - calleeObj->IsIdentifier() && calleeObj->AsIdentifier()->Name() == compiler::Signatures::ETS_GLOBAL; + bool isCalleeObjETSGlobal = calleeObj->TsType()->AsETSObjectType()->GetDeclNode()->IsClassDefinition() && + calleeObj->TsType()->AsETSObjectType()->GetDeclNode()->AsClassDefinition()->IsGlobal(); // for callExpr `a.foo`, there are 3 situations: // 1.`a.foo` is private method call of class A; // 2.`a.foo` is extension function of `A`(function with receiver `A`) @@ -489,16 +489,16 @@ checker::Signature *ResolveCallForETSExtensionFuncHelperType(checker::ETSExtensi ArenaVector GetUnionTypeSignatures(ETSChecker *checker, checker::ETSUnionType *etsUnionType) { - ArenaVector callSignatures(checker->Allocator()->Adapter()); + ArenaVector callSignatures(checker->ProgramAllocator()->Adapter()); for (auto *constituentType : etsUnionType->ConstituentTypes()) { if (constituentType->IsETSFunctionType()) { - ArenaVector tmpCallSignatures(checker->Allocator()->Adapter()); + ArenaVector tmpCallSignatures(checker->ProgramAllocator()->Adapter()); tmpCallSignatures = constituentType->AsETSFunctionType()->CallSignatures(); callSignatures.insert(callSignatures.end(), tmpCallSignatures.begin(), tmpCallSignatures.end()); } if (constituentType->IsETSUnionType()) { - ArenaVector tmpCallSignatures(checker->Allocator()->Adapter()); + ArenaVector tmpCallSignatures(checker->ProgramAllocator()->Adapter()); tmpCallSignatures = GetUnionTypeSignatures(checker, constituentType->AsETSUnionType()); callSignatures.insert(callSignatures.end(), tmpCallSignatures.begin(), tmpCallSignatures.end()); } @@ -529,9 +529,6 @@ void ProcessExclamationMark(ETSChecker *checker, ir::UnaryExpression *expr, chec expr->SetTsType(tsType); return; } - if (operandType->IsETSEnumType()) { - expr->Argument()->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - } expr->SetTsType(checker->GlobalETSBooleanType()); } @@ -562,12 +559,7 @@ void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, break; } - if (operandType->HasTypeFlag(checker::TypeFlag::CONSTANT)) { - expr->SetTsType(checker->BitwiseNegateNumericType(operandType, expr)); - break; - } - - expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType)); + expr->Argument()->SetTsType(expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType))); break; } case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { @@ -576,7 +568,6 @@ void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, } default: { ES2PANDA_UNREACHABLE(); - break; } } } @@ -605,11 +596,9 @@ checker::Type *GetIteratorType(ETSChecker *checker, checker::Type *elemType, ir: auto *decl = variable->Declaration(); if (decl->IsConstDecl() || decl->IsReadonlyDecl()) { - const auto errorMsg = + const auto &errorMsg = decl->IsConstDecl() ? diagnostic::INVALID_CONST_ASSIGNMENT : diagnostic::INVALID_READONLY_ASSIGNMENT; - // NOTE(pronaip): see memory corruption issue in 23053, replace with LogError once resolved - checker->LogTypeError({errorMsg.Message().substr(0, errorMsg.Message().size() - 2), variable->Name()}, - decl->Node()->Start()); + checker->LogError(errorMsg, {variable->Name()}, decl->Node()->Start()); } iterType = left->AsIdentifier()->TsType(); } else if (left->IsVariableDeclaration()) { @@ -645,7 +634,7 @@ bool CheckReturnType(ETSChecker *checker, checker::Type *funcReturnType, checker return false; } if (!checker::AssignmentContext(checker->Relation(), stArgument, argumentType, funcReturnType, - stArgument->Start(), {}, + stArgument->Start(), std::nullopt, checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) // CC-OFFNXT(G.FMT.02) project code style .IsAssignable()) { @@ -658,7 +647,8 @@ bool CheckReturnType(ETSChecker *checker, checker::Type *funcReturnType, checker if (containingFunc->IsAsyncFunc() && funcReturnType->IsETSObjectType() && funcReturnType->AsETSObjectType()->GetOriginalBaseType() == checker->GlobalBuiltinPromiseType()) { auto promiseArg = funcReturnType->AsETSObjectType()->TypeArguments()[0]; - checker::AssignmentContext(checker->Relation(), stArgument, argumentType, promiseArg, stArgument->Start(), {}, + checker::AssignmentContext(checker->Relation(), stArgument, argumentType, promiseArg, stArgument->Start(), + std::nullopt, checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW); if (checker->Relation()->IsTrue()) { return true; @@ -666,7 +656,8 @@ bool CheckReturnType(ETSChecker *checker, checker::Type *funcReturnType, checker } if (!checker::AssignmentContext(checker->Relation(), stArgument, argumentType, funcReturnType, stArgument->Start(), - {}, checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) + std::nullopt, + checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) // CC-OFFNXT(G.FMT.02) project code style .IsAssignable()) { checker->LogError(diagnostic::ARROW_TYPE_MISMATCH, {argumentType, funcReturnType}, stArgument->Start()); @@ -682,6 +673,7 @@ void InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, ch funcReturnType = stArgument == nullptr ? checker->GlobalVoidType() : checker->GetNonConstantType(stArgument->Check(checker)); if (funcReturnType->IsTypeError()) { + containingFunc->Signature()->RemoveSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE); return; } @@ -699,7 +691,7 @@ void InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, ch auto *argumentType = arrowFunc->TsType(); funcReturnType = typeAnnotation->GetType(checker); if (!checker::AssignmentContext(checker->Relation(), arrowFunc, argumentType, funcReturnType, - stArgument->Start(), {}, + stArgument->Start(), std::nullopt, checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) // CC-OFFNXT(G.FMT.02) project code style .IsAssignable()) { @@ -719,6 +711,32 @@ void InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, ch } } +bool IsArrayExpressionValidInitializerForType(ETSChecker *checker, const Type *const arrayExprPreferredType) +{ + const auto validForTarget = arrayExprPreferredType == nullptr // preferred type will be inferred from elements + || arrayExprPreferredType->IsETSArrayType() // valid for fixed array type + || arrayExprPreferredType->IsETSResizableArrayType() // valid for resizable array type + || arrayExprPreferredType->IsETSTupleType() // valid for tuple type + || checker->Relation()->IsSupertypeOf(arrayExprPreferredType, // valid for 'Object' + checker->GlobalETSObjectType()); + + return validForTarget; +} + +void CastPossibleTupleOnRHS(ETSChecker *checker, ir::AssignmentExpression *expr) +{ + if (expr->Left()->IsMemberExpression() && + expr->Left()->AsMemberExpression()->Object()->TsType()->IsETSTupleType() && + expr->OperatorType() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { + auto *storedTupleType = expr->Left()->AsMemberExpression()->Object()->TsType(); + + const checker::CastingContext tupleCast( + checker->Relation(), diagnostic::CAST_FAIL_UNREACHABLE, {}, + checker::CastingContext::ConstructorData {expr->Right(), expr->Right()->TsType(), storedTupleType, + expr->Right()->Start(), TypeRelationFlag::NO_THROW}); + } +} + void ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type *&funcReturnType, ir::ReturnStatement *st, ir::Expression *stArgument) { @@ -774,4 +792,26 @@ bool CheckReturnTypeNecessity(ir::MethodDefinition *node) return needReturnType; } +void CheckAllConstPropertyInitialized(checker::ETSChecker *checker, ir::ETSModule *pkg) +{ + auto globalDecl = std::find_if(pkg->Statements().begin(), pkg->Statements().end(), [](ir::AstNode *node) { + return node->IsClassDeclaration() && node->AsClassDeclaration()->Definition()->IsGlobal(); + }); + if (globalDecl == pkg->Statements().end()) { + return; + } + + auto const &globalClassBody = (*globalDecl)->AsClassDeclaration()->Definition()->AsClassDefinition()->Body(); + for (auto const *prop : globalClassBody) { + if (!prop->IsClassProperty()) { + continue; + } + + if (prop->AsClassProperty()->Key()->Variable()->HasFlag(varbinder::VariableFlags::INIT_IN_STATIC_BLOCK) && + !prop->AsClassProperty()->Key()->Variable()->HasFlag(varbinder::VariableFlags::INITIALIZED)) { + checker->LogError(diagnostic::MISSING_INIT_FOR_CONST_PACKAGE_PROP, {}, prop->Start()); + } + } +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ETSAnalyzerHelpers.h b/ets2panda/checker/ETSAnalyzerHelpers.h index 708af010866f9aa6f3e3c1c96329f7407525c613..979d6413ac63d58a4c73e16aabef6a38c793068f 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.h +++ b/ets2panda/checker/ETSAnalyzerHelpers.h @@ -58,9 +58,12 @@ bool CheckReturnType(ETSChecker *checker, checker::Type *funcReturnType, checker ir::Expression *stArgument, ir::ScriptFunction *containingFunc); void InferReturnType(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type *&funcReturnType, ir::Expression *stArgument); +bool IsArrayExpressionValidInitializerForType(ETSChecker *checker, const Type *arrayExprPreferredType); +void CastPossibleTupleOnRHS(ETSChecker *checker, ir::AssignmentExpression *expr); void ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type *&funcReturnType, ir::ReturnStatement *st, ir::Expression *stArgument); bool CheckReturnTypeNecessity(ir::MethodDefinition *node); +void CheckAllConstPropertyInitialized(checker::ETSChecker *checker, ir::ETSModule *pkg); } // namespace ark::es2panda::checker #endif // ES2PANDA_CHECKER_ETSANALYZERHELPERS_H diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index a8d7a1a488875ba41d5a2ddf08cbba87c2283469..01e68b8bac1558bd1cc48be51c9d1a66d9b08084 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -13,6 +13,10 @@ * limitations under the License. */ +#include +#include +#include + #include "ETSchecker.h" #include "es2panda.h" @@ -33,6 +37,59 @@ namespace ark::es2panda::checker { +void ETSChecker::ReputCheckerData() +{ + readdedChecker_.insert(this); + for (auto &[_, extPrograms] : Program()->ExternalSources()) { + (void)_; + auto *extProg = extPrograms.front(); + if (!extProg->IsASTLowered()) { + continue; + } + auto eChecker = extProg->Checker()->AsETSChecker(); + + if (!HasStatus(CheckerStatus::BUILTINS_INITIALIZED)) { + SetGlobalTypesHolder(eChecker->GetGlobalTypesHolder()); + AddStatus(CheckerStatus::BUILTINS_INITIALIZED); + } + + if (auto it = readdedChecker_.find(eChecker); it != readdedChecker_.end()) { + continue; + } + readdedChecker_.insert(eChecker->readdedChecker_.begin(), eChecker->readdedChecker_.end()); + auto computedAbstractMapToCopy = eChecker->GetCachedComputedAbstracts(); + for (auto &[key, value] : *computedAbstractMapToCopy) { + if (GetCachedComputedAbstracts()->find(key) != GetCachedComputedAbstracts()->end()) { + continue; + } + auto &[v1, v2] = value; + ArenaVector newV1(Allocator()->Adapter()); + ArenaUnorderedSet newV2(Allocator()->Adapter()); + newV1.assign(v1.cbegin(), v1.cend()); + newV2.insert(v2.cbegin(), v2.cend()); + GetCachedComputedAbstracts()->try_emplace(key, newV1, newV2); + } + + auto &globalArraySigs = eChecker->globalArraySignatures_; + globalArraySignatures_.insert(globalArraySigs.cbegin(), globalArraySigs.cend()); + + auto &apparentTypes = eChecker->apparentTypes_; + apparentTypes_.insert(apparentTypes.cbegin(), apparentTypes.cend()); + + auto &objectInstantiationMap = eChecker->objectInstantiationMap_; + for (auto &[key, value] : objectInstantiationMap) { + if (objectInstantiationMap_.find(key) == objectInstantiationMap_.end()) { + objectInstantiationMap_.insert(objectInstantiationMap.cbegin(), objectInstantiationMap.cend()); + } + } + + auto &invokeToArrowSignatures = eChecker->invokeToArrowSignatures_; + invokeToArrowSignatures_.insert(invokeToArrowSignatures.cbegin(), invokeToArrowSignatures.cend()); + auto &arrowToFuncInterfaces = eChecker->arrowToFuncInterfaces_; + arrowToFuncInterfaces_.insert(arrowToFuncInterfaces.cbegin(), arrowToFuncInterfaces.cend()); + } +} + static util::StringView InitBuiltin(ETSChecker *checker, std::string_view signature) { const auto varMap = checker->VarBinder()->TopScope()->Bindings(); @@ -52,8 +109,7 @@ static util::StringView InitBuiltin(ETSChecker *checker, std::string_view signat void ETSChecker::CheckObjectLiteralKeys(const ArenaVector &properties) { - static std::set names; - names.clear(); + std::set names; for (auto property : properties) { if (!property->IsProperty()) { @@ -61,12 +117,12 @@ void ETSChecker::CheckObjectLiteralKeys(const ArenaVector &pro } auto propertyDecl = property->AsProperty(); auto propKey = propertyDecl->Key(); - if (!propKey->IsIdentifier()) { + if (!propKey->IsIdentifier() && !propKey->IsStringLiteral()) { continue; } // number kind only used here - auto propName = propKey->AsIdentifier()->Name(); + auto propName = propKey->IsIdentifier() ? propKey->AsIdentifier()->Name() : propKey->AsStringLiteral()->Str(); if (names.find(propName) != names.end()) { LogError(diagnostic::OBJ_LIT_PROPERTY_REDECLARATION, {}, property->Start()); } @@ -151,6 +207,7 @@ static constexpr std::string_view BUILTINS_TO_INIT[] = { compiler::Signatures::BUILTIN_FUNCTIONR14_CLASS, compiler::Signatures::BUILTIN_FUNCTIONR15_CLASS, compiler::Signatures::BUILTIN_FUNCTIONR16_CLASS, + compiler::Signatures::BUILTIN_FUNCTIONN_CLASS, compiler::Signatures::BUILTIN_LAMBDAR0_CLASS, compiler::Signatures::BUILTIN_LAMBDAR1_CLASS, compiler::Signatures::BUILTIN_LAMBDAR2_CLASS, @@ -168,8 +225,25 @@ static constexpr std::string_view BUILTINS_TO_INIT[] = { compiler::Signatures::BUILTIN_LAMBDAR14_CLASS, compiler::Signatures::BUILTIN_LAMBDAR15_CLASS, compiler::Signatures::BUILTIN_LAMBDAR16_CLASS, - compiler::Signatures::BUILTIN_FUNCTIONN_CLASS, compiler::Signatures::BUILTIN_LAMBDAN_CLASS, + compiler::Signatures::BUILTIN_TUPLE0_CLASS, + compiler::Signatures::BUILTIN_TUPLE1_CLASS, + compiler::Signatures::BUILTIN_TUPLE2_CLASS, + compiler::Signatures::BUILTIN_TUPLE3_CLASS, + compiler::Signatures::BUILTIN_TUPLE4_CLASS, + compiler::Signatures::BUILTIN_TUPLE5_CLASS, + compiler::Signatures::BUILTIN_TUPLE6_CLASS, + compiler::Signatures::BUILTIN_TUPLE7_CLASS, + compiler::Signatures::BUILTIN_TUPLE8_CLASS, + compiler::Signatures::BUILTIN_TUPLE9_CLASS, + compiler::Signatures::BUILTIN_TUPLE10_CLASS, + compiler::Signatures::BUILTIN_TUPLE11_CLASS, + compiler::Signatures::BUILTIN_TUPLE12_CLASS, + compiler::Signatures::BUILTIN_TUPLE13_CLASS, + compiler::Signatures::BUILTIN_TUPLE14_CLASS, + compiler::Signatures::BUILTIN_TUPLE15_CLASS, + compiler::Signatures::BUILTIN_TUPLE16_CLASS, + compiler::Signatures::BUILTIN_TUPLEN_CLASS, }; // clang-format on @@ -237,8 +311,6 @@ void ETSChecker::InitializeBuiltin(varbinder::Variable *var, const util::StringV bool ETSChecker::StartChecker(varbinder::VarBinder *varbinder, const util::Options &options) { - Initialize(varbinder); - if (options.IsParseOnly()) { return false; } @@ -266,9 +338,6 @@ bool ETSChecker::StartChecker(varbinder::VarBinder *varbinder, const util::Optio debugInfoPlugin_->PostCheck(); } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - BuildDynamicImportClass(); - #ifndef NDEBUG for (auto *func : varbinder->Functions()) { ES2PANDA_ASSERT(!func->Node()->AsScriptFunction()->Scope()->Name().Empty()); @@ -307,13 +376,18 @@ void ETSChecker::CheckProgram(parser::Program *program, bool runAnalysis) for (auto &[_, extPrograms] : program->ExternalSources()) { (void)_; for (auto *extProg : extPrograms) { - checker::SavedCheckerContext savedContext(this, Context().Status(), Context().ContainingClass()); - AddStatus(checker::CheckerStatus::IN_EXTERNAL); - CheckProgram(extProg, VarBinder()->IsGenStdLib()); + if (!extProg->IsASTLowered()) { + extProg->PushChecker(this); + varbinder::RecordTableContext recordTableCtx(VarBinder()->AsETSBinder(), extProg); + checker::SavedCheckerContext savedContext(this, Context().Status(), Context().ContainingClass()); + AddStatus(checker::CheckerStatus::IN_EXTERNAL); + CheckProgram(extProg, VarBinder()->IsGenStdLib()); + } } } ES2PANDA_ASSERT(Program()->Ast()->IsProgram()); + Program()->Ast()->Check(this); if (runAnalysis && !IsAnyError()) { @@ -361,41 +435,80 @@ Type *ETSChecker::GlobalByteType() const return GetGlobalTypesHolder()->GlobalByteType(); } +Type *ETSChecker::GlobalByteBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalByteBuiltinType(); +} + Type *ETSChecker::GlobalShortType() const { return GetGlobalTypesHolder()->GlobalShortType(); } +Type *ETSChecker::GlobalShortBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalShortBuiltinType(); +} + Type *ETSChecker::GlobalIntType() const { return GetGlobalTypesHolder()->GlobalIntType(); } +Type *ETSChecker::GlobalIntBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); +} + Type *ETSChecker::GlobalLongType() const { return GetGlobalTypesHolder()->GlobalLongType(); } +Type *ETSChecker::GlobalLongBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalLongBuiltinType(); +} + Type *ETSChecker::GlobalFloatType() const { return GetGlobalTypesHolder()->GlobalFloatType(); } +Type *ETSChecker::GlobalFloatBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalFloatBuiltinType(); +} + Type *ETSChecker::GlobalDoubleType() const { return GetGlobalTypesHolder()->GlobalDoubleType(); } +Type *ETSChecker::GlobalDoubleBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalDoubleBuiltinType(); +} + Type *ETSChecker::GlobalCharType() const { return GetGlobalTypesHolder()->GlobalCharType(); } +Type *ETSChecker::GlobalCharBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalCharBuiltinType(); +} Type *ETSChecker::GlobalETSBooleanType() const { return GetGlobalTypesHolder()->GlobalETSBooleanType(); } +Type *ETSChecker::GlobalETSBooleanBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); +} + Type *ETSChecker::GlobalVoidType() const { return GetGlobalTypesHolder()->GlobalETSVoidType(); @@ -448,6 +561,11 @@ ETSUnionType *ETSChecker::GlobalETSNullishObjectType() const return ret != nullptr ? ret->AsETSUnionType() : nullptr; } +ETSObjectType *ETSChecker::GlobalBuiltinETSResizableArrayType() const +{ + return AsETSObjectType(&GlobalTypesHolder::GlobalArrayBuiltinType); +} + ETSObjectType *ETSChecker::GlobalBuiltinETSStringType() const { return AsETSObjectType(&GlobalTypesHolder::GlobalETSStringBuiltinType); @@ -508,6 +626,11 @@ ETSObjectType *ETSChecker::GlobalBuiltinLambdaType(size_t nargs, bool hasRest) c return AsETSObjectType(&GlobalTypesHolder::GlobalLambdaBuiltinType, nargs, hasRest); } +ETSObjectType *ETSChecker::GlobalBuiltinTupleType(size_t nargs) const +{ + return AsETSObjectType(&GlobalTypesHolder::GlobalTupleBuiltinType, nargs); +} + size_t ETSChecker::GlobalBuiltinFunctionTypeVariadicThreshold() const { return GetGlobalTypesHolder()->VariadicFunctionTypeThreshold(); @@ -569,30 +692,29 @@ Type *ETSChecker::InvalidateType(ir::Typed *node) return node->SetTsType(GlobalTypeError()); } -Type *ETSChecker::TypeError(ir::Typed *node, std::string_view message, const lexer::SourcePosition &at) +Type *ETSChecker::TypeError(ir::Typed *node, const diagnostic::DiagnosticKind &diagKind, + const lexer::SourcePosition &at) { - LogTypeError(message, at); - return InvalidateType(node); + return TypeError(node, diagKind, util::DiagnosticMessageParams {}, at); } -Type *ETSChecker::TypeError(ir::Typed *node, const util::DiagnosticMessageParams &list, - const lexer::SourcePosition &at) +Type *ETSChecker::TypeError(ir::Typed *node, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, const lexer::SourcePosition &at) { - LogTypeError(list, at); + LogError(diagKind, list, at); return InvalidateType(node); } -Type *ETSChecker::TypeError(varbinder::Variable *var, std::string_view message, const lexer::SourcePosition &at) +Type *ETSChecker::TypeError(varbinder::Variable *var, const diagnostic::DiagnosticKind &diagKind, + const lexer::SourcePosition &at) { - LogTypeError(message, at); - var->SetTsType(GlobalTypeError()); - return var->TsType(); + return TypeError(var, diagKind, {}, at); } -Type *ETSChecker::TypeError(varbinder::Variable *var, const util::DiagnosticMessageParams &list, - const lexer::SourcePosition &at) +Type *ETSChecker::TypeError(varbinder::Variable *var, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, const lexer::SourcePosition &at) { - LogTypeError(list, at); + LogError(diagKind, list, at); var->SetTsType(GlobalTypeError()); return var->TsType(); } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 65ad47441bebb608fba6f96c2ea5143675c543ac..c57c46c019fa0f1e6308c3c602d314ef6843c696 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -16,13 +16,15 @@ #ifndef ES2PANDA_CHECKER_ETS_CHECKER_H #define ES2PANDA_CHECKER_ETS_CHECKER_H +#include #include #include "checker/checker.h" +#include "checker/types/globalTypesHolder.h" +#include "checker/types/ets/etsResizableArrayType.h" #include "checker/types/ets/types.h" #include "checker/resolveResult.h" -#include "ir/ts/tsInterfaceDeclaration.h" #include "ir/visitor/AstVisitor.h" #include "util/helpers.h" @@ -62,25 +64,34 @@ struct PairHash { using ComputedAbstracts = ArenaUnorderedMap, ArenaUnorderedSet>>; using ArrayMap = ArenaUnorderedMap, ETSArrayType *, PairHash>; +using ObjectInstantiationMap = ArenaUnorderedMap>; using GlobalArraySignatureMap = ArenaUnorderedMap; using DynamicCallIntrinsicsMap = ArenaUnorderedMap>; +using FunctionSignatureMap = ArenaUnorderedMap; +using FunctionInterfaceMap = ArenaUnorderedMap; using DynamicClassIntrinsicsMap = ArenaUnorderedMap; using DynamicLambdaObjectSignatureMap = ArenaUnorderedMap; using FunctionalInterfaceMap = ArenaUnorderedMap; using TypeMapping = ArenaUnorderedMap; using DynamicCallNamesMap = ArenaMap, uint32_t>; using ConstraintCheckRecord = std::tuple *, const Substitution *, lexer::SourcePosition>; -using DiagnosticInfo = std::pair, util::DiagnosticMessageParams>; +// can't use util::DiagnosticWithParams because std::optional can't contain references +using MaybeDiagnosticInfo = + std::optional>; +using AstNodePtr = ir::AstNode *; class ETSChecker final : public Checker { public: - explicit ETSChecker(util::DiagnosticEngine &diagnosticEngine) + explicit ETSChecker(ThreadSafeArenaAllocator *allocator, util::DiagnosticEngine &diagnosticEngine, + ThreadSafeArenaAllocator *programAllocator = nullptr) // NOLINTNEXTLINE(readability-redundant-member-init) - : Checker(diagnosticEngine), + : Checker(allocator, diagnosticEngine, programAllocator), arrayTypes_(Allocator()->Adapter()), pendingConstraintCheckRecords_(Allocator()->Adapter()), + objectInstantiationMap_(Allocator()->Adapter()), + invokeToArrowSignatures_(Allocator()->Adapter()), + arrowToFuncInterfaces_(Allocator()->Adapter()), globalArraySignatures_(Allocator()->Adapter()), - cachedComputedAbstracts_(Allocator()->Adapter()), dynamicIntrinsics_ {DynamicCallIntrinsicsMap {Allocator()->Adapter()}, DynamicCallIntrinsicsMap {Allocator()->Adapter()}}, dynamicClasses_ {DynamicClassIntrinsicsMap(Allocator()->Adapter()), @@ -90,7 +101,8 @@ public: apparentTypes_(Allocator()->Adapter()), dynamicCallNames_ { {DynamicCallNamesMap(Allocator()->Adapter()), DynamicCallNamesMap(Allocator()->Adapter())}}, - overloadSigContainer_(Allocator()->Adapter()) + overloadSigContainer_(Allocator()->Adapter()), + readdedChecker_(Allocator()->Adapter()) { } @@ -125,9 +137,19 @@ public: Type *GlobalETSBigIntType() const; Type *GlobalWildcardType() const; + Type *GlobalByteBuiltinType() const; + Type *GlobalShortBuiltinType() const; + Type *GlobalIntBuiltinType() const; + Type *GlobalLongBuiltinType() const; + Type *GlobalFloatBuiltinType() const; + Type *GlobalDoubleBuiltinType() const; + Type *GlobalCharBuiltinType() const; + Type *GlobalETSBooleanBuiltinType() const; + ETSObjectType *GlobalETSObjectType() const; ETSUnionType *GlobalETSNullishType() const; ETSUnionType *GlobalETSNullishObjectType() const; + ETSObjectType *GlobalBuiltinETSResizableArrayType() const; ETSObjectType *GlobalBuiltinETSStringType() const; ETSObjectType *GlobalBuiltinETSBigIntType() const; ETSObjectType *GlobalBuiltinTypeType() const; @@ -144,6 +166,8 @@ public: ETSObjectType *GlobalBuiltinLambdaType(size_t nargs, bool hasRest) const; size_t GlobalBuiltinFunctionTypeVariadicThreshold() const; + ETSObjectType *GlobalBuiltinTupleType(size_t nargs) const; + ETSObjectType *GlobalBuiltinDynamicType(Language lang) const; GlobalArraySignatureMap &GlobalArrayTypes(); @@ -151,13 +175,14 @@ public: Type *GlobalTypeError() const; [[nodiscard]] Type *InvalidateType(ir::Typed *node); - [[nodiscard]] Type *TypeError(ir::Typed *node, std::string_view message, - const lexer::SourcePosition &at); - [[nodiscard]] Type *TypeError(ir::Typed *node, const util::DiagnosticMessageParams &list, + [[nodiscard]] Type *TypeError(ir::Typed *node, const diagnostic::DiagnosticKind &diagKind, const lexer::SourcePosition &at); - [[nodiscard]] Type *TypeError(varbinder::Variable *var, std::string_view message, const lexer::SourcePosition &at); - [[nodiscard]] Type *TypeError(varbinder::Variable *var, const util::DiagnosticMessageParams &list, + [[nodiscard]] Type *TypeError(ir::Typed *node, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, const lexer::SourcePosition &at); + [[nodiscard]] Type *TypeError(varbinder::Variable *var, const diagnostic::DiagnosticKind &diagKind, const lexer::SourcePosition &at); + [[nodiscard]] Type *TypeError(varbinder::Variable *var, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, const lexer::SourcePosition &at); void InitializeBuiltins(varbinder::ETSBinder *varbinder); void InitializeBuiltin(varbinder::Variable *var, const util::StringView &name); @@ -169,6 +194,8 @@ public: Type *GuaranteedTypeForUncheckedCast(Type *base, Type *substituted); Type *GuaranteedTypeForUncheckedCallReturn(Signature *sig); Type *GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable *prop); + Type *GuaranteedTypeForUnionFieldAccess(ir::MemberExpression *memberExpression, ETSUnionType *etsUnionType); + void ReputCheckerData(); [[nodiscard]] bool IsETSChecker() const noexcept override { @@ -187,16 +214,18 @@ public: void ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set *extendsSet, const lexer::SourcePosition &pos); void ResolveDeclaredMembersOfObject(const Type *type); + lexer::Number ExtractNumericValue(Type const *const indexType); std::optional GetTupleElementAccessValue(const Type *type); bool ValidateArrayIndex(ir::Expression *expr, bool relaxed = false); - bool ValidateTupleIndex(const ETSTupleType *tuple, ir::MemberExpression *expr); + bool ValidateTupleIndex(const ETSTupleType *tuple, ir::MemberExpression *expr, bool reportError = true); bool ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple, ir::MemberExpression *expr); ETSObjectType *CheckThisOrSuperAccess(ir::Expression *node, ETSObjectType *classType, std::string_view msg); void CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type); ETSTypeParameter *SetUpParameterType(ir::TSTypeParameter *param); - void CheckIfOverrideIsValidInInterface(ETSObjectType *classType, Signature *sig, ir::ScriptFunction *func); + void GetInterfacesOfClass(ETSObjectType *type, ArenaVector &interfaces); + void CheckIfOverrideIsValidInInterface(ETSObjectType *classType, Signature *sig, Signature *sigFunc); void CheckFunctionRedeclarationInInterface(ETSObjectType *classType, ArenaVector &similarSignatures, - ir::ScriptFunction *func); + Signature *sigFunc); void ValidateAbstractMethodsToBeImplemented(ArenaVector &abstractsToBeImplemented, ETSObjectType *classType, const std::vector &implementedSignatures); @@ -253,6 +282,7 @@ public: void CheckValidInheritance(ETSObjectType *classType, ir::ClassDefinition *classDef); void CheckProperties(ETSObjectType *classType, ir::ClassDefinition *classDef, varbinder::LocalVariable *it, varbinder::LocalVariable *found, ETSObjectType *interfaceFound); + void CheckReadonlyClassPropertyInImplementedInterface(ETSObjectType *classType, varbinder::LocalVariable *field); void TransformProperties(ETSObjectType *classType); void CheckGetterSetterProperties(ETSObjectType *classType); void AddElementsToModuleObject(ETSObjectType *moduleObj, const util::StringView &str); @@ -266,6 +296,8 @@ public: ETSObjectType *GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target); bool HasETSFunctionType(ir::TypeNode *typeAnnotation); + void VariableTypeFromInitializer(varbinder::Variable *variable, Type *annotationType, Type *initType); + // Type creation ByteType *CreateByteType(int8_t value); ETSBooleanType *CreateETSBooleanType(bool value); @@ -277,6 +309,8 @@ public: CharType *CreateCharType(char16_t value); ETSBigIntType *CreateETSBigIntLiteralType(util::StringView value); ETSStringType *CreateETSStringLiteralType(util::StringView value); + ETSResizableArrayType *CreateETSMultiDimResizableArrayType(Type *element, size_t dimSize); + ETSResizableArrayType *CreateETSResizableArrayType(Type *element); ETSArrayType *CreateETSArrayType(Type *elementType, bool isCachePolluting = false); Type *CreateETSUnionType(Span constituentTypes); template @@ -289,6 +323,7 @@ public: return CreateETSUnionType(Span(constituentTypes)); } Type *CreateUnionFromKeyofType(ETSObjectType *const type); + void ProcessTypeMembers(ETSObjectType *type, ArenaVector &literals); ETSAsyncFuncReturnType *CreateETSAsyncFuncReturnTypeFromPromiseType(ETSObjectType *promiseType); ETSAsyncFuncReturnType *CreateETSAsyncFuncReturnTypeFromBaseType(Type *baseType); ETSTypeAliasType *CreateETSTypeAliasType(util::StringView name, const ir::AstNode *declNode, @@ -317,7 +352,6 @@ public: // Arithmetic Type *NegateNumericType(Type *type, ir::Expression *node); - Type *BitwiseNegateNumericType(Type *type, ir::Expression *node); bool CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::TokenType op); [[nodiscard]] bool CheckBinaryPlusMultDivOperandsForUnionType(const Type *leftType, const Type *rightType, const ir::Expression *left, @@ -382,7 +416,10 @@ public: void InferTypesForLambda(ir::ScriptFunction *lambda, ir::ETSFunctionType *calleeType, Signature *maybeSubstitutedFunctionSig = nullptr); void InferTypesForLambda(ir::ScriptFunction *lambda, Signature *signature); - void TryInferTypeForLambdaTypeAlias(ir::AssignmentExpression *expr, ETSFunctionType *calleeType); + void TryInferTypeForLambdaTypeAlias(ir::ArrowFunctionExpression *expr, ETSFunctionType *calleeType); + bool ResolveLambdaArgumentType(Signature *signature, ir::Expression *argument, size_t paramPosition, + size_t argumentPosition, TypeRelationFlag resolutionFlags); + bool TrailingLambdaTypeInference(Signature *signature, const ArenaVector &arguments); bool TypeInference(Signature *signature, const ArenaVector &arguments, TypeRelationFlag flags = TypeRelationFlag::NONE); bool CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, ir::ArrowFunctionExpression *arrowFuncExpr, @@ -392,14 +429,21 @@ public: bool CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction *lambda); bool CheckLambdaAssignableUnion(ir::AstNode *typeAnn, ir::ScriptFunction *lambda); bool IsCompatibleTypeArgument(ETSTypeParameter *typeParam, Type *typeArgument, const Substitution *substitution); + Substitution *NewSubstitution() { - return Allocator()->New(Allocator()->Adapter()); + return ProgramAllocator()->New(ProgramAllocator()->Adapter()); } + Substitution *CopySubstitution(const Substitution *src) { - return Allocator()->New(*src); + return ProgramAllocator()->New(*src); } + bool ValidateTypeSubstitution(const ArenaVector &typeParams, Type *ctype, Type *argumentType, + Substitution *substitution); + bool ProcessUntypedParameter(ir::AstNode *declNode, size_t paramIndex, Signature *paramSig, Signature *argSig, + Substitution *substitution); + void EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *typeArg); [[nodiscard]] bool EnhanceSubstitutionForType(const ArenaVector &typeParams, Type *paramType, Type *argumentType, Substitution *substitution); @@ -413,6 +457,9 @@ public: Type *argumentType, Substitution *substitution); [[nodiscard]] bool EnhanceSubstitutionForArray(const ArenaVector &typeParams, ETSArrayType *paramType, Type *argumentType, Substitution *substitution); + [[nodiscard]] bool EnhanceSubstitutionForResizableArray(const ArenaVector &typeParams, + ETSResizableArrayType *paramType, Type *argumentType, + Substitution *substitution); std::pair, bool> CreateUnconstrainedTypeParameters( ir::TSTypeParameterDeclaration const *typeParams); void AssignTypeParameterConstraints(ir::TSTypeParameterDeclaration const *typeParams); @@ -448,11 +495,15 @@ public: void SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature *&prevSig, std::tuple info, bool lookForClassType); + void CollectSuitableSignaturesForTypeInference(size_t paramIdx, ArenaVector &signatures, + ArenaMultiMap &bestSignaturesForParameter, + const ArenaVector &arguments); ArenaMultiMap GetSuitableSignaturesForParameter( const std::vector &argTypeInferenceRequired, size_t paramCount, ArenaVector &signatures, - const lexer::SourcePosition &pos); + const ArenaVector &arguments, const lexer::SourcePosition &pos); Signature *ChooseMostSpecificSignature(ArenaVector &signatures, const std::vector &argTypeInferenceRequired, + const ArenaVector &arguments, const lexer::SourcePosition &pos, size_t argumentsSize = ULONG_MAX); Signature *ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpression *callExpr, ArenaVector const &signatures, @@ -490,12 +541,11 @@ public: OverrideErrorCode CheckOverride(Signature *signature, Signature *other); bool IsMethodOverridesOther(Signature *base, Signature *derived); bool IsOverridableIn(Signature *signature); - [[nodiscard]] bool AreOverrideEquivalent(Signature *s1, Signature *s2); + [[nodiscard]] bool AreOverrideCompatible(Signature *s1, Signature *s2); [[nodiscard]] bool IsReturnTypeSubstitutable(Signature *s1, Signature *s2); bool NeedToVerifySignatureVisibility(Signature *signature, const lexer::SourcePosition &pos); - void ValidateSignatureAccessibility(ETSObjectType *callee, const ir::CallExpression *callExpr, Signature *signature, - const lexer::SourcePosition &pos, - const DiagnosticInfo &errorInfo = {std::nullopt, {}}); + void ValidateSignatureAccessibility(ETSObjectType *callee, Signature *signature, const lexer::SourcePosition &pos, + const MaybeDiagnosticInfo &maybeErrorInfo = std::nullopt); void CheckCapturedVariables(); void CheckCapturedVariableInSubnodes(ir::AstNode *node, varbinder::Variable *var); void CheckCapturedVariable(ir::AstNode *node, varbinder::Variable *var); @@ -540,6 +590,8 @@ public: const ir::TSTypeParameterInstantiation *typeParams, size_t idx); Type *GetTypeFromTypeParameterReference(varbinder::LocalVariable *var, const lexer::SourcePosition &pos); Type *GetNonConstantType(Type *type); + checker::Type *GetElementTypeOfArray(checker::Type *type); + const checker::Type *GetElementTypeOfArray(const checker::Type *type) const; bool IsNullLikeOrVoidExpression(const ir::Expression *expr) const; bool IsConstantExpression(ir::Expression *expr, Type *type); void ValidateUnaryOperatorOperand(varbinder::Variable *variable); @@ -549,6 +601,9 @@ public: void CheckFunctionSignatureAnnotations(const ArenaVector ¶ms, ir::TSTypeParameterDeclaration *typeParams, ir::TypeNode *returnTypeAnnotation); + bool CheckAndLogInvalidThisUsage(const ir::TypeNode *type, const diagnostic::DiagnosticKind &diagnostic); + bool IsFixedArray(ir::ETSTypeReferencePart *part); + void ValidateThisUsage(const ir::TypeNode *returnTypeAnnotation); void CheckAnnotations(const ArenaVector &annotations); void CheckAmbientAnnotation(ir::AnnotationDeclaration *annoImpl, ir::AnnotationDeclaration *annoDecl); bool CheckAmbientAnnotationFieldInitializerValue(ir::Expression *init, ir::Expression *expected); @@ -666,6 +721,8 @@ public: varbinder::ClassScope *scope, bool isSetter, ETSChecker *checker); void GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *originalProp, ETSObjectType *classType); + void SetupGetterSetterFlags(ir::ClassProperty *originalProp, ETSObjectType *classType, ir::MethodDefinition *getter, + ir::MethodDefinition *setter, const bool inExternal); Type *GetImportSpecifierObjectType(ir::ETSImportDeclaration *importDecl, ir::Identifier *ident); void ImportNamespaceObjectTypeAddReExportType(ir::ETSImportDeclaration *importDecl, checker::ETSObjectType *lastObjectType, ir::Identifier *ident); @@ -800,6 +857,13 @@ public: return util::NodeAllocator::ForceSetParent(Allocator(), std::forward(args)...); } + template + T *ProgramAllocNode(Args &&...args) + { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return util::NodeAllocator::ForceSetParent(ProgramAllocator(), std::forward(args)...); + } + ArenaVector &PendingConstraintCheckRecords(); size_t &ConstraintCheckScopesCount(); @@ -844,6 +908,21 @@ public: return overloadSigContainer_; } + ObjectInstantiationMap &GetObjectInstantiationMap() + { + return objectInstantiationMap_; + } + + FunctionSignatureMap &GetInvokeToArrowSignatures() + { + return invokeToArrowSignatures_; + } + + FunctionInterfaceMap &GetArrowToFuncInterfaces() + { + return arrowToFuncInterfaces_; + } + void CleanUp() override { Checker::CleanUp(); @@ -851,7 +930,7 @@ public: pendingConstraintCheckRecords_.clear(); constraintCheckScopesCount_ = 0; globalArraySignatures_.clear(); - cachedComputedAbstracts_.clear(); + GetCachedComputedAbstracts()->clear(); for (auto &dynamicCallIntrinsicsMap : dynamicIntrinsics_) { dynamicCallIntrinsicsMap.clear(); } @@ -869,6 +948,33 @@ public: overloadSigContainer_.clear(); } + // This helper finds the intersection of two callSignatures sets + // The result is stored in callSignatures of newly created ETSFunctionType + checker::ETSFunctionType *IntersectSignatureSets(const checker::ETSFunctionType *left, + const checker::ETSFunctionType *right); + + ComputedAbstracts *GetCachedComputedAbstracts() + { + if (cachedComputedAbstracts_ == nullptr) { + InitCachedComputedAbstracts(); + } + return cachedComputedAbstracts_; + } + + void SetCachedComputedAbstracts(ComputedAbstracts *cachedComputedAbstracts) + { + cachedComputedAbstracts_ = cachedComputedAbstracts; + } + + void InitCachedComputedAbstracts() + { + // clang-format off + cachedComputedAbstracts_ = ProgramAllocator()->New, + ArenaUnorderedSet>>>(ProgramAllocator()->Adapter()); + // clang-format on + } + private: std::pair GetTargetIdentifierAndType(ir::Identifier *ident); void NotResolvedError(ir::Identifier *const ident, const varbinder::Variable *classVar, @@ -937,6 +1043,8 @@ private: void CheckProgram(parser::Program *program, bool runAnalysis = false); void CheckWarnings(parser::Program *program, const util::Options &options); + Type *ResolveUnionUncheckedType(ArenaVector &&apparentTypes); + bool ComputeSuperType(ETSObjectType *type); template @@ -959,10 +1067,15 @@ private: const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags); // Trailing lambda void MoveTrailingBlockToEnclosingBlockStatement(ir::CallExpression *callExpr); + ir::ScriptFunction *CreateLambdaFunction(ir::BlockStatement *trailingBlock, Signature *sig); void TransformTraillingLambda(ir::CallExpression *callExpr, Signature *sig); ArenaVector ExtendArgumentsWithFakeLamda(ir::CallExpression *callExpr); // Static invoke + bool SetStaticInvokeValues(ir::Identifier *const ident, ir::Identifier *classId, ir::Identifier *methodId, + varbinder::LocalVariable *instantiateMethod); + void CreateTransformedCallee(ir::Identifier *classId, ir::Identifier *methodId, ir::Identifier *const ident, + varbinder::LocalVariable *instantiateMethod); bool TryTransformingToStaticInvoke(ir::Identifier *ident, const Type *resolvedType); // Partial @@ -980,9 +1093,12 @@ private: ArrayMap arrayTypes_; ArenaVector pendingConstraintCheckRecords_; + ObjectInstantiationMap objectInstantiationMap_; + FunctionSignatureMap invokeToArrowSignatures_; + FunctionInterfaceMap arrowToFuncInterfaces_; size_t constraintCheckScopesCount_ {0}; GlobalArraySignatureMap globalArraySignatures_; - ComputedAbstracts cachedComputedAbstracts_; + ComputedAbstracts *cachedComputedAbstracts_ {nullptr}; // NOTE(aleksisch): Extract dynamic from checker to separate class std::array dynamicIntrinsics_; std::array dynamicClasses_; @@ -994,6 +1110,7 @@ private: evaluate::ScopedDebugInfoPlugin *debugInfoPlugin_ {nullptr}; std::unordered_set elementStack_; ArenaVector overloadSigContainer_; + ArenaSet readdedChecker_; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/IsolatedDeclgenChecker.cpp b/ets2panda/checker/IsolatedDeclgenChecker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed623f5cb40b5a90349d0e03a25238b1c9f52e82 --- /dev/null +++ b/ets2panda/checker/IsolatedDeclgenChecker.cpp @@ -0,0 +1,341 @@ +/* + * 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 "checker/IsolatedDeclgenChecker.h" +#include "clang.h" +#include "utils/logger.h" + +namespace ark::es2panda::checker { +using AstNodePtr = ir::AstNode *; + +void IsolatedDeclgenChecker::LogError(const diagnostic::DiagnosticKind &diagnostic, + const util::DiagnosticMessageParams &diagnosticParams, + const lexer::SourcePosition &pos) +{ + diagnosticEngine_.LogDiagnostic(diagnostic, diagnosticParams, pos); +} + +void IsolatedDeclgenChecker::Check(ir::ClassProperty *ast) +{ + if (ast->Parent()->IsAnnotationUsage()) { + return; + } + if (ast->TypeAnnotation() == nullptr) { + LogError(diagnostic::PROPERTY_MUST_HAVE_EXPLICIT_TYPE_ANNOTATION_WITH_ISOLATED_DECL, {}, ast->Start()); + } +} + +void IsolatedDeclgenChecker::Check(ir::ObjectExpression *ast) +{ + for (auto property : ast->Properties()) { + if (property->IsSpreadElement()) { + LogError(diagnostic::OBJECTS_THAT_CONTAIN_SPREAD_ASSIGNMENTS_CANNOT_BE_INFERRED_WITH_ISOLATED_DECL, {}, + property->Start()); + } + } +} + +static bool IsEnumArray(ir::ArrayExpression *ast) +{ + if (ast->Elements().empty()) { + return false; + } + auto *arrayParent = ast->Parent(); + if (arrayParent == nullptr || !arrayParent->IsClassProperty()) { + return false; + } + auto *classProperty = arrayParent->AsClassProperty(); + if (classProperty == nullptr || classProperty->Parent() == nullptr) { + return false; + } + auto *classDecl = classProperty->Parent()->AsClassDefinition(); + return !(classDecl == nullptr || !classDecl->InternalName().StartsWith("enum.")); +} + +void IsolatedDeclgenChecker::Check(ir::ArrayExpression *ast) +{ + if (IsEnumArray(ast)) { + return; + } + for (auto element : ast->Elements()) { + if (!element->IsStringLiteral() && !element->IsNumberLiteral() && !element->IsBooleanLiteral()) { + LogError(diagnostic::ONLY_CONST_ARRAYS_CAN_BE_INFERRED_WITH_ISOLATED_DECL, {}, element->Start()); + } + } +} + +void IsolatedDeclgenChecker::Check(ir::ETSParameterExpression *ast) +{ + if (ast->TypeAnnotation() == nullptr) { + LogError(diagnostic::PARAMETER_MUST_HAVE_EXPLICIT_TYPE_ANNOTATION_WITH_ISOLATED_DECL, {}, ast->Start()); + } +} + +void IsolatedDeclgenChecker::Check(ir::ExportDefaultDeclaration *ast) +{ + auto *decl = ast->Decl(); + if (decl == nullptr) { + LogError(diagnostic::DEFAULT_EXPORTS__CANNOT_BE_INFERRED_WITH_ISOLATED_DECL, {}, ast->Start()); + return; + } + if (decl->IsClassDeclaration()) { + auto *classDecl = decl->AsClassDeclaration(); + if (classDecl == nullptr) { + LogError(diagnostic::DEFAULT_EXPORTS__CANNOT_BE_INFERRED_WITH_ISOLATED_DECL, {}, ast->Start()); + } + return; + } + if (decl->IsTSInterfaceDeclaration()) { + auto *interfaceDecl = decl->AsTSInterfaceDeclaration(); + if (interfaceDecl == nullptr) { + LogError(diagnostic::DEFAULT_EXPORTS__CANNOT_BE_INFERRED_WITH_ISOLATED_DECL, {}, ast->Start()); + } + return; + } + if (decl->IsTSEnumDeclaration()) { + auto *enumDecl = decl->AsTSEnumDeclaration(); + if (enumDecl == nullptr) { + LogError(diagnostic::DEFAULT_EXPORTS__CANNOT_BE_INFERRED_WITH_ISOLATED_DECL, {}, ast->Start()); + } + return; + } + if (decl->IsFunctionDeclaration()) { + auto *funcDecl = decl->AsFunctionDeclaration(); + if (funcDecl == nullptr) { + LogError(diagnostic::DEFAULT_EXPORTS__CANNOT_BE_INFERRED_WITH_ISOLATED_DECL, {}, ast->Start()); + } + return; + } + if (decl->IsClassProperty()) { + auto *classProperty = decl->AsClassProperty(); + if (classProperty == nullptr) { + LogError(diagnostic::DEFAULT_EXPORTS__CANNOT_BE_INFERRED_WITH_ISOLATED_DECL, {}, ast->Start()); + } + return; + } + LogError(diagnostic::DEFAULT_EXPORTS__CANNOT_BE_INFERRED_WITH_ISOLATED_DECL, {}, ast->Start()); +} + +std::string GetLiteralType(const ir::Literal *literal) +{ + if (literal->IsStringLiteral()) { + return "String"; + } + if (literal->IsNumberLiteral()) { + return "Number"; + } + if (literal->IsBooleanLiteral()) { + return "Boolean"; + } + return ""; +} + +std::string IsolatedDeclgenChecker::ProcessLiteralArgument(ir::Literal *literal, ir::ReturnStatement *returnStatement) +{ + std::string literalType = GetLiteralType(literal); + if (!literalType.empty()) { + return literalType; + } + LogError(diagnostic::FUNCTION_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL, {}, + returnStatement->Start()); + return ""; +} + +std::string IsolatedDeclgenChecker::ProcessIdentifierArgument(ir::Identifier *identifier, + ir::ReturnStatement *returnStatement) +{ + auto idVar = identifier->Variable(); + if (idVar == nullptr) { + LogError(diagnostic::FUNCTION_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL, {}, + returnStatement->Start()); + return ""; + } + auto decl = idVar->Declaration(); + if (decl == nullptr) { + LogError(diagnostic::FUNCTION_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL, {}, + returnStatement->Start()); + return ""; + } + + if (decl->IsLetOrConstDecl()) { + return decl->Node() + ->AsClassProperty() + ->TypeAnnotation() + ->AsETSTypeReference() + ->Part() + ->Name() + ->AsIdentifier() + ->Name() + .Mutf8(); + } + LogError(diagnostic::FUNCTION_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL, {}, + returnStatement->Start()); + return ""; +} + +std::string IsolatedDeclgenChecker::ProcessConstArrayArgument(ir::ArrayExpression *arrayExpr, + ir::ReturnStatement *returnStatement) +{ + if (arrayExpr->Elements().empty() || !arrayExpr->Elements()[0]->IsLiteral()) { + LogError(diagnostic::FUNCTION_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL, {}, + returnStatement->Start()); + return ""; + } + + return "Array<" + GetLiteralType((arrayExpr->Elements()[0])->AsLiteral()) + ">"; +} + +std::string IsolatedDeclgenChecker::ProcessNewClassInstanceExpressionArgument( + ir::ETSNewClassInstanceExpression *newClassInstance, ir::ReturnStatement *returnStatement) +{ + auto *classType = newClassInstance->GetTypeRef(); + if (classType == nullptr) { + LogError(diagnostic::FUNCTION_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL, {}, + returnStatement->Start()); + return ""; + } + return classType->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Name().Mutf8(); +} + +std::string IsolatedDeclgenChecker::InferReturnTypeForArgument(ir::ReturnStatement *returnStatement) +{ + if (returnStatement->Argument() == nullptr) { + return "void"; + } + auto *returnType = returnStatement->ReturnType(); + auto returnTypeStr = returnStatement->ReturnType()->ToString(); + if (returnType != nullptr && returnTypeStr.find(ERROR_TYPE) == std::string::npos) { + return returnTypeStr; + } + auto *argument = returnStatement->Argument(); + if (argument->IsLiteral()) { + auto *literal = argument->AsLiteral(); + return ProcessLiteralArgument(literal, returnStatement); + } + if (argument->IsETSNewClassInstanceExpression()) { + auto *newClassInstance = argument->AsETSNewClassInstanceExpression(); + return ProcessNewClassInstanceExpressionArgument(newClassInstance, returnStatement); + } + if (argument->IsETSParameterExpression()) { + auto *etsParam = argument->AsETSParameterExpression(); + return etsParam->TypeAnnotation()->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Name().Mutf8(); + } + if (argument->IsArrayExpression()) { + auto *arrayExpr = argument->AsArrayExpression(); + return ProcessConstArrayArgument(arrayExpr, returnStatement); + } + if (argument->IsIdentifier()) { + auto *identifier = argument->AsIdentifier(); + return ProcessIdentifierArgument(identifier, returnStatement); + } + + LogError(diagnostic::FUNCTION_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL, {}, + returnStatement->Start()); + return ""; +} + +std::string IsolatedDeclgenChecker::Check(ir::ScriptFunction *ast) +{ + auto &returnStatements = ast->ReturnStatements(); + if (returnStatements.empty()) { + return "void"; + } + if (returnStatements.size() == 1) { + return InferReturnTypeForArgument(returnStatements[0]); + } + + std::set returnTypes; + for (const auto &returnStatement : returnStatements) { + auto returnType = InferReturnTypeForArgument(returnStatement); + if (!returnType.empty()) { + returnTypes.insert(returnType); + } else { + return ""; + } + } + + if (returnTypes.size() == 1) { + return *returnTypes.begin(); + } + std::string returnTypeStr; + for (const auto &returnType : returnTypes) { + if (returnTypeStr.empty()) { + returnTypeStr = returnType; + } else { + returnTypeStr += " | " + returnType; + } + } + + return returnTypeStr; +} + +void IsolatedDeclgenChecker::CheckBeforeChecker() +{ + program_.Ast()->TransformChildrenRecursively( + [&](ir::AstNode *ast) -> AstNodePtr { + if (ast->IsClassProperty()) { + Check(ast->AsClassProperty()); + return ast; + } + + if (ast->IsETSParameterExpression()) { + this->Check(ast->AsETSParameterExpression()); + return ast; + } + + if (ast->IsArrayExpression()) { + Check(ast->AsArrayExpression()); + return ast; + } + + if (ast->IsObjectExpression()) { + Check(ast->AsObjectExpression()); + return ast; + } + if (ast->IsExportDefaultDeclaration()) { + Check(ast->AsExportDefaultDeclaration()); + return ast; + } + + return ast; + }, + "CheckIsolatedDeclBeforeChecker"); +} + +void IsolatedDeclgenChecker::CheckAfterChecker() +{ + program_.Ast()->TransformChildrenRecursively( + [&](ir::AstNode *ast) -> AstNodePtr { + if (!ast->IsScriptFunction()) { + return ast; + } + + auto *scriptFunction = ast->AsScriptFunction(); + auto *returnType = scriptFunction->Signature()->ReturnType(); + if (returnType == nullptr) { + return ast; + } + std::string returnTypeStr = Check(scriptFunction); + if (returnType->ToString().find(ERROR_TYPE) == std::string::npos) { + scriptFunction->SetIsolatedDeclgenReturnType(returnType->ToString()); + return ast; + } + scriptFunction->SetIsolatedDeclgenReturnType(returnTypeStr); + + return ast; + }, + "CheckIsolatedDeclAfterChecker"); +} +} // namespace ark::es2panda::checker \ No newline at end of file diff --git a/ets2panda/checker/IsolatedDeclgenChecker.h b/ets2panda/checker/IsolatedDeclgenChecker.h new file mode 100644 index 0000000000000000000000000000000000000000..eef54b02323d6c3573da4c1201e0142ea85ca0a4 --- /dev/null +++ b/ets2panda/checker/IsolatedDeclgenChecker.h @@ -0,0 +1,63 @@ +/* + * 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 ES2PANDA_CHECKER_ISOLATED_DECLGEN_CHECKER_H +#define ES2PANDA_CHECKER_ISOLATED_DECLGEN_CHECKER_H + +#include +#include "macros.h" +#include "checker/checker.h" + +namespace ark::es2panda::checker { +class IsolatedDeclgenChecker { +public: + explicit IsolatedDeclgenChecker(util::DiagnosticEngine &diagnosticEngine, parser::Program &program) + : diagnosticEngine_(diagnosticEngine), program_(program) + { + } + ~IsolatedDeclgenChecker() = default; + + NO_COPY_SEMANTIC(IsolatedDeclgenChecker); + NO_MOVE_SEMANTIC(IsolatedDeclgenChecker); + + void CheckBeforeChecker(); + void CheckAfterChecker(); + + void Check(ir::ClassProperty *ast); + void Check(ir::ObjectExpression *ast); + void Check(ir::ArrayExpression *ast); + void Check(ir::ETSParameterExpression *ast); + void Check(ir::ExportDefaultDeclaration *ast); + + std::string Check(ir::ScriptFunction *ast); + +private: + std::string InferReturnTypeForArgument(ir::ReturnStatement *returnStatement); + + std::string ProcessLiteralArgument(ir::Literal *literal, ir::ReturnStatement *returnStatement); + std::string ProcessIdentifierArgument(ir::Identifier *identifier, ir::ReturnStatement *returnStatement); + std::string ProcessConstArrayArgument(ir::ArrayExpression *array, ir::ReturnStatement *returnStatement); + std::string ProcessNewClassInstanceExpressionArgument(ir::ETSNewClassInstanceExpression *newClassInstanceExpression, + ir::ReturnStatement *returnStatement); + + void LogError(const diagnostic::DiagnosticKind &diagnostic, const util::DiagnosticMessageParams &diagnosticParams, + const lexer::SourcePosition &pos); + +private: + util::DiagnosticEngine &diagnosticEngine_; + parser::Program &program_; +}; +} // namespace ark::es2panda::checker + +#endif // ES2PANDA_CHECKER_ISOLATED_DECLGEN_CHECKER_H \ No newline at end of file diff --git a/ets2panda/checker/JSchecker.cpp b/ets2panda/checker/JSchecker.cpp index 3efe6f5b8d7bbc0d6d74297acdd42fcab796c441..62c02cc2064b2540fbdcc5551816e2681d53fa0f 100644 --- a/ets2panda/checker/JSchecker.cpp +++ b/ets2panda/checker/JSchecker.cpp @@ -23,7 +23,6 @@ namespace ark::es2panda::checker { bool JSChecker::StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const util::Options &options) { - Initialize(varbinder); varbinder->IdentifierAnalysis(); if (options.IsDumpAst()) { diff --git a/ets2panda/checker/JSchecker.h b/ets2panda/checker/JSchecker.h index 91f85fc93a169cbb3edac902f911ee99aa9be53d..3e261069aa8196ca0803ad84e0d67a53e8d9112d 100644 --- a/ets2panda/checker/JSchecker.h +++ b/ets2panda/checker/JSchecker.h @@ -23,7 +23,11 @@ namespace ark::es2panda::checker { class JSChecker : public Checker { public: // NOLINTNEXTLINE(readability-redundant-member-init) - explicit JSChecker(util::DiagnosticEngine &diagnosticEngine) : Checker(diagnosticEngine) {} + explicit JSChecker([[maybe_unused]] ThreadSafeArenaAllocator *allocator, util::DiagnosticEngine &diagnosticEngine, + [[maybe_unused]] ThreadSafeArenaAllocator *programAllocator = nullptr) + : Checker(allocator, diagnosticEngine, programAllocator) + { + } bool StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const util::Options &options) override; diff --git a/ets2panda/checker/SemanticAnalyzer.h b/ets2panda/checker/SemanticAnalyzer.h index 8397c5162b331f8afa10370cf70069bb01cd82cc..b0db804c0861695bd2c965bb20e8f232feabd08c 100644 --- a/ets2panda/checker/SemanticAnalyzer.h +++ b/ets2panda/checker/SemanticAnalyzer.h @@ -39,7 +39,6 @@ #include "ir/ets/etsFunctionType.h" #include "ir/ets/etsImportDeclaration.h" #include "ir/ets/etsKeyofType.h" -#include "ir/ets/etsLaunchExpression.h" #include "ir/ets/etsNewArrayInstanceExpression.h" #include "ir/ets/etsNewClassInstanceExpression.h" #include "ir/ets/etsNewMultiDimArrayInstanceExpression.h" @@ -49,6 +48,7 @@ #include "ir/ets/etsModule.h" #include "ir/ets/etsStringLiteralType.h" #include "ir/ets/etsNeverType.h" +#include "ir/ets/etsNonNullishTypeNode.h" #include "ir/ets/etsNullishTypes.h" #include "ir/ets/etsStructDeclaration.h" #include "ir/ets/etsTypeReference.h" diff --git a/ets2panda/checker/TSAnalyzer.cpp b/ets2panda/checker/TSAnalyzer.cpp index 25a4cf6789233015b76a24acba45fe96a21f25b0..cfaad3f534778bcc113cfa6f35b12ba77bdffdfb 100644 --- a/ets2panda/checker/TSAnalyzer.cpp +++ b/ets2panda/checker/TSAnalyzer.cpp @@ -1253,9 +1253,8 @@ checker::Type *TSAnalyzer::Check(ir::ReturnStatement *st) const returnType = checker->CheckTypeCached(st->Argument()); } - checker->IsTypeAssignableTo(returnType, funcReturnType, - {"Type '", returnType, "' is not assignable to type '", funcReturnType, "'."}, - st->Start()); + checker->IsTypeAssignableTo(returnType, funcReturnType, diagnostic::INVALID_ASSIGNMNENT_2, + {returnType, funcReturnType}, st->Start()); } return nullptr; @@ -1356,11 +1355,8 @@ static void CheckSimpleVariableDeclaration(checker::TSChecker *checker, ir::Vari } if (previousType != nullptr) { - checker->IsTypeIdenticalTo(bindingVar->TsType(), previousType, - {"Subsequent variable declaration must have the same type. Variable '", - bindingVar->Name(), "' must be of type '", previousType, "', but here has type '", - bindingVar->TsType(), "'."}, - declarator->Id()->Start()); + checker->IsTypeIdenticalTo(bindingVar->TsType(), previousType, diagnostic::DIFFERENT_SUBSEQ_DECL, + {bindingVar->Name(), previousType, bindingVar->TsType()}, declarator->Id()->Start()); } checker->RemoveStatus(checker::CheckerStatus::IN_CONST_CONTEXT); @@ -1498,12 +1494,8 @@ checker::Type *TSAnalyzer::Check(ir::TSAsExpression *expr) const checker::Type *exprType = checker->GetBaseTypeOfLiteralType(expr->Expr()->Check(checker)); checker::Type *targetType = expr->TypeAnnotation()->GetType(checker); - checker->IsTypeComparableTo( - targetType, exprType, - {"Conversion of type '", exprType, "' to type '", targetType, - "' may be a mistake because neither type sufficiently overlaps with the other. If this was ", - "intentional, convert the expression to 'unknown' first."}, - expr->Start()); + checker->IsTypeComparableTo(targetType, exprType, diagnostic::DISJOINT_CONVERSION, {exprType, targetType}, + expr->Start()); return targetType; } @@ -1940,10 +1932,8 @@ static void CheckInheritedPropertiesAreIdentical(checker::TSChecker *checker, ch } else if (res->second.second != type) { checker::Type *sourceType = checker->GetTypeOfVariable(inheritedProp); checker::Type *targetType = checker->GetTypeOfVariable(res->second.first); - checker->IsTypeIdenticalTo(sourceType, targetType, - {"Interface '", type, "' cannot simultaneously extend types '", - res->second.second, "' and '", base->AsInterfaceType(), "'."}, - locInfo); + checker->IsTypeIdenticalTo(sourceType, targetType, diagnostic::IFACE_MULTIPLE_EXTENSION, + {type, res->second.second, base->AsInterfaceType()}, locInfo); } } } @@ -1971,9 +1961,8 @@ checker::Type *TSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const CheckInheritedPropertiesAreIdentical(checker, resolvedInterface, st->Id()->Start()); for (auto *base : resolvedInterface->Bases()) { - checker->IsTypeAssignableTo( - resolvedInterface, base, - {"Interface '", st->Id()->Name(), "' incorrectly extends interface '", base, "'"}, st->Id()->Start()); + checker->IsTypeAssignableTo(resolvedInterface, base, diagnostic::IFACE_INVALID_EXTENDS, + {st->Id()->Name(), base}, st->Id()->Start()); } checker->CheckIndexConstraints(resolvedInterface); diff --git a/ets2panda/checker/TSAnalyzerUnreachable.cpp b/ets2panda/checker/TSAnalyzerUnreachable.cpp index 2d555f09ed85d26bd9ddd084cde1517ffff37f74..e5c22b6907deb5347cbd8553504c68ee31ae8b77 100644 --- a/ets2panda/checker/TSAnalyzerUnreachable.cpp +++ b/ets2panda/checker/TSAnalyzerUnreachable.cpp @@ -89,11 +89,6 @@ checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSImportDeclaration *node ES2PANDA_UNREACHABLE(); } -checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSLaunchExpression *expr) const -{ - ES2PANDA_UNREACHABLE(); -} - checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSNewArrayInstanceExpression *expr) const { ES2PANDA_UNREACHABLE(); @@ -144,6 +139,11 @@ checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSTypeReferencePart *node ES2PANDA_UNREACHABLE(); } +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSNonNullishTypeNode *node) const +{ + ES2PANDA_UNREACHABLE(); +} + checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::ETSNullType *node) const { ES2PANDA_UNREACHABLE(); diff --git a/ets2panda/checker/TSchecker.cpp b/ets2panda/checker/TSchecker.cpp index 9e820dfc4d067f98c1dfe1c36f675edcd0e9ed44..4fe4acde5426a0b21f5bd43b23d7fb79f17e0d44 100644 --- a/ets2panda/checker/TSchecker.cpp +++ b/ets2panda/checker/TSchecker.cpp @@ -23,7 +23,6 @@ namespace ark::es2panda::checker { bool TSChecker::StartChecker([[maybe_unused]] varbinder::VarBinder *varbinder, const util::Options &options) { - Initialize(varbinder); varbinder->IdentifierAnalysis(); if (options.IsDumpAst()) { diff --git a/ets2panda/checker/TSchecker.h b/ets2panda/checker/TSchecker.h index b4993e16668979ab001c1a45cc59332e9d1a993c..4d360a1f4fa9a948ca4eace745779c1adb8b7aaf 100644 --- a/ets2panda/checker/TSchecker.h +++ b/ets2panda/checker/TSchecker.h @@ -121,7 +121,11 @@ struct TupleTypeInfo { class TSChecker : public Checker { public: // NOLINTNEXTLINE(readability-redundant-member-init) - explicit TSChecker(util::DiagnosticEngine &diagnosticEngine) : Checker(diagnosticEngine) {} + explicit TSChecker([[maybe_unused]] ThreadSafeArenaAllocator *allocator, util::DiagnosticEngine &diagnosticEngine, + [[maybe_unused]] ThreadSafeArenaAllocator *programAllocator) + : Checker(allocator, diagnosticEngine, programAllocator) + { + } Type *GlobalNumberType() { diff --git a/ets2panda/checker/checker.cpp b/ets2panda/checker/checker.cpp index b5c962d1d22f396639e9e713da355f1cc9a67013..39c4be1b5982acc392442724bc58a9d76b98126a 100644 --- a/ets2panda/checker/checker.cpp +++ b/ets2panda/checker/checker.cpp @@ -20,13 +20,15 @@ #include "checker/types/ts/unionType.h" namespace ark::es2panda::checker { -Checker::Checker(util::DiagnosticEngine &diagnosticEngine) - : allocator_(SpaceType::SPACE_TYPE_COMPILER, nullptr, true), +Checker::Checker(ThreadSafeArenaAllocator *allocator, util::DiagnosticEngine &diagnosticEngine, + ThreadSafeArenaAllocator *programAllocator) + : allocator_(allocator), + programAllocator_(programAllocator), context_(this, CheckerStatus::NO_OPTS), - globalTypes_(allocator_.New(&allocator_)), - relation_(allocator_.New(this)), diagnosticEngine_(diagnosticEngine) { + relation_ = ProgramAllocator()->New(this); + globalTypes_ = ProgramAllocator()->New(ProgramAllocator()); } void Checker::Initialize(varbinder::VarBinder *varbinder) @@ -42,9 +44,9 @@ void Checker::LogError(const diagnostic::DiagnosticKind &diagnostic, diagnosticEngine_.LogDiagnostic(diagnostic, diagnosticParams, pos); } -void Checker::LogTypeError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos) +void Checker::LogError(const diagnostic::DiagnosticKind &diagnostic, const lexer::SourcePosition &pos) { - diagnosticEngine_.LogSemanticError(list, pos); + LogError(diagnostic, {}, pos); } void Checker::LogTypeError(std::string_view message, const lexer::SourcePosition &pos) @@ -52,14 +54,10 @@ void Checker::LogTypeError(std::string_view message, const lexer::SourcePosition diagnosticEngine_.LogSemanticError(message, pos); } -void Checker::Warning(const std::string_view message, const lexer::SourcePosition &pos) const +void Checker::LogDiagnostic(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams &list, + const lexer::SourcePosition &pos) { - diagnosticEngine_.LogWarning(message, pos); -} - -void Checker::ReportWarning(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos) -{ - diagnosticEngine_.LogWarning(list, pos); + diagnosticEngine_.LogDiagnostic(kind, list, pos); } bool Checker::IsAllTypesAssignableTo(Type *source, Type *target) @@ -79,24 +77,21 @@ bool Checker::IsTypeIdenticalTo(Type *source, Type *target) return relation_->IsIdenticalTo(source, target); } -bool Checker::IsTypeIdenticalTo(Type *source, Type *target, const std::string &errMsg, - const lexer::SourcePosition &errPos) +bool Checker::IsTypeIdenticalTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &diagParams, const lexer::SourcePosition &errPos) { if (!IsTypeIdenticalTo(source, target)) { - relation_->RaiseError(errMsg, errPos); + relation_->GetChecker()->LogError(diagKind, diagParams, errPos); + return false; } return true; } -bool Checker::IsTypeIdenticalTo(Type *source, Type *target, const util::DiagnosticMessageParams &list, +bool Checker::IsTypeIdenticalTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind, const lexer::SourcePosition &errPos) { - if (!IsTypeIdenticalTo(source, target)) { - relation_->RaiseError(list, errPos); - } - - return true; + return IsTypeIdenticalTo(source, target, diagKind, {}, errPos); } bool Checker::IsTypeAssignableTo(Type *source, Type *target) @@ -104,21 +99,11 @@ bool Checker::IsTypeAssignableTo(Type *source, Type *target) return relation_->IsAssignableTo(source, target); } -bool Checker::IsTypeAssignableTo(Type *source, Type *target, const std::string &errMsg, - const lexer::SourcePosition &errPos) +bool Checker::IsTypeAssignableTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, const lexer::SourcePosition &errPos) { if (!IsTypeAssignableTo(source, target)) { - relation_->RaiseError(errMsg, errPos); - } - - return true; -} - -bool Checker::IsTypeAssignableTo(Type *source, Type *target, const util::DiagnosticMessageParams &list, - const lexer::SourcePosition &errPos) -{ - if (!IsTypeAssignableTo(source, target)) { - relation_->RaiseError(list, errPos); + relation_->RaiseError(diagKind, list, errPos); } return true; @@ -129,21 +114,11 @@ bool Checker::IsTypeComparableTo(Type *source, Type *target) return relation_->IsComparableTo(source, target); } -bool Checker::IsTypeComparableTo(Type *source, Type *target, const std::string &errMsg, - const lexer::SourcePosition &errPos) +bool Checker::IsTypeComparableTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, const lexer::SourcePosition &errPos) { if (!IsTypeComparableTo(source, target)) { - relation_->RaiseError(errMsg, errPos); - } - - return true; -} - -bool Checker::IsTypeComparableTo(Type *source, Type *target, const util::DiagnosticMessageParams &list, - const lexer::SourcePosition &errPos) -{ - if (!IsTypeComparableTo(source, target)) { - relation_->RaiseError(list, errPos); + relation_->RaiseError(diagKind, list, errPos); } return true; @@ -203,9 +178,11 @@ ScopeContext::ScopeContext(Checker *checker, varbinder::Scope *newScope) void Checker::CleanUp() { + if (!program_->IsASTLowered()) { + globalTypes_ = allocator_->New(allocator_); + } context_ = CheckerContext(this, CheckerStatus::NO_OPTS); - globalTypes_ = allocator_.New(&allocator_); - relation_ = allocator_.New(this); + relation_ = allocator_->New(this); identicalResults_.cached.clear(); assignableResults_.cached.clear(); comparableResults_.cached.clear(); diff --git a/ets2panda/checker/checker.h b/ets2panda/checker/checker.h index e4ee6da08a6070409351758da22f125bd49fa415..c41af2dbd818e3aa0df7266e0b115847fb411979 100644 --- a/ets2panda/checker/checker.h +++ b/ets2panda/checker/checker.h @@ -18,6 +18,7 @@ #include "checker/checkerContext.h" #include "checker/SemanticAnalyzer.h" +#include "checker/types/globalTypesHolder.h" #include "util/diagnosticEngine.h" namespace ark::es2panda::util { @@ -49,6 +50,7 @@ namespace ark::es2panda::checker { class ETSChecker; class InterfaceType; class GlobalTypesHolder; +class SemanticAnalyzer; using StringLiteralPool = std::unordered_map; using NumberLiteralPool = std::unordered_map; @@ -62,15 +64,16 @@ using ArgRange = std::pair; class Checker { public: - explicit Checker(util::DiagnosticEngine &diagnosticEngine); + explicit Checker(ThreadSafeArenaAllocator *allocator, util::DiagnosticEngine &diagnosticEngine, + ThreadSafeArenaAllocator *programAllocator = nullptr); virtual ~Checker() = default; NO_COPY_SEMANTIC(Checker); NO_MOVE_SEMANTIC(Checker); - [[nodiscard]] ArenaAllocator *Allocator() noexcept + [[nodiscard]] ThreadSafeArenaAllocator *Allocator() noexcept { - return &allocator_; + return allocator_; } [[nodiscard]] varbinder::Scope *Scope() const noexcept @@ -103,11 +106,21 @@ public: return relation_; } + void InitGlobalTypes() + { + globalTypes_ = ProgramAllocator()->New(ProgramAllocator()); + } + [[nodiscard]] GlobalTypesHolder *GetGlobalTypesHolder() const noexcept { return globalTypes_; } + void SetGlobalTypesHolder(GlobalTypesHolder *globalTypes) + { + globalTypes_ = globalTypes; + } + [[nodiscard]] RelationHolder &IdenticalResults() noexcept { return identicalResults_; @@ -169,23 +182,27 @@ public: const util::DiagnosticMessageParams &diagnosticParams = {}); void LogError(const diagnostic::DiagnosticKind &diagnostic, const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos); + void LogError(const diagnostic::DiagnosticKind &diagnostic, const lexer::SourcePosition &pos); void LogTypeError(std::string_view message, const lexer::SourcePosition &pos); void LogTypeError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos); - void Warning(std::string_view message, const lexer::SourcePosition &pos) const; - void ReportWarning(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos); + void LogDiagnostic(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams &list, + const lexer::SourcePosition &pos); + void LogDiagnostic(const diagnostic::DiagnosticKind &kind, const lexer::SourcePosition &pos) + { + LogDiagnostic(kind, {}, pos); + } bool IsTypeIdenticalTo(Type *source, Type *target); - bool IsTypeIdenticalTo(Type *source, Type *target, const std::string &errMsg, const lexer::SourcePosition &errPos); - bool IsTypeIdenticalTo(Type *source, Type *target, const util::DiagnosticMessageParams &list, + bool IsTypeIdenticalTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &diagParams, const lexer::SourcePosition &errPos); + bool IsTypeIdenticalTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind, const lexer::SourcePosition &errPos); bool IsTypeAssignableTo(Type *source, Type *target); - bool IsTypeAssignableTo(Type *source, Type *target, const std::string &errMsg, const lexer::SourcePosition &errPos); - bool IsTypeAssignableTo(Type *source, Type *target, const util::DiagnosticMessageParams &list, - const lexer::SourcePosition &errPos); + bool IsTypeAssignableTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, const lexer::SourcePosition &errPos); bool IsTypeComparableTo(Type *source, Type *target); - bool IsTypeComparableTo(Type *source, Type *target, const std::string &errMsg, const lexer::SourcePosition &errPos); - bool IsTypeComparableTo(Type *source, Type *target, const util::DiagnosticMessageParams &list, - const lexer::SourcePosition &errPos); + bool IsTypeComparableTo(Type *source, Type *target, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, const lexer::SourcePosition &errPos); bool AreTypesComparable(Type *source, Type *target); bool IsTypeEqualityComparableTo(Type *source, Type *target); bool IsAllTypesAssignableTo(Type *source, Type *target); @@ -217,14 +234,20 @@ public: virtual void CleanUp(); + [[nodiscard]] ThreadSafeArenaAllocator *ProgramAllocator() + { + return programAllocator_ == nullptr ? allocator_ : programAllocator_; + } + protected: parser::Program *Program() const; void SetProgram(parser::Program *program); private: - ArenaAllocator allocator_; + ThreadSafeArenaAllocator *allocator_; + ThreadSafeArenaAllocator *programAllocator_ {nullptr}; CheckerContext context_; - GlobalTypesHolder *globalTypes_; + GlobalTypesHolder *globalTypes_ {nullptr}; TypeRelation *relation_; SemanticAnalyzer *analyzer_ {}; varbinder::VarBinder *varbinder_ {}; @@ -232,11 +255,11 @@ private: varbinder::Scope *scope_ {}; util::DiagnosticEngine &diagnosticEngine_; - RelationHolder identicalResults_ {{}, RelationType::IDENTICAL}; - RelationHolder assignableResults_ {{}, RelationType::ASSIGNABLE}; - RelationHolder comparableResults_ {{}, RelationType::COMPARABLE}; - RelationHolder uncheckedCastableResults_ {{}, RelationType::UNCHECKED_CASTABLE}; - RelationHolder supertypeResults_ {{}, RelationType::SUPERTYPE}; + RelationHolder identicalResults_ {Allocator(), RelationType::IDENTICAL}; + RelationHolder assignableResults_ {Allocator(), RelationType::ASSIGNABLE}; + RelationHolder comparableResults_ {Allocator(), RelationType::COMPARABLE}; + RelationHolder uncheckedCastableResults_ {Allocator(), RelationType::UNCHECKED_CASTABLE}; + RelationHolder supertypeResults_ {Allocator(), RelationType::SUPERTYPE}; std::unordered_map typeStack_; std::unordered_set namedTypeStack_; @@ -263,29 +286,15 @@ private: class TypeStackElement { public: - explicit TypeStackElement(Checker *checker, void *element, const util::DiagnosticMessageParams &list, + explicit TypeStackElement(Checker *checker, void *element, const std::optional &diag, const lexer::SourcePosition &pos, bool isRecursive = false) - : checker_(checker), element_(element), hasErrorChecker_(false), isRecursive_(isRecursive), cleanup_(true) - { - if (!checker->typeStack_.insert({element, nullptr}).second) { - if (isRecursive_) { - cleanup_ = false; - } else { - checker_->LogTypeError(list, pos); - element_ = nullptr; - } - } - } - - explicit TypeStackElement(Checker *checker, void *element, std::string_view err, const lexer::SourcePosition &pos, - bool isRecursive = false) - : checker_(checker), element_(element), hasErrorChecker_(false), isRecursive_(isRecursive), cleanup_(true) + : checker_(checker), element_(element), isRecursive_(isRecursive) { if (!checker->typeStack_.insert({element, nullptr}).second) { if (isRecursive_) { cleanup_ = false; } else { - checker_->LogTypeError(err, pos); + checker_->LogError(diag->kind, diag->params, pos); element_ = nullptr; } } @@ -325,9 +334,9 @@ public: private: Checker *checker_; void *element_; - bool hasErrorChecker_; + bool hasErrorChecker_ {false}; bool isRecursive_; - bool cleanup_; + bool cleanup_ {true}; }; template diff --git a/ets2panda/checker/checkerContext.cpp b/ets2panda/checker/checkerContext.cpp index a71ce444760e3a7265daec87290db0a9fdeb36d2..b8da863c9b340d571fb4daa2bd1bab4c91eeea8f 100644 --- a/ets2panda/checker/checkerContext.cpp +++ b/ets2panda/checker/checkerContext.cpp @@ -277,8 +277,7 @@ SmartCastArray CheckerContext::CheckTryBlock(ir::BlockStatement const &tryBlock) // (other cases are not interested) bool CheckerContext::IsInValidChain(ir::AstNode const *parent) noexcept { - while (parent != nullptr && !parent->IsIfStatement() && !parent->IsWhileStatement() && - !parent->IsConditionalExpression()) { + while (parent != nullptr) { if (parent->IsBinaryExpression()) { auto const operation = parent->AsBinaryExpression()->OperatorType(); if (operation != lexer::TokenType::PUNCTUATOR_LOGICAL_OR && @@ -289,8 +288,10 @@ bool CheckerContext::IsInValidChain(ir::AstNode const *parent) noexcept if (parent->AsUnaryExpression()->OperatorType() != lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) { return false; } + } else if (parent->IsExpression()) { + return parent->IsConditionalExpression(); } else { - return false; + return true; } parent = parent->Parent(); } @@ -315,8 +316,8 @@ void CheckerContext::CheckIdentifierSmartCastCondition(ir::Identifier const *con return; } - ES2PANDA_ASSERT(testCondition_.variable == nullptr); if (identifier->TsType()->PossiblyETSNullish()) { + ES2PANDA_ASSERT(testCondition_.variable == nullptr); testCondition_ = {variable, parent_->AsETSChecker()->GlobalETSNullType(), true, false}; } } @@ -348,16 +349,31 @@ void CheckerContext::CheckBinarySmartCastCondition(ir::BinaryExpression *const b } if (auto const operatorType = binaryExpression->OperatorType(); operatorType == lexer::TokenType::KEYW_INSTANCEOF) { - ES2PANDA_ASSERT(testCondition_.variable == nullptr); if (binaryExpression->Left()->IsIdentifier()) { - testCondition_ = {binaryExpression->Left()->AsIdentifier()->Variable(), - binaryExpression->Right()->TsType()}; + if (binaryExpression->Right()->TsType() == nullptr) { + return; + } + // NOTE(pantos) Issue with generics + // eg + // class C { ... } + // let x = new C<...> + // if (x instanceof C && x.fld instanceof ... + const auto variable = binaryExpression->Left()->AsIdentifier()->Variable(); + auto type = binaryExpression->Right()->TsType(); + auto smartIt = smartCasts_.find(variable); + // NOTE(pantos) Handle union types e.g. C|C|... + if (type->HasTypeFlag(TypeFlag::GENERIC) && smartIt != smartCasts_.end() && type->IsETSObjectType() && + type->AsETSObjectType()->IsSameBasedGeneric(type->AsETSObjectType()->GetRelation(), smartIt->second)) { + // Replace generic type with instantiated one, e.g. C with C + type = smartIt->second; + } + ES2PANDA_ASSERT(testCondition_.variable == nullptr); + testCondition_ = {variable, type}; } } else if (operatorType == lexer::TokenType::PUNCTUATOR_STRICT_EQUAL || operatorType == lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL || operatorType == lexer::TokenType::PUNCTUATOR_EQUAL || operatorType == lexer::TokenType::PUNCTUATOR_NOT_EQUAL) { - ES2PANDA_ASSERT(testCondition_.variable == nullptr); CheckSmartCastEqualityCondition(binaryExpression); } } @@ -398,6 +414,7 @@ void CheckerContext::CheckSmartCastEqualityCondition(ir::BinaryExpression *const operatorType == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; if (testedType->DefinitelyETSNullish()) { + ES2PANDA_ASSERT(testCondition_.variable == nullptr); testCondition_ = {variable, testedType, negate, strict}; } } diff --git a/ets2panda/checker/ets/aliveAnalyzer.cpp b/ets2panda/checker/ets/aliveAnalyzer.cpp index 7c9a9142ba7166f3d60cf3132387f7c6e2cc3e82..ff2ba27302437785434c2801d9608996fdfe6f70 100644 --- a/ets2panda/checker/ets/aliveAnalyzer.cpp +++ b/ets2panda/checker/ets/aliveAnalyzer.cpp @@ -189,7 +189,7 @@ void AliveAnalyzer::AnalyzeStat(const ir::AstNode *node) } if (status_ == LivenessStatus::DEAD) { - checker_->LogError(diagnostic::UNREACHABLE_STMT, {}, node->Start()); + checker_->LogDiagnostic(diagnostic::UNREACHABLE_STMT, node->Start()); return; } @@ -406,7 +406,7 @@ void AliveAnalyzer::AnalyzeSwitch(const ir::SwitchStatement *switchStmt) if (status_ == LivenessStatus::ALIVE && !caseClause->Consequent().empty() && i < size - 1) { // NOTE(user) Add lint categories and option to enable/disable compiler warnings - checker_->Warning("Possible fall-through into case", caseClause->Start()); + checker_->LogDiagnostic(diagnostic::MAYBE_FALLTHROUGH, caseClause->Start()); } } @@ -458,7 +458,7 @@ void AliveAnalyzer::AnalyzeTry(const ir::TryStatement *tryStmt) if (status_ == LivenessStatus::DEAD) { isAlive = false; // NOTE(user) Add lint categories and option to enable/disable compiler warnings - checker_->Warning("Finally clause cannot complete normally", tryStmt->FinallyBlock()->Start()); + checker_->LogDiagnostic(diagnostic::FINALLY_CANT_COMPLETE, tryStmt->FinallyBlock()->Start()); } } diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 541ce796f971297e5767aef49ab40f446e3e9a76..b0b3e32efd5af3ce71e4525bf4e8fca6e88a970f 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -186,54 +186,6 @@ Type *ETSChecker::NegateNumericType(Type *type, ir::Expression *node) return result; } -Type *ETSChecker::BitwiseNegateNumericType(Type *type, ir::Expression *node) -{ - ES2PANDA_ASSERT(type->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_INTEGRAL)); - - TypeFlag typeKind = ETSType(type); - - Type *result = nullptr; - - switch (typeKind) { - case TypeFlag::BYTE: { - result = CreateByteType(static_cast(~static_cast(type->AsByteType()->GetValue()))); - break; - } - case TypeFlag::CHAR: { - result = CreateCharType(~(type->AsCharType()->GetValue())); - break; - } - case TypeFlag::SHORT: { - result = CreateShortType(static_cast(~static_cast(type->AsShortType()->GetValue()))); - break; - } - case TypeFlag::INT: { - result = CreateIntType(static_cast(~static_cast(type->AsIntType()->GetValue()))); - break; - } - case TypeFlag::LONG: { - result = CreateLongType(static_cast(~static_cast(type->AsLongType()->GetValue()))); - break; - } - case TypeFlag::FLOAT: { - result = CreateIntType( - ~static_cast(CastFloatToInt(type->AsFloatType()->GetValue()))); - break; - } - case TypeFlag::DOUBLE: { - result = CreateLongType( - ~static_cast(CastFloatToInt(type->AsDoubleType()->GetValue()))); - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - node->SetTsType(result); - return result; -} - Type *ETSChecker::HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) { ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && @@ -712,8 +664,11 @@ static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOper (typeL->IsETSNullType() && typeR->IsETSPrimitiveType())) { return checker->CreateETSUnionType({typeL, typeR}); } - // Do not comparing reference equality for enum. + if (typeL->IsETSEnumType() && typeR->IsETSEnumType()) { + if (checker->Relation()->IsIdenticalTo(typeL, typeR)) { + return typeL; + } return nullptr; } @@ -808,7 +763,7 @@ std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expres return {GlobalETSBooleanType(), leftType}; } - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); + auto *const promotedType = std::get<0>(BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp)); FlagExpressionWithUnboxing(leftType, unboxedL, left); FlagExpressionWithUnboxing(rightType, unboxedR, right); @@ -822,19 +777,12 @@ std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expres } if (promotedType == nullptr) { - if (NonNumericTypesAreAppropriateForComparison(this, leftType, rightType)) { - return {GlobalETSBooleanType(), GlobalETSBooleanType()}; + if (!NonNumericTypesAreAppropriateForComparison(this, leftType, rightType)) { + LogError(diagnostic::BINOP_INCOMPARABLE, {}, pos); } - - LogError(diagnostic::BINOP_INCOMPARABLE, {}, pos); return {GlobalETSBooleanType(), GlobalETSBooleanType()}; } - if (bothConst) { - checker::Type *tsType = HandleRelationOperationOnTypes(leftType, rightType, operationType); - return {tsType, tsType}; - } - return {GlobalETSBooleanType(), promotedType}; } @@ -1189,10 +1137,6 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) checker::Type *rightType = right->Check(this); - if (rightType == nullptr) { - rightType = right->Check(this); - } - if (right->IsTypeNode()) { rightType = right->AsTypeNode()->GetType(this); } diff --git a/ets2panda/checker/ets/arithmetic.h b/ets2panda/checker/ets/arithmetic.h index 9e08b1e46e32a4fae19e8436d5f7be1a5c9d491e..aa9d61d049f7e07c92076f83b514ad491b2b0580 100644 --- a/ets2panda/checker/ets/arithmetic.h +++ b/ets2panda/checker/ets/arithmetic.h @@ -146,7 +146,7 @@ Type *ETSChecker::PerformArithmeticOperationOnTypes(Type *left, Type *right, lex } } - return Allocator()->New(result); + return ProgramAllocator()->New(result); } template <> @@ -241,7 +241,7 @@ Type *ETSChecker::HandleBitWiseArithmetic(Type *left, Type *right, lexer::TokenT } } - return Allocator()->New(result); + return ProgramAllocator()->New(result); } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/assignAnalyzer.cpp b/ets2panda/checker/ets/assignAnalyzer.cpp index 21d8514aec1e1865bdeb90cc3e207b7dc22abd31..9ed3378f8b6291b2736918792b1958e78018b098 100644 --- a/ets2panda/checker/ets/assignAnalyzer.cpp +++ b/ets2panda/checker/ets/assignAnalyzer.cpp @@ -190,16 +190,11 @@ void AssignAnalyzer::Analyze(const ir::AstNode *node) AnalyzeNodes(node); } -void AssignAnalyzer::Warning(const std::string_view message, const lexer::SourcePosition &pos) +void AssignAnalyzer::Warning(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams &list, + const lexer::SourcePosition &pos) { ++numErrors_; - checker_->Warning(message, pos); -} - -void AssignAnalyzer::Warning(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos) -{ - ++numErrors_; - checker_->ReportWarning(list, pos); + checker_->LogDiagnostic(kind, list, pos); } void AssignAnalyzer::AnalyzeNodes(const ir::AstNode *node) @@ -485,7 +480,9 @@ void AssignAnalyzer::ProcessClassDefStaticFields(const ir::ClassDefinition *clas for (const auto it : classDef->Body()) { if (it->IsClassStaticBlock() || (it->IsStatic() && it->IsMethodDefinition() && - it->AsMethodDefinition()->Key()->AsIdentifier()->Name().Is(compiler::Signatures::INIT_METHOD))) { + (it->AsMethodDefinition()->Key()->AsIdentifier()->Name().Is(compiler::Signatures::INIT_METHOD) || + it->AsMethodDefinition()->Key()->AsIdentifier()->Name().StartsWith( + compiler::Signatures::INITIALIZER_BLOCK_INIT)))) { AnalyzeNodes(it); ClearPendingExits(); } @@ -1016,10 +1013,6 @@ void AssignAnalyzer::AnalyzeId(const ir::Identifier *id) return; // inside ObjectExpression } - if (id->Parent()->IsTypeofExpression() && id->Parent()->AsTypeofExpression()->Argument() == id) { - return; // according to the spec 'typeof' works on uninitialized variables too - } - if (id->Parent()->IsBinaryExpression()) { const ir::BinaryExpression *binExpr = id->Parent()->AsBinaryExpression(); if ((binExpr->OperatorType() == lexer::TokenType::PUNCTUATOR_EQUAL || @@ -1294,6 +1287,26 @@ varbinder::Variable *AssignAnalyzer::GetBoundVariable(const ir::AstNode *node) return ret; } +static const ir::AstNode *CheckInterfaceProp(const ark::es2panda::ir::AstNode *const node, + const ir::ClassDefinition *classDef) +{ + util::StringView methodName = node->AsMethodDefinition()->Key()->AsIdentifier()->Name(); + // the property from interface should start with to distinguish from its getter/setter. + std::string interfaceProp = std::string("") + std::string(methodName.Utf8()); + for (const auto it : classDef->Body()) { + // Check if there is corresponding class property in the same class. + if (it->IsClassProperty() && !it->IsStatic()) { + const auto *prop = it->AsClassProperty(); + auto *propIdentifier = prop->Key()->AsIdentifier(); + if (propIdentifier->Name().Is(interfaceProp)) { + // Use property node as declNode to ensure obtaining NodeId and add it to inits. + return prop; + } + } + } + return nullptr; +} + const ir::AstNode *AssignAnalyzer::GetDeclaringNode(const ir::AstNode *node) { if (node->IsClassProperty() || node->IsVariableDeclarator()) { @@ -1322,9 +1335,29 @@ const ir::AstNode *AssignAnalyzer::GetDeclaringNode(const ir::AstNode *node) } } + if (ret != nullptr) { + // if declNode is a getter/setter method, actual node initialized should be a class proterty node. + if ((ret->Modifiers() & ir::ModifierFlags::GETTER_SETTER) != 0U) { + if (const auto *interfaceProp = CheckInterfaceProp(ret, classDef_); interfaceProp != nullptr) { + ret = interfaceProp; + } + } + } + return ret; } +static bool IsDefaultValueType(const Type *type, bool isNonReadonlyField) +{ + if (type == nullptr) { + return false; + } + return (type->IsETSPrimitiveType() || type->IsETSNeverType() || type->IsETSUndefinedType() || + type->IsETSNullType() || + (type->PossiblyETSUndefined() && (!type->HasTypeFlag(checker::TypeFlag::GENERIC) || + (isNonReadonlyField && !CHECK_GENERIC_NON_READONLY_PROPERTIES)))); +} + bool AssignAnalyzer::VariableHasDefaultValue(const ir::AstNode *node) { ES2PANDA_ASSERT(node != nullptr); @@ -1342,11 +1375,7 @@ bool AssignAnalyzer::VariableHasDefaultValue(const ir::AstNode *node) } else { ES2PANDA_UNREACHABLE(); } - - return type != nullptr && - (type->IsETSPrimitiveType() || - (type->PossiblyETSUndefined() && (!type->HasTypeFlag(checker::TypeFlag::GENERIC) || - (isNonReadonlyField && !CHECK_GENERIC_NON_READONLY_PROPERTIES)))); + return IsDefaultValueType(type, isNonReadonlyField); } void AssignAnalyzer::LetInit(const ir::AstNode *node) @@ -1377,9 +1406,9 @@ void AssignAnalyzer::LetInit(const ir::AstNode *node) if (classDef_ == globalClass_ || (adr < classFirstAdr_ || adr >= firstAdr_)) { if (declNode->IsClassProperty() && classDef_ != declNode->Parent()) { - Warning({"Cannot assign to '", name, "' because it is a read-only property."}, pos); + Warning(diagnostic::ASSIGN_TO_READONLY, {name}, pos); } else if (!uninits_.IsMember(adr)) { - Warning({Capitalize(type).c_str(), " '", name, "' might already have been assigned."}, pos); + Warning(diagnostic::MAYBE_REASSIGNED, {Capitalize(type).c_str(), name}, pos); } else { uninit(adr); } @@ -1417,6 +1446,10 @@ void AssignAnalyzer::CheckInit(const ir::AstNode *node) // property of an other class return; } + + if (node->IsDefinite()) { + return; + } } if (classDef_ == globalClass_ || (adr < classFirstAdr_ || adr >= firstAdr_)) { @@ -1431,12 +1464,10 @@ void AssignAnalyzer::CheckInit(const ir::AstNode *node) std::stringstream ss; if (node->IsClassProperty()) { - ss << "Property '" << name << "' might not have been initialized."; + checker_->LogError(diagnostic::PROPERTY_MAYBE_MISSING_INIT, {name}, pos); } else { - ss << Capitalize(type) << " '" << name << "' is used before being assigned."; + checker_->LogError(diagnostic::USE_BEFORE_INIT, {Capitalize(type), name}, pos); } - - Warning(ss.str(), pos); } } } diff --git a/ets2panda/checker/ets/assignAnalyzer.h b/ets2panda/checker/ets/assignAnalyzer.h index 3e7f664d5126e3700f2eee737ea0b43798574709..621a24ba9e18239450879b044fd7fa70b0bf1823 100644 --- a/ets2panda/checker/ets/assignAnalyzer.h +++ b/ets2panda/checker/ets/assignAnalyzer.h @@ -136,15 +136,15 @@ private: void AnalyzeArrowFunctionExpr(const ir::ArrowFunctionExpression *arrowFuncExpr); // utils - void Warning(std::string_view message, const lexer::SourcePosition &pos); - void Warning(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos); + void Warning(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams &list, + const lexer::SourcePosition &pos); bool Trackable(const ir::AstNode *node) const; bool IsConstUninitializedField(const ir::AstNode *node) const; bool IsConstUninitializedStaticField(const ir::AstNode *node) const; void NewVar(const ir::AstNode *node); void LetInit(const ir::AstNode *node); void CheckInit(const ir::AstNode *node); - void Split(bool setToNull); + void Split(const bool setToNull); void Merge(); void CheckPendingExits(); NodeId GetNodeId(const ir::AstNode *node) const; diff --git a/ets2panda/checker/ets/baseAnalyzer.cpp b/ets2panda/checker/ets/baseAnalyzer.cpp index 8fdf75f0370fcd3303d1743fd9f9dbcfb74375a4..8e0feca8c055357e4e5e7763b34f4d02367cd4c7 100644 --- a/ets2panda/checker/ets/baseAnalyzer.cpp +++ b/ets2panda/checker/ets/baseAnalyzer.cpp @@ -92,6 +92,7 @@ LivenessStatus BaseAnalyzer::ResolveContinues(const ir::AstNode *node) template LivenessStatus BaseAnalyzer::ResolveBreaks(const ir::AstNode *node) { + oldPendingExits_.clear(); return ResolveJump(node, ir::AstNodeType::BREAK_STATEMENT); } diff --git a/ets2panda/checker/ets/boxingConverter.h b/ets2panda/checker/ets/boxingConverter.h index 1adaa2493f00add5bf88eea45059109cfd785cc5..46491a450e19697938b9790c24c136a11f924fa4 100644 --- a/ets2panda/checker/ets/boxingConverter.h +++ b/ets2panda/checker/ets/boxingConverter.h @@ -16,8 +16,8 @@ #ifndef ES2PANDA_COMPILER_CHECKER_ETS_BOXING_CONVERTER_H #define ES2PANDA_COMPILER_CHECKER_ETS_BOXING_CONVERTER_H -#include "checker/ets/typeConverter.h" #include "checker/types/ets/etsObjectType.h" +#include "checker/ets/typeConverter.h" namespace ark::es2panda::checker { class BoxingConverter : public TypeConverter { diff --git a/ets2panda/checker/ets/castingContext.cpp b/ets2panda/checker/ets/castingContext.cpp index 3c91223fdc61ce31b03da86ce0b779601061bf38..0f1c377aaa3d61389ec083ad314ea99ca5704da2 100644 --- a/ets2panda/checker/ets/castingContext.cpp +++ b/ets2panda/checker/ets/castingContext.cpp @@ -18,8 +18,8 @@ #include "checker/ETSchecker.h" namespace ark::es2panda::checker { -CastingContext::CastingContext(TypeRelation *relation, const util::DiagnosticMessageParams &list, - ConstructorData &&data) +CastingContext::CastingContext(TypeRelation *relation, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, ConstructorData &&data) { flags_ |= data.extraFlags; @@ -35,7 +35,7 @@ CastingContext::CastingContext(TypeRelation *relation, const util::DiagnosticMes relation->Result(true); } if (!relation->IsTrue() && (flags_ & TypeRelationFlag::NO_THROW) == 0) { - relation->RaiseError(list, data.pos); + relation->RaiseError(diagKind, list, data.pos); } } diff --git a/ets2panda/checker/ets/castingContext.h b/ets2panda/checker/ets/castingContext.h index 0226ec6be70e662d2e410344cf4487462e21e137..a023f88eb48af354d30214bd711db74b6637a1ef 100644 --- a/ets2panda/checker/ets/castingContext.h +++ b/ets2panda/checker/ets/castingContext.h @@ -31,7 +31,8 @@ public: }; // NOLINTEND(cppcoreguidelines-pro-type-member-init) - CastingContext(TypeRelation *relation, const util::DiagnosticMessageParams &list, ConstructorData &&data); + CastingContext(TypeRelation *relation, const diagnostic::DiagnosticKind &diagKind, + const util::DiagnosticMessageParams &list, ConstructorData &&data); [[nodiscard]] bool UncheckedCast() const noexcept; diff --git a/ets2panda/checker/ets/conversion.cpp b/ets2panda/checker/ets/conversion.cpp index e165cb0e9a3491fecc9d078e62921ba3bce4567f..345a1a4f672ee164be2b91985212a77493fc625f 100644 --- a/ets2panda/checker/ets/conversion.cpp +++ b/ets2panda/checker/ets/conversion.cpp @@ -346,14 +346,12 @@ void String(TypeRelation *const relation, Type *const source) auto *const tempInt = relation->GetChecker()->AsETSChecker()->GetGlobalTypesHolder()->GlobalIntType(); WideningPrimitive(relation, source, tempInt); Boxing(relation, tempInt); - relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); return; } if (source->HasTypeFlag(TypeFlag::ETS_BOOLEAN | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE)) { Boxing(relation, source); - relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); return; } diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index 503cb2567ebd0d96dc82c3a7e7c23919ee8ff76b..f5d2544345b31dd7d9677a2248c32ca4b9186ba8 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -85,25 +85,25 @@ void ProcessScopesNode(ETSChecker *checker, ir::AstNode *node) ir::ETSParameterExpression *ETSChecker::AddParam(util::StringView name, ir::TypeNode *type) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *paramIdent = AllocNode(name, Allocator()); + auto *paramIdent = ProgramAllocNode(name, ProgramAllocator()); if (type != nullptr) { paramIdent->SetTsTypeAnnotation(type); type->SetParent(paramIdent); } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return AllocNode(paramIdent, false, Allocator()); + return ProgramAllocNode(paramIdent, false, ProgramAllocator()); } template ir::MethodDefinition *ETSChecker::CreateDynamicCallIntrinsic(ir::Expression *callee, const ArenaVector &arguments, Language lang) { - ArenaVector params(Allocator()->Adapter()); + ArenaVector params(ProgramAllocator()->Adapter()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto dynamicTypeNode = AllocNode(GlobalBuiltinDynamicType(lang), Allocator()); + auto dynamicTypeNode = ProgramAllocNode(GlobalBuiltinDynamicType(lang), ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto intTypeNode = AllocNode(ir::PrimitiveType::INT, Allocator()); + auto intTypeNode = ProgramAllocNode(ir::PrimitiveType::INT, ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *objParam = AddParam("obj", dynamicTypeNode); @@ -115,46 +115,47 @@ ir::MethodDefinition *ETSChecker::CreateDynamicCallIntrinsic(ir::Expression *cal param2 = AddParam("qname_start", intTypeNode); params.push_back(param2); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - param2 = AddParam("qname_len", intTypeNode->Clone(Allocator(), nullptr)); + param2 = AddParam("qname_len", intTypeNode->Clone(ProgramAllocator(), nullptr)); } else { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - param2 = AddParam("this", dynamicTypeNode->Clone(Allocator(), nullptr)); + param2 = AddParam("this", dynamicTypeNode->Clone(ProgramAllocator(), nullptr)); } params.push_back(param2); for (size_t i = 0; i < arguments.size(); i++) { - util::UString paramName("p" + std::to_string(i), Allocator()); + util::UString paramName("p" + std::to_string(i), ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto paramType = arguments[i]->TsType()->IsLambdaObject() // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ? dynamicTypeNode->Clone(Allocator(), nullptr) + ? dynamicTypeNode->Clone(ProgramAllocator(), nullptr) // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - : AllocNode(arguments[i]->TsType(), Allocator()); + : ProgramAllocNode(arguments[i]->TsType(), ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) params.emplace_back(AddParam(paramName.View(), paramType)); } auto funcSignature = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ir::FunctionSignature(nullptr, std::move(params), dynamicTypeNode->Clone(Allocator(), nullptr)); + ir::FunctionSignature(nullptr, std::move(params), dynamicTypeNode->Clone(ProgramAllocator(), nullptr)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *func = AllocNode( - Allocator(), ir::ScriptFunction::ScriptFunctionData {nullptr, std::move(funcSignature), - ir::ScriptFunctionFlags::METHOD, ir::ModifierFlags::NONE}); + auto *func = ProgramAllocNode( + ProgramAllocator(), + ir::ScriptFunction::ScriptFunctionData {nullptr, std::move(funcSignature), ir::ScriptFunctionFlags::METHOD, + ir::ModifierFlags::NONE}); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *name = AllocNode(compiler::Signatures::STATIC_INVOKE_METHOD, Allocator()); + auto *name = ProgramAllocNode(compiler::Signatures::STATIC_INVOKE_METHOD, ProgramAllocator()); func->SetIdent(name); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcExpr = AllocNode(func); + auto *funcExpr = ProgramAllocNode(func); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *method = AllocNode( + auto *method = ProgramAllocNode( // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ir::MethodDefinitionKind::METHOD, func->Id()->Clone(Allocator(), nullptr), funcExpr, - ir::ModifierFlags::PUBLIC | ir::ModifierFlags::NATIVE | ir::ModifierFlags::STATIC, Allocator(), false); + ir::MethodDefinitionKind::METHOD, func->Id()->Clone(ProgramAllocator(), nullptr), funcExpr, + ir::ModifierFlags::PUBLIC | ir::ModifierFlags::NATIVE | ir::ModifierFlags::STATIC, ProgramAllocator(), false); return method; } @@ -185,7 +186,7 @@ Signature *ETSChecker::ResolveDynamicCallExpression(ir::Expression *callee, cons auto mapIt = dynamicIntrinsics.find(lang); if (mapIt == dynamicIntrinsics.cend()) { - std::tie(mapIt, std::ignore) = dynamicIntrinsics.emplace(lang, Allocator()->Adapter()); + std::tie(mapIt, std::ignore) = dynamicIntrinsics.emplace(lang, ProgramAllocator()->Adapter()); } auto &map = mapIt->second; @@ -208,7 +209,7 @@ Signature *ETSChecker::ResolveDynamicCallExpression(ir::Expression *callee, cons auto klass = GetDynamicClass(lang, isConstruct); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *method = CreateDynamicCallIntrinsic(callee, arguments, lang); - auto props = ArenaVector(Allocator()->Adapter()); + auto props = ArenaVector(ProgramAllocator()->Adapter()); props.emplace_back(method); klass->Definition()->AddProperties(std::move(props)); @@ -221,7 +222,7 @@ Signature *ETSChecker::ResolveDynamicCallExpression(ir::Expression *callee, cons } method->Function()->Signature()->SetReturnType(GlobalBuiltinDynamicType(lang)); - map.emplace(util::UString(key, Allocator()).View(), method->Function()); + map.emplace(util::UString(key, ProgramAllocator()).View(), method->Function()); return method->Function()->Signature(); } @@ -237,22 +238,22 @@ template Signature *ETSChecker::ResolveDynamicCallExpression ETSChecker::CreateStaticScriptFunction( ClassInitializerBuilder const &builder) { - ArenaVector statements(Allocator()->Adapter()); - ArenaVector params(Allocator()->Adapter()); + ArenaVector statements(ProgramAllocator()->Adapter()); + ArenaVector params(ProgramAllocator()->Adapter()); ir::ScriptFunction *func; ir::Identifier *id; builder(&statements, nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *body = AllocNode(Allocator(), std::move(statements)); + auto *body = ProgramAllocNode(ProgramAllocator(), std::move(statements)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - id = AllocNode(compiler::Signatures::CCTOR, Allocator()); + id = ProgramAllocNode(compiler::Signatures::CCTOR, ProgramAllocator()); auto signature = ir::FunctionSignature(nullptr, std::move(params), nullptr); // clang-format off // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - func = AllocNode( - Allocator(), ir::ScriptFunction::ScriptFunctionData { + func = ProgramAllocNode( + ProgramAllocator(), ir::ScriptFunction::ScriptFunctionData { body, std::move(signature), ir::ScriptFunctionFlags::STATIC_BLOCK | ir::ScriptFunctionFlags::EXPRESSION, @@ -267,24 +268,24 @@ std::pair ETSChecker::CreateStaticScript std::pair ETSChecker::CreateScriptFunction( ClassInitializerBuilder const &builder) { - ArenaVector statements(Allocator()->Adapter()); - ArenaVector params(Allocator()->Adapter()); + ArenaVector statements(ProgramAllocator()->Adapter()); + ArenaVector params(ProgramAllocator()->Adapter()); ir::ScriptFunction *func; ir::Identifier *id; builder(&statements, ¶ms); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *body = AllocNode(Allocator(), std::move(statements)); + auto *body = ProgramAllocNode(ProgramAllocator(), std::move(statements)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - id = AllocNode(compiler::Signatures::CTOR, Allocator()); + id = ProgramAllocNode(compiler::Signatures::CTOR, ProgramAllocator()); auto funcSignature = ir::FunctionSignature(nullptr, std::move(params), nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - func = AllocNode(Allocator(), - ir::ScriptFunction::ScriptFunctionData { - body, std::move(funcSignature), - ir::ScriptFunctionFlags::CONSTRUCTOR | ir::ScriptFunctionFlags::EXPRESSION, - ir::ModifierFlags::PUBLIC}); + func = ProgramAllocNode( + ProgramAllocator(), ir::ScriptFunction::ScriptFunctionData {body, std::move(funcSignature), + ir::ScriptFunctionFlags::CONSTRUCTOR | + ir::ScriptFunctionFlags::EXPRESSION, + ir::ModifierFlags::PUBLIC}); func->SetIdent(id); return std::make_pair(func, id); @@ -297,10 +298,10 @@ ir::ClassStaticBlock *ETSChecker::CreateClassStaticInitializer(const ClassInitia auto [func, id] = CreateStaticScriptFunction(builder); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcExpr = AllocNode(func); + auto *funcExpr = ProgramAllocNode(func); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *staticBlock = AllocNode(funcExpr, Allocator()); + auto *staticBlock = ProgramAllocNode(funcExpr, ProgramAllocator()); staticBlock->AddModifier(ir::ModifierFlags::STATIC); return staticBlock; @@ -313,59 +314,67 @@ ir::MethodDefinition *ETSChecker::CreateClassInstanceInitializer(const ClassInit auto [func, id] = CreateScriptFunction(builder); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcExpr = AllocNode(func); + auto *funcExpr = ProgramAllocNode(func); auto *ctor = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, id->Clone(Allocator(), nullptr), - funcExpr, ir::ModifierFlags::NONE, Allocator(), false); + ProgramAllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + id->Clone(ProgramAllocator(), nullptr), funcExpr, + ir::ModifierFlags::NONE, ProgramAllocator(), false); return ctor; } ir::ClassStaticBlock *ETSChecker::CreateDynamicCallClassInitializer(Language lang, bool isConstruct) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return CreateClassStaticInitializer([this, lang, - isConstruct](ArenaVector *statements, - [[maybe_unused]] ArenaVector *params) { - auto [builtin_class_name, builtin_method_name] = - util::Helpers::SplitSignature(isConstruct ? compiler::Signatures::Dynamic::InitNewClassBuiltin(lang) - : compiler::Signatures::Dynamic::InitCallClassBuiltin(lang)); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *classId = AllocNode(builtin_class_name, Allocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *methodId = AllocNode(builtin_method_name, Allocator()); - auto *callee = + return CreateClassStaticInitializer( + [this, lang, isConstruct](ArenaVector *statements, + [[maybe_unused]] ArenaVector *params) { + auto [builtin_class_name, builtin_method_name] = + util::Helpers::SplitSignature(isConstruct ? compiler::Signatures::Dynamic::InitNewClassBuiltin(lang) + : compiler::Signatures::Dynamic::InitCallClassBuiltin(lang)); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto *classId = ProgramAllocNode(builtin_class_name, ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + auto *methodId = ProgramAllocNode(builtin_method_name, ProgramAllocator()); + auto *callee = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, + false, false); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *initCall = AllocNode(callee, ArenaVector(Allocator()->Adapter()), - nullptr, false); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto *initCall = ProgramAllocNode( + callee, ArenaVector(ProgramAllocator()->Adapter()), nullptr, false); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - statements->push_back(AllocNode(initCall)); - }); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + statements->push_back(ProgramAllocNode(initCall)); + }); } ir::ClassDeclaration *ETSChecker::BuildClass(util::StringView name, const ClassBuilder &builder) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *classId = AllocNode(name, Allocator()); + auto *classId = ProgramAllocNode(name, ProgramAllocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *classDef = AllocNode(Allocator(), classId, ir::ClassDefinitionModifiers::CLASS_DECL, - ir::ModifierFlags::NONE, Language(Language::Id::ETS)); + auto *classDef = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocNode(ProgramAllocator(), classId, ir::ClassDefinitionModifiers::CLASS_DECL, + ir::ModifierFlags::NONE, Language(Language::Id::ETS)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *classDecl = AllocNode(classDef, Allocator()); + auto *classDecl = ProgramAllocNode(classDef, ProgramAllocator()); - VarBinder()->Program()->Ast()->Statements().push_back(classDecl); + VarBinder()->Program()->Ast()->AddStatement(classDecl); classDecl->SetParent(VarBinder()->Program()->Ast()); - varbinder::BoundContext boundCtx(VarBinder()->AsETSBinder()->GetGlobalRecordTable(), classDef); + auto varBinder = VarBinder()->AsETSBinder(); + bool isExternal = VarBinder()->Program() != varBinder->GetGlobalRecordTable()->Program(); + auto recordTable = isExternal ? varBinder->GetExternalRecordTable().at(varBinder->Program()) + : VarBinder()->AsETSBinder()->GetGlobalRecordTable(); + varbinder::BoundContext boundCtx(recordTable, classDef); - ArenaVector classBody(Allocator()->Adapter()); + ArenaVector classBody(ProgramAllocator()->Adapter()); builder(&classBody); @@ -379,14 +388,13 @@ ir::ClassDeclaration *ETSChecker::BuildClass(util::StringView name, const ClassB ir::ClassProperty *ETSChecker::CreateStaticReadonlyField(const char *name) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldIdent = AllocNode(name, Allocator()); + auto *fieldIdent = ProgramAllocNode(name, ProgramAllocator()); auto flags = ir::ModifierFlags::STATIC | ir::ModifierFlags::PRIVATE | ir::ModifierFlags::READONLY; // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *field = AllocNode(fieldIdent, nullptr, - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(ir::PrimitiveType::INT, Allocator()), - flags, Allocator(), false); - + auto *field = ProgramAllocNode( + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + fieldIdent, nullptr, ProgramAllocNode(ir::PrimitiveType::INT, ProgramAllocator()), flags, + ProgramAllocator(), false); return field; } @@ -414,39 +422,42 @@ void ETSChecker::ClassInitializerFromImport(ir::ETSImportDeclaration *import, Ar auto builtin = compiler::Signatures::Dynamic::LoadModuleBuiltin(import->Language()); auto [builtin_class_name, builtin_method_name] = util::Helpers::SplitSignature(builtin); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *classId = AllocNode(builtin_class_name, Allocator()); + auto *classId = ProgramAllocNode(builtin_class_name, ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *methodId = AllocNode(builtin_method_name, Allocator()); + auto *methodId = ProgramAllocNode(builtin_method_name, ProgramAllocator()); auto *callee = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + ProgramAllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, + false); // NOTE: #23698. Make 'ohmUrl' mandatory in 'dynamicPaths'. - util::StringView ohmUrl = util::UString(import->OhmUrl(), Allocator()).View(); + util::StringView ohmUrl = util::UString(import->OhmUrl(), ProgramAllocator()).View(); if (ohmUrl.Empty()) { ohmUrl = import->ResolvedSource(); if (ark::os::file::File::IsRegularFile(ohmUrl.Mutf8())) { - ohmUrl = util::UString(ark::os::RemoveExtension(ohmUrl.Mutf8()), Allocator()).View(); + ohmUrl = util::UString(ark::os::RemoveExtension(ohmUrl.Mutf8()), ProgramAllocator()).View(); } } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ArenaVector callParams({AllocNode(ohmUrl)}, Allocator()->Adapter()); + ArenaVector callParams({ProgramAllocNode(ohmUrl)}, + ProgramAllocator()->Adapter()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *loadCall = AllocNode(callee, std::move(callParams), nullptr, false); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *moduleClassId = AllocNode(compiler::Signatures::DYNAMIC_MODULE_CLASS, Allocator()); + auto *loadCall = ProgramAllocNode(callee, std::move(callParams), nullptr, false); + auto *moduleClassId = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocNode(compiler::Signatures::DYNAMIC_MODULE_CLASS, ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldId = AllocNode(import->AssemblerName(), Allocator()); + auto *fieldId = ProgramAllocNode(import->AssemblerName(), ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *property = AllocNode(moduleClassId, fieldId, ir::MemberExpressionKind::PROPERTY_ACCESS, - false, false); + auto *property = ProgramAllocNode(moduleClassId, fieldId, + ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); auto *initializer = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(property, loadCall, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + ProgramAllocNode(property, loadCall, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - statements->push_back(AllocNode(initializer)); + statements->push_back(ProgramAllocNode(initializer)); } ir::ClassStaticBlock *ETSChecker::CreateDynamicModuleClassInitializer( @@ -465,33 +476,36 @@ ir::ClassStaticBlock *ETSChecker::CreateDynamicModuleClassInitializer( ir::MethodDefinition *ETSChecker::CreateClassMethod(const std::string_view name, ir::ScriptFunctionFlags funcFlags, ir::ModifierFlags modifierFlags, const MethodBuilder &builder) { - ArenaVector params(Allocator()->Adapter()); + ArenaVector params(ProgramAllocator()->Adapter()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *id = AllocNode(name, Allocator()); + auto *id = ProgramAllocNode(name, ProgramAllocator()); - ArenaVector statements(Allocator()->Adapter()); + ArenaVector statements(ProgramAllocator()->Adapter()); Type *returnType = nullptr; builder(&statements, ¶ms, &returnType); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *body = AllocNode(Allocator(), std::move(statements)); - auto funcSignature = - ir::FunctionSignature(nullptr, std::move(params), - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - returnType == nullptr ? nullptr : AllocNode(returnType, Allocator())); + auto *body = ProgramAllocNode(ProgramAllocator(), std::move(statements)); + auto funcSignature = ir::FunctionSignature( + nullptr, std::move(params), + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + returnType == nullptr ? nullptr : ProgramAllocNode(returnType, ProgramAllocator())); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *func = AllocNode( - Allocator(), ir::ScriptFunction::ScriptFunctionData {body, std::move(funcSignature), funcFlags, modifierFlags}); + auto *func = ProgramAllocNode( + ProgramAllocator(), + ir::ScriptFunction::ScriptFunctionData {body, std::move(funcSignature), funcFlags, modifierFlags}); func->SetIdent(id); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcExpr = AllocNode(func); + auto *funcExpr = ProgramAllocNode(func); auto *method = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(ir::MethodDefinitionKind::METHOD, func->Id()->Clone(Allocator(), nullptr), - funcExpr, modifierFlags, Allocator(), false); + ProgramAllocNode(ir::MethodDefinitionKind::METHOD, + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + func->Id()->Clone(ProgramAllocator(), nullptr), funcExpr, modifierFlags, + ProgramAllocator(), false); return method; } @@ -514,37 +528,41 @@ ir::MethodDefinition *ETSChecker::CreateLambdaObjectClassInvokeMethod(Signature compiler::Signatures::LAMBDA_OBJECT_INVOKE, ir::ScriptFunctionFlags::METHOD, ir::ModifierFlags::PUBLIC, [this, invokeSignature, retTypeAnnotation](ArenaVector *statements, ArenaVector *params, Type **returnType) { - util::UString thisParamName(std::string("this"), Allocator()); + util::UString thisParamName(std::string("this"), ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ir::ETSParameterExpression *thisParam = AddParam(thisParamName.View(), nullptr); params->push_back(thisParam); - ArenaVector callParams(Allocator()->Adapter()); + ArenaVector callParams(ProgramAllocator()->Adapter()); for (auto *invokeParam : invokeSignature->Params()) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto paramName = - util::UString(std::string("p") + std::to_string(callParams.size()), Allocator()).View(); + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + util::UString(std::string("p") + std::to_string(callParams.size()), ProgramAllocator()).View(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *param = AddParam(paramName, AllocNode(invokeParam->TsType(), Allocator())); + auto *param = AddParam(paramName, + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocNode(invokeParam->TsType(), ProgramAllocator())); params->push_back(param); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - callParams.push_back(param->Clone(Allocator(), nullptr)); + callParams.push_back(param->Clone(ProgramAllocator(), nullptr)); } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *properyId = AllocNode("jsvalue_lambda", Allocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *callee = AllocNode(thisParam->Clone(Allocator(), nullptr), properyId, - ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + auto *properyId = ProgramAllocNode("jsvalue_lambda", ProgramAllocator()); + auto *callee = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocNode(thisParam->Clone(ProgramAllocator(), nullptr), properyId, + ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *callLambda = AllocNode(callee, std::move(callParams), nullptr, false); + auto *callLambda = ProgramAllocNode(callee, std::move(callParams), nullptr, false); auto *castToRetTypeExpr = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(callLambda, retTypeAnnotation->Clone(Allocator(), nullptr), false); + ProgramAllocNode(callLambda, retTypeAnnotation->Clone(ProgramAllocator(), nullptr), + false); castToRetTypeExpr->SetTsType(invokeSignature->ReturnType()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *retStatement = AllocNode(castToRetTypeExpr); + auto *retStatement = ProgramAllocNode(castToRetTypeExpr); statements->push_back(retStatement); *returnType = invokeSignature->ReturnType(); @@ -563,21 +581,23 @@ void ETSChecker::EmitDynamicModuleClassInitCall() auto *cctorBody = staticBlock->Function()->Body()->AsBlockStatement(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *classId = AllocNode(compiler::Signatures::DYNAMIC_MODULE_CLASS, Allocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *methodId = AllocNode(compiler::Signatures::DYNAMIC_MODULE_CLASS_INIT, Allocator()); + auto *classId = ProgramAllocNode(compiler::Signatures::DYNAMIC_MODULE_CLASS, ProgramAllocator()); + auto *methodId = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocNode(compiler::Signatures::DYNAMIC_MODULE_CLASS_INIT, ProgramAllocator()); auto *callee = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + ProgramAllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, + false); - ArenaVector callParams(Allocator()->Adapter()); + ArenaVector callParams(ProgramAllocator()->Adapter()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *initCall = AllocNode(callee, std::move(callParams), nullptr, false); + auto *initCall = ProgramAllocNode(callee, std::move(callParams), nullptr, false); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const node = AllocNode(initCall); + auto *const node = ProgramAllocNode(initCall); node->SetParent(cctorBody); - cctorBody->Statements().push_back(node); + cctorBody->AddStatement(node); ProcessScopesNode(this, node); ProcessCheckerNode(this, node); @@ -600,19 +620,19 @@ void ETSChecker::BuildClassBodyFromDynamicImports(const ArenaVectorAssemblerName() = util::UString(assemblyName, Allocator()).View(); + import->SetAssemblerName(util::UString(assemblyName, ProgramAllocator()).View()); fields.insert(import->AssemblerName()); imports.push_back(import); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldIdent = AllocNode(import->AssemblerName(), Allocator()); + auto *fieldIdent = ProgramAllocNode(import->AssemblerName(), ProgramAllocator()); auto flags = ir::ModifierFlags::STATIC | ir::ModifierFlags::PUBLIC | ir::ModifierFlags::READONLY; // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *field = AllocNode( + auto *field = ProgramAllocNode( fieldIdent, nullptr, // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(GlobalBuiltinDynamicType(import->Language()), Allocator()), flags, - Allocator(), false); + ProgramAllocNode(GlobalBuiltinDynamicType(import->Language()), ProgramAllocator()), + flags, ProgramAllocator(), false); classBody->push_back(field); } @@ -650,24 +670,27 @@ ir::MethodDefinition *ETSChecker::CreateLambdaObjectClassInitializer(ETSObjectTy ir::ETSParameterExpression *thisParam = AddParam(varbinder::VarBinder::MANDATORY_PARAM_THIS, nullptr); params->push_back(thisParam); - util::UString jsvalueParamName(std::string("jsvalue_param"), Allocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ir::ETSParameterExpression *jsvalueParam = AddParam( + util::UString jsvalueParamName(std::string("jsvalue_param"), ProgramAllocator()); + ir::ETSParameterExpression *jsvalueParam = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - jsvalueParamName.View(), AllocNode(GlobalBuiltinJSValueType(), Allocator())); + AddParam(jsvalueParamName.View(), + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocNode(GlobalBuiltinJSValueType(), ProgramAllocator())); params->push_back(jsvalueParam); + auto *moduleClassId = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocNode(varbinder::VarBinder::MANDATORY_PARAM_THIS, ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *moduleClassId = AllocNode(varbinder::VarBinder::MANDATORY_PARAM_THIS, Allocator()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldId = AllocNode("jsvalue_lambda", Allocator()); + auto *fieldId = ProgramAllocNode("jsvalue_lambda", ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *property = AllocNode(moduleClassId, fieldId, - ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + auto *property = ProgramAllocNode( + moduleClassId, fieldId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *initializer = AllocNode(property, jsvalueParam->Clone(Allocator(), nullptr), - lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + auto *initializer = ProgramAllocNode( + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + property, jsvalueParam->Clone(ProgramAllocator(), nullptr), lexer::TokenType::PUNCTUATOR_SUBSTITUTION); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - statements->push_back(AllocNode(initializer)); + statements->push_back(ProgramAllocNode(initializer)); }, functionalInterface); } @@ -691,12 +714,12 @@ void ETSChecker::BuildLambdaObjectClass(ETSObjectType *functionalInterface, ir:: functionalInterface](ArenaVector *classBody) { auto assemblyName = "jsvalue_lambda"; // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldIdent = AllocNode(assemblyName, Allocator()); + auto *fieldIdent = ProgramAllocNode(assemblyName, ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *field = AllocNode( + auto *field = ProgramAllocNode( // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - fieldIdent, nullptr, AllocNode(GlobalBuiltinJSValueType(), Allocator()), - ir::ModifierFlags::PRIVATE, Allocator(), false); + fieldIdent, nullptr, ProgramAllocNode(GlobalBuiltinJSValueType(), ProgramAllocator()), + ir::ModifierFlags::PRIVATE, ProgramAllocator(), false); classBody->push_back(field); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) classBody->push_back(CreateLambdaObjectClassInitializer(functionalInterface)); diff --git a/ets2panda/checker/ets/etsWarningAnalyzer.cpp b/ets2panda/checker/ets/etsWarningAnalyzer.cpp index 3a395fe53dfba5e5adf660ae01617a86c91343c4..f8709512c2c9bf0c646e968b59322d5613a6cfa0 100644 --- a/ets2panda/checker/ets/etsWarningAnalyzer.cpp +++ b/ets2panda/checker/ets/etsWarningAnalyzer.cpp @@ -421,23 +421,17 @@ void ETSWarningAnalyzer::ETSWarningImplicitBoxingUnboxing(const ir::AstNode *nod node->Iterate([&](auto *childNode) { ETSWarningImplicitBoxingUnboxing(childNode); }); } -void ETSWarningAnalyzer::LogWarning(const std::string &message, const lexer::SourcePosition &position) -{ - diagnosticEngine_.LogWarning(message, position); -} - void ETSWarningAnalyzer::LogWarning(const diagnostic::DiagnosticKind &diagnostic, const lexer::SourcePosition &position) const { - util::DiagnosticMessageParams diagnosticParams; - this->LogWarning(diagnostic, diagnosticParams, position); + this->LogWarning(diagnostic, {}, position); } void ETSWarningAnalyzer::LogWarning(const diagnostic::DiagnosticKind &diagnostic, - util::DiagnosticMessageParams &diagnosticParams, + const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &position) const { - diagnosticEngine_.LogWarning(diagnostic, std::move(diagnosticParams), position); + diagnosticEngine_.LogDiagnostic(diagnostic, diagnosticParams, position); } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/etsWarningAnalyzer.h b/ets2panda/checker/ets/etsWarningAnalyzer.h index 13f1a0b80b8ea1e650a09e207716b06e2ecdefa2..6a41550de33ac2945b21cec67b04b6e18a7fa880 100644 --- a/ets2panda/checker/ets/etsWarningAnalyzer.h +++ b/ets2panda/checker/ets/etsWarningAnalyzer.h @@ -57,8 +57,7 @@ public: } private: - void LogWarning(const std::string &message, const lexer::SourcePosition &position); - void LogWarning(const diagnostic::DiagnosticKind &diagnostic, util::DiagnosticMessageParams &diagnosticParams, + void LogWarning(const diagnostic::DiagnosticKind &diagnostic, const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &position) const; void LogWarning(const diagnostic::DiagnosticKind &diagnostic, const lexer::SourcePosition &position) const; diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index a2a2b73e270071cd3c7c1d0c6678f34c959f1be7..d1b97e2378531ce44842b26bf5b12aae08e1345f 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -13,7 +13,9 @@ * limitations under the License. */ +#include "checker/types/ets/etsResizableArrayType.h" #include "checker/types/ets/etsTupleType.h" +#include "generated/signatures.h" #include "varbinder/ETSBinder.h" #include "checker/ETSchecker.h" #include "checker/ets/function_helpers.h" @@ -53,6 +55,8 @@ #include "parser/program/program.h" #include "util/helpers.h" +#include + namespace ark::es2panda::checker { // NOTE: #14993 merge with InstantiationContext::ValidateTypeArg @@ -113,6 +117,10 @@ bool ETSChecker::EnhanceSubstitutionForType(const ArenaVector &typeParam if (paramType->IsETSUnionType()) { return EnhanceSubstitutionForUnion(typeParams, paramType->AsETSUnionType(), argumentType, substitution); } + if (paramType->IsETSResizableArrayType()) { + return EnhanceSubstitutionForResizableArray(typeParams, paramType->AsETSResizableArrayType(), argumentType, + substitution); + } if (paramType->IsETSObjectType()) { return EnhanceSubstitutionForObject(typeParams, paramType->AsETSObjectType(), argumentType, substitution); } @@ -126,23 +134,31 @@ bool ETSChecker::EnhanceSubstitutionForType(const ArenaVector &typeParam return true; } +bool ETSChecker::ValidateTypeSubstitution(const ArenaVector &typeParams, Type *ctype, Type *argumentType, + Substitution *substitution) +{ + if (!EnhanceSubstitutionForType(typeParams, ctype, argumentType, substitution)) { + return false; + } + return !ctype->IsETSTypeParameter() || + (substitution->count(ctype->AsETSTypeParameter()) > 0 && + Relation()->IsAssignableTo(argumentType, substitution->at(ctype->AsETSTypeParameter()))); +} + bool ETSChecker::EnhanceSubstitutionForUnion(const ArenaVector &typeParams, ETSUnionType *paramUn, Type *argumentType, Substitution *substitution) { if (!argumentType->IsETSUnionType()) { - return std::any_of( - paramUn->ConstituentTypes().begin(), paramUn->ConstituentTypes().end(), - [this, typeParams, argumentType, substitution](Type *ctype) { - return EnhanceSubstitutionForType(typeParams, ctype, argumentType, substitution) && - (!ctype->IsETSTypeParameter() || - (substitution->find(ctype->AsETSTypeParameter()) != substitution->end() && - Relation()->IsAssignableTo(argumentType, substitution->at(ctype->AsETSTypeParameter())))); - }); + bool foundValid = false; + for (Type *ctype : paramUn->ConstituentTypes()) { + foundValid |= ValidateTypeSubstitution(typeParams, ctype, argumentType, substitution); + } + return foundValid; } auto *const argUn = argumentType->AsETSUnionType(); - ArenaVector paramWlist(Allocator()->Adapter()); - ArenaVector argWlist(Allocator()->Adapter()); + ArenaVector paramWlist(ProgramAllocator()->Adapter()); + ArenaVector argWlist(ProgramAllocator()->Adapter()); for (auto *pc : paramUn->ConstituentTypes()) { for (auto *ac : argUn->ConstituentTypes()) { @@ -166,6 +182,70 @@ bool ETSChecker::EnhanceSubstitutionForUnion(const ArenaVector &typePara return true; } +bool ETSChecker::ProcessUntypedParameter(ir::AstNode *declNode, size_t paramIndex, Signature *paramSig, + Signature *argSig, Substitution *substitution) +{ + if (!declNode->IsETSParameterExpression() || !HasStatus(CheckerStatus::IN_TYPE_INFER)) { + return false; + } + + auto *paramExpr = declNode->AsETSParameterExpression(); + if (paramExpr->Ident()->TypeAnnotation() != nullptr) { + return false; + } + + Type *paramType = paramSig->Params()[paramIndex]->TsType(); + Type *inferredType = paramType->Substitute(Relation(), substitution); + + varbinder::Variable *argParam = argSig->Params()[paramIndex]; + argParam->SetTsType(inferredType); + paramExpr->Ident()->SetTsType(inferredType); + + return true; +} + +static void RemoveInvalidTypeMarkers(ir::AstNode *node) noexcept +{ + std::function doNode = [&](ir::AstNode *nn) { + if (nn->IsTyped() && !(nn->IsExpression() && nn->AsExpression()->IsTypeNode()) && + nn->AsTyped()->TsType() != nullptr && nn->AsTyped()->TsType()->IsTypeError()) { + nn->AsTyped()->SetTsType(nullptr); + } + if (nn->IsIdentifier() && nn->AsIdentifier()->TsType() != nullptr && + nn->AsIdentifier()->TsType()->IsTypeError()) { + nn->AsIdentifier()->SetVariable(nullptr); + } + if (!nn->IsETSTypeReference()) { + nn->Iterate([&](ir::AstNode *child) { doNode(child); }); + } + }; + + doNode(node); +} + +static void ResetInferredNode(ETSChecker *checker) +{ + auto relation = checker->Relation(); + auto resetFuncState = [](ir::ArrowFunctionExpression *expr) { + auto *func = expr->Function(); + func->SetSignature(nullptr); + func->ClearReturnStatements(); + expr->SetTsType(nullptr); + }; + + const bool hasValidNode = relation->GetNode() != nullptr && relation->GetNode()->IsArrowFunctionExpression(); + if (!checker->HasStatus(CheckerStatus::IN_TYPE_INFER) || !hasValidNode) { + return; + } + + auto *arrowFunc = relation->GetNode()->AsArrowFunctionExpression(); + relation->SetNode(nullptr); + + RemoveInvalidTypeMarkers(arrowFunc); + resetFuncState(arrowFunc); + arrowFunc->Check(checker); +} + bool ETSChecker::EnhanceSubstitutionForFunction(const ArenaVector &typeParams, ETSFunctionType *paramType, Type *argumentType, Substitution *substitution) { @@ -173,32 +253,36 @@ bool ETSChecker::EnhanceSubstitutionForFunction(const ArenaVector &typeP return EnhanceSubstitutionForType(typeParams, ptype, atype, substitution); }; - if (argumentType->IsETSFunctionType()) { - auto parameterSignature = paramType->ArrowSignature(); - auto argumentSignature = argumentType->AsETSFunctionType()->ArrowSignature(); - // NOTE(gogabr): handle rest parameter for argumentSignature - if (parameterSignature->MinArgCount() < argumentSignature->MinArgCount()) { - return false; - } - bool res = true; - size_t const commonArity = std::min(argumentSignature->ArgCount(), parameterSignature->ArgCount()); - for (size_t idx = 0; idx < commonArity; idx++) { - auto *declNode = argumentSignature->Params()[idx]->Declaration()->Node(); - if (declNode->IsETSParameterExpression() && - declNode->AsETSParameterExpression()->Ident()->TypeAnnotation() == nullptr) { - continue; - } - res &= enhance(parameterSignature->Params()[idx]->TsType(), argumentSignature->Params()[idx]->TsType()); - } + if (!argumentType->IsETSFunctionType()) { + return true; + } + + auto *paramSig = paramType->ArrowSignature(); + auto *argSig = argumentType->AsETSFunctionType()->ArrowSignature(); + + if (paramSig->MinArgCount() < argSig->MinArgCount()) { + return false; + } - if (argumentSignature->HasRestParameter() && parameterSignature->HasRestParameter()) { - res &= enhance(parameterSignature->RestVar()->TsType(), argumentSignature->RestVar()->TsType()); + bool res = true; + const size_t commonArity = std::min(argSig->ArgCount(), paramSig->ArgCount()); + + for (size_t idx = 0; idx < commonArity; idx++) { + auto *declNode = argSig->Params()[idx]->Declaration()->Node(); + if (ProcessUntypedParameter(declNode, idx, paramSig, argSig, substitution)) { + continue; } - res &= enhance(parameterSignature->ReturnType(), argumentSignature->ReturnType()); - return res; + res &= enhance(paramSig->Params()[idx]->TsType(), argSig->Params()[idx]->TsType()); } - return true; + ResetInferredNode(this); + + if (argSig->HasRestParameter() && paramSig->HasRestParameter()) { + res &= enhance(paramSig->RestVar()->TsType(), argSig->RestVar()->TsType()); + } + res &= enhance(paramSig->ReturnType(), argSig->ReturnType()); + + return res; } // Try to find the base type somewhere in object subtypes. Incomplete, yet safe @@ -257,6 +341,16 @@ bool ETSChecker::EnhanceSubstitutionForArray(const ArenaVector &typePara return EnhanceSubstitutionForType(typeParams, paramType->ElementType(), elementType, substitution); } +bool ETSChecker::EnhanceSubstitutionForResizableArray(const ArenaVector &typeParams, + ETSResizableArrayType *const paramType, Type *const argumentType, + Substitution *const substitution) +{ + auto *const elementType = + argumentType->IsETSResizableArrayType() ? argumentType->AsETSResizableArrayType()->ElementType() : argumentType; + + return EnhanceSubstitutionForType(typeParams, paramType->ElementType(), elementType, substitution); +} + Signature *ETSChecker::ValidateParameterlessConstructor(Signature *signature, const lexer::SourcePosition &pos, bool throwError) { @@ -290,11 +384,36 @@ bool ETSChecker::ValidateArgumentAsIdentifier(const ir::Identifier *identifier) return result.variable != nullptr && (result.variable->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE)); } +static void ClearPreferredTypeForArray(checker::ETSChecker *checker, ir::Expression *argument, Type *paramType, + TypeRelationFlag flags, bool needRecheck) +{ + if (argument->IsArrayExpression()) { + // fixed array and resizeable array will cause problem here, so clear it. + argument->AsArrayExpression()->ClearPreferredType(); + argument->AsArrayExpression()->SetPreferredTypeBasedOnFuncParam(checker, paramType, flags); + } else if (argument->IsETSNewArrayInstanceExpression()) { + argument->AsETSNewArrayInstanceExpression()->ClearPreferredType(); + argument->AsETSNewArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(checker, paramType, flags); + } else if (argument->IsETSNewMultiDimArrayInstanceExpression()) { + argument->AsETSNewMultiDimArrayInstanceExpression()->ClearPreferredType(); + argument->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredTypeBasedOnFuncParam(checker, paramType, + flags); + } else { + return; + } + if (needRecheck) { + argument->Check(checker); + } +} + bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, const ArenaVector &arguments, TypeRelationFlag flags, const std::vector &argTypeInferenceRequired, bool reportError) { - auto const commonArity = std::min(arguments.size(), substitutedSig->ArgCount()); + auto commonArity = std::min(arguments.size(), substitutedSig->ArgCount()); + if ((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0) { + commonArity = commonArity - 1; + } for (size_t index = 0; index < commonArity; ++index) { auto &argument = arguments[index]; @@ -319,17 +438,16 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, if (argTypeInferenceRequired[index]) { ES2PANDA_ASSERT(argument->IsArrowFunctionExpression()); - auto *const arrowFuncExpr = argument->AsArrowFunctionExpression(); - ir::ScriptFunction *const lambda = arrowFuncExpr->Function(); - if (CheckLambdaAssignable(substitutedSig->Function()->Params()[index], lambda)) { + // Note: If the signatures are from lambdas, then they have no `Function`. + ir::ScriptFunction *const lambda = argument->AsArrowFunctionExpression()->Function(); + auto targetParm = substitutedSig->GetSignatureInfo()->params[index]->Declaration()->Node(); + if (CheckLambdaAssignable(targetParm->AsETSParameterExpression(), lambda)) { continue; } return false; } - if (argument->IsArrayExpression()) { - argument->AsArrayExpression()->SetPreferredTypeBasedOnFuncParam(this, paramType, flags); - } + ClearPreferredTypeForArray(this, argument, paramType, flags, false); if (argument->IsIdentifier() && ValidateArgumentAsIdentifier(argument->AsIdentifier())) { LogError(diagnostic::ARG_IS_CLASS_ID, {}, argument->Start()); @@ -342,6 +460,13 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, } } + if ((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0 && arguments.back()->IsArrowFunctionExpression()) { + ir::ScriptFunction *const lambda = arguments.back()->AsArrowFunctionExpression()->Function(); + auto targetParm = substitutedSig->GetSignatureInfo()->params.back()->Declaration()->Node(); + if (!CheckLambdaAssignable(targetParm->AsETSParameterExpression(), lambda)) { + return false; + } + } return true; } @@ -354,9 +479,9 @@ bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, i flags |= TypeRelationFlag::ONLY_CHECK_WIDENING; - auto const invocationCtx = checker::InvocationContext( - Relation(), argument, argumentType, targetType, argument->Start(), - {"Type '", argumentType, "' is not compatible with type '", targetType, "' at index ", index + 1}, flags); + auto const invocationCtx = + checker::InvocationContext(Relation(), argument, argumentType, targetType, argument->Start(), + {{diagnostic::TYPE_MISMATCH_AT_IDX, {argumentType, targetType, index + 1}}}, flags); return invocationCtx.IsInvocable() || CheckOptionalLambdaFunction(argument, substitutedSig, index); } @@ -364,34 +489,41 @@ bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, i bool ETSChecker::IsValidRestArgument(ir::Expression *const argument, Signature *const substitutedSig, const TypeRelationFlag flags, const std::size_t index) { + if (argument->IsObjectExpression()) { + // Object literals should be checked separately afterwards after call resolution + return true; + } const auto argumentType = argument->Check(this); - auto *targetType = substitutedSig->RestVar()->TsType(); - if (targetType->IsETSTupleType()) { - // NOTE (mmartin): check tuple assignability for rest arguments - LogTypeError("Tuple types for rest arguments are not yet implemented", argument->Start()); + auto *restParam = substitutedSig->RestVar()->TsType(); + if (restParam->IsETSTupleType()) { return false; } + if (argument->HasAstNodeFlags(ir::AstNodeFlags::RESIZABLE_REST)) { + return true; + } - targetType = substitutedSig->RestVar()->TsType()->AsETSArrayType()->ElementType(); + auto targetType = GetElementTypeOfArray(restParam); if (substitutedSig->OwnerVar() == nullptr) { targetType = MaybeBoxType(targetType); } - auto const invocationCtx = - checker::InvocationContext(Relation(), argument, argumentType, targetType, argument->Start(), - {"Type '", argumentType, "' is not compatible with rest parameter type '", - targetType, "' at index ", index + 1}, - flags); + auto const invocationCtx = checker::InvocationContext( + Relation(), argument, argumentType, targetType, argument->Start(), + {{diagnostic::REST_PARAM_INCOMPAT_AT, {argumentType, targetType, index + 1}}}, flags); return invocationCtx.IsInvocable(); } bool ETSChecker::ValidateSignatureRestParams(Signature *substitutedSig, const ArenaVector &arguments, - TypeRelationFlag flags, bool reportError, const bool unique) + TypeRelationFlag flags, bool reportError, + [[maybe_unused]] const bool unique) { size_t const argumentCount = arguments.size(); auto const commonArity = std::min(substitutedSig->ArgCount(), argumentCount); auto const restCount = argumentCount - commonArity; + if (argumentCount == commonArity && substitutedSig->RestVar()->TsType()->IsETSTupleType()) { + return false; + } for (size_t index = commonArity; index < argumentCount; ++index) { auto &argument = arguments[index]; @@ -413,17 +545,19 @@ bool ETSChecker::ValidateSignatureRestParams(Signature *substitutedSig, const Ar Type *targetType = substitutedSig->RestVar()->TsType(); // backing out of check that results in a signature mismatch would be difficult // so only attempt it if there is only one candidate signature - if (unique && restArgument->IsArrayExpression()) { + if (restArgument->IsArrayExpression()) { restArgument->AsArrayExpression()->SetPreferredType(targetType); } auto const argumentType = restArgument->Check(this); auto const invocationCtx = checker::InvocationContext( Relation(), restArgument, argumentType, substitutedSig->RestVar()->TsType(), argument->Start(), - {"Type '", argumentType, "' is not compatible with rest parameter type '", - substitutedSig->RestVar()->TsType(), "' at index ", index + 1}, + {{diagnostic::REST_PARAM_INCOMPAT_AT, {argumentType, substitutedSig->RestVar()->TsType(), index + 1}}}, flags); if (!invocationCtx.IsInvocable()) { + if (restArgument->IsArrayExpression()) { + ModifyPreferredType(restArgument->AsArrayExpression(), nullptr); + } return false; } } @@ -441,9 +575,7 @@ Signature *ETSChecker::ValidateSignature( // setting the boxing/unboxing flag for the arguments if needed. // So handle substitution arguments only in the case of unique function or collecting signature phase. Signature *const signature = - ((flags & TypeRelationFlag::ONLY_CHECK_BOXING_UNBOXING) == 0 && !unique) - ? baseSignature - : MaybeSubstituteTypeParameters(this, baseSignature, typeArguments, arguments, pos, flags); + MaybeSubstituteTypeParameters(this, baseSignature, typeArguments, arguments, pos, flags); if (signature == nullptr) { return nullptr; } @@ -451,8 +583,13 @@ Signature *ETSChecker::ValidateSignature( size_t const argCount = arguments.size(); auto const hasRestParameter = signature->RestVar() != nullptr; auto const reportError = (flags & TypeRelationFlag::NO_THROW) == 0; + size_t compareCount = argCount; + if ((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0 && !signature->Params().empty() && + signature->Params().back()->Declaration()->Node()->AsETSParameterExpression()->IsOptional()) { + compareCount = compareCount - 1; + } - if (argCount < signature->MinArgCount() || (argCount > signature->ArgCount() && !hasRestParameter)) { + if (compareCount < signature->MinArgCount() || (argCount > signature->ArgCount() && !hasRestParameter)) { if (reportError) { LogError(diagnostic::PARAM_COUNT_MISMATCH, {signature->MinArgCount(), argCount}, pos); } @@ -471,7 +608,7 @@ Signature *ETSChecker::ValidateSignature( } // Check rest parameter(s) if any exists - if (!hasRestParameter || count >= argCount) { + if (!hasRestParameter || (count >= argCount && !signature->RestVar()->TsType()->IsETSTupleType())) { return signature; } if (!ValidateSignatureRestParams(signature, arguments, flags, reportError, unique)) { @@ -522,17 +659,16 @@ std::array GetFlagVariants() // NOTE(boglarkahaag): Not in sync with specification, but solves the issues with rest params for now (#17483) return { TypeRelationFlag::NO_THROW | TypeRelationFlag::NO_UNBOXING | TypeRelationFlag::NO_BOXING | - TypeRelationFlag::IGNORE_REST_PARAM, + TypeRelationFlag::IGNORE_REST_PARAM | TypeRelationFlag::NO_WIDENING, TypeRelationFlag::NO_THROW | TypeRelationFlag::NO_UNBOXING | TypeRelationFlag::NO_BOXING, - TypeRelationFlag::NO_THROW | TypeRelationFlag::IGNORE_REST_PARAM, - TypeRelationFlag::NO_THROW, + TypeRelationFlag::NO_THROW | TypeRelationFlag::IGNORE_REST_PARAM | TypeRelationFlag::NO_WIDENING, + TypeRelationFlag::NO_THROW | TypeRelationFlag::NO_WIDENING, TypeRelationFlag::NO_THROW | TypeRelationFlag::WIDENING | TypeRelationFlag::NO_UNBOXING | TypeRelationFlag::NO_BOXING | TypeRelationFlag::IGNORE_REST_PARAM, TypeRelationFlag::NO_THROW | TypeRelationFlag::WIDENING | TypeRelationFlag::NO_UNBOXING | TypeRelationFlag::NO_BOXING, TypeRelationFlag::NO_THROW | TypeRelationFlag::WIDENING | TypeRelationFlag::IGNORE_REST_PARAM, TypeRelationFlag::NO_THROW | TypeRelationFlag::WIDENING, - TypeRelationFlag::NO_THROW | TypeRelationFlag::STRING_TO_CHAR, }; } @@ -541,7 +677,7 @@ ArenaVector ETSChecker::CollectSignatures(ArenaVector const ArenaVector &arguments, const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags) { - ArenaVector compatibleSignatures(Allocator()->Adapter()); + ArenaVector compatibleSignatures(ProgramAllocator()->Adapter()); std::vector argTypeInferenceRequired = FindTypeInferenceArguments(arguments); Signature *notVisibleSignature = nullptr; @@ -569,25 +705,15 @@ ArenaVector ETSChecker::CollectSignatures(ArenaVector // If there's only one signature, we don't need special checks for boxing/unboxing/widening. // We are also able to provide more specific error messages. if (signatures.size() == 1) { - TypeRelationFlag flags = TypeRelationFlag::WIDENING | TypeRelationFlag::STRING_TO_CHAR | resolveFlags; + TypeRelationFlag flags = TypeRelationFlag::WIDENING | resolveFlags; collectSignatures(flags); } else { for (auto flags : GetFlagVariants()) { - // CollectSignatures gathers the possible signatures, but in doing so, it also sets the boxing/unboxing - // flags where necessary. Since these might not be the actually used functions in every cases, - // this setting needs to be delayed for compatibleSignatures. In case of only one signature, - // it is not required, only when the signatures.size() > 1 - flags = flags | resolveFlags | TypeRelationFlag::ONLY_CHECK_BOXING_UNBOXING; + flags = flags | resolveFlags; collectSignatures(flags); - if (compatibleSignatures.empty()) { - continue; - } - for (auto signature : compatibleSignatures) { - flags &= ~TypeRelationFlag::ONLY_CHECK_BOXING_UNBOXING; - ValidateSignature(std::make_tuple(signature, typeArguments, flags), arguments, pos, - argTypeInferenceRequired, signatures.size() == 1); + if (!compatibleSignatures.empty()) { + break; } - break; } } @@ -598,12 +724,41 @@ ArenaVector ETSChecker::CollectSignatures(ArenaVector return compatibleSignatures; } +static void ClearUnboxingFlags(TypeRelation *relation, Signature *sig, ir::Expression *argument, size_t index) +{ + auto identical = relation->IsIdenticalTo(sig->Params()[index]->TsType(), argument->TsType()); + // NOTE(gaborarontakacs): The unboxing flag, which was added due to overloading, needs to be removed when it's + // unnecessary for the most specific signature. + // Do not remove the flag for tuples, e.g., `let a = [21 as Number] as [number]`, + // because unboxing will be executed later during the function call in this case. + // This condition may be removed after refactoring primitive types. + if (identical && argument->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG) && + !(argument->IsMemberExpression() && argument->AsMemberExpression()->Object()->TsType()->IsETSTupleType())) { + argument->RemoveBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG); + } +} + +static void UpdateArrayArgsAndUnboxingFlags(ETSChecker *checker, Signature *sig, + const ArenaVector &arguments) +{ + auto const commonArity = std::min(arguments.size(), sig->ArgCount()); + for (size_t index = 0; index < commonArity; ++index) { + auto argument = arguments[index]; + auto const paramType = checker->GetNonNullishType(sig->Params()[index]->TsType()); + auto flags = TypeRelationFlag::NO_THROW | TypeRelationFlag::BOXING | TypeRelationFlag::UNBOXING | + TypeRelationFlag::WIDENING; + ClearPreferredTypeForArray(checker, argument, paramType, flags, true); + ClearUnboxingFlags(checker->Relation(), sig, argument, index); + } +} + Signature *ETSChecker::GetMostSpecificSignature(ArenaVector &compatibleSignatures, const ArenaVector &arguments, const lexer::SourcePosition &pos, TypeRelationFlag resolveFlags) { std::vector argTypeInferenceRequired = FindTypeInferenceArguments(arguments); - Signature *mostSpecificSignature = ChooseMostSpecificSignature(compatibleSignatures, argTypeInferenceRequired, pos); + Signature *mostSpecificSignature = + ChooseMostSpecificSignature(compatibleSignatures, argTypeInferenceRequired, arguments, pos); if (mostSpecificSignature == nullptr) { LogError(diagnostic::AMBIGUOUS_FUNC_REF, {compatibleSignatures.front()->Function()->Id()->Name()}, pos); @@ -615,6 +770,9 @@ Signature *ETSChecker::GetMostSpecificSignature(ArenaVector &compat return nullptr; } + // revalidate signature for arrays + UpdateArrayArgsAndUnboxingFlags(this, mostSpecificSignature, arguments); + return mostSpecificSignature; } @@ -702,7 +860,7 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector } const auto candidateLength = candidate->Function()->Params().size(); - if (candidateLength > currentMinLength) { + if (candidateLength > currentMinLength && !candidate->HasRestParameter()) { continue; } @@ -713,7 +871,11 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector } const auto currentLength = result->Function()->Params().size(); - if (candidateLength < currentLength) { + if (candidate->HasRestParameter() && result->HasRestParameter()) { + if (result->Owner() == candidate->Owner()) { + result = nullptr; + } + } else if (candidateLength < currentLength) { result = candidate; // Shorter parameter count wins currentMinLength = result->Function()->Params().size(); } else if (candidateLength == currentLength) { @@ -727,17 +889,18 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector return result; } -static Type *GetParatmeterTypeOrRestAtIdx(Signature *sig, const size_t idx) +static Type *GetParatmeterTypeOrRestAtIdx(checker::ETSChecker *checker, Signature *sig, const size_t idx) { return idx < sig->ArgCount() ? sig->Params().at(idx)->TsType() - : sig->RestVar()->TsType()->AsETSArrayType()->ElementType(); + : checker->GetElementTypeOfArray(sig->RestVar()->TsType()); } -static void InitMostSpecificType(const ArenaVector &signatures, [[maybe_unused]] Type *&mostSpecificType, - [[maybe_unused]] Signature *&prevSig, const size_t idx) +static void InitMostSpecificType(checker::ETSChecker *checker, const ArenaVector &signatures, + [[maybe_unused]] Type *&mostSpecificType, [[maybe_unused]] Signature *&prevSig, + const size_t idx) { for (auto *sig : signatures) { - if (Type *sigType = GetParatmeterTypeOrRestAtIdx(sig, idx); + if (Type *sigType = GetParatmeterTypeOrRestAtIdx(checker, sig, idx); sigType->IsETSObjectType() && !sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { mostSpecificType = sigType; prevSig = sig; @@ -751,7 +914,7 @@ void ETSChecker::SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature bool lookForClassType) { auto [pos, idx, sig] = info; - Type *sigType = GetParatmeterTypeOrRestAtIdx(sig, idx); + Type *sigType = GetParatmeterTypeOrRestAtIdx(this, sig, idx); const bool isClassType = sigType->IsETSObjectType() && !sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE); if (isClassType == lookForClassType) { @@ -769,9 +932,43 @@ void ETSChecker::SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature } } -static void CollectSuitableSignaturesForTypeInference(size_t paramIdx, ArenaVector &signatures, - ArenaMultiMap &bestSignaturesForParameter) +void ETSChecker::CollectSuitableSignaturesForTypeInference( + size_t paramIdx, ArenaVector &signatures, + ArenaMultiMap &bestSignaturesForParameter, const ArenaVector &arguments) { + // For lambda parameters, attempt to obtain the most matching signature through the number of lambda parameters + ES2PANDA_ASSERT(arguments.at(paramIdx)->IsArrowFunctionExpression()); + [[maybe_unused]] size_t paramCount = + arguments.at(paramIdx)->AsArrowFunctionExpression()->Function()->Params().size(); + size_t minMatchArgCount = SIZE_MAX; + + for (auto *sig : signatures) { + auto *sigParamType = GetNonNullishType(sig->Params().at(paramIdx)->TsType()); + if (!sigParamType->IsETSFunctionType()) { + continue; + } + + auto sigParamArgCount = sigParamType->AsETSFunctionType()->ArrowSignature()->ArgCount(); + ES2PANDA_ASSERT(sigParamArgCount >= paramCount); + + minMatchArgCount = std::min(minMatchArgCount, sigParamArgCount); + } + + for (auto *sig : signatures) { + auto *sigParamType = GetNonNullishType(sig->Params().at(paramIdx)->TsType()); + if (!sigParamType->IsETSFunctionType()) { + continue; + } + + if (sigParamType->AsETSFunctionType()->ArrowSignature()->ArgCount() == minMatchArgCount) { + bestSignaturesForParameter.insert({paramIdx, sig}); + } + } + + if (bestSignaturesForParameter.find(paramIdx) != bestSignaturesForParameter.end()) { + return; + } + for (auto *sig : signatures) { if (paramIdx >= sig->Params().size() || !sig->Params().at(paramIdx)->TsType()->IsETSObjectType() || !sig->Params().at(paramIdx)->TsType()->AsETSObjectType()->IsGlobalETSObjectType()) { @@ -782,24 +979,30 @@ static void CollectSuitableSignaturesForTypeInference(size_t paramIdx, ArenaVect ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter( const std::vector &argTypeInferenceRequired, size_t paramCount, ArenaVector &signatures, - const lexer::SourcePosition &pos) + const ArenaVector &arguments, const lexer::SourcePosition &pos) { // Collect which signatures are most specific for each parameter. - ArenaMultiMap bestSignaturesForParameter(Allocator()->Adapter()); + ArenaMultiMap bestSignaturesForParameter(ProgramAllocator()->Adapter()); const checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx(Relation(), TypeRelationFlag::ONLY_CHECK_WIDENING); for (size_t i = 0; i < paramCount; ++i) { - if (i >= argTypeInferenceRequired.size() || argTypeInferenceRequired[i]) { - CollectSuitableSignaturesForTypeInference(i, signatures, bestSignaturesForParameter); + if (i >= argTypeInferenceRequired.size()) { + for (auto *sig : signatures) { + bestSignaturesForParameter.insert({i, sig}); + } + continue; + } + if (argTypeInferenceRequired[i]) { + CollectSuitableSignaturesForTypeInference(i, signatures, bestSignaturesForParameter, arguments); continue; } // 1st step: check which is the most specific parameter type for i. parameter. Type *mostSpecificType = signatures.front()->Params().at(i)->TsType(); Signature *prevSig = signatures.front(); - InitMostSpecificType(signatures, mostSpecificType, prevSig, i); + InitMostSpecificType(this, signatures, mostSpecificType, prevSig, i); for (auto *sig : signatures) { SearchAmongMostSpecificTypes(mostSpecificType, prevSig, std::make_tuple(pos, i, sig), true); } @@ -808,7 +1011,7 @@ ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter } for (auto *sig : signatures) { - Type *sigType = GetParatmeterTypeOrRestAtIdx(sig, i); + Type *sigType = GetParatmeterTypeOrRestAtIdx(this, sig, i); if (Relation()->IsIdenticalTo(sigType, mostSpecificType)) { bestSignaturesForParameter.insert({i, sig}); } @@ -819,6 +1022,7 @@ ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter Signature *ETSChecker::ChooseMostSpecificSignature(ArenaVector &signatures, const std::vector &argTypeInferenceRequired, + const ArenaVector &arguments, const lexer::SourcePosition &pos, size_t argumentsSize) { ES2PANDA_ASSERT(signatures.empty() == false); @@ -844,8 +1048,12 @@ Signature *ETSChecker::ChooseMostSpecificSignature(ArenaVector &sig return *zeroParamSignature; } // If there are multiple rest parameter signatures with different argument types, throw error - if (signatures.size() > 1 && std::any_of(signatures.begin(), signatures.end(), [signatures](const auto *param) { - return param->RestVar()->TsType() != signatures.front()->RestVar()->TsType(); + if (signatures.size() > 1 && + std::any_of(signatures.begin(), signatures.end(), [signatures, this](const auto *param) { + auto left = MaybeBoxType(GetElementTypeOfArray(param->RestVar()->TsType())); + auto right = MaybeBoxType(GetElementTypeOfArray(signatures.front()->RestVar()->TsType())); + Relation()->IsIdenticalTo(left, right); + return !Relation()->IsTrue(); })) { LogError(diagnostic::AMBIGUOUS_CALL_2, {signatures.front()->Function()->Id()->Name()}, pos); return nullptr; @@ -857,7 +1065,7 @@ Signature *ETSChecker::ChooseMostSpecificSignature(ArenaVector &sig } ArenaMultiMap bestSignaturesForParameter = - GetSuitableSignaturesForParameter(argTypeInferenceRequired, paramCount, signatures, pos); + GetSuitableSignaturesForParameter(argTypeInferenceRequired, paramCount, signatures, arguments, pos); // Find the signature that are most specific for all parameters. Signature *mostSpecificSignature = FindMostSpecificSignature(signatures, bestSignaturesForParameter, paramCount); @@ -878,8 +1086,8 @@ Signature *ETSChecker::ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpres ArenaVector &arguments) { auto *trailingLambda = arguments.back()->AsArrowFunctionExpression(); - ArenaVector normalSig(Allocator()->Adapter()); - ArenaVector sigContainLambdaWithReceiverAsParam(Allocator()->Adapter()); + ArenaVector normalSig(ProgramAllocator()->Adapter()); + ArenaVector sigContainLambdaWithReceiverAsParam(ProgramAllocator()->Adapter()); Signature *signature = nullptr; for (auto sig : signatures) { if (!IsLastParameterLambdaWithReceiver(sig)) { @@ -890,7 +1098,7 @@ Signature *ETSChecker::ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpres auto *candidateFunctionType = sig->Function()->Params().back()->AsETSParameterExpression()->TypeAnnotation()->AsETSFunctionType(); auto *currentReceiver = candidateFunctionType->Params()[0]; - trailingLambda->Function()->Params().emplace_back(currentReceiver); + trailingLambda->Function()->EmplaceParams(currentReceiver); sigContainLambdaWithReceiverAsParam.emplace_back(sig); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) signature = ValidateSignatures(sigContainLambdaWithReceiverAsParam, callExpr->TypeParams(), arguments, @@ -900,7 +1108,7 @@ Signature *ETSChecker::ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpres return signature; } sigContainLambdaWithReceiverAsParam.clear(); - trailingLambda->Function()->Params().clear(); + trailingLambda->Function()->ClearParams(); } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return ValidateSignatures(normalSig, callExpr->TypeParams(), arguments, callExpr->Start(), "call", @@ -936,7 +1144,7 @@ void ETSChecker::UpdateDeclarationFromSignature(ir::CallExpression *expr, checke while (!declNode->IsMethodDefinition()) { declNode = declNode->Parent(); } - auto allocator = Allocator(); + auto allocator = ProgramAllocator(); auto newDecl = allocator->New(allocator, sigName, declNode); auto newVar = allocator->New(newDecl, varbinder::VariableFlags::METHOD | varbinder::VariableFlags::SYNTHETIC); @@ -964,8 +1172,9 @@ Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVectorArguments()); + TrailingLambdaTypeInference(sig, callExpr->Arguments()); UpdateDeclarationFromSignature(callExpr, sig); + callExpr->SetIsTrailingCall(true); return sig; } @@ -1000,7 +1209,8 @@ void ETSChecker::CheckObjectLiteralArguments(Signature *signature, ArenaVector= signature->Params().size()) { ES2PANDA_ASSERT(signature->RestVar()); - tp = signature->RestVar()->TsType(); + // Use element type as rest object literal type + tp = GetElementTypeOfArray(signature->RestVar()->TsType()); } else { // #22952: infer optional parameter heuristics tp = GetNonNullishType(signature->Params()[index]->TsType()); @@ -1014,8 +1224,8 @@ void ETSChecker::CheckObjectLiteralArguments(Signature *signature, ArenaVectorGetOverloadInfo(); - ArenaVector overloads(checker->Allocator()->Adapter()); + ir::OverloadInfo &ldInfo = method->GetOverloadInfoForUpdate(); + ArenaVector overloads(checker->ProgramAllocator()->Adapter()); for (ir::MethodDefinition *const currentFunc : method->Overloads()) { ldInfo.isDeclare &= currentFunc->IsDeclare(); @@ -1026,11 +1236,16 @@ static bool CollectOverload(checker::ETSChecker *checker, ir::MethodDefinition * method->Id()->Variable()->SetTsType(checker->GlobalTypeError()); return false; } - auto *const overloadType = checker->BuildMethodType(currentFunc->Function()); + + auto *const overloadType = currentFunc->TsType() != nullptr ? currentFunc->TsType()->AsETSFunctionType() + : checker->BuildMethodType(currentFunc->Function()); ldInfo.needHelperOverload |= checker->CheckIdenticalOverloads(funcType, overloadType, currentFunc, ldInfo.isDeclare); - currentFunc->SetTsType(overloadType); + if (currentFunc->TsType() == nullptr) { + currentFunc->SetTsType(overloadType); + } + auto overloadSig = currentFunc->Function()->Signature(); funcType->AddCallSignature(overloadSig); if (overloadSig->IsExtensionAccessor()) { @@ -1074,12 +1289,11 @@ checker::Type *ETSChecker::BuildMethodSignature(ir::MethodDefinition *method) if (!CollectOverload(this, method, funcType)) { return GlobalTypeError(); } - ir::OverloadInfo &ldInfo = method->GetOverloadInfo(); + ir::OverloadInfo &ldInfo = method->GetOverloadInfoForUpdate(); ldInfo.needHelperOverload &= ldInfo.isDeclare; if (ldInfo.needHelperOverload) { - Warning("Function " + std::string(funcType->Name()) + " with this assembly signature already declared.", - method->Start()); + LogDiagnostic(diagnostic::FUNCTION_ASM_SIG_COLLISION, {std::string(funcType->Name())}, method->Start()); } return method->Id()->Variable()->SetTsType(funcType); @@ -1227,6 +1441,12 @@ SignatureInfo *ETSChecker::ComposeSignatureInfo(ir::TSTypeParameterDeclaration * ES2PANDA_ASSERT(IsAnyError()); return nullptr; } + auto restParamType = param->RestParameter()->TypeAnnotation()->GetType(this); + if (!restParamType->IsETSTupleType() && !restParamType->IsETSArrayType() && + !restParamType->IsETSResizableArrayType()) { + LogError(diagnostic::ONLY_ARRAY_OR_TUPLE_FOR_REST, {}, param->Start()); + return nullptr; + } signatureInfo->restVar = SetupSignatureParameter(param, param->TypeAnnotation()->GetType(this)); ES2PANDA_ASSERT(signatureInfo->restVar != nullptr); } @@ -1259,9 +1479,18 @@ void ETSChecker::ValidateMainSignature(ir::ScriptFunction *func) void ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig) { 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) { + return; + } auto *nameVar = isArrow ? nullptr : func->Id()->Variable(); auto funcName = nameVar == nullptr ? util::StringView() : nameVar->Name(); + if (func->IsConstructor() && func->IsStatic()) { + LogError(diagnostic::INVALID_DECORATOR_CONSTRUCTOR, {}, func->Start()); + return; + } + if ((func->IsConstructor() || !func->IsStatic()) && !func->IsArrow()) { auto thisVar = func->Scope()->ParamScope()->Params().front(); thisVar->SetTsType(Context().ContainingClass()); @@ -1293,6 +1522,7 @@ void ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool isConstru } VarBinder()->AsETSBinder()->BuildFunctionName(func); + Program()->AddToFunctionScopes(func->Scope()); } checker::ETSFunctionType *ETSChecker::BuildMethodType(ir::ScriptFunction *func) @@ -1301,10 +1531,10 @@ checker::ETSFunctionType *ETSChecker::BuildMethodType(ir::ScriptFunction *func) auto *nameVar = func->Id()->Variable(); ETSFunctionType *funcType; if (func->IsDynamic()) { - funcType = CreateETSDynamicMethodType(nameVar->Name(), {{func->Signature()}, Allocator()->Adapter()}, + funcType = CreateETSDynamicMethodType(nameVar->Name(), {{func->Signature()}, ProgramAllocator()->Adapter()}, func->Language()); } else { - funcType = CreateETSMethodType(nameVar->Name(), {{func->Signature()}, Allocator()->Adapter()}); + funcType = CreateETSMethodType(nameVar->Name(), {{func->Signature()}, ProgramAllocator()->Adapter()}); } funcType->SetVariable(nameVar); return funcType; @@ -1391,6 +1621,16 @@ OverrideErrorCode ETSChecker::CheckOverride(Signature *signature, Signature *oth return OverrideErrorCode::OVERRIDDEN_FINAL; } + auto *ownerNode = signature->Owner()->GetDeclNode(); + auto *superNode = other->Owner()->GetDeclNode(); + bool bothRealClasses = (ownerNode != nullptr) && ownerNode->IsClassDefinition() && (superNode != nullptr) && + superNode->IsClassDefinition() && signature->Owner()->HasObjectFlag(ETSObjectFlags::CLASS) && + other->Owner()->HasObjectFlag(ETSObjectFlags::CLASS); + if (bothRealClasses && signature->HasSignatureFlag(SignatureFlags::ABSTRACT) && + !other->HasSignatureFlag(SignatureFlags::ABSTRACT)) { + return OverrideErrorCode::ABSTRACT_OVERRIDES_CONCRETE; + } + if (!other->ReturnType()->IsETSTypeParameter()) { if (!IsReturnTypeSubstitutable(signature, other)) { return OverrideErrorCode::INCOMPATIBLE_RETURN; @@ -1462,6 +1702,10 @@ void ETSChecker::ReportOverrideError(Signature *signature, Signature *overridden "overridden method."; break; } + case OverrideErrorCode::ABSTRACT_OVERRIDES_CONCRETE: { + reason = "an abstract method cannot override a non-abstract instance method."; + break; + } default: { ES2PANDA_UNREACHABLE(); } @@ -1493,7 +1737,9 @@ bool CheckTypeParameterConstraints(ArenaVector typeParamList1, ArenaVect bool ETSChecker::CheckOverride(Signature *signature, ETSObjectType *site) { - auto *target = site->GetProperty(signature->Function()->Id()->Name(), PropertySearchFlags::SEARCH_METHOD); + PropertySearchFlags flags = + PropertySearchFlags::SEARCH_METHOD | PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION; + auto *target = site->GetProperty(signature->Function()->Id()->Name(), flags); bool isOverridingAnySignature = false; if (target == nullptr) { @@ -1598,9 +1844,9 @@ bool ETSChecker::NeedToVerifySignatureVisibility(Signature *signature, const lex signature->HasSignatureFlag(SignatureFlags::PROTECTED)); } -void ETSChecker::ValidateSignatureAccessibility(ETSObjectType *callee, const ir::CallExpression *callExpr, - Signature *signature, const lexer::SourcePosition &pos, - const DiagnosticInfo &errorInfo) +void ETSChecker::ValidateSignatureAccessibility(ETSObjectType *callee, Signature *signature, + const lexer::SourcePosition &pos, + const MaybeDiagnosticInfo &maybeErrorInfo) { if (!NeedToVerifySignatureVisibility(signature, pos)) { return; @@ -1611,14 +1857,6 @@ void ETSChecker::ValidateSignatureAccessibility(ETSObjectType *callee, const ir: ES2PANDA_ASSERT(declNode && (declNode->IsClassDefinition() || declNode->IsTSInterfaceDeclaration())); if (declNode->IsTSInterfaceDeclaration()) { - const auto *enclosingFunc = - util::Helpers::FindAncestorGivenByType(callExpr, ir::AstNodeType::SCRIPT_FUNCTION)->AsScriptFunction(); - if (callExpr->Callee()->IsMemberExpression() && - callExpr->Callee()->AsMemberExpression()->Object()->IsThisExpression() && - signature->Function()->IsPrivate() && !enclosingFunc->IsPrivate()) { - LogError(diagnostic::THIS_OUTSIDE_METHOD_CTX, {}, enclosingFunc->Start()); - } - if (containingClass == declNode->AsTSInterfaceDeclaration()->TsType() && isContainingSignatureInherited) { return; } @@ -1636,12 +1874,12 @@ void ETSChecker::ValidateSignatureAccessibility(ETSObjectType *callee, const ir: return; } - const auto [diagnostic, diagnosticParams] = errorInfo; - if (diagnostic == std::nullopt) { + if (!maybeErrorInfo.has_value()) { LogError(diagnostic::SIG_INVISIBLE, {signature->Function()->Id()->Name(), signature}, pos); return; } - LogError(diagnostic.value(), diagnosticParams, pos); + const auto [diagnostic, diagnosticParams] = *maybeErrorInfo; + LogError(diagnostic, diagnosticParams, pos); } void ETSChecker::CheckCapturedVariable(ir::AstNode *const node, varbinder::Variable *const var) @@ -1700,7 +1938,7 @@ void ETSChecker::CheckCapturedVariables() } } -bool ETSChecker::AreOverrideEquivalent(Signature *const s1, Signature *const s2) +bool ETSChecker::AreOverrideCompatible(Signature *const s1, Signature *const s2) { // Two functions, methods or constructors M and N have the same signature if // their names and type parameters (if any) are the same, and their formal parameter @@ -1716,6 +1954,9 @@ bool ETSChecker::AreOverrideEquivalent(Signature *const s1, Signature *const s2) bool ETSChecker::IsReturnTypeSubstitutable(Signature *const s1, Signature *const s2) { + if (s2->HasSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE)) { + s2->Function()->Parent()->Parent()->Check(this); + } auto *const r1 = s1->ReturnType(); auto *const r2 = s2->ReturnType(); @@ -1734,6 +1975,18 @@ bool ETSChecker::IsReturnTypeSubstitutable(Signature *const s1, Signature *const return Relation()->IsIdenticalTo(r2, r1); } + auto const hasThisReturnType = [](Signature *s) { + auto *retAnn = s->Function()->ReturnTypeAnnotation(); + return retAnn != nullptr && retAnn->IsTSThisType(); + }; + // - If S2 is a 'this' type(polymorphic) and S1 must be also 'this' + // If the overridden method (s2) has a 'this' return type, then the overriding method (s1) must also have it. + bool s1HasThisType = hasThisReturnType(s1); + bool s2HasThisType = hasThisReturnType(s2); + if (!s1HasThisType && s2HasThisType) { + return false; + } + // - If R1 is a reference type then R1, adapted to the type parameters of d2 (link to generic methods), is a // subtype of R2. ES2PANDA_ASSERT(IsReferenceType(r1)); @@ -1770,13 +2023,13 @@ ir::MethodDefinition *ETSChecker::CreateMethod(const util::StringView &name, ir: ir::AstNode *body) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *nameId = AllocNode(name, Allocator()); + auto *nameId = ProgramAllocNode(name, ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *scope = VarBinder()->Allocator()->New(Allocator(), paramScope); + auto *scope = ProgramAllocator()->New(ProgramAllocator(), paramScope); // clang-format off // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const func = AllocNode( - Allocator(), ir::ScriptFunction::ScriptFunctionData { + auto *const func = ProgramAllocNode( + ProgramAllocator(), ir::ScriptFunction::ScriptFunctionData { // CC-OFFNXT(G.FMT.05-CPP) project codestyle clang format off body, ir::FunctionSignature(nullptr, std::move(params), returnType), flags, modifiers}); // clang-format on @@ -1797,12 +2050,14 @@ ir::MethodDefinition *ETSChecker::CreateMethod(const util::StringView &name, ir: } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcExpr = AllocNode(func); + auto *funcExpr = ProgramAllocNode(func); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *nameClone = nameId->Clone(Allocator(), nullptr); + auto *nameClone = nameId->Clone(ProgramAllocator(), nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *method = AllocNode(ir::MethodDefinitionKind::METHOD, nameClone, funcExpr, modifiers, - Allocator(), false); + auto *method = util::NodeAllocator::ForceSetParent( + ProgramAllocator(), ir::MethodDefinitionKind::METHOD, nameClone, funcExpr, modifiers, ProgramAllocator(), + false); + return method; } @@ -1815,7 +2070,7 @@ 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(Allocator(), paramOld->Parent())->AsETSParameterExpression(); + auto *const paramNew = paramOld->Clone(ProgramAllocator(), paramOld->Parent())->AsETSParameterExpression(); varbinder::Variable *var = VarBinder()->AddParamDecl(paramNew); Type *paramType = paramOld->Variable()->TsType(); @@ -1881,11 +2136,8 @@ void ETSChecker::MoveTrailingBlockToEnclosingBlockStatement(ir::CallExpression * } using SFunctionData = ir::ScriptFunction::ScriptFunctionData; -void ETSChecker::TransformTraillingLambda(ir::CallExpression *callExpr, Signature *sig) +ir::ScriptFunction *ETSChecker::CreateLambdaFunction(ir::BlockStatement *trailingBlock, Signature *sig) { - auto *trailingBlock = callExpr->TrailingBlock(); - ES2PANDA_ASSERT(trailingBlock != nullptr); - auto *funcParamScope = varbinder::LexicalScope(VarBinder()).GetScope(); auto paramCtx = varbinder::LexicalScope::Enter(VarBinder(), funcParamScope, false); @@ -1903,17 +2155,18 @@ void ETSChecker::TransformTraillingLambda(ir::CallExpression *callExpr, Signatur } } - ArenaVector params(Allocator()->Adapter()); + ArenaVector params(ProgramAllocator()->Adapter()); ir::ScriptFunctionFlags flags = ir::ScriptFunctionFlags::ARROW; bool trailingLambdaHasReceiver = false; if (IsLastParameterLambdaWithReceiver(sig)) { auto *actualLambdaType = sig->Function()->Params().back()->AsETSParameterExpression()->TypeAnnotation()->AsETSFunctionType(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *receiverOfTrailingBlock = actualLambdaType->Params()[0]->Clone(Allocator(), nullptr)->AsExpression(); + auto *receiverOfTrailingBlock = + actualLambdaType->Params()[0]->Clone(ProgramAllocator(), nullptr)->AsExpression(); auto *receiverVar = receiverOfTrailingBlock->AsETSParameterExpression()->Ident()->Variable(); auto *receiverVarClone = - Allocator()->New(receiverVar->Declaration(), receiverVar->Flags()); + ProgramAllocator()->New(receiverVar->Declaration(), receiverVar->Flags()); receiverVarClone->SetTsType(receiverVar->TsType()); receiverVarClone->SetScope(funcParamScope); funcScope->InsertBinding(receiverVarClone->Name(), receiverVarClone); @@ -1922,8 +2175,8 @@ void ETSChecker::TransformTraillingLambda(ir::CallExpression *callExpr, Signatur trailingLambdaHasReceiver = true; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcNode = AllocNode( - Allocator(), + auto *funcNode = ProgramAllocNode( + ProgramAllocator(), SFunctionData {trailingBlock, ir::FunctionSignature(nullptr, std::move(params), nullptr, trailingLambdaHasReceiver), flags}); funcNode->SetScope(funcScope); @@ -1931,14 +2184,25 @@ void ETSChecker::TransformTraillingLambda(ir::CallExpression *callExpr, Signatur funcParamScope->BindNode(funcNode); trailingBlock->SetScope(funcScope); - ReplaceScope(funcNode->Body(), trailingBlock, funcScope); + + return funcNode; +} + +void ETSChecker::TransformTraillingLambda(ir::CallExpression *callExpr, Signature *sig) +{ + auto *trailingBlock = callExpr->TrailingBlock(); + ES2PANDA_ASSERT(trailingBlock != nullptr); + + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto *funcNode = CreateLambdaFunction(trailingBlock, sig); + funcNode->AddFlag(ir::ScriptFunctionFlags::TRAILING_LAMBDA); + ReplaceScope(funcNode->Body(), trailingBlock, funcNode->Scope()); callExpr->SetTrailingBlock(nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *arrowFuncNode = AllocNode(funcNode, Allocator()); + auto *arrowFuncNode = ProgramAllocNode(funcNode, ProgramAllocator()); arrowFuncNode->SetRange(trailingBlock->Range()); arrowFuncNode->SetParent(callExpr); - callExpr->Arguments().push_back(arrowFuncNode); } @@ -1946,22 +2210,22 @@ ArenaVector ETSChecker::ExtendArgumentsWithFakeLamda(ir::CallE { auto funcCtx = varbinder::LexicalScope(VarBinder()); auto *funcScope = funcCtx.GetScope(); - ArenaVector params(Allocator()->Adapter()); + ArenaVector params(ProgramAllocator()->Adapter()); - ArenaVector statements(Allocator()->Adapter()); + ArenaVector statements(ProgramAllocator()->Adapter()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *body = AllocNode(Allocator(), std::move(statements)); + auto *body = ProgramAllocNode(ProgramAllocator(), std::move(statements)); body->SetScope(funcScope); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcNode = AllocNode( - Allocator(), + auto *funcNode = ProgramAllocNode( + ProgramAllocator(), ir::ScriptFunction::ScriptFunctionData {body, ir::FunctionSignature(nullptr, std::move(params), nullptr), ir::ScriptFunctionFlags::ARROW}); funcNode->SetScope(funcScope); funcScope->BindNode(funcNode); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *arrowFuncNode = AllocNode(funcNode, Allocator()); + auto *arrowFuncNode = ProgramAllocNode(funcNode, ProgramAllocator()); arrowFuncNode->SetParent(callExpr); ArenaVector fakeArguments = callExpr->Arguments(); @@ -2077,4 +2341,5 @@ bool ETSChecker::HasSameAssemblySignatures(ETSFunctionType const *const func1, } return false; } + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/function_helpers.h b/ets2panda/checker/ets/function_helpers.h index e44d54ffc032cb575ef34b495c7c944419efd55f..2ed4c6b430b254b5237d17726eaa2200711f2c37 100644 --- a/ets2panda/checker/ets/function_helpers.h +++ b/ets2panda/checker/ets/function_helpers.h @@ -100,6 +100,9 @@ static void InferUntilFail(Signature const *const signature, const ArenaVectorIsArrowFunctionExpression()) { + checker->Relation()->SetNode(arg); + } if (checker->EnhanceSubstitutionForType(sigInfo->typeParams, paramType, argType, substitution)) { inferStatus[ix] = true; @@ -137,14 +140,13 @@ static const Substitution *BuildImplicitSubstitutionForArguments(ETSChecker *che return nullptr; } } - - if (substitution->size() != sigParams.size() && - (signature->Function()->ReturnTypeAnnotation() == nullptr || - !checker->EnhanceSubstitutionForType(sigInfo->typeParams, - signature->Function()->ReturnTypeAnnotation()->TsType(), - signature->ReturnType(), substitution))) { - return nullptr; - } + } + if (substitution->size() != sigParams.size() && + (signature->Function()->ReturnTypeAnnotation() == nullptr || + !checker->EnhanceSubstitutionForType(sigInfo->typeParams, + signature->Function()->ReturnTypeAnnotation()->TsType(), + signature->ReturnType(), substitution))) { + return nullptr; } return substitution; diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 5c4064f4273961eb370d38c53bd69710f47f4808..82a6fdb2c2b478b9eaf620d12aa8df2c5dc60cd6 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -18,13 +18,13 @@ #include "checker/types/globalTypesHolder.h" #include "checker/types/ets/etsTupleType.h" #include "checker/ets/typeRelationContext.h" +#include "checker/ets/typeConverter.h" #include "evaluate/scopedDebugInfoPlugin.h" #include "compiler/lowering/scopesInit/scopesInitPhase.h" #include "compiler/lowering/util.h" -#include "utils/arena_containers.h" -#include "util/ustring.h" namespace ark::es2panda::checker { + varbinder::Variable *ETSChecker::FindVariableInFunctionScope(const util::StringView name) { return Scope() != nullptr ? Scope()->FindInFunctionScope(name, varbinder::ResolveBindingOptions::ALL).variable @@ -128,7 +128,7 @@ void ETSChecker::WrongContextErrorClassifyByType(ir::Identifier *ident) break; default: - LogTypeError({"Identifier '", ident->Name(), "' is used in wrong context."}, ident->Start()); + LogError(diagnostic::ID_WRONG_CTX, {ident->Name()}, ident->Start()); return; } LogError(diagnostic::ID_IN_WRONG_CTX, {identCategoryName.c_str(), ident->Name()}, ident->Start()); @@ -288,7 +288,8 @@ Type *ETSChecker::ResolveIdentifier(ir::Identifier *ident) resolved = ExtraCheckForResolvedError(ident); if (resolved == nullptr) { auto [decl, var] = VarBinder()->NewVarDecl( - ident->Start(), !ident->IsErrorPlaceHolder() ? ident->Name() : compiler::GenName(Allocator()).View()); + ident->Start(), + !ident->IsErrorPlaceHolder() ? ident->Name() : compiler::GenName(ProgramAllocator()).View()); var->SetScope(VarBinder()->GetScope()); ident->SetVariable(var); decl->BindNode(ident); @@ -524,28 +525,41 @@ void ETSChecker::ResolveReturnStatement(checker::Type *funcReturnType, checker:: checker::Type *ETSChecker::CheckArrayElements(ir::ArrayExpression *init) { - ArenaVector elementTypes(Allocator()->Adapter()); - for (auto e : init->AsArrayExpression()->Elements()) { - Type *eType = e->Check(this); - if (eType->HasTypeFlag(TypeFlag::TYPE_ERROR)) { - return eType; + ArenaVector elementTypes(ProgramAllocator()->Adapter()); + for (auto *elementNode : init->AsArrayExpression()->Elements()) { + Type *elementType = elementNode->Check(this); + if (elementType->IsTypeError()) { + return elementType; + } + + if (elementNode->IsSpreadElement() && elementType->IsETSTupleType()) { + for (auto *typeFromTuple : elementType->AsETSTupleType()->GetTupleTypesList()) { + elementTypes.emplace_back(typeFromTuple); + } + + continue; + } + + if (elementNode->IsSpreadElement() && elementType->IsETSArrayType()) { + elementType = elementType->AsETSArrayType()->ElementType(); } - elementTypes.push_back(GetNonConstantType(eType)); + + elementTypes.push_back(GetNonConstantType(elementType)); } if (elementTypes.empty()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return Allocator()->New(GlobalETSObjectType()); + return ProgramAllocator()->New(GlobalETSObjectType()); } auto const isNumeric = [](checker::Type *ct) { return ct->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); }; auto const isChar = [](checker::Type *ct) { return ct->HasTypeFlag(TypeFlag::CHAR); }; - auto const elementType = + auto *const arrayElementType = std::all_of(elementTypes.begin(), elementTypes.end(), isNumeric) ? std::all_of(elementTypes.begin(), elementTypes.end(), isChar) ? GlobalCharType() : GlobalDoubleType() : CreateETSUnionType(std::move(elementTypes)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return Allocator()->New(elementType); + return CreateETSResizableArrayType(arrayElementType); } void ETSChecker::InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::ArrowFunctionExpression *init) @@ -600,37 +614,36 @@ checker::Type *PreferredObjectTypeFromAnnotation(checker::Type *annotationType) } checker::Type *resolvedType = nullptr; + int objectTypeCount = 0; for (auto constituentType : annotationType->AsETSUnionType()->ConstituentTypes()) { if (constituentType->IsETSObjectType()) { - if (resolvedType != nullptr) { - return nullptr; + objectTypeCount++; + if (resolvedType == nullptr) { + resolvedType = constituentType; } - resolvedType = constituentType; } } - return resolvedType; -} - -bool ETSChecker::CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, - checker::Type *annotationType, varbinder::Variable *const bindingVar) -{ - if (typeAnnotation == nullptr) { - if (init->IsArrayExpression()) { - annotationType = CheckArrayElements(init->AsArrayExpression()); - if (bindingVar != nullptr) { - bindingVar->SetTsType(annotationType); - } - } + // If there's exactly one object type, return it + if (objectTypeCount == 1) { + return resolvedType; + } - if (init->IsObjectExpression()) { - LogError(diagnostic::CANNOT_INFER_OBJ_LIT, {ident->Name()}, ident->Start()); - return false; - } + // If there are multiple object types, return the union type itself + // so that our union resolution logic can handle it + if (objectTypeCount > 1) { + return annotationType; } + // If there are no object types, return nullptr + return nullptr; +} + +bool SetPreferredTypeForExpression(ETSChecker *checker, ir::Identifier *ident, ir::TypeNode *typeAnnotation, + ir::Expression *init, checker::Type *annotationType) +{ if (init->IsMemberExpression() && init->AsMemberExpression()->Object()->IsObjectExpression()) { - LogError(diagnostic::MEMBER_OF_OBJECT_LIT, {}, ident->Start()); + checker->LogError(diagnostic::MEMBER_OF_OBJECT_LIT, {}, ident->Start()); } if (annotationType != nullptr && annotationType->HasTypeFlag(TypeFlag::TYPE_ERROR)) { @@ -638,12 +651,12 @@ bool ETSChecker::CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, } if ((init->IsMemberExpression()) && (annotationType != nullptr)) { - SetArrayPreferredTypeForNestedMemberExpressions(init->AsMemberExpression(), annotationType); + checker->SetArrayPreferredTypeForNestedMemberExpressions(init->AsMemberExpression(), annotationType); } if (init->IsArrayExpression() && (annotationType != nullptr) && !annotationType->IsETSDynamicType()) { if (annotationType->IsETSTupleType() && - !IsArrayExprSizeValidForTuple(init->AsArrayExpression(), annotationType->AsETSTupleType())) { + !checker->IsArrayExprSizeValidForTuple(init->AsArrayExpression(), annotationType->AsETSTupleType())) { return false; } @@ -654,14 +667,45 @@ bool ETSChecker::CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, init->AsObjectExpression()->SetPreferredType(PreferredObjectTypeFromAnnotation(annotationType)); } + if (init->IsETSNewArrayInstanceExpression() && annotationType != nullptr) { + init->AsETSNewArrayInstanceExpression()->SetPreferredType(annotationType); + } + if (init->IsETSNewMultiDimArrayInstanceExpression() && annotationType != nullptr) { + init->AsETSNewMultiDimArrayInstanceExpression()->SetPreferredType(annotationType); + } + if (typeAnnotation != nullptr && init->IsArrowFunctionExpression()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - InferAliasLambdaType(typeAnnotation, init->AsArrowFunctionExpression()); + checker->InferAliasLambdaType(typeAnnotation, init->AsArrowFunctionExpression()); } return true; } +bool ETSChecker::CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, + checker::Type *annotationType, varbinder::Variable *const bindingVar) +{ + if (typeAnnotation == nullptr) { + if (init->IsArrayExpression()) { + annotationType = CheckArrayElements(init->AsArrayExpression()); + } else if (init->IsETSNewArrayInstanceExpression()) { + annotationType = init->AsETSNewArrayInstanceExpression()->TypeReference()->GetType(this); + annotationType = CreateETSResizableArrayType(annotationType); + } else if (init->IsETSNewMultiDimArrayInstanceExpression()) { + auto multiArray = init->AsETSNewMultiDimArrayInstanceExpression(); + annotationType = multiArray->TypeReference()->GetType(this); + annotationType = CreateETSMultiDimResizableArrayType(annotationType, multiArray->Dimensions().size()); + } else if (init->IsObjectExpression()) { + LogError(diagnostic::CANNOT_INFER_OBJ_LIT, {ident->Name()}, ident->Start()); + return false; + } + if (bindingVar != nullptr) { + bindingVar->SetTsType(annotationType); + } + } + return SetPreferredTypeForExpression(this, ident, typeAnnotation, init, annotationType); +} + void ETSChecker::CheckEnumType(ir::Expression *init, checker::Type *initType, const util::StringView &varName) { if (initType->IsETSObjectType() && initType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::ENUM) && @@ -747,10 +791,10 @@ static void CheckRecordType(ir::Expression *init, checker::Type *annotationType, checker::AssignmentContext( checker->Relation(), p->Key(), keyType, typeArguments[0], p->Key()->Start(), - {"Type '", keyType, "' is not compatible with type '", typeArguments[0], "' at index 1"}); + util::DiagnosticWithParams {diagnostic::TYPE_MISMATCH_AT_IDX, {keyType, typeArguments[0], size_t(1)}}); checker::AssignmentContext( checker->Relation(), p->Value(), valueType, typeArguments[1], p->Value()->Start(), - {"Type '", valueType, "' is not compatible with type '", typeArguments[1], "' at index 2"}); + util::DiagnosticWithParams {diagnostic::TYPE_MISMATCH_AT_IDX, {valueType, typeArguments[1], size_t(2)}}); } } @@ -802,14 +846,14 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T if (typeAnnotation != nullptr) { CheckRecordType(init, annotationType, this); AssignmentContext(Relation(), init, initType, annotationType, init->Start(), - {"Type '", initType, "' cannot be assigned to type '", annotationType, "'"}); + {{diagnostic::INVALID_ASSIGNMNENT, {initType, annotationType}}}); if (!Relation()->IsTrue()) { return annotationType; } } if (IsOmitConstInit(flags) && ShouldPreserveConstantTypeInVariableDeclaration(annotationType, initType)) { - bindingVar->SetTsType(init->TsType()); + VariableTypeFromInitializer(bindingVar, MaybeUnboxType(annotationType), initType); } } else { CheckEnumType(init, initType, ident->Name()); @@ -822,6 +866,22 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T return FixOptionalVariableType(bindingVar, flags, init); } +void ETSChecker::VariableTypeFromInitializer(varbinder::Variable *variable, Type *annotationType, Type *initType) +{ + if (!initType->IsConstantType()) { + return; + } + + if (!initType->IsETSPrimitiveType()) { + variable->SetTsType(initType); + return; + } + + ES2PANDA_ASSERT(annotationType->IsETSPrimitiveType()); + // We suppose here that all required checks were passed and correct conversion is possible without accuracy loss + variable->SetTsType(TypeConverter::ConvertConstantTypes(initType, annotationType, ProgramAllocator())); +} + static checker::Type *ResolveGetter(checker::ETSChecker *checker, ir::MemberExpression *const expr, ETSFunctionType *funcType) { @@ -846,7 +906,7 @@ static checker::Type *ResolveGetter(checker::ETSChecker *checker, ir::MemberExpr return nullptr; } - checker->ValidateSignatureAccessibility(objType, nullptr, originalGetter, expr->Start()); + checker->ValidateSignatureAccessibility(objType, originalGetter, expr->Start()); return originalGetter->ReturnType(); } @@ -859,7 +919,7 @@ Signature *ETSChecker::FindRelativeExtensionGetter(ir::MemberExpression *const e return sig; } - ArenaVector arguments(Allocator()->Adapter()); + ArenaVector arguments(ProgramAllocator()->Adapter()); arguments.insert(arguments.begin(), expr->Object()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) Signature *signature = ValidateSignatures(funcType->GetExtensionAccessorSigs(), nullptr, arguments, expr->Start(), @@ -881,7 +941,7 @@ Signature *ETSChecker::FindRelativeExtensionSetter(ir::MemberExpression *expr, E } Signature *signature = nullptr; - ArenaVector arguments(Allocator()->Adapter()); + ArenaVector arguments(ProgramAllocator()->Adapter()); arguments.insert(arguments.begin(), expr->Object()); if (expr->Parent()->IsAssignmentExpression()) { arguments.emplace_back(expr->Parent()->AsAssignmentExpression()->Right()); @@ -926,8 +986,8 @@ checker::Type *ETSChecker::GetExtensionAccessorReturnType(ir::MemberExpression * auto signature = FindRelativeExtensionSetter(expr, eAccType); if (signature != nullptr && !expr->Parent()->IsUpdateExpression()) { // for a.m += otherExpr, we need to validateSignature again. - ArenaVector arguments(Allocator()->Adapter()); - ArenaVector candidateSig(Allocator()->Adapter()); + ArenaVector arguments(ProgramAllocator()->Adapter()); + ArenaVector candidateSig(ProgramAllocator()->Adapter()); candidateSig.emplace_back(signature); arguments.emplace_back(expr->Object()); arguments.emplace_back(expr->Parent()->AsAssignmentExpression()->Right()); @@ -1109,6 +1169,11 @@ checker::Type *CheckerContext::GetUnionOfTypes(checker::Type *const type1, check return type1 == nullptr ? type2 : type1; } + const auto never = parent_->AsETSChecker()->GlobalETSNeverType(); + if (type1 == never || type2 == never) { + return type1 == never ? type2 : type1; + } + return parent_->AsETSChecker()->CreateETSUnionType({type1, type2}); } @@ -1145,9 +1210,9 @@ checker::Type *CheckerContext::GetIntersectionOfTypes(checker::Type *const type1 return type1; } - ArenaVector typeSet1(checker->Allocator()->Adapter()); - ArenaVector typeSet2(checker->Allocator()->Adapter()); - ArenaVector intersection(checker->Allocator()->Adapter()); + ArenaVector typeSet1(checker->ProgramAllocator()->Adapter()); + ArenaVector typeSet2(checker->ProgramAllocator()->Adapter()); + ArenaVector intersection(checker->ProgramAllocator()->Adapter()); if (type1->IsETSUnionType()) { typeSet1 = type1->AsETSUnionType()->ConstituentTypes(); @@ -1569,7 +1634,7 @@ std::vector ETSChecker::GetNameForSynteticObjectType(const uti while (std::getline(ss, token, delimiter)) { if (!token.empty()) { - util::UString sV(token, Allocator()); + util::UString sV(token, ProgramAllocator()); syntheticName.emplace_back(sV.View()); } } @@ -1604,9 +1669,10 @@ void ETSChecker::BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleO for (auto [_, var] : bindings) { (void)_; auto [found, aliasedName] = FindSpecifierForModuleObject(importDecl, var->AsLocalVariable()->Name()); - if ((var->AsLocalVariable()->Declaration()->Node()->IsExported() || - var->AsLocalVariable()->Declaration()->Node()->IsExportedType()) && - found) { + if (!var->AsLocalVariable()->Declaration()->Node()->IsValidInCurrentPhase()) { + continue; + } + if ((var->AsLocalVariable()->Declaration()->Node()->IsExported()) && found) { if (!aliasedName.Empty()) { moduleObjType->AddReExportAlias(var->Declaration()->Name(), aliasedName); } @@ -1652,7 +1718,7 @@ void ETSChecker::SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjT // Check imported properties before assigning them to module object if (!program->IsASTChecked()) { // NOTE: helps to avoid endless loop in case of recursive imports that uses all bindings - program->MarkASTAsChecked(); + program->SetASTChecked(); program->Ast()->Check(this); } @@ -1685,7 +1751,7 @@ void ETSChecker::SetrModuleObjectTsType(ir::Identifier *local, checker::ETSObjec Type *ETSChecker::GetReferencedTypeFromBase([[maybe_unused]] Type *baseType, [[maybe_unused]] ir::Expression *name) { - return TypeError(name, "Invalid type reference.", name->Start()); + return TypeError(name, diagnostic::INVALID_TYPE_REF, name->Start()); } Type *ETSChecker::GetReferencedTypeBase(ir::Expression *name) @@ -1716,6 +1782,8 @@ Type *ETSChecker::ResolveReferencedType(varbinder::LocalVariable *refVar, const switch (refVar->Declaration()->Node()->Type()) { case ir::AstNodeType::TS_INTERFACE_DECLARATION: return GetTypeFromInterfaceReference(refVar); + case ir::AstNodeType::TS_ENUM_DECLARATION: + return GlobalTypeError(); case ir::AstNodeType::CLASS_DECLARATION: case ir::AstNodeType::STRUCT_DECLARATION: case ir::AstNodeType::CLASS_DEFINITION: @@ -1737,6 +1805,29 @@ Type *ETSChecker::ResolveReferencedType(varbinder::LocalVariable *refVar, const } } +checker::Type *ETSChecker::GetElementTypeOfArray(checker::Type *type) +{ + if (type->IsTypeError()) { + return GlobalTypeError(); + } + if (type->IsETSArrayType()) { + return type->AsETSArrayType()->ElementType(); + } + + ES2PANDA_ASSERT(type->IsETSResizableArrayType()); + return type->AsETSResizableArrayType()->ElementType(); +} + +const checker::Type *ETSChecker::GetElementTypeOfArray(const checker::Type *type) const +{ + if (type->IsETSArrayType()) { + return type->AsETSArrayType()->ElementType(); + } + + ES2PANDA_ASSERT(type->IsETSResizableArrayType()); + return type->AsETSResizableArrayType()->ElementType(); +} + void ETSChecker::ConcatConstantString(util::UString &target, Type *type) { switch (ETSType(type)) { @@ -1793,7 +1884,7 @@ Type *ETSChecker::HandleStringConcatenation(Type *leftType, Type *rightType) return GlobalETSStringLiteralType(); } - util::UString concatenated(Allocator()); + util::UString concatenated(ProgramAllocator()); ConcatConstantString(concatenated, leftType); ConcatConstantString(concatenated, rightType); @@ -1996,7 +2087,7 @@ std::string ETSChecker::GetStringFromIdentifierValue(checker::Type *caseType) co } case TypeFlag::ETS_OBJECT: { VarBinder()->ThrowError(caseType->AsETSObjectType()->Variable()->Declaration()->Node()->Start(), - "not implemented"); + diagnostic::NOT_IMPLEMENTED); return "error"; } default: { @@ -2005,7 +2096,7 @@ std::string ETSChecker::GetStringFromIdentifierValue(checker::Type *caseType) co } } -bool IsConstantMemberOrIdentifierExpression(ir::Expression *expression) +bool IsConstantMemberOrIdentifierExpression(ir::Expression *expression, bool checkForConst = false) { varbinder::Variable *var = nullptr; if (expression->IsIdentifier()) { @@ -2013,8 +2104,13 @@ bool IsConstantMemberOrIdentifierExpression(ir::Expression *expression) } else if (expression->IsMemberExpression()) { var = expression->AsMemberExpression()->PropVar(); } - return var != nullptr && (var->Declaration()->IsConstDecl() || - (var->Declaration()->IsReadonlyDecl() && var->HasFlag(varbinder::VariableFlags::STATIC))); + + if (var == nullptr) { + return false; + } + bool isConst = checkForConst ? (var->TsType()->HasTypeFlag(checker::TypeFlag::CONSTANT)) : true; + return ((var->Declaration()->IsConstDecl() && isConst) || + (var->Declaration()->IsReadonlyDecl() && var->HasFlag(varbinder::VariableFlags::STATIC))); } static bool IsValidSwitchType(checker::Type *caseType) @@ -2026,7 +2122,7 @@ static bool IsValidSwitchType(checker::Type *caseType) void CheckEnumCaseUnqualified(ETSChecker *checker, ir::Expression const *const caseTest) { if (!caseTest->IsMemberExpression()) { - checker->LogTypeError("Enum switch case must be unqualified name of an enum constant", caseTest->Start()); + checker->LogError(diagnostic::SWITCH_ENUM_NOT_UNQUALIFIED_ENUM_CONST, {}, caseTest->Start()); return; } @@ -2039,12 +2135,12 @@ void CheckEnumCaseUnqualified(ETSChecker *checker, ir::Expression const *const c } else if (baseObject->IsMemberExpression()) { enumName = baseObject->AsMemberExpression()->Property()->AsIdentifier()->Name(); } else { - checker->LogTypeError("Enum switch case must be unqualified name of an enum constant", caseTest->Start()); + checker->LogError(diagnostic::SWITCH_ENUM_NOT_UNQUALIFIED_ENUM_CONST, {}, caseTest->Start()); } auto enumType = caseTest->TsType()->AsETSObjectType(); if (enumName != enumType->Name()) { - checker->LogTypeError("Enum switch case must be unqualified name of an enum constant", caseTest->Start()); + checker->LogError(diagnostic::SWITCH_ENUM_NOT_UNQUALIFIED_ENUM_CONST, {}, caseTest->Start()); } } @@ -2171,7 +2267,7 @@ void ETSChecker::CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expr { currentCase->Check(this); - if (!IsConstantMemberOrIdentifierExpression(currentCase)) { + if (!IsConstantMemberOrIdentifierExpression(currentCase, true)) { return; } @@ -2270,7 +2366,7 @@ util::StringView ETSChecker::GetHashFromTypeArguments(const ArenaVector ss << it << compiler::Signatures::MANGLE_SEPARATOR; } - return util::UString(ss.str(), Allocator()).View(); + return util::UString(ss.str(), ProgramAllocator()).View(); } util::StringView ETSChecker::GetHashFromSubstitution(const Substitution *substitution, const bool extensionFuncFlag) @@ -2296,7 +2392,7 @@ util::StringView ETSChecker::GetHashFromSubstitution(const Substitution *substit if (extensionFuncFlag) { ss << "extensionFunctionType;"; } - return util::UString(ss.str(), Allocator()).View(); + return util::UString(ss.str(), ProgramAllocator()).View(); } util::StringView ETSChecker::GetHashFromFunctionType(ir::ETSFunctionType *type) @@ -2329,7 +2425,7 @@ util::StringView ETSChecker::GetHashFromFunctionType(ir::ETSFunctionType *type) ss << "rethrows;"; } - return util::UString(ss.str(), Allocator()).View(); + return util::UString(ss.str(), ProgramAllocator()).View(); } ETSObjectType *ETSChecker::GetOriginalBaseType(Type *const object) @@ -2478,12 +2574,12 @@ void ETSChecker::ModifyPreferredType(ir::ArrayExpression *const arrayExpr, Type } } -void ETSChecker::TryInferTypeForLambdaTypeAlias(ir::AssignmentExpression *expr, ETSFunctionType *calleeType) +void ETSChecker::TryInferTypeForLambdaTypeAlias(ir::ArrowFunctionExpression *expr, ETSFunctionType *calleeType) { - ES2PANDA_ASSERT(expr->Right()->IsArrowFunctionExpression()); + ES2PANDA_ASSERT(expr->IsArrowFunctionExpression()); ES2PANDA_ASSERT(calleeType->IsETSArrowType()); - ir::ScriptFunction *const lambda = expr->Right()->AsArrowFunctionExpression()->Function(); + ir::ScriptFunction *const lambda = expr->AsArrowFunctionExpression()->Function(); auto *signature = calleeType->CallSignaturesOfMethodOrArrow()[0]; if (signature->Params().size() >= lambda->Params().size() && NeedTypeInference(lambda)) { @@ -2506,7 +2602,7 @@ bool ETSChecker::IsInLocalClass(const ir::AstNode *node) const ir::Expression *ETSChecker::GenerateImplicitInstantiateArg(const std::string &className) { std::string implicitInstantiateArgument = "()=>{return new " + className + "()}"; - parser::Program program(Allocator(), VarBinder()); + parser::Program program(ProgramAllocator(), VarBinder()); auto parser = parser::ETSParser(&program, nullptr, DiagnosticEngine()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *argExpr = parser.CreateExpression(implicitInstantiateArgument); @@ -2522,18 +2618,27 @@ ir::Expression *ETSChecker::GenerateImplicitInstantiateArg(const std::string &cl return argExpr; } +static void ReInitScopesForTypeAnnotation(ETSChecker *checker, ir::TypeNode *typeAnno, varbinder::Scope *paramScope) +{ + if (typeAnno != nullptr) { + compiler::ClearTypesVariablesAndScopes(typeAnno); + auto classCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), paramScope); + compiler::InitScopesPhaseETS::RunExternalNode(typeAnno, checker->VarBinder()); + } +} + ir::ClassProperty *ETSChecker::ClassPropToImplementationProp(ir::ClassProperty *classProp, varbinder::ClassScope *scope) { classProp->Key()->AsIdentifier()->SetName( util::UString(std::string(compiler::Signatures::PROPERTY) + classProp->Key()->AsIdentifier()->Name().Mutf8(), - Allocator()) + ProgramAllocator()) .View()); classProp->AddModifier(ir::ModifierFlags::PRIVATE); - auto *fieldDecl = Allocator()->New(classProp->Key()->AsIdentifier()->Name()); + auto *fieldDecl = ProgramAllocator()->New(classProp->Key()->AsIdentifier()->Name()); fieldDecl->BindNode(classProp); - auto fieldVar = scope->InstanceFieldScope()->AddDecl(Allocator(), fieldDecl, ScriptExtension::ETS); + auto fieldVar = scope->InstanceFieldScope()->AddDecl(ProgramAllocator(), fieldDecl, ScriptExtension::ETS); fieldVar->AddFlag(varbinder::VariableFlags::PROPERTY); fieldVar->SetScope(scope->InstanceFieldScope()); @@ -2541,11 +2646,13 @@ ir::ClassProperty *ETSChecker::ClassPropToImplementationProp(ir::ClassProperty * fieldVar->SetTsType(classProp->TsType()); auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), scope); + ReInitScopesForTypeAnnotation(this, classProp->TypeAnnotation(), scope); compiler::InitScopesPhaseETS::RunExternalNode(classProp->Value(), VarBinder()); return classProp; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, ArenaVector ¶ms, ir::ClassProperty *const field, varbinder::FunctionParamScope *paramScope, bool isSetter) @@ -2555,18 +2662,20 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A ir::Expression *baseExpression; if ((field->Modifiers() & ir::ModifierFlags::SUPER_OWNER) != 0U) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - baseExpression = Allocator()->New(); + baseExpression = ProgramAllocator()->New(); } else { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - baseExpression = Allocator()->New(); + baseExpression = ProgramAllocator()->New(); } baseExpression->SetParent(classDef); baseExpression->SetTsType(classDef->TsType()); auto *memberExpression = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(baseExpression, field->Key()->AsIdentifier()->Clone(Allocator(), nullptr), - ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + ProgramAllocNode(baseExpression, + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + field->Key()->AsIdentifier()->Clone(ProgramAllocator(), nullptr), + ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); memberExpression->SetTsType(field->TsType()); memberExpression->SetPropVar(field->Key()->Variable()->AsLocalVariable()); memberExpression->SetRange(classDef->Range()); @@ -2576,46 +2685,48 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A if (!isSetter) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - stmts.push_back(AllocNode(memberExpression)); + stmts.push_back(ProgramAllocNode(memberExpression)); return; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *paramIdent = field->Key()->AsIdentifier()->Clone(Allocator(), nullptr); + auto *paramIdent = field->Key()->AsIdentifier()->Clone(ProgramAllocator(), nullptr); if (field->TypeAnnotation() != nullptr) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const typeAnnotation = field->TypeAnnotation()->Clone(Allocator(), paramIdent); + auto *const typeAnnotation = field->TypeAnnotation()->Clone(ProgramAllocator(), paramIdent); paramIdent->SetTsTypeAnnotation(typeAnnotation); + ReInitScopesForTypeAnnotation(this, typeAnnotation, paramScope); } else { paramIdent->SetTsType(field->TsType()); } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *paramExpression = AllocNode(paramIdent, false, Allocator()); + auto *paramExpression = ProgramAllocNode(paramIdent, false, ProgramAllocator()); paramExpression->SetRange(paramIdent->Range()); - auto [paramVar, node] = paramScope->AddParamDecl(Allocator(), paramExpression); + auto [paramVar, node] = paramScope->AddParamDecl(ProgramAllocator(), VarBinder(), paramExpression); if (node != nullptr) { - VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name()); + VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name(), paramVar->Declaration()->Type()); } + paramIdent->SetVariable(paramVar); paramExpression->SetVariable(paramVar); params.push_back(paramExpression); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto ident = AllocNode(paramExpression->Ident()->Name(), Allocator()); + auto ident = ProgramAllocNode(paramExpression->Ident()->Name(), ProgramAllocator()); ident->SetVariable(paramExpression->Variable()); auto *assignmentExpression = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(memberExpression, ident, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + ProgramAllocNode(memberExpression, ident, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); ident->SetParent(assignmentExpression); assignmentExpression->SetTsType(paramVar->TsType()); assignmentExpression->SetRange({field->Start(), field->End()}); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - stmts.push_back(AllocNode(assignmentExpression)); + stmts.push_back(ProgramAllocNode(assignmentExpression)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - stmts.push_back(Allocator()->New(nullptr)); + stmts.push_back(ProgramAllocator()->New(nullptr)); } static ir::BlockStatement *GenGetterSetterBodyHelper(ETSChecker *checker, ArenaVector &stmts, @@ -2625,60 +2736,75 @@ static ir::BlockStatement *GenGetterSetterBodyHelper(ETSChecker *checker, ArenaV if (property->IsDeclare()) { return nullptr; } - auto *body = checker->AllocNode(checker->Allocator(), std::move(stmts)); + auto *body = checker->ProgramAllocNode(checker->ProgramAllocator(), std::move(stmts)); body->SetScope(functionScope); return body; } -ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty *const property, - ir::ClassProperty *const field, - varbinder::ClassScope *classScope, bool isSetter, - ETSChecker *checker) +// Need to avoid codecheck +static std::tuple GenGetterSetterScriptFunc( + ir::ClassProperty *const property, ir::ClassProperty *const field, varbinder::ClassScope *classScope, bool isSetter, + ETSChecker *checker) { - auto *paramScope = checker->Allocator()->New(checker->Allocator(), classScope); - auto *functionScope = checker->Allocator()->New(checker->Allocator(), paramScope); + auto *paramScope = + checker->ProgramAllocator()->New(checker->ProgramAllocator(), classScope); + auto *functionScope = + checker->ProgramAllocator()->New(checker->ProgramAllocator(), paramScope); functionScope->BindParamScope(paramScope); paramScope->BindFunctionScope(functionScope); - ArenaVector params(checker->Allocator()->Adapter()); - ArenaVector stmts(checker->Allocator()->Adapter()); + ArenaVector params(checker->ProgramAllocator()->Adapter()); + ArenaVector stmts(checker->ProgramAllocator()->Adapter()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) checker->GenerateGetterSetterBody(stmts, params, field, paramScope, isSetter); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto funcFlags = isSetter ? ir::ScriptFunctionFlags::SETTER : ir::ScriptFunctionFlags::GETTER | ir::ScriptFunctionFlags::HAS_RETURN; - auto *const returnTypeAnn = isSetter || field->TypeAnnotation() == nullptr - ? nullptr - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - : field->TypeAnnotation()->Clone(checker->Allocator(), nullptr); + auto *returnTypeAnn = isSetter || field->TypeAnnotation() == nullptr + ? nullptr + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + : field->TypeAnnotation()->Clone(checker->ProgramAllocator(), nullptr); + ReInitScopesForTypeAnnotation(checker, returnTypeAnn, paramScope); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ir::ModifierFlags modifierFlag = (ir::ModifierFlags::PUBLIC | static_cast(property->Modifiers() & ir::ModifierFlags::DECLARE) | (isSetter ? ir::ModifierFlags::SETTER : ir::ModifierFlags::GETTER)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *func = checker->AllocNode( - checker->Allocator(), + auto *func = checker->ProgramAllocNode( + checker->ProgramAllocator(), // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ir::ScriptFunction::ScriptFunctionData {GenGetterSetterBodyHelper(checker, stmts, property, functionScope), ir::FunctionSignature(nullptr, std::move(params), returnTypeAnn), funcFlags, modifierFlag}); + paramScope->BindNode(func); + return {func, functionScope, modifierFlag}; +} +ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty *const property, + ir::ClassProperty *const field, + varbinder::ClassScope *classScope, bool isSetter, + ETSChecker *checker) +{ + auto [func, functionScope, modifierFlag] = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + GenGetterSetterScriptFunc(property, field, classScope, isSetter, checker); func->SetRange(field->Range()); func->SetScope(functionScope); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *methodIdent = property->Key()->AsIdentifier()->Clone(checker->Allocator(), nullptr); + auto *methodIdent = property->Key()->AsIdentifier()->Clone(checker->ProgramAllocator(), nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcExpr = checker->AllocNode(func); + auto *funcExpr = checker->ProgramAllocNode(func); funcExpr->SetRange(func->Range()); func->AddFlag(ir::ScriptFunctionFlags::METHOD); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *method = checker->AllocNode(ir::MethodDefinitionKind::METHOD, methodIdent, funcExpr, - modifierFlag, checker->Allocator(), false); - auto *decl = checker->Allocator()->New(checker->Allocator(), - property->Key()->AsIdentifier()->Name(), method); - auto *var = checker->Allocator()->New(decl, varbinder::VariableFlags::VAR); + auto *method = checker->ProgramAllocNode( + isSetter ? ir::MethodDefinitionKind::SET : ir::MethodDefinitionKind::GET, methodIdent, funcExpr, modifierFlag, + checker->ProgramAllocator(), false); + auto *decl = checker->ProgramAllocator()->New( + checker->ProgramAllocator(), property->Key()->AsIdentifier()->Name(), method); + auto *var = checker->ProgramAllocator()->New(decl, varbinder::VariableFlags::VAR); var->AddFlag(varbinder::VariableFlags::METHOD); methodIdent->SetVariable(var); @@ -2686,16 +2812,16 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty method->Id()->SetMutator(); method->SetRange(field->Range()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - method->Function()->SetIdent(method->Id()->Clone(checker->Allocator(), nullptr)); + method->Function()->SetIdent(method->Id()->Clone(checker->ProgramAllocator(), nullptr)); method->Function()->AddModifier(method->Modifiers()); method->SetVariable(var); method->SetParent(field->Parent()); - paramScope->BindNode(func); functionScope->BindNode(func); auto classCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), classScope); checker->VarBinder()->AsETSBinder()->ResolveMethodDefinition(method); + method->Function()->ClearFlag(ir::ScriptFunctionFlags::EXTERNAL); functionScope->BindName(classScope->Node()->AsClassDefinition()->InternalName()); method->Check(checker); @@ -2712,9 +2838,9 @@ ir::ClassProperty *GetImplementationClassProp(ETSChecker *checker, ir::ClassProp auto *const scope = checker->Scope()->AsClassScope(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *const classProp = checker->ClassPropToImplementationProp( - interfaceProp->Clone(checker->Allocator(), originalProp->Parent()), scope); + interfaceProp->Clone(checker->ProgramAllocator(), originalProp->Parent()), scope); classType->AddProperty(classProp->Key()->Variable()->AsLocalVariable()); - classDef->Body().push_back(classProp); + classDef->EmplaceBody(classProp); return classProp; } @@ -2728,8 +2854,9 @@ ir::ClassProperty *GetImplementationClassProp(ETSChecker *checker, ir::ClassProp return classProp; } -static void SetupGetterSetterFlags(ir::ClassProperty *originalProp, ETSObjectType *classType, - ir::MethodDefinition *getter, ir::MethodDefinition *setter, const bool inExternal) +void ETSChecker::SetupGetterSetterFlags(ir::ClassProperty *originalProp, ETSObjectType *classType, + ir::MethodDefinition *getter, ir::MethodDefinition *setter, + const bool inExternal) { auto *const classDef = classType->GetDeclNode()->AsClassDefinition(); for (auto &method : {getter, setter}) { @@ -2754,7 +2881,7 @@ static void SetupGetterSetterFlags(ir::ClassProperty *originalProp, ETSObjectTyp method->AddModifier(ir::ModifierFlags::DECLARE); method->Function()->AddModifier(ir::ModifierFlags::DECLARE); } - + this->CheckOverride(method->Function()->Signature()); method->SetParent(classDef); classType->AddProperty(method->Variable()->AsLocalVariable()); } @@ -2764,7 +2891,7 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin { auto *const classDef = classType->GetDeclNode()->AsClassDefinition(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *interfaceProp = originalProp->Clone(Allocator(), originalProp->Parent()); + auto *interfaceProp = originalProp->Clone(ProgramAllocator(), originalProp->Parent()); interfaceProp->ClearModifier(ir::ModifierFlags::GETTER_SETTER); auto *const scope = Scope()->AsClassScope(); @@ -2772,6 +2899,7 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin interfaceProp->SetRange(originalProp->Range()); auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), scope); + ReInitScopesForTypeAnnotation(this, interfaceProp->TypeAnnotation(), scope); compiler::InitScopesPhaseETS::RunExternalNode(interfaceProp->Value(), VarBinder()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -2779,7 +2907,7 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ir::MethodDefinition *getter = GenerateDefaultGetterSetter(interfaceProp, classProp, scope, false, this); - classDef->Body().push_back(getter); + classDef->EmplaceBody(getter); const auto &name = getter->Key()->AsIdentifier()->Name(); @@ -2790,9 +2918,9 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin : nullptr; auto *const methodScope = scope->InstanceMethodScope(); - auto *const decl = Allocator()->New(Allocator(), name, getter); + auto *const decl = ProgramAllocator()->New(ProgramAllocator(), name, getter); - auto *var = methodScope->AddDecl(Allocator(), decl, ScriptExtension::ETS); + auto *var = methodScope->AddDecl(ProgramAllocator(), decl, ScriptExtension::ETS); if (var == nullptr) { auto *const prevDecl = methodScope->FindDecl(name); for (const auto &method : {getter, setter}) { @@ -2815,6 +2943,7 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin } } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic bool ETSChecker::TryTransformingToStaticInvoke(ir::Identifier *const ident, const Type *resolvedType) { ES2PANDA_ASSERT(ident->Parent()->IsCallExpression()); @@ -2845,9 +2974,9 @@ bool ETSChecker::TryTransformingToStaticInvoke(ir::Identifier *const ident, cons return true; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *classId = AllocNode(className, Allocator()); + auto *classId = ProgramAllocNode(className, ProgramAllocator()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *methodId = AllocNode(propertyName, Allocator()); + auto *methodId = ProgramAllocNode(propertyName, ProgramAllocator()); if (propertyName == compiler::Signatures::STATIC_INSTANTIATE_METHOD) { methodId->SetVariable(instantiateMethod); } else if (propertyName == compiler::Signatures::STATIC_INVOKE_METHOD) { @@ -2856,7 +2985,8 @@ bool ETSChecker::TryTransformingToStaticInvoke(ir::Identifier *const ident, cons auto *transformedCallee = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + ProgramAllocNode(classId, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, + false); classId->SetRange(ident->Range()); methodId->SetRange(ident->Range()); @@ -2917,15 +3047,16 @@ Type *ETSChecker::GetImportSpecifierObjectType(ir::ETSImportDeclaration *importD auto const internalName = util::UString( moduleName.Mutf8().append(compiler::Signatures::METHOD_SEPARATOR).append(compiler::Signatures::ETS_GLOBAL), - Allocator()) + ProgramAllocator()) .View(); - auto *moduleObjectType = Allocator()->New( - Allocator(), moduleName, internalName, std::make_tuple(ident, checker::ETSObjectFlags::CLASS, Relation())); + auto *moduleObjectType = + ProgramAllocator()->New(ProgramAllocator(), moduleName, internalName, + std::make_tuple(ident, checker::ETSObjectFlags::CLASS, Relation())); - auto *rootDecl = Allocator()->New(moduleName); + auto *rootDecl = ProgramAllocator()->New(moduleName); varbinder::LocalVariable *rootVar = - Allocator()->New(rootDecl, varbinder::VariableFlags::NONE); + ProgramAllocator()->New(rootDecl, varbinder::VariableFlags::NONE); rootVar->SetTsType(moduleObjectType); ImportNamespaceObjectTypeAddReExportType(importDecl, moduleObjectType, ident); @@ -2962,11 +3093,12 @@ ir::CallExpression *ETSChecker::CreateExtensionAccessorCall(ETSChecker *checker, ir::Expression *callExpr = nullptr; if (expr->Object()->IsETSNewClassInstanceExpression()) { args.insert(args.begin(), expr->Object()); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - callExpr = checker->AllocNode(expr->Property(), std::move(args), nullptr, false, false); + callExpr = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + checker->ProgramAllocNode(expr->Property(), std::move(args), nullptr, false, false); } else { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - callExpr = checker->AllocNode(expr, std::move(args), nullptr, false, false); + callExpr = checker->ProgramAllocNode(expr, std::move(args), nullptr, false, false); } callExpr->SetRange(expr->Range()); return callExpr->AsCallExpression(); @@ -3025,4 +3157,33 @@ void ETSChecker::SetPreferredTypeIfPossible(ir::Expression *const expr, Type *co } } +checker::ETSFunctionType *ETSChecker::IntersectSignatureSets(const checker::ETSFunctionType *left, + const checker::ETSFunctionType *right) +{ + auto sameSig = [this](checker::Signature *leftSig, checker::Signature *rightSig) { + auto relation = Relation(); + if ((leftSig->Flags() & ~checker::SignatureFlags::FINAL) != + (rightSig->Flags() & ~checker::SignatureFlags::FINAL)) { + return false; + } + return relation->SignatureIsIdenticalTo(rightSig, leftSig); + }; + + if (left->CallSignatures().size() > right->CallSignatures().size()) { + std::swap(left, right); + } + + ArenaVector intersection {ProgramAllocator()->Adapter()}; + + for (const auto sig : left->CallSignatures()) { + auto found = right->FindSpecificSignature( + [sig, &sameSig](checker::Signature *otherSig) { return sameSig(sig, otherSig); }); + if (found != nullptr) { + intersection.push_back(found); + } + } + + return CreateETSMethodType(left->Name(), std::move(intersection)); +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/narrowingConverter.h b/ets2panda/checker/ets/narrowingConverter.h index 19f9e141382ff96c4fce4f6e28d068221d4b241e..f42051d88b9042d717680e29e899a2d0f472c87b 100644 --- a/ets2panda/checker/ets/narrowingConverter.h +++ b/ets2panda/checker/ets/narrowingConverter.h @@ -16,8 +16,8 @@ #ifndef ES2PANDA_COMPILER_CHECKER_ETS_NARROWING_CONVERTER_H #define ES2PANDA_COMPILER_CHECKER_ETS_NARROWING_CONVERTER_H -#include "checker/ets/typeConverter.h" #include "checker/ETSchecker.h" +#include "checker/ets/typeConverter.h" #include "util/helpers.h" namespace ark::es2panda::checker { @@ -185,9 +185,6 @@ private: } if (Relation()->InCastingContext() || util::Helpers::IsTargetFitInSourceRange(value)) { - auto narrowedValue = CalculateNarrowedValue(Target(), Source(), value); - TargetType *newType = Checker()->Allocator()->New(narrowedValue); - Relation()->GetNode()->SetTsType(newType); Relation()->Result(true); return; } diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index a4214d466df8dc76727bea3977565e4a63970f96..cbf729d09f454287d1086ccf8e384f6ecc21ea42 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -13,12 +13,14 @@ * limitations under the License. */ +#include #include "checker/ETSchecker.h" #include "checker/ets/typeRelationContext.h" #include "checker/types/ets/etsDynamicType.h" #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsTupleType.h" #include "checker/types/ets/etsPartialTypeParameter.h" +#include "compiler/lowering/phase.h" #include "ir/base/classDefinition.h" #include "ir/base/classElement.h" #include "ir/base/classProperty.h" @@ -46,13 +48,14 @@ #include "varbinder/variableFlags.h" #include "generated/signatures.h" #include "generated/diagnostic.h" +#include "util/helpers.h" namespace ark::es2panda::checker { static bool CheckGetterSetterDecl(varbinder::LocalVariable const *child, varbinder::LocalVariable const *parent) { auto readonlyCheck = [](varbinder::LocalVariable const *var, bool isParent, bool isReadonly) { - if (!var->TsType()->IsETSFunctionType() || var->TsType()->IsETSArrowType()) { + if (!var->TsType()->IsETSMethodType()) { return true; } @@ -82,7 +85,7 @@ static bool CheckGetterSetterDecl(varbinder::LocalVariable const *child, varbind static bool CheckFunctionDecl(varbinder::LocalVariable *child, varbinder::LocalVariable *parent) { ES2PANDA_ASSERT(child->Declaration()->Type() == parent->Declaration()->Type()); - if (!child->TsType()->IsETSFunctionType()) { + if (!child->TsType()->IsETSMethodType()) { return true; } @@ -140,7 +143,7 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) } auto *classDef = type->GetDeclNode()->AsClassDefinition(); - TypeStackElement tse(this, type, {"Cyclic inheritance involving ", type->Name(), "."}, classDef->Ident()->Start()); + TypeStackElement tse(this, type, {{diagnostic::CYCLIC_INHERITANCE, {type->Name()}}}, classDef->Ident()->Start()); if (tse.HasTypeError()) { type->AddObjectFlag(ETSObjectFlags::RESOLVED_SUPER); return false; @@ -230,7 +233,7 @@ void ETSChecker::GetInterfacesOfInterface(ETSObjectType *type) auto *declNode = type->GetDeclNode()->AsTSInterfaceDeclaration(); - TypeStackElement tse(this, type, {"Cyclic inheritance involving ", type->Name(), "."}, declNode->Id()->Start()); + TypeStackElement tse(this, type, {{diagnostic::CYCLIC_INHERITANCE, {type->Name()}}}, declNode->Id()->Start()); if (tse.HasTypeError()) { type->AddObjectFlag(ETSObjectFlags::RESOLVED_INTERFACES); declNode->SetTsType(GlobalTypeError()); @@ -261,7 +264,7 @@ std::pair, bool> ETSChecker::CreateUnconstrainedTypeParamete ir::TSTypeParameterDeclaration const *typeParams) { bool ok = true; - ArenaVector result {Allocator()->Adapter()}; + ArenaVector result {ProgramAllocator()->Adapter()}; checker::ScopeContext scopeCtx(this, typeParams->Scope()); // Note: we have to run pure check loop first to avoid endless loop because of possible circular dependencies @@ -310,14 +313,18 @@ bool ETSChecker::CheckDefaultTypeParameter(const ir::TSTypeParameter *param, Typ if (defaultTypePart->Name()->IsTSQualifiedName()) { defaultTypePart->Name()->Check(this); } + if (IsFixedArray(defaultTypePart)) { + defaultTypePart->Check(this); + } auto *const variable = defaultTypePart->GetIdent()->Variable(); - ES2PANDA_ASSERT(variable != nullptr); - if (variable->TsType() == nullptr && (variable->Flags() & varbinder::VariableFlags::TYPE_PARAMETER) != 0U && + auto defaultType = variable == nullptr ? defaultTypePart->TsType() : variable->TsType(); + if (defaultType == nullptr && variable != nullptr && + (variable->Flags() & varbinder::VariableFlags::TYPE_PARAMETER) != 0U && typeParameterDecls.count(variable) == 0U) { LogError(diagnostic::TYPE_PARAM_USE_BEFORE_DEFINE, {defaultTypePart->Name()->AsIdentifier()->Name().Utf8()}, node->Start()); ok = false; - } else if (variable->TsType() != nullptr && variable->TsType()->IsTypeError()) { + } else if (defaultType != nullptr && defaultType->IsTypeError()) { ok = false; } } @@ -475,8 +482,11 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) if (classDef->IsAbstract()) { classType->AddObjectFlag(checker::ETSObjectFlags::ABSTRACT); } - } else { + } else if (var->TsType()->IsETSObjectType()) { classType = var->TsType()->AsETSObjectType(); + } else { + ES2PANDA_ASSERT(IsAnyError()); + return GlobalTypeError(); } classDef->SetTsType(classType); @@ -639,9 +649,9 @@ void ETSChecker::ResolveDeclaredMembersOfObject(const Type *type) auto savedContext = checker::SavedCheckerContext(this, status, objectType); checker::ScopeContext scopeCtx(this, scope); + ResolveDeclaredDeclsOfObject(this, objectType, scope->AsClassScope()); ResolveDeclaredFieldsOfObject(this, objectType, scope->AsClassScope()); ResolveDeclaredMethodsOfObject(this, objectType, scope->AsClassScope()); - ResolveDeclaredDeclsOfObject(this, objectType, scope->AsClassScope()); } bool ETSChecker::HasETSFunctionType(ir::TypeNode *typeAnnotation) @@ -710,15 +720,15 @@ void ETSChecker::CreateFunctionTypesFromAbstracts(const std::vector if (found != nullptr) { found->AddCallSignature(it); } else { - target->push_back(CreateETSMethodType(name, {{it}, Allocator()->Adapter()})); + target->push_back(CreateETSMethodType(name, {{it}, ProgramAllocator()->Adapter()})); } } } void ETSChecker::ComputeAbstractsFromInterface(ETSObjectType *interfaceType) { - auto cached = cachedComputedAbstracts_.find(interfaceType); - if (cached != cachedComputedAbstracts_.end()) { + auto cached = GetCachedComputedAbstracts()->find(interfaceType); + if (cached != GetCachedComputedAbstracts()->end()) { return; } @@ -726,13 +736,13 @@ void ETSChecker::ComputeAbstractsFromInterface(ETSObjectType *interfaceType) ComputeAbstractsFromInterface(it); } - ArenaVector merged(Allocator()->Adapter()); + ArenaVector merged(ProgramAllocator()->Adapter()); CreateFunctionTypesFromAbstracts(CollectAbstractSignaturesFromObject(interfaceType), &merged); - ArenaUnorderedSet abstractInheritanceTarget(Allocator()->Adapter()); + ArenaUnorderedSet abstractInheritanceTarget(ProgramAllocator()->Adapter()); for (auto *interface : interfaceType->Interfaces()) { - auto found = cachedComputedAbstracts_.find(interface); - ES2PANDA_ASSERT(found != cachedComputedAbstracts_.end()); + auto found = GetCachedComputedAbstracts()->find(interface); + ES2PANDA_ASSERT(found != GetCachedComputedAbstracts()->end()); if (!abstractInheritanceTarget.insert(found->first).second) { continue; @@ -745,18 +755,18 @@ void ETSChecker::ComputeAbstractsFromInterface(ETSObjectType *interfaceType) } } - cachedComputedAbstracts_.insert({interfaceType, {merged, abstractInheritanceTarget}}); + GetCachedComputedAbstracts()->insert({interfaceType, {merged, abstractInheritanceTarget}}); } ArenaVector &ETSChecker::GetAbstractsForClass(ETSObjectType *classType) { - ArenaVector merged(Allocator()->Adapter()); + ArenaVector merged(ProgramAllocator()->Adapter()); CreateFunctionTypesFromAbstracts(CollectAbstractSignaturesFromObject(classType), &merged); - ArenaUnorderedSet abstractInheritanceTarget(Allocator()->Adapter()); + ArenaUnorderedSet abstractInheritanceTarget(ProgramAllocator()->Adapter()); if (classType->SuperType() != nullptr) { - auto base = cachedComputedAbstracts_.find(classType->SuperType()); - ES2PANDA_ASSERT(base != cachedComputedAbstracts_.end()); + auto base = GetCachedComputedAbstracts()->find(classType->SuperType()); + ES2PANDA_ASSERT(base != GetCachedComputedAbstracts()->end()); MergeComputedAbstracts(merged, base->second.first); abstractInheritanceTarget.insert(base->first); @@ -767,8 +777,8 @@ ArenaVector &ETSChecker::GetAbstractsForClass(ETSObjectType * for (auto *it : classType->Interfaces()) { ComputeAbstractsFromInterface(it); - auto found = cachedComputedAbstracts_.find(it); - ES2PANDA_ASSERT(found != cachedComputedAbstracts_.end()); + auto found = GetCachedComputedAbstracts()->find(it); + ES2PANDA_ASSERT(found != GetCachedComputedAbstracts()->end()); if (!abstractInheritanceTarget.insert(found->first).second) { continue; @@ -781,23 +791,28 @@ ArenaVector &ETSChecker::GetAbstractsForClass(ETSObjectType * } } - return cachedComputedAbstracts_.insert({classType, {merged, abstractInheritanceTarget}}).first->second.first; + return GetCachedComputedAbstracts()->insert({classType, {merged, abstractInheritanceTarget}}).first->second.first; } -static bool DoObjectImplementInterface(const ETSObjectType *interfaceType, const ETSObjectType *target) +[[maybe_unused]] static bool DoObjectImplementInterface(const ETSObjectType *interfaceType, const ETSObjectType *target, + const ETSChecker *checker) { - return std::any_of(interfaceType->Interfaces().begin(), interfaceType->Interfaces().end(), - [&target](auto *it) { return it == target || DoObjectImplementInterface(it, target); }); + auto &interfaces = interfaceType->Interfaces(); + return std::any_of(interfaces.begin(), interfaces.end(), [&target, checker](auto *it) { + return it->IsSameBasedGeneric(checker->Relation(), target) || DoObjectImplementInterface(it, target, checker); + }); } static bool CheckIfInterfaceCanBeFoundOnDifferentPaths(const ETSObjectType *classType, - const ETSObjectType *interfaceType) + const ETSObjectType *interfaceType, const ETSChecker *checker) { return std::count_if(classType->Interfaces().begin(), classType->Interfaces().end(), - [&interfaceType](auto *it) { return DoObjectImplementInterface(it, interfaceType); }) == 1; + [&interfaceType, checker](auto *it) { + return DoObjectImplementInterface(it, interfaceType, checker); + }) == 1; } -static void GetInterfacesOfClass(ETSObjectType *type, ArenaVector &interfaces) +void ETSChecker::GetInterfacesOfClass(ETSObjectType *type, ArenaVector &interfaces) { for (auto &classInterface : type->Interfaces()) { if (std::find(interfaces.begin(), interfaces.end(), classInterface) == interfaces.end()) { @@ -807,51 +822,85 @@ static void GetInterfacesOfClass(ETSObjectType *type, ArenaVectorSignature(), sig) && func->IsStatic() == sig->Function()->IsStatic()) { - if (CheckIfInterfaceCanBeFoundOnDifferentPaths(classType, func->Signature()->Owner()) && - (Relation()->IsSupertypeOf(func->Signature()->Owner(), sig->Owner()) || - Relation()->IsSupertypeOf(sig->Owner(), func->Signature()->Owner()))) { + bool throwError = false; + if (AreOverrideCompatible(sig, sigFunc) && sigFunc->Function()->IsStatic() == sig->Function()->IsStatic()) { + SavedTypeRelationFlagsContext const savedFlags(Relation(), Relation()->GetTypeRelationFlags() | + TypeRelationFlag::IGNORE_TYPE_PARAMETERS); + if (CheckIfInterfaceCanBeFoundOnDifferentPaths(classType, sigFunc->Owner(), this) && + (Relation()->IsSupertypeOf(sigFunc->Owner(), sig->Owner()) || + Relation()->IsSupertypeOf(sig->Owner(), sigFunc->Owner()))) { return; } + throwError = true; + } else if (sigFunc->Function()->IsStatic() == sig->Function()->IsStatic()) { + Relation()->Result(false); + SavedTypeRelationFlagsContext savedFlagsCtx(Relation(), TypeRelationFlag::NO_RETURN_TYPE_CHECK); + Relation()->SignatureIsIdenticalTo(sig, sigFunc); + if ((Relation()->IsTrue() && + (sig->GetSignatureInfo()->restVar == nullptr) == (sigFunc->GetSignatureInfo()->restVar == nullptr)) || + (HasSameAssemblySignature(sigFunc, sig))) { + throwError = true; + } + } + if (throwError) { LogError(diagnostic::INTERFACE_METHOD_COLLISION, - {sig->Function()->Id()->Name(), sig->Owner()->Name(), func->Signature()->Owner()->Name()}, + {sig->Function()->Id()->Name(), sig->Owner()->Name(), sigFunc->Owner()->Name()}, classType->GetDeclNode()->Start()); } } void ETSChecker::CheckFunctionRedeclarationInInterface(ETSObjectType *classType, - ArenaVector &similarSignatures, - ir::ScriptFunction *func) + ArenaVector &similarSignatures, Signature *sigFunc) { for (auto *const sig : similarSignatures) { - if (sig != func->Signature() && func->HasBody()) { - if (classType == sig->Owner()) { + if (sig == sigFunc) { + return; + } + if (sigFunc->Function()->Id()->Name() == sig->Function()->Id()->Name()) { + if (classType->IsSameBasedGeneric(Relation(), sig->Owner())) { return; } - - CheckIfOverrideIsValidInInterface(classType, sig, func); + if (Relation()->IsIdenticalTo(sig->Owner(), sigFunc->Owner())) { + continue; + } + CheckIfOverrideIsValidInInterface(classType, sig, sigFunc); } } - similarSignatures.push_back(func->Signature()); + similarSignatures.push_back(sigFunc); +} + +static void CallRedeclarationCheckForCorrectSignature(ir::MethodDefinition *method, ETSFunctionType *funcType, + ArenaVector &similarSignatures, + ETSObjectType *classType, ETSChecker *checker) +{ + ir::ScriptFunction *func = method->Function(); + if (!func->IsAbstract()) { + auto *sigFunc = funcType->FindSignature(func); + checker->CheckFunctionRedeclarationInInterface(classType, similarSignatures, sigFunc); + } } void ETSChecker::CheckInterfaceFunctions(ETSObjectType *classType) { - ArenaVector interfaces(Allocator()->Adapter()); - ArenaVector similarSignatures(Allocator()->Adapter()); + ArenaVector interfaces(ProgramAllocator()->Adapter()); + ArenaVector similarSignatures(ProgramAllocator()->Adapter()); interfaces.emplace_back(classType); - checker::GetInterfacesOfClass(classType, interfaces); + GetInterfacesOfClass(classType, interfaces); for (auto *const &interface : interfaces) { for (auto *const &prop : interface->Methods()) { - ir::AstNode *node = prop->Declaration()->Node(); - ir::ScriptFunction *func = node->AsMethodDefinition()->Function(); - if (func->Body() != nullptr) { - CheckFunctionRedeclarationInInterface(classType, similarSignatures, func); + ir::MethodDefinition *node = prop->Declaration()->Node()->AsMethodDefinition(); + if (prop->TsType()->IsTypeError()) { + continue; + } + auto *funcType = prop->TsType()->AsETSFunctionType(); + CallRedeclarationCheckForCorrectSignature(node, funcType, similarSignatures, classType, this); + for (auto *const &overload : node->Overloads()) { + CallRedeclarationCheckForCorrectSignature(overload, funcType, similarSignatures, classType, this); } } } @@ -907,7 +956,7 @@ void ETSChecker::ValidateAbstractSignature(ArenaVector::itera continue; } - if (!AreOverrideEquivalent(*abstractSignature, substImplemented) || + if (!AreOverrideCompatible(*abstractSignature, substImplemented) || !IsReturnTypeSubstitutable(substImplemented, *abstractSignature)) { continue; } @@ -941,20 +990,23 @@ void ETSChecker::ValidateNonOverriddenFunction(ETSObjectType *classType, ArenaVe while (!functionOverridden && superClassType != nullptr) { for (auto *field : superClassType->Fields()) { if (field->Name() == (*it)->Name()) { - auto *newProp = - field->Declaration()->Node()->Clone(Allocator(), classType->GetDeclNode())->AsClassProperty(); + auto *newProp = field->Declaration() + ->Node() + ->Clone(ProgramAllocator(), classType->GetDeclNode()) + ->AsClassProperty(); newProp->AddModifier(ir::ModifierFlags::SUPER_OWNER); newProp->AddModifier(isGetSet.isGetter && isGetSet.isSetter ? ir::ModifierFlags::GETTER_SETTER : isGetSet.isGetter ? ir::ModifierFlags::GETTER : ir::ModifierFlags::SETTER); - auto *newFieldDecl = Allocator()->New(newProp->Key()->AsIdentifier()->Name()); + auto *newFieldDecl = + ProgramAllocator()->New(newProp->Key()->AsIdentifier()->Name()); newFieldDecl->BindNode(newProp); auto newFieldVar = classType->GetDeclNode() ->Scope() ->AsClassScope() ->InstanceFieldScope() - ->AddDecl(Allocator(), newFieldDecl, ScriptExtension::ETS) + ->AddDecl(ProgramAllocator(), newFieldDecl, ScriptExtension::ETS) ->AsLocalVariable(); newFieldVar->AddFlag(varbinder::VariableFlags::PROPERTY); newFieldVar->AddFlag(varbinder::VariableFlags::PUBLIC); @@ -1172,6 +1224,7 @@ void ETSChecker::CheckClassDefinition(ir::ClassDefinition *classDef) if ((static_cast(classDef)->Modifiers() & ir::ModifierFlags::FUNCTIONAL) == 0) { ValidateOverriding(classType, classDef->Start()); } + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) TransformProperties(classType); CheckClassElement(classDef); @@ -1294,7 +1347,7 @@ void ETSChecker::CheckThisOrSuperCallInConstructor(ETSObjectType *classType, Sig (it->AsExpressionStatement()->GetExpression()->AsCallExpression()->Callee()->IsThisExpression() || it->AsExpressionStatement()->GetExpression()->AsCallExpression()->Callee()->IsSuperExpression())) { ArenaVector expressions = - ArenaVector(Allocator()->Adapter()); + ArenaVector(ProgramAllocator()->Adapter()); expressions.insert(expressions.end(), it->AsExpressionStatement()->GetExpression()->AsCallExpression()->Arguments().begin(), it->AsExpressionStatement()->GetExpression()->AsCallExpression()->Arguments().end()); @@ -1345,7 +1398,8 @@ void ETSChecker::CheckExpressionsInConstructor(const ArenaVector ETSChecker::CheckMemberOrCallOrObjectExpressionInConstructor( const ir::Expression *arg) { - ArenaVector expressions = ArenaVector(Allocator()->Adapter()); + ArenaVector expressions = + ArenaVector(ProgramAllocator()->Adapter()); if (arg->IsMemberExpression()) { if ((arg->AsMemberExpression()->Object()->IsSuperExpression() || @@ -1365,7 +1419,8 @@ ArenaVector ETSChecker::CheckMemberOrCallOrObjectExpress arg->AsCallExpression()->Callee()->AsMemberExpression()->Object()->IsThisExpression()) && !arg->AsCallExpression()->Callee()->AsMemberExpression()->Property()->IsStatic()) { const auto what = - (arg->AsCallExpression()->Callee()->AsMemberExpression()->IsSuperExpression() ? "super" : "this"); + (arg->AsCallExpression()->Callee()->AsMemberExpression()->Object()->IsSuperExpression() ? "super" + : "this"); LogError(diagnostic::THIS_OR_SUPER_IN_CTOR, {what}, arg->Start()); } } else if (arg->IsObjectExpression()) { @@ -1463,6 +1518,37 @@ void ETSChecker::CheckInnerClassMembers(const ETSObjectType *classType) } } +lexer::Number ETSChecker::ExtractNumericValue(Type const *const indexType) +{ + TypeFlag typeKind = ETSType(indexType); + lexer::Number resNum; + switch (typeKind) { + case TypeFlag::BYTE: { + resNum = lexer::Number(indexType->AsByteType()->GetValue()); + break; + } + case TypeFlag::SHORT: { + resNum = lexer::Number(indexType->AsShortType()->GetValue()); + break; + } + case TypeFlag::INT: { + resNum = lexer::Number(indexType->AsIntType()->GetValue()); + break; + } + case TypeFlag::FLOAT: { + resNum = lexer::Number(indexType->AsFloatType()->GetValue()); + break; + } + case TypeFlag::DOUBLE: { + resNum = lexer::Number(indexType->AsDoubleType()->GetValue()); + break; + } + default: + break; + } + return resNum; +} + bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) { auto const expressionType = expr->Check(this); @@ -1476,23 +1562,29 @@ bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) } Type const *const indexType = ApplyUnaryOperatorPromotion(expressionType); - if (relaxed && indexType != nullptr && indexType->HasTypeFlag(TypeFlag::ETS_FLOATING_POINT)) { - if (!expr->IsNumberLiteral()) { - return true; - } - auto num = expr->AsNumberLiteral()->Number(); - ES2PANDA_ASSERT(num.IsReal()); - double value = num.GetDouble(); + if (relaxed && indexType != nullptr) { + lexer::Number resNum = ExtractNumericValue(indexType); + double value = resNum.GetDouble(); double intpart; if (std::modf(value, &intpart) != 0.0) { LogError(diagnostic::INDEX_NONINTEGRAL_FLOAT, {}, expr->Start()); return false; } - return true; + bool tildeFlag = false; + if (expr->IsUnaryExpression() && + expr->AsUnaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_TILDE) { + tildeFlag = true; + } + if ((tildeFlag && value > 0) || (!tildeFlag && value < 0)) { + LogError(diagnostic::NEGATIVE_INDEX, {}, expr->Start()); + return false; + } } - if (indexType == nullptr || !indexType->HasTypeFlag(TypeFlag::ETS_ARRAY_INDEX)) { + if (indexType == nullptr || + (!indexType->HasTypeFlag(relaxed ? (TypeFlag::ETS_ARRAY_INDEX | TypeFlag::ETS_FLOATING_POINT) + : TypeFlag::ETS_ARRAY_INDEX))) { std::stringstream message(""); expressionType->ToString(message); @@ -1530,7 +1622,8 @@ std::optional ETSChecker::GetTupleElementAccessValue(const Type *co } } -bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberExpression *const expr) +bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberExpression *const expr, + const bool reportError) { auto const expressionType = expr->Property()->Check(this); auto const *const unboxedExpressionType = MaybeUnboxInRelation(expressionType); @@ -1546,18 +1639,24 @@ bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberE if (exprType->IsETSObjectType() && (unboxedExpressionType != nullptr)) { return ValidateTupleIndexFromEtsObject(tuple, expr); } - LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Property()->Start()); + if (reportError) { + LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Property()->Start()); + } return false; } if (!exprType->HasTypeFlag(TypeFlag::ETS_ARRAY_INDEX | TypeFlag::LONG)) { - LogError(diagnostic::TUPLE_INDEX_NOT_INT, {}, expr->Property()->Start()); + if (reportError) { + LogError(diagnostic::TUPLE_INDEX_NOT_INT, {}, expr->Property()->Start()); + } return false; } auto exprValue = GetTupleElementAccessValue(exprType); if (!exprValue.has_value() || (*exprValue >= tuple->GetTupleSize())) { - LogError(diagnostic::TUPLE_INDEX_OOB, {}, expr->Property()->Start()); + if (reportError) { + LogError(diagnostic::TUPLE_INDEX_OOB, {}, expr->Property()->Start()); + } return false; } @@ -1598,7 +1697,8 @@ ETSObjectType *ETSChecker::CheckThisOrSuperAccess(ir::Expression *node, ETSObjec return classType; } - if (node->Parent()->IsCallExpression() && (node->Parent()->AsCallExpression()->Callee() == node)) { + if (node->Parent()->IsCallExpression() && (node->Parent()->AsCallExpression()->Callee() == node) && + !node->Parent()->HasAstNodeFlags(ir::AstNodeFlags::RESIZABLE_REST)) { if (Context().ContainingSignature() == nullptr) { LogError(diagnostic::CTOR_CLASS_NOT_FIRST, {msg}, node->Start()); return classType; @@ -1641,7 +1741,7 @@ void ETSChecker::CheckCyclicConstructorCall(Signature *signature) auto *funcBody = signature->Function()->Body()->AsBlockStatement(); - TypeStackElement tse(this, signature, "Recursive constructor invocation", signature->Function()->Start()); + TypeStackElement tse(this, signature, {{diagnostic::RECURSIVE_CTOR}}, signature->Function()->Start()); if (tse.HasTypeError()) { return; } @@ -1655,7 +1755,7 @@ void ETSChecker::CheckCyclicConstructorCall(Signature *signature) ->Callee() ->IsThisExpression()) { auto *constructorCall = funcBody->Statements()[0]->AsExpressionStatement()->GetExpression()->AsCallExpression(); - if (constructorCall->TsType()->HasTypeFlag(TypeFlag::TYPE_ERROR)) { + if (constructorCall->TsType() == nullptr || constructorCall->TsType()->HasTypeFlag(TypeFlag::TYPE_ERROR)) { LogError(diagnostic::NO_SUCH_CTOR_SIG, {}, constructorCall->Start()); return; } @@ -1694,10 +1794,17 @@ void ETSChecker::ValidateNamespaceProperty(varbinder::Variable *property, const const ir::Identifier *ident) { ir::AstNode *parent = nullptr; - if (property->TsType() != nullptr && property->TsType()->IsETSMethodType()) { - auto funcType = property->TsType()->AsETSFunctionType(); - property = funcType->CallSignatures()[0]->OwnerVar(); - ES2PANDA_ASSERT(property != nullptr); + if (property->TsType() != nullptr && !property->TsType()->IsTypeError()) { + if (property->TsType()->IsETSMethodType()) { + auto funcType = property->TsType()->AsETSFunctionType(); + property = funcType->CallSignatures()[0]->OwnerVar(); + ES2PANDA_ASSERT(property != nullptr); + } else { + if (ident->Parent()->IsMemberExpression() && + ident->Parent()->AsMemberExpression()->Object()->IsSuperExpression()) { + LogError(diagnostic::SUPER_NOT_ACCESSIBLE, {ident->Name()}, ident->Start()); + } + } } if (property->Declaration() == nullptr) { @@ -1715,7 +1822,7 @@ void ETSChecker::ValidateNamespaceProperty(varbinder::Variable *property, const parent = node->Parent(); } - bool isExported = node->IsExported() || node->IsExportedType() || node->IsDefaultExported(); + bool isExported = node->IsExported() || node->IsDefaultExported(); if (parent != nullptr && parent->IsClassDefinition() && parent->AsClassDefinition()->IsNamespaceTransformed() && !parent->AsClassDefinition()->IsDeclare() && !isExported) { LogError(diagnostic::NOT_EXPORTED, {ident->Name(), target->Name()}, ident->Start()); @@ -1944,10 +2051,9 @@ ETSFunctionType *ETSChecker::ResolveAccessorTypeByFlag(ir::MemberExpression *con { ETSFunctionType *finalRes = nullptr; auto const &sourcePos = memberExpr->Property()->Start(); - auto callExpr = memberExpr->Parent()->IsCallExpression() ? memberExpr->Parent()->AsCallExpression() : nullptr; if ((searchFlag & PropertySearchFlags::IS_GETTER) != 0) { if (propType != nullptr && propType->HasTypeFlag(TypeFlag::GETTER)) { - ValidateSignatureAccessibility(memberExpr->ObjType(), callExpr, propType->FindGetter(), sourcePos); + ValidateSignatureAccessibility(memberExpr->ObjType(), propType->FindGetter(), sourcePos); finalRes = propType; } @@ -1968,7 +2074,7 @@ ETSFunctionType *ETSChecker::ResolveAccessorTypeByFlag(ir::MemberExpression *con if (propType != nullptr) { ValidateReadonlyProperty(memberExpr, propType, sourcePos); if (propType->FindSetter() != nullptr) { - ValidateSignatureAccessibility(memberExpr->ObjType(), callExpr, propType->FindSetter(), sourcePos); + ValidateSignatureAccessibility(memberExpr->ObjType(), propType->FindSetter(), sourcePos); finalRes = propType; } } @@ -2004,17 +2110,18 @@ std::vector ETSChecker::ValidateAccessor(ir::MemberExpression * } if (finalRes == propType) { - resolveRes.emplace_back(Allocator()->New(oAcc, ResolvedKind::PROPERTY)); + resolveRes.emplace_back(ProgramAllocator()->New(oAcc, ResolvedKind::PROPERTY)); return resolveRes; } - resolveRes.emplace_back(Allocator()->New(eAcc, ResolvedKind::EXTENSION_ACCESSOR)); + resolveRes.emplace_back(ProgramAllocator()->New(eAcc, ResolvedKind::EXTENSION_ACCESSOR)); return resolveRes; } ir::ClassProperty *ETSChecker::FindClassProperty(const ETSObjectType *const objectType, const ETSFunctionType *propType) { auto propName = - util::UString(std::string(compiler::Signatures::PROPERTY) + propType->Name().Mutf8(), Allocator()).View(); + util::UString(std::string(compiler::Signatures::PROPERTY) + propType->Name().Mutf8(), ProgramAllocator()) + .View(); ir::ClassProperty *classProp = nullptr; if (objectType->GetDeclNode()->IsClassDefinition()) { @@ -2086,7 +2193,7 @@ std::vector ETSChecker::ResolveMemberReference(const ir::Member if (target->IsETSDynamicType() && !target->AsETSDynamicType()->HasDecl()) { auto propName = memberExpr->Property()->AsIdentifier()->Name(); varbinder::LocalVariable *propVar = target->AsETSDynamicType()->GetPropertyDynamic(propName, this); - resolveRes.emplace_back(Allocator()->New(propVar, ResolvedKind::PROPERTY)); + resolveRes.emplace_back(ProgramAllocator()->New(propVar, ResolvedKind::PROPERTY)); return resolveRes; } @@ -2104,7 +2211,7 @@ std::vector ETSChecker::ResolveMemberReference(const ir::Member // Note: extension function only for instance. ValidateResolvedProperty(&prop, target, memberExpr->Property()->AsIdentifier(), searchFlag); if (prop != nullptr) { - resolveRes.emplace_back(Allocator()->New(prop, ResolvedKind::PROPERTY)); + resolveRes.emplace_back(ProgramAllocator()->New(prop, ResolvedKind::PROPERTY)); } return resolveRes; } @@ -2126,13 +2233,13 @@ std::vector ETSChecker::ResolveMemberReference(const ir::Member LogError(diagnostic::EXTENSION_ACCESSOR_INVALID_CALL, {}, memberExpr->Start()); return resolveRes; } - resolveRes.emplace_back(Allocator()->New(globalFunctionVar, resolvedKind)); + resolveRes.emplace_back(ProgramAllocator()->New(globalFunctionVar, resolvedKind)); } else { ValidateResolvedProperty(&prop, target, memberExpr->Property()->AsIdentifier(), searchFlag); } if (prop != nullptr) { - resolveRes.emplace_back(Allocator()->New(prop, ResolvedKind::PROPERTY)); + resolveRes.emplace_back(ProgramAllocator()->New(prop, ResolvedKind::PROPERTY)); } return resolveRes; } @@ -2152,11 +2259,9 @@ void ETSChecker::WarnForEndlessLoopInGetterSetter(const ir::MemberExpression *co } if (parent != nullptr && ident->Name() == parent->AsMethodDefinition()->Function()->Id()->Name()) { if (parent->AsMethodDefinition()->Function()->IsGetter()) { - Warning("Reading the value of the property inside its getter may lead to an endless loop.", - memberExpr->Property()->AsIdentifier()->Start()); + LogDiagnostic(diagnostic::GETTER_LOOP, memberExpr->Property()->AsIdentifier()->Start()); } else { - Warning("Assigning new value to the property inside its setter may lead to an endless loop.", - memberExpr->Property()->AsIdentifier()->Start()); + LogDiagnostic(diagnostic::SETTER_LOOP, memberExpr->Property()->AsIdentifier()->Start()); } } } @@ -2166,6 +2271,9 @@ void ETSChecker::CheckValidInheritance(ETSObjectType *classType, ir::ClassDefini if (classType->SuperType() == nullptr) { return; } + if (classType->SuperType()->IsETSDynamicType()) { + LogError(diagnostic::EXTEND_DYNAMIC, {classDef->Ident()->Name()}, classDef->Start()); + } const auto &allProps = classType->GetAllProperties(); @@ -2246,8 +2354,41 @@ void ETSChecker::CheckProperties(ETSObjectType *classType, ir::ClassDefinition * interfaceFound->GetDeclNode()->Start()); return; } - LogError(diagnostic::INHERITED_CLASS_TYPE_MISMATCH, {classType->SuperType()->Name(), targetType, it->Name()}, - classDef->Super()->Start()); + auto pos = classDef->Super() == nullptr ? classDef->Ident()->Start() : classDef->Super()->Start(); + LogError(diagnostic::INHERITED_CLASS_TYPE_MISMATCH, {classType->SuperType()->Name(), targetType, it->Name()}, pos); +} + +void ETSChecker::CheckReadonlyClassPropertyInImplementedInterface(ETSObjectType *classType, + varbinder::LocalVariable *field) +{ + const auto searchFlag = PropertySearchFlags::SEARCH_ALL | PropertySearchFlags::SEARCH_IN_BASE | + PropertySearchFlags::SEARCH_IN_INTERFACES | + PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION; + const auto &interfaceList = GetInterfaces(classType); + if (field == nullptr || field->Declaration() == nullptr || field->Declaration()->Node() == nullptr || + !field->Declaration()->Node()->IsClassProperty() || + !field->Declaration()->Node()->AsClassProperty()->IsReadonly()) { + return; + } + + for (auto *interface : interfaceList) { + ES2PANDA_ASSERT(interface != nullptr); + auto *propertyFound = interface->GetProperty(field->Name(), searchFlag); + if (propertyFound == nullptr) { + continue; + } + + ES2PANDA_ASSERT(propertyFound->TsType() != nullptr); + if (!propertyFound->TsType()->IsETSFunctionType()) { + continue; + } + + auto setter = propertyFound->TsType()->AsETSFunctionType()->FindSetter(); + if (setter != nullptr) { + LogError(diagnostic::INTERFACE_PROPERTY_REQUIRES_SETTER, {interface->Name(), field->Name()}, + field->Declaration()->Node()->Start()); + } + } } void ETSChecker::TransformProperties(ETSObjectType *classType) @@ -2266,15 +2407,22 @@ void ETSChecker::TransformProperties(ETSObjectType *classType) if (!field->HasFlag(varbinder::VariableFlags::PUBLIC)) { LogError(diagnostic::INTERFACE_PROP_NOT_PUBLIC, {}, field->Declaration()->Node()->Start()); } + CheckReadonlyClassPropertyInImplementedInterface(classType, field); classType->RemoveProperty(field); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) GenerateGetterSetterPropertyAndMethod(originalProp, classType); } - auto it = classDef->Body().begin(); - while (it != classDef->Body().end()) { + auto &body = classDef->Body(); + if (!std::any_of(body.cbegin(), body.cend(), [](const ir::AstNode *node) { + return node->IsClassProperty() && (node->Modifiers() & ir::ModifierFlags::GETTER_SETTER) != 0U; + })) { + return; + } + auto it = classDef->BodyForUpdate().begin(); + while (it != classDef->BodyForUpdate().end()) { if ((*it)->IsClassProperty() && ((*it)->Modifiers() & ir::ModifierFlags::GETTER_SETTER) != 0U) { - it = classDef->Body().erase(it); + it = classDef->BodyForUpdate().erase(it); } else { ++it; } @@ -2321,10 +2469,9 @@ void ETSChecker::CheckGetterSetterProperties(ETSObjectType *classType) void ETSChecker::AddElementsToModuleObject(ETSObjectType *moduleObj, const util::StringView &str) { for (const auto &[name, var] : VarBinder()->GetScope()->Bindings()) { - if (name.Is(str.Mutf8()) || name.Is(compiler::Signatures::ETS_GLOBAL)) { + if (name.Is(str.Mutf8()) || util::Helpers::IsGlobalVar(var)) { continue; } - ES2PANDA_ASSERT(name.Utf8().find(compiler::Signatures::ETS_GLOBAL) == std::string::npos); if (var->HasFlag(varbinder::VariableFlags::METHOD)) { moduleObj->AddProperty(var->AsLocalVariable()); @@ -2339,14 +2486,18 @@ void ETSChecker::AddElementsToModuleObject(ETSObjectType *moduleObj, const util: // This function computes effective runtime view of type Type *ETSChecker::GetApparentType(Type *type) { - if (auto it = apparentTypes_.find(type); LIKELY(it != apparentTypes_.end())) { + auto currChecker = compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker(); + auto &apparentTypes = currChecker->apparentTypes_; + + if (auto it = apparentTypes.find(type); LIKELY(it != apparentTypes.end())) { return it->second; } - auto cached = [this, type](Type *res) { + + auto cached = [&apparentTypes, type](Type *res) { if (type != res) { - apparentTypes_.insert({type, res}); + apparentTypes.insert({type, res}); } - apparentTypes_.insert({res, res}); + apparentTypes.insert({res, res}); return res; }; @@ -2369,9 +2520,12 @@ Type *ETSChecker::GetApparentType(Type *type) if (type->IsETSArrayType()) { return cached(type); } + if (type->IsETSStringType()) { + return GlobalBuiltinETSStringType(); + } if (type->IsETSUnionType()) { bool differ = false; - ArenaVector newConstituent(Allocator()->Adapter()); + ArenaVector newConstituent(ProgramAllocator()->Adapter()); for (auto const &ct : type->AsETSUnionType()->ConstituentTypes()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) newConstituent.push_back(GetApparentType(ct)); @@ -2384,7 +2538,9 @@ Type *ETSChecker::GetApparentType(Type *type) Type const *ETSChecker::GetApparentType(Type const *type) const { - if (auto it = apparentTypes_.find(type); LIKELY(it != apparentTypes_.end())) { + auto currChecker = compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker(); + auto &apparentTypes = currChecker->apparentTypes_; + if (auto it = apparentTypes.find(type); LIKELY(it != apparentTypes.end())) { return it->second; } // Relaxed for some types @@ -2395,6 +2551,9 @@ Type const *ETSChecker::GetApparentType(Type const *type) const if (type->IsETSArrayType()) { return type; } + if (type->IsETSStringType()) { + return GlobalBuiltinETSStringType(); + } if (type->IsETSUnionType() || type->IsETSNonNullishType() || type->IsETSPartialTypeParameter()) { ASSERT_PRINT(false, std::string("Type ") + type->ToString() + " was not found in apparent_types_"); } diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 2fd200a131e6cd6143de62339c34ffa1e26ca6bf..1fa0493279befe6b6429cb10983fd5d8b5782f9d 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -36,6 +36,7 @@ #include "ir/ts/tsEnumMember.h" #include "ir/ts/tsTypeParameter.h" #include "ir/ets/etsUnionType.h" +#include "ir/ets/etsTuple.h" #include "varbinder/declaration.h" #include "checker/ETSchecker.h" #include "varbinder/ETSBinder.h" @@ -46,6 +47,7 @@ #include "generated/diagnostic.h" namespace ark::es2panda::checker { + void ETSChecker::CheckTruthinessOfType(ir::Expression *expr) { auto const testType = expr->Check(this); @@ -93,7 +95,7 @@ Type *ETSChecker::GetNonNullishType(Type *type) return type; } if (type->IsETSTypeParameter()) { - return Allocator()->New(type->AsETSTypeParameter()); + return ProgramAllocator()->New(type->AsETSTypeParameter()); } if (type->IsETSPartialTypeParameter()) { return type->AsETSPartialTypeParameter()->GetUnderlying(); @@ -102,7 +104,7 @@ Type *ETSChecker::GetNonNullishType(Type *type) return GetGlobalTypesHolder()->GlobalETSNeverType(); } - ArenaVector copied(Allocator()->Adapter()); + ArenaVector copied(ProgramAllocator()->Adapter()); for (auto const &t : type->AsETSUnionType()->ConstituentTypes()) { if (t->IsETSNullType() || t->IsETSUndefinedType()) { continue; @@ -128,7 +130,7 @@ Type *ETSChecker::RemoveNullType(Type *const type) } ES2PANDA_ASSERT(type->IsETSUnionType()); - ArenaVector copiedTypes(Allocator()->Adapter()); + ArenaVector copiedTypes(ProgramAllocator()->Adapter()); for (auto *constituentType : type->AsETSUnionType()->ConstituentTypes()) { if (!constituentType->IsETSNullType()) { @@ -156,7 +158,7 @@ Type *ETSChecker::RemoveUndefinedType(Type *const type) } ES2PANDA_ASSERT(type->IsETSUnionType()); - ArenaVector copiedTypes(Allocator()->Adapter()); + ArenaVector copiedTypes(ProgramAllocator()->Adapter()); for (auto *constituentType : type->AsETSUnionType()->ConstituentTypes()) { if (!constituentType->IsETSUndefinedType()) { @@ -176,7 +178,7 @@ std::pair ETSChecker::RemoveNullishTypes(Type *type) if (type->IsETSTypeParameter()) { return {GetGlobalTypesHolder()->GlobalETSNullishType(), - Allocator()->New(type->AsETSTypeParameter())}; + ProgramAllocator()->New(type->AsETSTypeParameter())}; } if (type->IsETSUndefinedType() || type->IsETSNullType()) { @@ -184,16 +186,17 @@ std::pair ETSChecker::RemoveNullishTypes(Type *type) } ES2PANDA_ASSERT(type->IsETSUnionType()); - ArenaVector nullishTypes(Allocator()->Adapter()); - ArenaVector notNullishTypes(Allocator()->Adapter()); + ArenaVector nullishTypes(ProgramAllocator()->Adapter()); + ArenaVector notNullishTypes(ProgramAllocator()->Adapter()); for (auto *constituentType : type->AsETSUnionType()->ConstituentTypes()) { if (constituentType->IsETSUndefinedType() || constituentType->IsETSNullType()) { nullishTypes.push_back(constituentType); } else { - notNullishTypes.push_back(!constituentType->IsETSTypeParameter() - ? constituentType - : Allocator()->New(constituentType->AsETSTypeParameter())); + notNullishTypes.push_back( + !constituentType->IsETSTypeParameter() + ? constituentType + : ProgramAllocator()->New(constituentType->AsETSTypeParameter())); } } @@ -290,21 +293,23 @@ bool Type::PossiblyETSString() const static bool IsValueTypedObjectType(ETSObjectType const *t) { - return t->IsGlobalETSObjectType() || t->HasObjectFlag(ETSObjectFlags::VALUE_TYPED); + ETSObjectFlags flags = ETSObjectFlags::FUNCTIONAL_REFERENCE | ETSObjectFlags::VALUE_TYPED | + ETSObjectFlags::ENUM_OBJECT | ETSObjectFlags::FUNCTIONAL; + return t->IsGlobalETSObjectType() || t->HasObjectFlag(flags); } bool Type::PossiblyETSValueTyped() const { - return MatchConstituentOrConstraint(this, [](const Type *t) { - return t->IsETSNullType() || t->IsETSUndefinedType() || - (t->IsETSObjectType() && IsValueTypedObjectType(t->AsETSObjectType())); - }); + return MatchConstituentOrConstraint(this, + [](const Type *t) { return t->IsETSNullType() || t->IsETSUndefinedType(); }) || + PossiblyETSValueTypedExceptNullish(); } bool Type::PossiblyETSValueTypedExceptNullish() const { - return MatchConstituentOrConstraint( - this, [](const Type *t) { return t->IsETSObjectType() && IsValueTypedObjectType(t->AsETSObjectType()); }); + return MatchConstituentOrConstraint(this, [](const Type *t) { + return t->IsETSFunctionType() || (t->IsETSObjectType() && IsValueTypedObjectType(t->AsETSObjectType())); + }); } bool Type::IsETSArrowType() const @@ -324,7 +329,8 @@ bool Type::IsETSMethodType() const TypeFlag::TYPE_ERROR | TypeFlag::ETS_NULL | TypeFlag::ETS_UNDEFINED | TypeFlag::ETS_OBJECT | TypeFlag::ETS_TYPE_PARAMETER | TypeFlag::WILDCARD | TypeFlag::ETS_NONNULLISH | TypeFlag::ETS_REQUIRED_TYPE_PARAMETER | TypeFlag::ETS_NEVER | TypeFlag::ETS_UNION | TypeFlag::ETS_ARRAY | - TypeFlag::FUNCTION | TypeFlag::ETS_PARTIAL_TYPE_PARAMETER | TypeFlag::ETS_TUPLE | TypeFlag::ETS_ENUM; + TypeFlag::FUNCTION | TypeFlag::ETS_PARTIAL_TYPE_PARAMETER | TypeFlag::ETS_TUPLE | TypeFlag::ETS_ENUM | + TypeFlag::ETS_READONLY; // Issues if (type->IsETSVoidType()) { // NOTE(vpukhov): #19701 void refactoring @@ -348,11 +354,6 @@ bool Type::IsETSPrimitiveType() const return HasTypeFlag(ETS_PRIMITIVE); } -bool Type::IsETSResizableArrayType() const -{ - return IsETSObjectType() && AsETSObjectType()->Name() == compiler::Signatures::ARRAY; -} - bool Type::IsETSPrimitiveOrEnumType() const { return IsETSPrimitiveType() || IsETSEnumType(); @@ -478,8 +479,12 @@ static Type *GetTypeFromVarLikeVariableDeclaration(ETSChecker *checker, varbinde if (var->Declaration()->Node()->IsIdentifier()) { declNode = declNode->Parent(); } - util::DiagnosticMessageParams err = {"Circular dependency detected for identifier: ", var->Declaration()->Name()}; - TypeStackElement tse(checker, var->Declaration(), err, declNode->Start()); + TypeStackElement tse( + checker, var->Declaration(), + // OHOS CC thinks initializer lists are statement blocks... + // CC-OFFNXT(G.FMT.03-CPP) project code style + {{diagnostic::CIRCULAR_DEPENDENCY, util::DiagnosticMessageParams {var->Declaration()->Name()}}}, + declNode->Start()); if (tse.HasTypeError()) { var->SetTsType(checker->GlobalTypeError()); return checker->GlobalTypeError(); @@ -637,6 +642,44 @@ Type *ETSChecker::GuaranteedTypeForUncheckedCallReturn(Signature *sig) return GuaranteedTypeForUncheckedCast(MaybeBoxType(baseSig->ReturnType()), MaybeBoxType(sig->ReturnType())); } +Type *ETSChecker::ResolveUnionUncheckedType(ArenaVector &&apparentTypes) +{ + if (apparentTypes.empty()) { + return nullptr; + } + auto *unionType = CreateETSUnionType(std::move(apparentTypes)); + if (unionType->IsETSUnionType()) { + checker::Type *typeLUB = unionType->AsETSUnionType()->GetAssemblerLUB(); + return typeLUB; + } + // Is case of single apparent type, just return itself + return unionType; +} + +Type *ETSChecker::GuaranteedTypeForUnionFieldAccess(ir::MemberExpression *memberExpression, ETSUnionType *etsUnionType) +{ + const auto &types = etsUnionType->ConstituentTypes(); + ArenaVector apparentTypes {ProgramAllocator()->Adapter()}; + const auto &propertyName = memberExpression->Property()->AsIdentifier()->Name(); + for (auto *type : types) { + auto searchFlags = PropertySearchFlags::SEARCH_FIELD | PropertySearchFlags::SEARCH_METHOD | + PropertySearchFlags::SEARCH_IN_BASE; + if (!type->IsETSObjectType()) { + return nullptr; + } + auto *fieldVar = type->AsETSObjectType()->GetProperty(propertyName, searchFlags); + if (fieldVar == nullptr) { + return nullptr; + } + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto *fieldType = GuaranteedTypeForUncheckedPropertyAccess(fieldVar); + if (fieldType != nullptr) { + apparentTypes.push_back(fieldType); + } + } + return ResolveUnionUncheckedType(std::move(apparentTypes)); +} + bool ETSChecker::IsAllowedTypeAliasRecursion(const ir::TSTypeAliasDeclaration *typeAliasNode, std::unordered_set &typeAliases) { @@ -691,8 +734,7 @@ Type *ETSChecker::GetTypeFromTypeAliasReference(varbinder::Variable *var) std::unordered_set typeAliases; auto isAllowedRecursion = IsAllowedTypeAliasRecursion(aliasTypeNode, typeAliases); - TypeStackElement tse(this, aliasTypeNode, "Circular type alias reference", aliasTypeNode->Start(), - isAllowedRecursion); + TypeStackElement tse(this, aliasTypeNode, {{diagnostic::CYCLIC_ALIAS}}, aliasTypeNode->Start(), isAllowedRecursion); if (tse.HasTypeError()) { var->SetTsType(GlobalTypeError()); @@ -755,7 +797,7 @@ Type *ETSChecker::GetTypeFromTypeParameterReference(varbinder::LocalVariable *va if ((var->Declaration()->Node()->AsTSTypeParameter()->Parent()->Parent()->IsClassDefinition() || var->Declaration()->Node()->AsTSTypeParameter()->Parent()->Parent()->IsTSInterfaceDeclaration()) && HasStatus(CheckerStatus::IN_STATIC_CONTEXT)) { - return TypeError(var, {"Cannot make a static reference to the non-static type ", var->Name()}, pos); + return TypeError(var, diagnostic::STATIC_REF_TO_NONSTATIC, {var->Name()}, pos); } return var->TsType(); @@ -904,10 +946,59 @@ void ETSChecker::CheckFunctionSignatureAnnotations(const ArenaVectorAnnotations()); } } +bool ETSChecker::CheckAndLogInvalidThisUsage(const ir::TypeNode *type, const diagnostic::DiagnosticKind &diagnostic) +{ + if (type->IsTSThisType()) { + LogError(diagnostic, {}, type->Start()); + return true; + } + return false; +} + +bool ETSChecker::IsFixedArray(ir::ETSTypeReferencePart *part) +{ + return part->Name()->IsIdentifier() && + part->Name()->AsIdentifier()->Name().Mutf8() == compiler::Signatures::FIXED_ARRAY_TYPE_NAME; +} + +void ETSChecker::ValidateThisUsage(const ir::TypeNode *returnTypeAnnotation) +{ + if (returnTypeAnnotation->IsETSUnionType()) { + auto types = returnTypeAnnotation->AsETSUnionType()->Types(); + for (auto type : types) { + if (CheckAndLogInvalidThisUsage(type, diagnostic::NOT_ALLOWED_THIS_IN_UNION_TYPE)) { + return; + } + ValidateThisUsage(type); + } + return; + } + if (returnTypeAnnotation->IsETSTuple()) { + auto types = returnTypeAnnotation->AsETSTuple()->GetTupleTypeAnnotationsList(); + for (auto type : types) { + if (CheckAndLogInvalidThisUsage(type, diagnostic::NOT_ALLOWED_THIS_IN_TUPLE_TYPE)) { + return; + } + ValidateThisUsage(type); + } + return; + } + if (returnTypeAnnotation->IsETSTypeReference() && + IsFixedArray(returnTypeAnnotation->AsETSTypeReference()->Part())) { + auto elementType = returnTypeAnnotation->AsETSTypeReference()->Part()->TypeParams()->Params()[0]; + if (CheckAndLogInvalidThisUsage(elementType, diagnostic::NOT_ALLOWED_THIS_IN_ARRAY_TYPE)) { + return; + } + ValidateThisUsage(elementType); + return; + } +} + void ETSChecker::CheckAnnotations(const ArenaVector &annotations) { if (annotations.empty()) { @@ -960,16 +1051,23 @@ void ETSChecker::HandleAnnotationRetention(ir::AnnotationUsage *anno, ir::Annota if (anno->Properties().size() != 1) { return; } - auto policyStr = anno->Properties()[0]->AsClassProperty()->Value()->AsStringLiteral()->Str().Mutf8(); - if (policyStr == compiler::Signatures::SOURCE_POLICY) { - annoDecl->SetSourceRetention(); - } else if (policyStr == compiler::Signatures::BYTECODE_POLICY) { - annoDecl->SetBytecodeRetention(); - } else if (policyStr == compiler::Signatures::RUNTIME_POLICY) { - annoDecl->SetRuntimeRetention(); - } else { - LogError(diagnostic::ANNOTATION_POLICY_INVALID, {}, anno->Properties()[0]->Start()); + const auto value = anno->Properties()[0]->AsClassProperty()->Value(); + if (value->IsStringLiteral()) { + const auto policyStr = value->AsStringLiteral()->Str().Mutf8(); + if (policyStr == compiler::Signatures::SOURCE_POLICY) { + annoDecl->SetSourceRetention(); + return; + } + if (policyStr == compiler::Signatures::BYTECODE_POLICY) { + annoDecl->SetBytecodeRetention(); + return; + } + if (policyStr == compiler::Signatures::RUNTIME_POLICY) { + annoDecl->SetRuntimeRetention(); + return; + } } + LogError(diagnostic::ANNOTATION_POLICY_INVALID, {}, anno->Properties()[0]->Start()); } void ETSChecker::CheckStandardAnnotation(ir::AnnotationUsage *anno) @@ -1013,7 +1111,7 @@ void ETSChecker::CheckSinglePropertyAnnotation(ir::AnnotationUsage *st, ir::Anno } auto singleField = annoDecl->Properties().at(0)->AsClassProperty(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto clone = singleField->TypeAnnotation()->Clone(Allocator(), param); + auto clone = singleField->TypeAnnotation()->Clone(ProgramAllocator(), param); param->SetTypeAnnotation(clone); ScopeContext scopeCtx(this, st->Scope()); param->Check(this); @@ -1029,7 +1127,7 @@ void ETSChecker::ProcessRequiredFields(ArenaUnorderedMapClone(checker->Allocator(), st); + auto *clone = entry.second->Clone(checker->ProgramAllocator(), st); st->AddProperty(clone); } } @@ -1046,7 +1144,7 @@ void ETSChecker::CheckMultiplePropertiesAnnotation(ir::AnnotationUsage *st, util } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto clone = result->second->TypeAnnotation()->Clone(Allocator(), param); + auto clone = result->second->TypeAnnotation()->Clone(ProgramAllocator(), param); param->SetTypeAnnotation(clone); ScopeContext scopeCtx(this, st->Scope()); param->Check(this); @@ -1307,19 +1405,27 @@ bool ETSChecker::CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction { ES2PANDA_ASSERT(param->IsETSParameterExpression()); ir::AstNode *typeAnn = param->AsETSParameterExpression()->Ident()->TypeAnnotation(); - if (typeAnn->IsETSTypeReference()) { + if (typeAnn == nullptr) { + return false; + } + if (typeAnn->IsETSTypeReference() && !typeAnn->AsETSTypeReference()->TsType()->IsETSArrayType()) { typeAnn = DerefETSTypeReference(typeAnn); } if (!typeAnn->IsETSFunctionType()) { // 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 - lambda->Parent()->Check(this); if (typeAnn->IsETSUnionType()) { + lambda->Parent()->Check(this); return CheckLambdaAssignableUnion(typeAnn, lambda); } + Type *paramType = param->AsETSParameterExpression()->Ident()->TsType(); - return paramType->IsETSObjectType() && Relation()->IsSupertypeOf(paramType, GlobalBuiltinFunctionType()); + if (Relation()->IsSupertypeOf(paramType, GlobalBuiltinFunctionType())) { + lambda->Parent()->Check(this); + return true; + } + return false; } ir::ETSFunctionType *calleeType = typeAnn->AsETSFunctionType(); @@ -1354,7 +1460,7 @@ bool ETSChecker::CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, functionFlags |= TypeRelationFlag::NO_THROW; checker::InvocationContext invocationCtx(Relation(), arrowFuncExpr, argumentType, parameterType, - arrowFuncExpr->Start(), {}, functionFlags); + arrowFuncExpr->Start(), std::nullopt, functionFlags); return invocationCtx.IsInvocable(); }; @@ -1372,7 +1478,7 @@ bool ETSChecker::CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, // Preserve actual lambda types ir::ScriptFunction *const lambda = arrowFuncExpr->Function(); - ArenaVector lambdaParamTypes {Allocator()->Adapter()}; + ArenaVector lambdaParamTypes {ProgramAllocator()->Adapter()}; for (auto *const lambdaParam : lambda->Params()) { lambdaParamTypes.emplace_back(lambdaParam->AsETSParameterExpression()->Ident()->TypeAnnotation()); } @@ -1409,59 +1515,81 @@ bool ETSChecker::CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, return false; } -bool ETSChecker::TypeInference(Signature *signature, const ArenaVector &arguments, - TypeRelationFlag flags) +bool ETSChecker::ResolveLambdaArgumentType(Signature *signature, ir::Expression *argument, size_t paramPosition, + size_t argumentPosition, TypeRelationFlag resolutionFlags) { - bool invocable = true; - auto const argumentCount = arguments.size(); - auto const commonArity = std::min(signature->ArgCount(), argumentCount); - - for (size_t index = 0U; index < commonArity; ++index) { - auto const &argument = arguments[index]; - if (!argument->IsArrowFunctionExpression()) { - continue; - } - - if (index == argumentCount - 1 && (flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0) { - continue; - } - - auto *const arrowFuncExpr = argument->AsArrowFunctionExpression(); - ir::ScriptFunction *const lambda = arrowFuncExpr->Function(); - if (!NeedTypeInference(lambda)) { - continue; - } + if (!argument->IsArrowFunctionExpression()) { + return true; + } - arrowFuncExpr->SetTsType(nullptr); + auto arrowFuncExpr = argument->AsArrowFunctionExpression(); + bool typeValid = true; + ir::ScriptFunction *const lambda = arrowFuncExpr->Function(); + if (!NeedTypeInference(lambda)) { + return typeValid; + } - auto const *const param = signature->Function()->Params()[index]->AsETSParameterExpression()->Ident(); - ir::AstNode *typeAnn = param->TypeAnnotation(); - Type *const parameterType = signature->Params()[index]->TsType(); + arrowFuncExpr->SetTsType(nullptr); + auto const *const param = + signature->GetSignatureInfo()->params[paramPosition]->Declaration()->Node()->AsETSParameterExpression(); + ir::AstNode *typeAnn = param->Ident()->TypeAnnotation(); + Type *const parameterType = signature->Params()[paramPosition]->TsType(); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - bool rc = CheckLambdaTypeAnnotation(typeAnn, arrowFuncExpr, parameterType, flags); - if (!rc && (flags & TypeRelationFlag::NO_THROW) == 0) { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + bool rc = CheckLambdaTypeAnnotation(typeAnn, arrowFuncExpr, parameterType, resolutionFlags); + if (!rc) { + if ((resolutionFlags & TypeRelationFlag::NO_THROW) == 0) { Type *const argumentType = arrowFuncExpr->Check(this); - LogError(diagnostic::LAMBDA_TYPE_MISMATCH, {argumentType, parameterType, index + 1}, + LogError(diagnostic::TYPE_MISMATCH_AT_IDX, {argumentType, parameterType, argumentPosition + 1}, arrowFuncExpr->Start()); + } + rc = false; + } else if ((lambda->Signature() != nullptr) && !lambda->HasReturnStatement()) { + // Need to check void return type here if there are no return statement(s) in the body. + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + if (!AssignmentContext(Relation(), ProgramAllocNode(ProgramAllocator()), GlobalVoidType(), + lambda->Signature()->ReturnType(), lambda->Start(), std::nullopt, + checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) + .IsAssignable()) { // CC-OFF(G.FMT.02-CPP) project code style + LogError(diagnostic::ARROW_TYPE_MISMATCH, {GlobalVoidType(), lambda->Signature()->ReturnType()}, + lambda->Body()->Start()); rc = false; - } else if ((lambda->Signature() != nullptr) && !lambda->HasReturnStatement()) { - // Need to check void return type here if there are no return statement(s) in the body. - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - if (!AssignmentContext(Relation(), AllocNode(Allocator()), GlobalVoidType(), - lambda->Signature()->ReturnType(), lambda->Start(), {}, - checker::TypeRelationFlag::DIRECT_RETURN | checker::TypeRelationFlag::NO_THROW) - .IsAssignable()) { // CC-OFF(G.FMT.02-CPP) project code style - LogError(diagnostic::ARROW_TYPE_MISMATCH, {GlobalVoidType(), lambda->Signature()->ReturnType()}, - lambda->Body()->Start()); - rc = false; - } } + } + + typeValid &= rc; - invocable &= rc; + return typeValid; +} + +bool ETSChecker::TrailingLambdaTypeInference(Signature *signature, const ArenaVector &arguments) +{ + ES2PANDA_ASSERT(arguments.back()->IsArrowFunctionExpression()); + const size_t lastParamPos = signature->GetSignatureInfo()->params.size() - 1; + const size_t lastArgPos = arguments.size() - 1; + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return ResolveLambdaArgumentType(signature, arguments.back(), lastParamPos, lastArgPos, TypeRelationFlag::NONE); +} + +bool ETSChecker::TypeInference(Signature *signature, const ArenaVector &arguments, + TypeRelationFlag inferenceFlags) +{ + bool typeConsistent = true; + auto const argumentCount = arguments.size(); + auto const minArity = std::min(signature->ArgCount(), argumentCount); + + for (size_t idx = 0U; idx < minArity; ++idx) { + auto const &argument = arguments[idx]; + + if (idx == argumentCount - 1 && (inferenceFlags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0) { + continue; + } + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + const bool valid = ResolveLambdaArgumentType(signature, argument, idx, idx, inferenceFlags); + typeConsistent &= valid; } - return invocable; + return typeConsistent; } // #22951 requires complete refactoring @@ -1506,4 +1634,5 @@ void ETSChecker::CheckExceptionClauseType(const std::vector + static TargetType *ConvertConstant(SourceType *source, ArenaAllocator *allocator) + { + if constexpr (std::is_same_v, std::decay_t>) { + return source; + } else { + auto target = allocator->New(static_cast(source->GetValue())); + + if constexpr (!std::is_same_v, DoubleType> && + !std::is_same_v, FloatType>) { + ES2PANDA_ASSERT(source->GetValue() == static_cast(target->GetValue())); + } else if constexpr (std::is_same_v, DoubleType>) { + ES2PANDA_ASSERT((std::is_same_v, FloatType>)); + ES2PANDA_ASSERT( + std::isnan(source->GetValue()) || std::isinf(source->GetValue()) || + (std::abs(source->GetValue()) <= static_cast(std::numeric_limits::max()) && + std::abs(source->GetValue()) >= static_cast(std::numeric_limits::min()))); + } + + return target; + } + } + + // Function should be used ONLY if all the required checks were passed and + // correct conversion is possible without accuracy loss! + template + static Type *ConvertConstantType(Type *source, ArenaAllocator *allocator) + { + switch (static_cast(source->TypeFlags() & TypeFlag::ETS_TYPE)) { + case TypeFlag::INT: + return ConvertConstant(source->AsIntType(), allocator); + + case TypeFlag::LONG: + return ConvertConstant(source->AsLongType(), allocator); + + case TypeFlag::DOUBLE: + return ConvertConstant(source->AsDoubleType(), allocator); + + case TypeFlag::SHORT: + return ConvertConstant(source->AsShortType(), allocator); + + case TypeFlag::FLOAT: + return ConvertConstant(source->AsFloatType(), allocator); + + case TypeFlag::BYTE: + return ConvertConstant(source->AsByteType(), allocator); + + case TypeFlag::CHAR: + return ConvertConstant(source->AsCharType(), allocator); + + default: + ES2PANDA_UNREACHABLE(); + } + } + + // Function should be used ONLY if all the required checks were passed and + // correct conversion is possible without accuracy loss! + static Type *ConvertConstantTypes(Type *source, Type *target, ArenaAllocator *allocator) + { + ES2PANDA_ASSERT(source->IsETSPrimitiveType() && target->IsETSPrimitiveType() && source->IsConstantType()); + + switch (static_cast(target->TypeFlags() & TypeFlag::ETS_TYPE)) { + case TypeFlag::INT: + return ConvertConstantType(source, allocator); + + case TypeFlag::LONG: + return ConvertConstantType(source, allocator); + + case TypeFlag::DOUBLE: + return ConvertConstantType(source, allocator); + + case TypeFlag::SHORT: + return ConvertConstantType(source, allocator); + + case TypeFlag::FLOAT: + return ConvertConstantType(source, allocator); + + case TypeFlag::BYTE: + return ConvertConstantType(source, allocator); + + case TypeFlag::CHAR: + return ConvertConstantType(source, allocator); + + default: + ES2PANDA_UNREACHABLE(); + } + } + private: ETSChecker *checker_; TypeRelation *relation_; diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index a462d3f9928406aeb4ea4be2de3ac731b3ea5d4e..53b6838523debd2753639fa0ebed2702c14a6745 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -18,33 +18,38 @@ #include "checker/types/ets/etsAsyncFuncReturnType.h" #include "checker/types/ets/etsEnumType.h" #include "checker/types/ets/etsDynamicFunctionType.h" +#include "checker/types/ets/etsResizableArrayType.h" #include "checker/types/globalTypesHolder.h" +#include "checker/types/type.h" #include "ir/statements/annotationDeclaration.h" +#include + namespace ark::es2panda::checker { + ByteType *ETSChecker::CreateByteType(int8_t value) { - return Allocator()->New(value); + return ProgramAllocator()->New(value); } ETSBooleanType *ETSChecker::CreateETSBooleanType(bool value) { - return Allocator()->New(value); + return ProgramAllocator()->New(value); } DoubleType *ETSChecker::CreateDoubleType(double value) { - return Allocator()->New(value); + return ProgramAllocator()->New(value); } FloatType *ETSChecker::CreateFloatType(float value) { - return Allocator()->New(value); + return ProgramAllocator()->New(value); } IntType *ETSChecker::CreateIntType(int32_t value) { - return Allocator()->New(value); + return ProgramAllocator()->New(value); } IntType *ETSChecker::CreateIntTypeFromType(Type *type) @@ -75,27 +80,54 @@ IntType *ETSChecker::CreateIntTypeFromType(Type *type) LongType *ETSChecker::CreateLongType(int64_t value) { - return Allocator()->New(value); + return ProgramAllocator()->New(value); } ShortType *ETSChecker::CreateShortType(int16_t value) { - return Allocator()->New(value); + return ProgramAllocator()->New(value); } CharType *ETSChecker::CreateCharType(char16_t value) { - return Allocator()->New(value); + return ProgramAllocator()->New(value); } ETSBigIntType *ETSChecker::CreateETSBigIntLiteralType(util::StringView value) { - return Allocator()->New(Allocator(), GlobalBuiltinETSBigIntType(), Relation(), value); + return ProgramAllocator()->New(ProgramAllocator(), GlobalBuiltinETSBigIntType(), Relation(), value); } ETSStringType *ETSChecker::CreateETSStringLiteralType(util::StringView value) { - return Allocator()->New(Allocator(), GlobalBuiltinETSStringType(), Relation(), value); + return ProgramAllocator()->New(ProgramAllocator(), GlobalBuiltinETSStringType(), Relation(), value); +} + +ETSResizableArrayType *ETSChecker::CreateETSMultiDimResizableArrayType(Type *element, size_t dimSize) +{ + ETSResizableArrayType *const arrayType = GlobalBuiltinETSResizableArrayType()->AsETSResizableArrayType(); + ES2PANDA_ASSERT(arrayType->TypeArguments().size() == 1U); + + Type *baseArrayType = element; + + for (size_t dim = 0; dim < dimSize; ++dim) { + Substitution *tmpSubstitution = NewSubstitution(); + EmplaceSubstituted(tmpSubstitution, arrayType->TypeArguments()[0]->AsETSTypeParameter()->GetOriginal(), + MaybeBoxType(baseArrayType)); + baseArrayType = arrayType->Substitute(Relation(), tmpSubstitution); + } + return baseArrayType->AsETSResizableArrayType(); +} + +ETSResizableArrayType *ETSChecker::CreateETSResizableArrayType(Type *element) +{ + ETSResizableArrayType *arrayType = GlobalBuiltinETSResizableArrayType()->AsETSResizableArrayType(); + ES2PANDA_ASSERT(arrayType->TypeArguments().size() == 1U); + + Substitution *substitution = NewSubstitution(); + EmplaceSubstituted(substitution, arrayType->TypeArguments()[0]->AsETSTypeParameter()->GetOriginal(), + MaybeBoxType(element)); + return arrayType->Substitute(Relation(), substitution); } ETSArrayType *ETSChecker::CreateETSArrayType(Type *elementType, bool isCachePolluting) @@ -105,11 +137,11 @@ ETSArrayType *ETSChecker::CreateETSArrayType(Type *elementType, bool isCachePoll return res->second; } - auto *arrayType = Allocator()->New(elementType); + auto *arrayType = ProgramAllocator()->New(elementType); std::stringstream ss; arrayType->ToAssemblerTypeWithRank(ss); - // arrayType->SetAssemblerName(util::UString(ss.str(), Allocator()).View()); + // arrayType->SetAssemblerName(util::UString(ss.str(), ProgramAllocator()).View()); auto it = arrayTypes_.insert({{elementType, isCachePolluting}, arrayType}); if (it.second && (!elementType->IsTypeParameter() || !elementType->IsETSTypeParameter())) { @@ -125,7 +157,7 @@ Type *ETSChecker::CreateETSUnionType(Span constituentTypes) return nullptr; } - ArenaVector newConstituentTypes(Allocator()->Adapter()); + ArenaVector newConstituentTypes(ProgramAllocator()->Adapter()); newConstituentTypes.assign(constituentTypes.begin(), constituentTypes.end()); ETSUnionType::NormalizeTypes(Relation(), newConstituentTypes); @@ -133,34 +165,34 @@ Type *ETSChecker::CreateETSUnionType(Span constituentTypes) return newConstituentTypes[0]; } - return Allocator()->New(this, std::move(newConstituentTypes)); + return ProgramAllocator()->New(this, std::move(newConstituentTypes)); } ETSTypeAliasType *ETSChecker::CreateETSTypeAliasType(util::StringView name, const ir::AstNode *declNode, bool isRecursive) { - return Allocator()->New(this, name, declNode, isRecursive); + return ProgramAllocator()->New(this, name, declNode, isRecursive); } ETSFunctionType *ETSChecker::CreateETSArrowType(Signature *signature) { - return Allocator()->New(this, signature); + return ProgramAllocator()->New(this, signature); } ETSFunctionType *ETSChecker::CreateETSMethodType(util::StringView name, ArenaVector &&signatures) { - return Allocator()->New(this, name, std::move(signatures)); + return ProgramAllocator()->New(this, name, std::move(signatures)); } ETSFunctionType *ETSChecker::CreateETSDynamicArrowType(Signature *signature, Language lang) { - return Allocator()->New(this, signature, lang); + return ProgramAllocator()->New(this, signature, lang); } ETSFunctionType *ETSChecker::CreateETSDynamicMethodType(util::StringView name, ArenaVector &&signatures, Language lang) { - return Allocator()->New(this, name, std::move(signatures), lang); + return ProgramAllocator()->New(this, name, std::move(signatures), lang); } static SignatureFlags ConvertToSignatureFlags(ir::ModifierFlags inModifiers, ir::ScriptFunctionFlags inFunctionFlags) @@ -202,7 +234,7 @@ Signature *ETSChecker::CreateSignature(SignatureInfo *info, Type *returnType, ir ES2PANDA_ASSERT(IsAnyError()); return nullptr; } - auto signature = Allocator()->New(info, returnType, func); + auto signature = ProgramAllocator()->New(info, returnType, func); auto convertedFlag = ConvertToSignatureFlags(func->Modifiers(), func->Flags()); func->HasReceiver() ? signature->AddSignatureFlag(SignatureFlags::EXTENSION_FUNCTION | convertedFlag) : signature->AddSignatureFlag(convertedFlag); @@ -216,7 +248,7 @@ Signature *ETSChecker::CreateSignature(SignatureInfo *info, Type *returnType, ir ES2PANDA_ASSERT(IsAnyError()); return nullptr; } - auto signature = Allocator()->New(info, returnType, nullptr); + auto signature = ProgramAllocator()->New(info, returnType, nullptr); signature->AddSignatureFlag(ConvertToSignatureFlags(ir::ModifierFlags::NONE, sff)); // synthetic arrow type signature flags auto extraFlags = SignatureFlags::ABSTRACT | SignatureFlags::CALL | SignatureFlags::PUBLIC; @@ -227,18 +259,18 @@ Signature *ETSChecker::CreateSignature(SignatureInfo *info, Type *returnType, ir SignatureInfo *ETSChecker::CreateSignatureInfo() { - return Allocator()->New(Allocator()); + return ProgramAllocator()->New(ProgramAllocator()); } ETSTypeParameter *ETSChecker::CreateTypeParameter() { - return Allocator()->New(); + return ProgramAllocator()->New(); } ETSExtensionFuncHelperType *ETSChecker::CreateETSExtensionFuncHelperType(ETSFunctionType *classMethodType, ETSFunctionType *extensionFunctionType) { - return Allocator()->New(classMethodType, extensionFunctionType); + return ProgramAllocator()->New(classMethodType, extensionFunctionType); } static std::pair GetObjectTypeDeclNames(ir::AstNode *node) @@ -268,7 +300,7 @@ static ETSObjectType *InitializeGlobalBuiltinObjectType(ETSChecker *checker, Glo return slot; }; - auto *const allocator = checker->Allocator(); + auto *const programAllocator = checker->ProgramAllocator(); switch (globalId) { case GlobalTypeId::ETS_OBJECT_BUILTIN: { @@ -283,15 +315,25 @@ static ETSObjectType *InitializeGlobalBuiltinObjectType(ETSChecker *checker, Glo auto *stringObj = setType(GlobalTypeId::ETS_STRING_BUILTIN, create(ETSObjectFlags::BUILTIN_STRING | ETSObjectFlags::STRING)) ->AsETSObjectType(); - setType(GlobalTypeId::ETS_STRING, allocator->New(allocator, stringObj, checker->Relation())); + setType(GlobalTypeId::ETS_STRING, + programAllocator->New(programAllocator, stringObj, checker->Relation())); return stringObj; } case GlobalTypeId::ETS_BIG_INT_BUILTIN: { auto *bigIntObj = setType(GlobalTypeId::ETS_BIG_INT_BUILTIN, create(ETSObjectFlags::BUILTIN_BIGINT))->AsETSObjectType(); - setType(GlobalTypeId::ETS_BIG_INT, allocator->New(allocator, bigIntObj)); + setType(GlobalTypeId::ETS_BIG_INT, programAllocator->New(programAllocator, bigIntObj)); return bigIntObj; } + case GlobalTypeId::ETS_ARRAY_BUILTIN: { + if (declNode->AsClassDefinition()->InternalName().Utf8() != "escompat.Array") { + return checker->CreateETSObjectType(declNode, flags); + } + auto *arrayObj = + setType(GlobalTypeId::ETS_ARRAY_BUILTIN, create(ETSObjectFlags::BUILTIN_ARRAY))->AsETSObjectType(); + setType(GlobalTypeId::ETS_ARRAY, programAllocator->New(programAllocator, arrayObj)); + return arrayObj; + } case GlobalTypeId::ETS_BOOLEAN_BUILTIN: return create(ETSObjectFlags::BUILTIN_BOOLEAN); case GlobalTypeId::ETS_BYTE_BUILTIN: @@ -356,19 +398,25 @@ ETSObjectType *ETSChecker::CreateETSObjectType(ir::AstNode *declNode, ETSObjectF if (declNode->IsClassDefinition() && (declNode->AsClassDefinition()->IsEnumTransformed())) { if (declNode->AsClassDefinition()->IsIntEnumTransformed()) { - return Allocator()->New(Allocator(), name, internalName, declNode, Relation()); + return ProgramAllocator()->New(ProgramAllocator(), name, internalName, declNode, + Relation()); } ES2PANDA_ASSERT(declNode->AsClassDefinition()->IsStringEnumTransformed()); - return Allocator()->New(Allocator(), name, internalName, declNode, Relation()); + return ProgramAllocator()->New(ProgramAllocator(), name, internalName, declNode, Relation()); + } + + if (internalName == compiler::Signatures::BUILTIN_ARRAY) { + return ProgramAllocator()->New(ProgramAllocator(), name, + std::make_tuple(declNode, flags, Relation())); } if (auto [lang, hasDecl] = CheckForDynamicLang(declNode, internalName); lang.IsDynamic()) { - return Allocator()->New(Allocator(), std::make_tuple(name, internalName, lang), - std::make_tuple(declNode, flags, Relation()), hasDecl); + return ProgramAllocator()->New(ProgramAllocator(), std::make_tuple(name, internalName, lang), + std::make_tuple(declNode, flags, Relation()), hasDecl); } - return Allocator()->New(Allocator(), name, internalName, - std::make_tuple(declNode, flags, Relation())); + return ProgramAllocator()->New(ProgramAllocator(), name, internalName, + std::make_tuple(declNode, flags, Relation())); } std::tuple ETSChecker::CreateBuiltinArraySignatureInfo(const ETSArrayType *arrayType, @@ -383,9 +431,9 @@ std::tuple ETSChecker::CreateBuiltinArraySign info->minArgCount = dim; for (size_t i = 0; i < dim; i++) { - util::UString param(std::to_string(i), Allocator()); + util::UString param(std::to_string(i), ProgramAllocator()); auto *paramVar = - varbinder::Scope::CreateVar(Allocator(), param.View(), varbinder::VariableFlags::NONE, nullptr); + varbinder::Scope::CreateVar(ProgramAllocator(), param.View(), varbinder::VariableFlags::NONE, nullptr); paramVar->SetTsType(GlobalIntType()); info->params.push_back(paramVar); @@ -395,22 +443,25 @@ std::tuple ETSChecker::CreateBuiltinArraySign ss << compiler::Signatures::MANGLE_SEPARATOR << compiler::Signatures::PRIMITIVE_VOID << compiler::Signatures::MANGLE_SEPARATOR; - auto internalName = util::UString(ss.str(), Allocator()).View(); + auto internalName = util::UString(ss.str(), ProgramAllocator()).View(); return {internalName, info}; } Signature *ETSChecker::CreateBuiltinArraySignature(const ETSArrayType *arrayType, size_t dim) { - auto res = globalArraySignatures_.find(arrayType); - if (res != globalArraySignatures_.end()) { + auto currentChecker = + compiler::GetPhaseManager()->Context() != nullptr ? compiler::GetPhaseManager()->Context()->GetChecker() : this; + auto &globalArraySignatures = currentChecker->AsETSChecker()->globalArraySignatures_; + auto res = globalArraySignatures.find(arrayType); + if (res != globalArraySignatures.end()) { return res->second; } auto [internalName, info] = CreateBuiltinArraySignatureInfo(arrayType, dim); auto *signature = CreateSignature(info, GlobalVoidType(), ir::ScriptFunctionFlags::NONE, false); signature->SetInternalName(internalName); - globalArraySignatures_.insert({arrayType, signature}); + globalArraySignatures.insert({arrayType, signature}); return signature; } @@ -426,67 +477,73 @@ ETSObjectType *ETSChecker::CreatePromiseOf(Type *type) return promiseType->Substitute(Relation(), substitution); } -Type *ETSChecker::CreateUnionFromKeyofType(ETSObjectType *const type) +static bool IsInValidKeyofTypeNode(ir::AstNode *node) { - ArenaVector stringLiterals(Allocator()->Adapter()); + return (node->Modifiers() & ir::ModifierFlags::PRIVATE) != 0 || + (node->Modifiers() & ir::ModifierFlags::PROTECTED) != 0; +} - std::deque superTypes; - superTypes.push_back(type); - auto addToUnion = [this, &stringLiterals](checker::ETSObjectType *it) { - if (it == GlobalETSObjectType()) { - return; - } - for (auto *method : it->Methods()) { - if (method->HasFlag(varbinder::VariableFlags::PRIVATE) || - method->HasFlag(varbinder::VariableFlags::PROTECTED)) { +void ETSChecker::ProcessTypeMembers(ETSObjectType *type, ArenaVector &literals) +{ + if (type == GlobalETSObjectType()) { + return; + } + + for (auto *method : type->Methods()) { + auto *methodDef = method->Declaration()->Node()->AsMethodDefinition(); + for (auto *overload : methodDef->Overloads()) { + if (IsInValidKeyofTypeNode(overload)) { continue; } - stringLiterals.push_back(this->CreateETSStringLiteralType(method->Name())); + literals.push_back(CreateETSStringLiteralType(overload->Key()->Variable()->Name())); } - for (auto *field : it->Fields()) { - if (field->HasFlag(varbinder::VariableFlags::PRIVATE) || - field->HasFlag(varbinder::VariableFlags::PROTECTED)) { - continue; - } - stringLiterals.push_back(this->CreateETSStringLiteralType(field->Name())); + if (!IsInValidKeyofTypeNode(method->Declaration()->Node())) { + literals.push_back(CreateETSStringLiteralType(method->Name())); } - }; + } - auto addObjToDeque = [&superTypes](checker::ETSObjectType *it) { - if (it->SuperType() != nullptr) { - superTypes.push_back(it->SuperType()); + for (auto *field : type->Fields()) { + if (IsInValidKeyofTypeNode(field->Declaration()->Node())) { + continue; } - if (it->Interfaces().empty()) { - return; + literals.push_back(CreateETSStringLiteralType(field->Name())); + } +} + +Type *ETSChecker::CreateUnionFromKeyofType(ETSObjectType *const type) +{ + ArenaVector stringLiterals(ProgramAllocator()->Adapter()); + std::deque superTypes; + superTypes.push_back(type); + auto enqueueSupers = [&](ETSObjectType *currentType) { + if (currentType->SuperType() != nullptr) { + superTypes.push_back(currentType->SuperType()); } - for (auto inteface : it->Interfaces()) { - superTypes.push_back(inteface); + for (auto interface : currentType->Interfaces()) { + superTypes.push_back(interface); } }; while (!superTypes.empty()) { - auto *extendsObject = superTypes.front(); + auto *currentType = superTypes.front(); superTypes.pop_front(); - addToUnion(extendsObject); - addObjToDeque(extendsObject); - } - if (stringLiterals.empty()) { - return GlobalETSNeverType(); + ProcessTypeMembers(currentType, stringLiterals); + enqueueSupers(currentType); } - return CreateETSUnionType(std::move(stringLiterals)); + return stringLiterals.empty() ? GlobalETSNeverType() : CreateETSUnionType(std::move(stringLiterals)); } ETSAsyncFuncReturnType *ETSChecker::CreateETSAsyncFuncReturnTypeFromPromiseType(ETSObjectType *promiseType) { - return Allocator()->New(Allocator(), Relation(), promiseType); + return ProgramAllocator()->New(ProgramAllocator(), Relation(), promiseType); } ETSAsyncFuncReturnType *ETSChecker::CreateETSAsyncFuncReturnTypeFromBaseType(Type *baseType) { auto const promiseType = CreatePromiseOf(MaybeBoxType(baseType)); - return Allocator()->New(Allocator(), Relation(), promiseType); + return ProgramAllocator()->New(ProgramAllocator(), Relation(), promiseType); } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index 408ddcb599c137bb4834be26ba2fb53dc45abfc3..f8a63c3124d2491566597e6e17444b8c26872b8a 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -30,7 +30,7 @@ bool AssignmentContext::ValidateArrayTypeInitializerByElement(TypeRelation *rela if (!AssignmentContext(relation, currentArrayElem, currentArrayElem->Check(relation->GetChecker()->AsETSChecker()), target->ElementType(), - currentArrayElem->Start(), {}, TypeRelationFlag::NO_THROW) + currentArrayElem->Start(), std::nullopt, TypeRelationFlag::NO_THROW) // CC-OFFNXT(G.FMT.06-CPP,G.FMT.02-CPP) project code style .IsAssignable()) { relation->GetChecker()->LogError(diagnostic::ARRAY_ELEMENT_INIT_TYPE_INCOMPAT, @@ -47,8 +47,7 @@ bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSType { if (checker_->HasStatus(CheckerStatus::IN_INSTANCEOF_CONTEXT)) { if (typeArgs != nullptr) { - checker_->ReportWarning( - {"Type parameter is erased from type '", type->Name(), "' when used in instanceof expression."}, pos); + checker_->LogDiagnostic(diagnostic::INSTANCEOF_ERASED, {type->Name()}, pos); } result_ = type; return true; @@ -180,7 +179,7 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ArenaVectorSubstitute(checker_->Relation(), substitution)->AsETSObjectType(); - type->GetInstantiationMap().try_emplace(hash, result_->AsETSObjectType()); + type->InsertInstantiationMap(hash, result_->AsETSObjectType()); result_->AddTypeFlag(TypeFlag::GENERIC); ctScope.TryCheckConstraints(); diff --git a/ets2panda/checker/ets/typeRelationContext.h b/ets2panda/checker/ets/typeRelationContext.h index 3a3f2b1d383cecc49f5a4bcec7269ecc8d1559b8..ef6c5017f9cb026520b83ba5f7166d0b5855baeb 100644 --- a/ets2panda/checker/ets/typeRelationContext.h +++ b/ets2panda/checker/ets/typeRelationContext.h @@ -25,7 +25,7 @@ class AssignmentContext { public: // CC-OFFNXT(G.FUN.01-CPP) solid logic AssignmentContext(TypeRelation *relation, ir::Expression *node, Type *source, Type *target, - const lexer::SourcePosition &pos, const util::DiagnosticMessageParams &list, + const lexer::SourcePosition &pos, std::optional diag = std::nullopt, TypeRelationFlag flags = TypeRelationFlag::NONE) { flags_ |= ((flags & TypeRelationFlag::NO_BOXING) != 0) ? TypeRelationFlag::NONE : TypeRelationFlag::BOXING; @@ -69,7 +69,7 @@ public: } if (!relation->IsTrue() && (flags_ & TypeRelationFlag::NO_THROW) == 0) { - relation->RaiseError(list, pos); + relation->RaiseError(diag->kind, diag->params, pos); } relation->SetNode(nullptr); @@ -93,7 +93,7 @@ class InvocationContext { public: // CC-OFFNXT(G.FUN.01-CPP) solid logic InvocationContext(TypeRelation *relation, ir::Expression *node, Type *source, Type *target, - const lexer::SourcePosition &pos, const util::DiagnosticMessageParams &list, + const lexer::SourcePosition &pos, const std::optional &diag, TypeRelationFlag initialFlags = TypeRelationFlag::NONE) { flags_ |= @@ -122,7 +122,7 @@ public: if (!relation->IsTrue()) { invocable_ = false; if ((initialFlags & TypeRelationFlag::NO_THROW) == 0) { - relation->RaiseError(list, pos); + relation->RaiseError(diag->kind, diag->params, pos); } return; } diff --git a/ets2panda/checker/ets/unboxingConverter.h b/ets2panda/checker/ets/unboxingConverter.h index a9d122bb674d18ed088ce91b0a933513dcb6da98..5a59a153753939098c6bcdb29233dc0c0b34264c 100644 --- a/ets2panda/checker/ets/unboxingConverter.h +++ b/ets2panda/checker/ets/unboxingConverter.h @@ -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 @@ -16,8 +16,8 @@ #ifndef ES2PANDA_COMPILER_CHECKER_ETS_UNBOXING_CONVERTER_H #define ES2PANDA_COMPILER_CHECKER_ETS_UNBOXING_CONVERTER_H -#include "checker/ets/typeConverter.h" #include "checker/types/ets/etsObjectType.h" +#include "checker/ets/typeConverter.h" namespace ark::es2panda::checker { diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 69ed5cb22c569d29fc1d81fd55c2e6f5b4ef0351..c77f536455038d1fbfc515fa394857d494d936f1 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -84,7 +84,7 @@ static std::pair GetPartialClassName(ETSChec { // Partial class name for class 'T' will be 'T$partial' auto const addSuffix = [checker](util::StringView name) { - return util::UString(name.Mutf8() + PARTIAL_CLASS_SUFFIX, checker->Allocator()).View(); + return util::UString(name.Mutf8() + PARTIAL_CLASS_SUFFIX, checker->ProgramAllocator()).View(); }; auto declIdent = typeNode->IsClassDefinition() ? typeNode->AsClassDefinition()->Ident() @@ -98,7 +98,7 @@ static std::pair GetPartialClassPro ir::AstNode *typeNode) { auto classDefProgram = typeNode->GetTopStatement()->AsETSModule()->Program(); - if (classDefProgram == checker->VarBinder()->Program()) { + if (classDefProgram == checker->VarBinder()->AsETSBinder()->GetGlobalRecordTable()->Program()) { return {classDefProgram, checker->VarBinder()->AsETSBinder()->GetGlobalRecordTable()}; } return {classDefProgram, checker->VarBinder()->AsETSBinder()->GetExternalRecordTable().at(classDefProgram)}; @@ -131,7 +131,7 @@ Type *ETSChecker::CreatePartialType(Type *const typeToBePartial) Type *ETSChecker::CreatePartialTypeParameter(ETSTypeParameter *typeToBePartial) { - return Allocator()->New(typeToBePartial, this); + return ProgramAllocator()->New(typeToBePartial, this); } Type *ETSChecker::CreatePartialTypeClass(ETSObjectType *typeToBePartial, ir::AstNode *typeDeclNode) @@ -204,8 +204,11 @@ Type *ETSChecker::HandlePartialInterface(ir::TSInterfaceDeclaration *interfaceDe partialInterDecl->Variable()); } + auto savedScope = VarBinder()->TopScope(); + VarBinder()->ResetTopScope(partialProgram->GlobalScope()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *partialType = CreatePartialTypeInterfaceDecl(interfaceDecl, typeToBePartial, partialInterDecl); + VarBinder()->ResetTopScope(savedScope); ES2PANDA_ASSERT(partialType != nullptr); NamedTypeStackElement ntse(this, partialType); @@ -216,12 +219,13 @@ ir::ClassProperty *ETSChecker::CreateNullishPropertyFromAccessor(ir::MethodDefin ir::ClassDefinition *const newClassDefinition) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *ident = accessor->Id()->Clone(Allocator(), nullptr); + auto *ident = accessor->Id()->Clone(ProgramAllocator(), nullptr); auto modifierFlag = accessor->Function()->IsGetter() && accessor->Overloads().empty() ? ir::ModifierFlags::READONLY : ir::ModifierFlags::NONE; - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *prop = Allocator()->New(ident, nullptr, nullptr, modifierFlag, Allocator(), false); + auto *prop = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocator()->New(ident, nullptr, nullptr, modifierFlag, ProgramAllocator(), false); prop->SetParent(newClassDefinition); ident->SetParent(prop); @@ -244,7 +248,7 @@ ir::ClassProperty *ETSChecker::CreateNullishPropertyFromAccessor(ir::MethodDefin auto tsType = accessor->Function()->IsGetter() ? callSign->ReturnType() : callSign->Params()[0]->TsType(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - prop->SetTypeAnnotation(Allocator()->New(tsType, Allocator())); + prop->SetTypeAnnotation(ProgramAllocator()->New(tsType, ProgramAllocator())); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return CreateNullishProperty(prop, newClassDefinition); @@ -259,28 +263,28 @@ ir::ClassProperty *ETSChecker::CreateNullishProperty(ir::ClassProperty *const pr // to 'undefined' anyway prop->SetValue(nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const propClone = prop->Clone(Allocator(), newTSInterfaceDefinition->Body())->AsClassProperty(); + auto *const propClone = prop->Clone(ProgramAllocator(), newTSInterfaceDefinition->Body())->AsClassProperty(); // Revert original property value prop->SetValue(propSavedValue); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - propClone->SetValue(Allocator()->New()); + propClone->SetValue(ProgramAllocator()->New()); auto *propTypeAnn = propClone->TypeAnnotation(); - ArenaVector types(Allocator()->Adapter()); + ArenaVector types(ProgramAllocator()->Adapter()); // Handle implicit type annotation if (propTypeAnn == nullptr) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - propTypeAnn = Allocator()->New(prop->TsType(), Allocator()); + propTypeAnn = ProgramAllocator()->New(prop->TsType(), ProgramAllocator()); } // Create new nullish type types.push_back(propTypeAnn); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - types.push_back(AllocNode(Allocator())); + types.push_back(ProgramAllocNode(ProgramAllocator())); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const unionType = AllocNode(std::move(types), Allocator()); + auto *const unionType = ProgramAllocNode(std::move(types), ProgramAllocator()); propClone->SetTypeAnnotation(unionType); // Set new parents @@ -299,27 +303,27 @@ ir::ClassProperty *ETSChecker::CreateNullishProperty(ir::ClassProperty *const pr // to 'undefined' anyway prop->SetValue(nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const propClone = prop->Clone(Allocator(), newClassDefinition)->AsClassProperty(); + auto *const propClone = prop->Clone(ProgramAllocator(), newClassDefinition)->AsClassProperty(); // Revert original property value prop->SetValue(propSavedValue); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - propClone->SetValue(Allocator()->New()); + propClone->SetValue(ProgramAllocator()->New()); propClone->AsClassProperty()->Value()->Check(this); ir::TypeNode *propertyTypeAnnotation = propClone->TypeAnnotation(); if (propertyTypeAnnotation == nullptr) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - propertyTypeAnnotation = Allocator()->New(prop->Check(this), Allocator()); + propertyTypeAnnotation = ProgramAllocator()->New(prop->Check(this), ProgramAllocator()); } // Create new nullish type annotation - ArenaVector types(Allocator()->Adapter()); + ArenaVector types(ProgramAllocator()->Adapter()); types.push_back(propertyTypeAnnotation); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - types.push_back(AllocNode(Allocator())); + types.push_back(ProgramAllocNode(ProgramAllocator())); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - propertyTypeAnnotation = AllocNode(std::move(types), Allocator()); + propertyTypeAnnotation = ProgramAllocNode(std::move(types), ProgramAllocator()); propClone->SetTypeAnnotation(propertyTypeAnnotation); propClone->SetTsType(nullptr); @@ -335,20 +339,20 @@ ir::TSTypeParameterDeclaration *ETSChecker::ProcessTypeParamAndGenSubstitution( ArenaMap *likeSubstitution, ir::TSTypeParameterDeclaration *newTypeParams = nullptr) { - ArenaVector typeParams(Allocator()->Adapter()); + ArenaVector typeParams(ProgramAllocator()->Adapter()); if (newTypeParams == nullptr) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - newTypeParams = AllocNode(std::move(typeParams), typeParams.size()); + newTypeParams = ProgramAllocNode(std::move(typeParams), typeParams.size()); } for (auto *const classOrInterfaceDefTypeParam : thisTypeParams->Params()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *newTypeParam = AllocNode( + auto *newTypeParam = ProgramAllocNode( // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - CloneNodeIfNotNullptr(classOrInterfaceDefTypeParam->Name(), Allocator()), + CloneNodeIfNotNullptr(classOrInterfaceDefTypeParam->Name(), ProgramAllocator()), // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - CloneNodeIfNotNullptr(classOrInterfaceDefTypeParam->Constraint(), Allocator()), + CloneNodeIfNotNullptr(classOrInterfaceDefTypeParam->Constraint(), ProgramAllocator()), // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - CloneNodeIfNotNullptr(classOrInterfaceDefTypeParam->DefaultType(), Allocator()), Allocator()); + CloneNodeIfNotNullptr(classOrInterfaceDefTypeParam->DefaultType(), ProgramAllocator()), ProgramAllocator()); newTypeParams->AddParam(newTypeParam); newTypeParam->SetParent(newTypeParams); (*likeSubstitution)[classOrInterfaceDefTypeParam] = newTypeParam; @@ -365,8 +369,9 @@ ir::TSTypeParameterInstantiation *ETSChecker::CreateNewSuperPartialRefTypeParams superRef->AsETSTypeReference()->Part()->TypeParams() == nullptr) { return superPartialRefTypeParams; } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - superPartialRefTypeParams = superRef->AsETSTypeReference()->Part()->TypeParams()->Clone(Allocator(), nullptr); + superPartialRefTypeParams = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + superRef->AsETSTypeReference()->Part()->TypeParams()->Clone(ProgramAllocator(), nullptr); superPartialRefTypeParams->SetTsType(nullptr); auto superRefParams = superPartialRefTypeParams->Params(); auto originRefParams = superRef->AsETSTypeReference()->Part()->TypeParams()->Params(); @@ -380,10 +385,11 @@ ir::TSTypeParameterInstantiation *ETSChecker::CreateNewSuperPartialRefTypeParams if (it != likeSubstitution->end()) { auto *typeParamRefPart = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(it->second->Name()->Clone(Allocator(), nullptr), Allocator()); + ProgramAllocNode(it->second->Name()->Clone(ProgramAllocator(), nullptr), + ProgramAllocator()); typeParamRefPart->Name()->SetParent(typeParamRefPart); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *typeParamRef = AllocNode(typeParamRefPart, Allocator()); + auto *typeParamRef = ProgramAllocNode(typeParamRefPart, ProgramAllocator()); typeParamRefPart->SetParent(typeParamRef); typeParamRef->SetParent(superPartialRefTypeParams); @@ -399,21 +405,23 @@ ir::ETSTypeReference *ETSChecker::BuildSuperPartialTypeReference( ir::ETSTypeReference *superPartialRef = nullptr; if (superPartialType != nullptr) { auto *superPartialDeclNode = superPartialType->AsETSObjectType()->GetDeclNode(); - auto *clonedId = superPartialDeclNode->IsClassDefinition() - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ? superPartialDeclNode->AsClassDefinition()->Ident()->Clone(Allocator(), nullptr) - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - : superPartialDeclNode->AsTSInterfaceDeclaration()->Id()->Clone(Allocator(), nullptr); + auto *clonedId = + superPartialDeclNode->IsClassDefinition() + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ? superPartialDeclNode->AsClassDefinition()->Ident()->Clone(ProgramAllocator(), nullptr) + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + : superPartialDeclNode->AsTSInterfaceDeclaration()->Id()->Clone(ProgramAllocator(), nullptr); auto *superPartialRefPart = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(clonedId, superPartialRefTypeParams, nullptr, Allocator()); + ProgramAllocNode(clonedId, superPartialRefTypeParams, nullptr, + ProgramAllocator()); superPartialRefPart->Name()->SetParent(superPartialRefPart); if (superPartialRefTypeParams != nullptr) { superPartialRefTypeParams->SetParent(superPartialRefPart); } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - superPartialRef = AllocNode(superPartialRefPart, Allocator()); + superPartialRef = ProgramAllocNode(superPartialRefPart, ProgramAllocator()); superPartialRefPart->SetParent(superPartialRef); } return superPartialRef; @@ -423,22 +431,23 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla ir::ClassDefinition *classDef) { if (classDef->TypeParams() != nullptr) { - ArenaVector typeParams(Allocator()->Adapter()); + ArenaVector typeParams(ProgramAllocator()->Adapter()); for (auto *const classDefTypeParam : classDef->TypeParams()->Params()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const newTypeParam = AllocNode( + auto *const newTypeParam = ProgramAllocNode( // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - CloneNodeIfNotNullptr(classDefTypeParam->Name(), Allocator()), + CloneNodeIfNotNullptr(classDefTypeParam->Name(), ProgramAllocator()), // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - CloneNodeIfNotNullptr(classDefTypeParam->Constraint(), Allocator()), + CloneNodeIfNotNullptr(classDefTypeParam->Constraint(), ProgramAllocator()), // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - CloneNodeIfNotNullptr(classDefTypeParam->DefaultType(), Allocator()), Allocator()); + CloneNodeIfNotNullptr(classDefTypeParam->DefaultType(), ProgramAllocator()), ProgramAllocator()); typeParams.emplace_back(newTypeParam); } auto *const newTypeParams = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(std::move(typeParams), classDef->TypeParams()->RequiredParams()); + ProgramAllocNode(std::move(typeParams), + classDef->TypeParams()->RequiredParams()); newClassDefinition->SetTypeParams(newTypeParams); newTypeParams->SetParent(newClassDefinition); @@ -459,7 +468,7 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla auto *const newProp = CreateNullishProperty(prop->AsClassProperty(), newClassDefinition); // Put the new property into the class declaration - newClassDefinition->Body().emplace_back(newProp); + newClassDefinition->EmplaceBody(newProp); } if (prop->IsMethodDefinition() && (prop->AsMethodDefinition()->Function()->IsGetter() || @@ -470,7 +479,7 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla continue; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - newClassDefinition->Body().emplace_back(CreateNullishPropertyFromAccessor(method, newClassDefinition)); + newClassDefinition->EmplaceBody(CreateNullishPropertyFromAccessor(method, newClassDefinition)); } } if (classDef->IsDeclare()) { @@ -484,12 +493,13 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla newClassDefinition->Variable()->SetTsType(nullptr); } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *const accessor, ir::TSInterfaceDeclaration *interface) { const auto interfaceCtx = varbinder::LexicalScope::Enter(VarBinder(), interface->Scope()); - auto *paramScope = Allocator()->New(Allocator(), interface->Scope()); - auto *functionScope = Allocator()->New(Allocator(), paramScope); + auto *paramScope = ProgramAllocator()->New(ProgramAllocator(), interface->Scope()); + auto *functionScope = ProgramAllocator()->New(ProgramAllocator(), paramScope); functionScope->BindParamScope(paramScope); paramScope->BindFunctionScope(functionScope); @@ -499,10 +509,11 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ir::MethodDefinition *nullishAccessor = accessor->Clone(Allocator(), interface->Body()); + ir::MethodDefinition *nullishAccessor = accessor->Clone(ProgramAllocator(), interface->Body()); - auto *decl = Allocator()->New(Allocator(), nullishAccessor->Id()->Name(), nullishAccessor); - auto *var = Allocator()->New(decl, varbinder::VariableFlags::VAR); + auto *decl = ProgramAllocator()->New(ProgramAllocator(), nullishAccessor->Id()->Name(), + nullishAccessor); + auto *var = ProgramAllocator()->New(decl, varbinder::VariableFlags::VAR); var->AddFlag(varbinder::VariableFlags::METHOD); nullishAccessor->Id()->SetVariable(var); nullishAccessor->SetVariable(var); @@ -513,7 +524,7 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co function->SetVariable(var); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - function->SetIdent(nullishAccessor->Id()->Clone(Allocator(), function)); + function->SetIdent(nullishAccessor->Id()->Clone(ProgramAllocator(), function)); function->SetScope(functionScope); paramScope->BindNode(function); functionScope->BindNode(function); @@ -522,36 +533,36 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co auto *propTypeAnn = function->ReturnTypeAnnotation(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - function->SetReturnTypeAnnotation(AllocNode( + function->SetReturnTypeAnnotation(ProgramAllocNode( // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - ArenaVector({propTypeAnn, AllocNode(Allocator())}, - Allocator()->Adapter()), - Allocator())); + ArenaVector({propTypeAnn, ProgramAllocNode(ProgramAllocator())}, + ProgramAllocator()->Adapter()), + ProgramAllocator())); } else { for (auto *params : function->Params()) { auto *paramExpr = params->AsETSParameterExpression(); auto *unionType = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode( + ProgramAllocNode( ArenaVector({paramExpr->Ident()->TypeAnnotation(), // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(Allocator())}, - Allocator()->Adapter()), - Allocator()); + ProgramAllocNode(ProgramAllocator())}, + ProgramAllocator()->Adapter()), + ProgramAllocator()); paramExpr->Ident()->SetTsTypeAnnotation(unionType); unionType->SetParent(paramExpr->Ident()); - auto [paramVar, node] = paramScope->AddParamDecl(Allocator(), paramExpr); + auto [paramVar, node] = paramScope->AddParamDecl(ProgramAllocator(), VarBinder(), paramExpr); if (node != nullptr) { - VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name()); + VarBinder()->ThrowRedeclaration(node->Start(), paramVar->Name(), paramVar->Declaration()->Type()); } paramExpr->SetVariable(paramVar); } } - nullishAccessor->SetOverloads(ArenaVector(Allocator()->Adapter())); + nullishAccessor->SetOverloads(ArenaVector(ProgramAllocator()->Adapter())); return nullishAccessor; } @@ -564,21 +575,21 @@ ir::TSInterfaceDeclaration *ETSChecker::CreateInterfaceProto(util::StringView na varbinder::LexicalScope::Enter(VarBinder(), interfaceDeclProgram->GlobalScope()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const interfaceId = AllocNode(name, Allocator()); - const auto [decl, var] = - VarBinder()->NewVarDecl(interfaceId->Start(), Allocator(), interfaceId->Name()); + auto *const interfaceId = ProgramAllocNode(name, ProgramAllocator()); + const auto [decl, var] = VarBinder()->NewVarDecl(interfaceId->Start(), ProgramAllocator(), + interfaceId->Name()); interfaceId->SetVariable(var); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *body = AllocNode(ArenaVector(Allocator()->Adapter())); - ArenaVector extends(Allocator()->Adapter()); + auto *body = ProgramAllocNode(ArenaVector(ProgramAllocator()->Adapter())); + ArenaVector extends(ProgramAllocator()->Adapter()); - ArenaVector typeParams(Allocator()->Adapter()); + ArenaVector typeParams(ProgramAllocator()->Adapter()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *newTypeParams = AllocNode(std::move(typeParams), typeParams.size()); + auto *newTypeParams = ProgramAllocNode(std::move(typeParams), typeParams.size()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto partialInterface = AllocNode( - Allocator(), std::move(extends), + auto partialInterface = ProgramAllocNode( + ProgramAllocator(), std::move(extends), ir::TSInterfaceDeclaration::ConstructorData {interfaceId, newTypeParams, body, isStatic, interfaceDeclProgram != VarBinder()->Program(), Language(Language::Id::ETS)}); @@ -591,10 +602,12 @@ ir::TSInterfaceDeclaration *ETSChecker::CreateInterfaceProto(util::StringView na // Put class declaration in global scope, and in program AST partialInterface->SetParent(interfaceDeclProgram->Ast()); - interfaceDeclProgram->Ast()->Statements().push_back(partialInterface); + interfaceDeclProgram->Ast()->AddStatement(partialInterface); interfaceDeclProgram->GlobalScope()->InsertBinding(name, var); partialInterface->AddModifier(flags); + partialInterface->ClearModifier(ir::ModifierFlags::EXPORTED); + partialInterface->ClearModifier(ir::ModifierFlags::DEFAULT_EXPORT); return partialInterface; } @@ -659,7 +672,7 @@ Type *ETSChecker::CreatePartialTypeInterfaceDecl(ir::TSInterfaceDeclaration *con // Create nullish properties of the partial class // Build the new Partial class based on the 'T' type parameter of 'Partial' auto *likeSubstitution = - Allocator()->New>(Allocator()->Adapter()); + ProgramAllocator()->New>(ProgramAllocator()->Adapter()); if (interfaceDecl->TypeParams() != nullptr) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -673,9 +686,9 @@ Type *ETSChecker::CreatePartialTypeInterfaceDecl(ir::TSInterfaceDeclaration *con // Add getter methods to instancemethodscope. for (auto *const prop : partialInterface->Body()->Body()) { if (prop->IsMethodDefinition() && prop->AsMethodDefinition()->Function()->IsGetter()) { - auto *decl = Allocator()->New( - Allocator(), prop->AsMethodDefinition()->Key()->AsIdentifier()->Name(), prop); - methodscope->AddDecl(Allocator(), decl, ScriptExtension::ETS); + auto *decl = ProgramAllocator()->New( + ProgramAllocator(), prop->AsMethodDefinition()->Key()->AsIdentifier()->Name(), prop); + methodscope->AddDecl(ProgramAllocator(), decl, ScriptExtension::ETS); } } @@ -693,7 +706,7 @@ Type *ETSChecker::CreatePartialTypeInterfaceDecl(ir::TSInterfaceDeclaration *con // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) BuildSuperPartialTypeReference(superPartialType, superPartialRefTypeParams); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - partialInterface->Extends().push_back(AllocNode(superPartialRef)); + partialInterface->EmplaceExtends(ProgramAllocNode(superPartialRef)); partialInterface->Extends().back()->SetParent(partialInterface); } } @@ -726,12 +739,12 @@ void ETSChecker::CreateConstructorForPartialType(ir::ClassDefinition *const part partialType->AddConstructSignature(ctorFunc->Signature()); ctorFunc->Signature()->SetOwner(partialType); ctor->SetParent(partialClassDef); - ctorId->SetVariable(Allocator()->New( - Allocator()->New(ctorId->Name()), varbinder::VariableFlags::METHOD)); + ctorId->SetVariable(ProgramAllocator()->New( + ProgramAllocator()->New(ctorId->Name()), varbinder::VariableFlags::METHOD)); ctor->Id()->SetVariable(ctorId->Variable()); // Put ctor in partial class body - partialClassDef->Body().emplace_back(ctor); + partialClassDef->EmplaceBody(ctor); } ir::ClassDefinition *ETSChecker::CreateClassPrototype(util::StringView name, parser::Program *const classDeclProgram) @@ -741,7 +754,7 @@ ir::ClassDefinition *ETSChecker::CreateClassPrototype(util::StringView name, par // Create class name, and declaration variable // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const classId = AllocNode(name, Allocator()); + auto *const classId = ProgramAllocNode(name, ProgramAllocator()); const auto [decl, var] = VarBinder()->NewVarDecl(classId->Start(), classId->Name()); classId->SetVariable(var); @@ -749,14 +762,14 @@ ir::ClassDefinition *ETSChecker::CreateClassPrototype(util::StringView name, par const auto classCtx = varbinder::LexicalScope(VarBinder()); auto *const classDef = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - AllocNode(Allocator(), classId, ir::ClassDefinitionModifiers::DECLARATION, - ir::ModifierFlags::NONE, Language(Language::Id::ETS)); + ProgramAllocNode(ProgramAllocator(), classId, ir::ClassDefinitionModifiers::DECLARATION, + ir::ModifierFlags::NONE, Language(Language::Id::ETS)); classDef->SetScope(classCtx.GetScope()); classDef->SetVariable(var); // Create class declaration node // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const classDecl = AllocNode(classDef, Allocator()); + auto *const classDecl = ProgramAllocNode(classDef, ProgramAllocator()); classDecl->SetParent(classDeclProgram->Ast()); // Class definition is scope bearer, not class declaration @@ -764,7 +777,7 @@ ir::ClassDefinition *ETSChecker::CreateClassPrototype(util::StringView name, par decl->BindNode(classDef); // Put class declaration in global scope, and in program AST - classDeclProgram->Ast()->Statements().push_back(classDecl); + classDeclProgram->Ast()->AddStatement(classDecl); classDeclProgram->GlobalScope()->InsertBinding(name, var); return classDef; @@ -796,7 +809,7 @@ Type *ETSChecker::HandleUnionForPartialType(ETSUnionType *const typeToBePartial) // Convert a union type to partial, by converting all types in it to partial, and making a new union // type out of them const auto *const unionTypeNode = typeToBePartial->AsETSUnionType(); - ArenaVector newTypesForUnion(Allocator()->Adapter()); + ArenaVector newTypesForUnion(ProgramAllocator()->Adapter()); for (auto *const typeFromUnion : unionTypeNode->ConstituentTypes()) { if ((typeFromUnion->Variable() != nullptr) && (typeFromUnion->Variable()->Declaration() != nullptr)) { @@ -846,24 +859,25 @@ Type *ETSChecker::CreatePartialTypeClassDef(ir::ClassDefinition *const partialCl std::pair ETSChecker::CreateScriptFunctionForConstructor( varbinder::FunctionScope *const scope) { - ArenaVector statements(Allocator()->Adapter()); - ArenaVector params(Allocator()->Adapter()); + ArenaVector statements(ProgramAllocator()->Adapter()); + ArenaVector params(ProgramAllocator()->Adapter()); ir::ScriptFunction *func {}; ir::Identifier *id {}; // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const body = AllocNode(Allocator(), std::move(statements)); + auto *const body = ProgramAllocNode(ProgramAllocator(), std::move(statements)); body->SetScope(scope); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - id = AllocNode(util::UString(std::string("constructor"), Allocator()).View(), Allocator()); + id = ProgramAllocNode(util::UString(std::string("constructor"), ProgramAllocator()).View(), + ProgramAllocator()); auto funcSignature = ir::FunctionSignature(nullptr, std::move(params), nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - func = AllocNode(Allocator(), - ir::ScriptFunction::ScriptFunctionData { - body, std::move(funcSignature), - ir::ScriptFunctionFlags::CONSTRUCTOR | ir::ScriptFunctionFlags::EXPRESSION, - ir::ModifierFlags::PUBLIC}); + func = ProgramAllocNode( + ProgramAllocator(), ir::ScriptFunction::ScriptFunctionData {body, std::move(funcSignature), + ir::ScriptFunctionFlags::CONSTRUCTOR | + ir::ScriptFunctionFlags::EXPRESSION, + ir::ModifierFlags::PUBLIC}); func->SetScope(scope); scope->BindNode(func); @@ -878,8 +892,8 @@ ir::MethodDefinition *ETSChecker::CreateNonStaticClassInitializer(varbinder::Cla { const auto classCtx = varbinder::LexicalScope::Enter(VarBinder(), classScope); - auto *paramScope = Allocator()->New(Allocator(), classScope); - auto *const functionScope = Allocator()->New(Allocator(), paramScope); + auto *paramScope = ProgramAllocator()->New(ProgramAllocator(), classScope); + auto *const functionScope = ProgramAllocator()->New(ProgramAllocator(), paramScope); functionScope->BindParamScope(paramScope); paramScope->BindFunctionScope(functionScope); @@ -900,14 +914,15 @@ ir::MethodDefinition *ETSChecker::CreateNonStaticClassInitializer(varbinder::Cla VarBinder()->Functions().push_back(functionScope); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *funcExpr = AllocNode(func); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const ctor = AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - id->Clone(Allocator(), classScope->Node()), funcExpr, - ir::ModifierFlags::NONE, Allocator(), false); + auto *funcExpr = ProgramAllocNode(func); + auto *const ctor = + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + ProgramAllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + id->Clone(ProgramAllocator(), classScope->Node()), funcExpr, + ir::ModifierFlags::NONE, ProgramAllocator(), false); - auto *const funcType = CreateETSMethodType(id->Name(), {{signature}, Allocator()->Adapter()}); + auto *const funcType = CreateETSMethodType(id->Name(), {{signature}, ProgramAllocator()->Adapter()}); ctor->SetTsType(funcType); return ctor; @@ -922,7 +937,8 @@ Type *ETSChecker::GetReadonlyType(Type *type) NamedTypeStackElement ntse(this, type); if (type->IsETSArrayType()) { - ETSArrayType *const clonedArrayType = Allocator()->New(type->AsETSArrayType()->ElementType()); + ETSArrayType *const clonedArrayType = + ProgramAllocator()->New(type->AsETSArrayType()->ElementType()); clonedArrayType->AddTypeFlag(TypeFlag::READONLY); return clonedArrayType; } @@ -939,10 +955,10 @@ Type *ETSChecker::GetReadonlyType(Type *type) return clonedType; } if (type->IsETSTypeParameter()) { - return Allocator()->New(type->AsETSTypeParameter()); + return ProgramAllocator()->New(type->AsETSTypeParameter()); } if (type->IsETSUnionType()) { - ArenaVector unionTypes(Allocator()->Adapter()); + ArenaVector unionTypes(ProgramAllocator()->Adapter()); for (auto *t : type->AsETSUnionType()->ConstituentTypes()) { unionTypes.emplace_back(t->IsETSObjectType() ? GetReadonlyType(t) : t->Clone(this)); } @@ -953,9 +969,10 @@ Type *ETSChecker::GetReadonlyType(Type *type) void ETSChecker::MakePropertiesReadonly(ETSObjectType *const classType) { - classType->UpdateTypeProperties(this, [this](auto *property, auto *propType) { - auto *newDecl = Allocator()->New(property->Name(), property->Declaration()->Node()); - auto *const propCopy = property->Copy(Allocator(), newDecl); + classType->UpdateTypeProperties([this](auto *property, auto *propType) { + auto *newDecl = + ProgramAllocator()->New(property->Name(), property->Declaration()->Node()); + auto *const propCopy = property->Copy(ProgramAllocator(), newDecl); propCopy->AddFlag(varbinder::VariableFlags::READONLY); propCopy->SetTsType(propType); return propCopy; @@ -980,7 +997,7 @@ Type *ETSChecker::HandleRequiredType(Type *typeToBeRequired) } if (typeToBeRequired->IsETSUnionType()) { - ArenaVector unionTypes(Allocator()->Adapter()); + ArenaVector unionTypes(ProgramAllocator()->Adapter()); for (auto *type : typeToBeRequired->AsETSUnionType()->ConstituentTypes()) { if (type->IsETSObjectType()) { type = type->Clone(this); @@ -1034,7 +1051,7 @@ void ETSChecker::MakePropertyNonNullish(ETSObjectType *const classType, varbinde auto *const propType = prop->TsType(); auto *const nonNullishPropType = GetNonNullishType(propType); - auto *const propCopy = prop->Copy(Allocator(), prop->Declaration()); + auto *const propCopy = prop->Copy(ProgramAllocator(), prop->Declaration()); propCopy->SetTsType(nonNullishPropType); classType->RemoveProperty(prop); @@ -1085,4 +1102,5 @@ void ETSChecker::ValidateObjectLiteralForRequiredType(const ETSObjectType *const } } } + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/validateHelpers.cpp b/ets2panda/checker/ets/validateHelpers.cpp index 68fca277ff47739cb7b3761fcaf5e88761cfeb77..f3ad9a385b9c4e0619ab024c454748e9602ecc35 100644 --- a/ets2panda/checker/ets/validateHelpers.cpp +++ b/ets2panda/checker/ets/validateHelpers.cpp @@ -47,7 +47,7 @@ void ETSChecker::ValidatePropertyAccess(varbinder::Variable *var, ETSObjectType return; } - std::ignore = TypeError(var, {"Property ", var->Name(), " is not visible here."}, pos); + std::ignore = TypeError(var, diagnostic::PROP_INVISIBLE, {var->Name()}, pos); } } @@ -56,8 +56,7 @@ void ETSChecker::ValidateCallExpressionIdentifier(ir::Identifier *const ident, T if (ident->Variable()->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE) && ident->Parent()->AsCallExpression()->Callee() != ident) { std::ignore = - TypeError(ident->Variable(), {"Class or interface '", ident->ToString(), "' cannot be used as object"}, - ident->Start()); + TypeError(ident->Variable(), diagnostic::CLASS_OR_IFACE_AS_OBJ, {ident->ToString()}, ident->Start()); } if (ident->Parent()->AsCallExpression()->Callee() != ident) { @@ -67,8 +66,7 @@ void ETSChecker::ValidateCallExpressionIdentifier(ir::Identifier *const ident, T ES2PANDA_ASSERT(ident->Variable() != nullptr); if (ident->Variable()->Declaration()->Node() != nullptr && ident->Variable()->Declaration()->Node()->IsImportNamespaceSpecifier()) { - std::ignore = TypeError( - ident->Variable(), {"Namespace style identifier ", ident->ToString(), " is not callable."}, ident->Start()); + std::ignore = TypeError(ident->Variable(), diagnostic::NAMESPACE_CALL, {ident->ToString()}, ident->Start()); } if (type->IsETSFunctionType() || type->IsETSDynamicType()) { return; @@ -78,7 +76,7 @@ void ETSChecker::ValidateCallExpressionIdentifier(ir::Identifier *const ident, T return; } - std::ignore = TypeError(ident->Variable(), "This expression is not callable.", ident->Start()); + std::ignore = TypeError(ident->Variable(), diagnostic::EXPR_NOT_CALLABLE, {}, ident->Start()); } void ETSChecker::ValidateNewClassInstanceIdentifier(ir::Identifier *const ident) @@ -88,7 +86,7 @@ void ETSChecker::ValidateNewClassInstanceIdentifier(ir::Identifier *const ident) if (ident->Parent()->AsETSNewClassInstanceExpression()->GetTypeRef() == ident && !resolved->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE) && !resolved->TsType()->IsTypeError()) { - LogTypeError({"Invalid reference '", ident->Name(), "'."}, ident->Start()); + LogError(diagnostic::REF_INVALID, {ident->Name()}, ident->Start()); } } @@ -127,13 +125,23 @@ void ETSChecker::ValidateAssignmentIdentifier(ir::Identifier *const ident, Type bool ETSChecker::ValidateBinaryExpressionIdentifier(ir::Identifier *const ident, Type *const type) { + auto const resolved = ident->Variable(); const auto *const binaryExpr = ident->Parent()->AsBinaryExpression(); bool isFinished = false; - if (binaryExpr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF && binaryExpr->Right() == ident) { + + if (binaryExpr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF && binaryExpr->Left() == ident) { if (!IsReferenceType(type)) { - std::ignore = TypeError(ident->Variable(), - {R"(Using the "instance of" operator with non-object type ")", ident->Name(), "\""}, - ident->Start()); + std::ignore = + TypeError(ident->Variable(), diagnostic::INSTANCEOF_NONOBJECT, {ident->Name()}, ident->Start()); + } + isFinished = true; + } + + if (binaryExpr->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING || + binaryExpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_OR || + binaryExpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) { + if ((resolved != nullptr) && (!resolved->Declaration()->PossibleTDZ() && !type->IsETSFunctionType())) { + WrongContextErrorClassifyByType(ident); } isFinished = true; } @@ -190,8 +198,8 @@ bool ETSChecker::ValidateAnnotationPropertyType(checker::Type *type) return false; } - if (type->IsETSArrayType()) { - return ValidateAnnotationPropertyType(type->AsETSArrayType()->ElementType()); + if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { + return ValidateAnnotationPropertyType(MaybeUnboxType(GetElementTypeOfArray(type))); } return type->HasTypeFlag(TypeFlag::ETS_NUMERIC | TypeFlag::ETS_ENUM | TypeFlag::ETS_BOOLEAN) || @@ -206,16 +214,22 @@ void ETSChecker::ValidateUnaryOperatorOperand(varbinder::Variable *variable) if (variable->Declaration()->IsConstDecl() || variable->Declaration()->IsReadonlyDecl()) { std::string_view fieldType = variable->Declaration()->IsConstDecl() ? "constant" : "readonly"; - if (HasStatus(CheckerStatus::IN_CONSTRUCTOR | CheckerStatus::IN_STATIC_BLOCK) && - !variable->HasFlag(varbinder::VariableFlags::EXPLICIT_INIT_REQUIRED)) { - std::ignore = TypeError(variable, {"Cannot reassign ", fieldType, " ", variable->Name()}, + if ((HasStatus(CheckerStatus::IN_CONSTRUCTOR | CheckerStatus::IN_STATIC_BLOCK) && + !variable->HasFlag(varbinder::VariableFlags::EXPLICIT_INIT_REQUIRED)) || + (variable->HasFlag(varbinder::VariableFlags::INIT_IN_STATIC_BLOCK) && + variable->HasFlag(varbinder::VariableFlags::INITIALIZED))) { + std::ignore = TypeError(variable, diagnostic::FIELD_REASSIGNMENT, {fieldType, variable->Name()}, variable->Declaration()->Node()->Start()); return; } if (!HasStatus(CheckerStatus::IN_CONSTRUCTOR | CheckerStatus::IN_STATIC_BLOCK)) { - std::ignore = TypeError(variable, {"Cannot assign to a ", fieldType, " variable ", variable->Name()}, + std::ignore = TypeError(variable, diagnostic::FIELD_ASSIGN_TYPE_MISMATCH, {fieldType, variable->Name()}, variable->Declaration()->Node()->Start()); } + + if (variable->HasFlag(varbinder::VariableFlags::INIT_IN_STATIC_BLOCK)) { + variable->AddFlag(varbinder::VariableFlags::INITIALIZED); + } } } @@ -304,7 +318,7 @@ bool ETSChecker::IsArrayExprSizeValidForTuple(const ir::ArrayExpression *const a } if (size != tuple->GetTupleSize()) { - LogError(diagnostic::TUPLE_TOO_FEW_ELEMS, {size, tuple->GetTupleSize()}, arrayExpr->Start()); + LogError(diagnostic::TUPLE_WRONG_NUMBER_OF_ELEMS, {size, tuple->GetTupleSize()}, arrayExpr->Start()); return false; } diff --git a/ets2panda/checker/ets/wideningConverter.h b/ets2panda/checker/ets/wideningConverter.h index 71508cadfcef8c04c483f04e36b7688e044825c1..00f65deda0daa1f03557f22fa6fc7a7228c6ca0a 100644 --- a/ets2panda/checker/ets/wideningConverter.h +++ b/ets2panda/checker/ets/wideningConverter.h @@ -16,8 +16,8 @@ #ifndef ES2PANDA_COMPILER_CHECKER_ETS_WIDENING_CONVERTER_H #define ES2PANDA_COMPILER_CHECKER_ETS_WIDENING_CONVERTER_H -#include "checker/ets/typeConverter.h" #include "checker/ETSchecker.h" +#include "checker/ets/typeConverter.h" namespace ark::es2panda::checker { @@ -209,7 +209,7 @@ private: if (!Relation()->OnlyCheckWidening()) { ES2PANDA_ASSERT(Relation()->GetNode()); - Relation()->GetNode()->SetTsType(Checker()->Allocator()->New(static_cast(value))); + Relation()->GetNode()->SetTsType(Checker()->ProgramAllocator()->New(static_cast(value))); } } }; diff --git a/ets2panda/checker/resolveResult.h b/ets2panda/checker/resolveResult.h index 2c91fd4b3eb479aa7465ea4fdd1d08bd5192d342..a2c09a86b65bc8911d23b354fb853cfd16645f97 100644 --- a/ets2panda/checker/resolveResult.h +++ b/ets2panda/checker/resolveResult.h @@ -24,6 +24,7 @@ enum class OverrideErrorCode { INCOMPATIBLE_TYPEPARAM, OVERRIDDEN_WEAKER, OVERRIDDEN_INTERNAL, + ABSTRACT_OVERRIDES_CONCRETE, }; enum class ResolvedKind { diff --git a/ets2panda/checker/ts/destructuringContext.cpp b/ets2panda/checker/ts/destructuringContext.cpp index fae375a1ba4ce8d279802dce319e360b20e4ccc7..95f65a54bb3774b404092e6be1cefd35534e21c7 100644 --- a/ets2panda/checker/ts/destructuringContext.cpp +++ b/ets2panda/checker/ts/destructuringContext.cpp @@ -80,11 +80,8 @@ void DestructuringContext::SetInferredTypeForVariable(varbinder::Variable *var, } if (var->TsType() != nullptr) { - checker_->IsTypeIdenticalTo(var->TsType(), inferredType, - {"Subsequent variable declaration must have the same type. Variable '", var->Name(), - "' must be of type '", var->TsType(), "', but here has type '", inferredType, - "'."}, - loc); + checker_->IsTypeIdenticalTo(var->TsType(), inferredType, diagnostic::DIFFERENT_SUBSEQ_DECL, + {var->Name(), var->TsType(), inferredType}, loc); return; } diff --git a/ets2panda/checker/ts/helpers.cpp b/ets2panda/checker/ts/helpers.cpp index 1762795939461a9115a2af76b31d4aa29f4d85e6..9c2455f558c2cf064c93663fee5cd0ffa05bf9b4 100644 --- a/ets2panda/checker/ts/helpers.cpp +++ b/ets2panda/checker/ts/helpers.cpp @@ -483,9 +483,7 @@ Type *TSChecker::GetTypeOfVariable(varbinder::Variable *var) varbinder::Decl *decl = var->Declaration(); - util::DiagnosticMessageParams params {"'", var->Name(), "' is referenced directly or indirectly in its ", - "own initializer ot type annotation."}; - TypeStackElement tse(this, decl->Node(), params, decl->Node()->Start()); + TypeStackElement tse(this, decl->Node(), {{diagnostic::CYCLIC_VAR_REF, {var->Name()}}}, decl->Node()->Start()); if (tse.HasTypeError()) { return GlobalErrorType(); } @@ -516,7 +514,7 @@ Type *TSChecker::GetTypeFromTypeAliasReference(ir::TSTypeReference *node, varbin return resolvedType; } - TypeStackElement tse(this, var, {"Type alias ", var->Name(), " circularly refences itself"}, node->Start()); + TypeStackElement tse(this, var, {{diagnostic::CYCLIC_ALIAS_2, {var->Name()}}}, node->Start()); if (tse.HasTypeError()) { return GlobalErrorType(); } diff --git a/ets2panda/checker/ts/object.cpp b/ets2panda/checker/ts/object.cpp index 35bfe5f05b9ad2176ca8ff66abe417b37d104bda..d0b36c61dc21745bb7fb0994b1f9c0f222731dd9 100644 --- a/ets2panda/checker/ts/object.cpp +++ b/ets2panda/checker/ts/object.cpp @@ -55,10 +55,8 @@ void TSChecker::CheckIndexConstraints(Type *type) for (auto *it : properties) { if (it->HasFlag(varbinder::VariableFlags::NUMERIC_NAME)) { Type *propType = GetTypeOfVariable(it); - IsTypeAssignableTo(propType, numberInfo->GetType(), - {"Property '", it->Name(), "' of type '", propType, - "' is not assignable to numeric index type '", numberInfo->GetType(), "'."}, - it->Declaration()->Node()->Start()); + IsTypeAssignableTo(propType, numberInfo->GetType(), diagnostic::PROP_ASSIGN_TO_NUMERIC_INDEX, + {it->Name(), propType, numberInfo->GetType()}, it->Declaration()->Node()->Start()); } } } @@ -66,10 +64,8 @@ void TSChecker::CheckIndexConstraints(Type *type) if (stringInfo != nullptr) { for (auto *it : properties) { Type *propType = GetTypeOfVariable(it); - IsTypeAssignableTo(propType, stringInfo->GetType(), - {"Property '", it->Name(), "' of type '", propType, - "' is not assignable to string index type '", stringInfo->GetType(), "'."}, - it->Declaration()->Node()->Start()); + IsTypeAssignableTo(propType, stringInfo->GetType(), diagnostic::PROP_ASSIGN_TO_STRING_INDEX, + {it->Name(), propType, stringInfo->GetType()}, it->Declaration()->Node()->Start()); } if (numberInfo != nullptr && !IsTypeAssignableTo(numberInfo->GetType(), stringInfo->GetType())) { @@ -442,7 +438,7 @@ ArenaVector TSChecker::GetBaseTypes(InterfaceType *type) ES2PANDA_ASSERT(type->Variable() && type->Variable()->Declaration()->IsInterfaceDecl()); varbinder::InterfaceDecl *decl = type->Variable()->Declaration()->AsInterfaceDecl(); - TypeStackElement tse(this, type, {"Type ", type->Name(), " recursively references itself as a base type."}, + TypeStackElement tse(this, type, {{diagnostic::RECURSIVE_EXTENSION, {type->Name()}}}, decl->Node()->AsTSInterfaceDeclaration()->Id()->Start()); if (tse.HasTypeError()) { type->Bases().clear(); @@ -540,10 +536,8 @@ bool TSChecker::ValidateInterfaceMemberRedeclaration(ObjectType *type, varbinder Type *targetType = GetTypeOfVariable(prop); Type *sourceType = GetTypeOfVariable(found); - IsTypeIdenticalTo(targetType, sourceType, - {"Subsequent property declarations must have the same type. Property ", prop->Name(), - " must be of type ", sourceType, ", but here has type ", targetType, "."}, - locInfo); + IsTypeIdenticalTo(targetType, sourceType, diagnostic::DIFFERENT_SUBSEQ_PROP_DECL, + {prop->Name(), sourceType, targetType}, locInfo); return false; } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/typeChecker/TypeChecker.h b/ets2panda/checker/typeChecker/TypeChecker.h index 239db9c7ff6e6274d8440affa6d82c1b8a4659ae..802f884a5c6a5d19d8dd23ba0a4add9ff72346b7 100644 --- a/ets2panda/checker/typeChecker/TypeChecker.h +++ b/ets2panda/checker/typeChecker/TypeChecker.h @@ -37,11 +37,6 @@ public: protected: explicit TypeChecker(Checker *checker) : checker_(checker) {} - void LogTypeError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &pos) - { - checker_->LogTypeError(list, pos); - } - void LogError(const diagnostic::DiagnosticKind &diagnostic, const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos) { diff --git a/ets2panda/checker/types/ets/charType.cpp b/ets2panda/checker/types/ets/charType.cpp index 044657176938dfc8ba8914c7faeea14277b7dc57..62fad52d6eb2f8e635e2943810a817976103d996 100644 --- a/ets2panda/checker/types/ets/charType.cpp +++ b/ets2panda/checker/types/ets/charType.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 @@ -37,11 +37,6 @@ void CharType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *s bool CharType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) { if (relation->InAssignmentContext()) { - if (target->IsETSStringType()) { - conversion::Boxing(relation, this); - relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); - return relation->Result(true); - } relation->GetChecker()->AsETSChecker()->CheckUnboxedTypeWidenable(relation, target, this); if (!relation->IsTrue()) { return false; @@ -72,11 +67,6 @@ void CharType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSStringType()) { - conversion::String(relation, this); - return; - } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)) { conversion::Boxing(relation, this); diff --git a/ets2panda/checker/types/ets/etsArrayType.cpp b/ets2panda/checker/types/ets/etsArrayType.cpp index 5a52ef15c3e19e24b10b262f93be7dbdfb1cda3f..2f0573d664103a80b83e96d590b62ca7d01da44c 100644 --- a/ets2panda/checker/types/ets/etsArrayType.cpp +++ b/ets2panda/checker/types/ets/etsArrayType.cpp @@ -14,6 +14,7 @@ */ #include "etsArrayType.h" +#include #include "varbinder/variable.h" #include "checker/ETSchecker.h" @@ -27,6 +28,7 @@ void ETSArrayType::ToString(std::stringstream &ss, bool precise) const if (HasTypeFlag(TypeFlag::READONLY)) { ss << "readonly "; } + ss << "FixedArray<"; bool needParens = (element_->IsETSUnionType() || element_->IsETSFunctionType()); if (needParens) { ss << "("; @@ -35,7 +37,7 @@ void ETSArrayType::ToString(std::stringstream &ss, bool precise) const if (needParens) { ss << ")"; } - ss << "[]"; + ss << ">"; } void ETSArrayType::ToAssemblerType(std::stringstream &ss) const @@ -60,21 +62,10 @@ void ETSArrayType::ToDebugInfoType(std::stringstream &ss) const uint32_t ETSArrayType::Rank() const { - const auto arrayHasNestedLevels = [](const Type *const iter) { - if (!iter->IsETSArrayType() && !iter->IsETSTupleType()) { - return false; - } - - const auto *const nestedElementType = - iter->IsETSArrayType() ? iter->AsETSArrayType()->ElementType() : iter->AsETSTupleType()->GetLubType(); - - return nestedElementType != iter; - }; - uint32_t rank = 1; - auto *iter = element_; - while (arrayHasNestedLevels(iter)) { - iter = iter->IsETSArrayType() ? iter->AsETSArrayType()->ElementType() : iter->AsETSTupleType()->GetLubType(); + const auto *iter = element_; + while (iter->IsETSArrayType() && iter->AsETSArrayType()->ElementType() != iter) { + iter = iter->AsETSArrayType()->ElementType(); rank++; } @@ -93,6 +84,22 @@ void ETSArrayType::Identical(TypeRelation *relation, Type *other) } } +static bool IsFixedArrayDeclaration(ir::AstNode *node) +{ + return node != nullptr && (node->IsArrayExpression() || node->IsETSNewArrayInstanceExpression() || + node->IsETSNewMultiDimArrayInstanceExpression()); +} + +bool ETSArrayType::AssignmentSource(TypeRelation *relation, Type *target) +{ + if (target->IsETSResizableArrayType() && IsFixedArrayDeclaration(relation->GetNode())) { + relation->IsAssignableTo(element_, target->AsETSResizableArrayType()->ElementType()); + // For lowering purpose + relation->GetNode()->SetTsType(target); + } + return relation->IsTrue(); +} + void ETSArrayType::AssignmentTarget(TypeRelation *relation, Type *source) { if (source->HasTypeFlag(TypeFlag::READONLY)) { diff --git a/ets2panda/checker/types/ets/etsArrayType.h b/ets2panda/checker/types/ets/etsArrayType.h index 78cceccd5e2018c57754eaacb687047a0b3b06ea..9794adb54f0f11e1a5cc0dfb2a2ffc7b528fdde4 100644 --- a/ets2panda/checker/types/ets/etsArrayType.h +++ b/ets2panda/checker/types/ets/etsArrayType.h @@ -51,6 +51,7 @@ public: uint32_t Rank() const override; void Identical(TypeRelation *relation, Type *other) override; + bool AssignmentSource(TypeRelation *relation, Type *target) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; void Cast(TypeRelation *relation, Type *target) override; void IsSupertypeOf(TypeRelation *relation, Type *source) override; diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h index e1ede4842b6fe35b3dc6ac4d712bf8e26ed064f2..e079ff71a6802e5d9e84768e4484c6288bc40fce 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h @@ -23,7 +23,7 @@ class GlobalTypesHolder; class ETSAsyncFuncReturnType : public ETSObjectType { public: - ETSAsyncFuncReturnType(ArenaAllocator *allocator, TypeRelation *relation, ETSObjectType *promiseType) + ETSAsyncFuncReturnType(ThreadSafeArenaAllocator *allocator, TypeRelation *relation, ETSObjectType *promiseType) : ETSObjectType(allocator, "", compiler::Signatures::BUILTIN_OBJECT, std::make_tuple(nullptr, ETSObjectFlags::ASYNC_FUNC_RETURN_TYPE, relation)), promiseType_(promiseType) diff --git a/ets2panda/checker/types/ets/etsBigIntType.h b/ets2panda/checker/types/ets/etsBigIntType.h index 279c5d08170a65b67037458472b7d959bcc61005..8ed5f40ccb1f3ecdda34f88f5fdc60eee0483297 100644 --- a/ets2panda/checker/types/ets/etsBigIntType.h +++ b/ets2panda/checker/types/ets/etsBigIntType.h @@ -21,14 +21,14 @@ namespace ark::es2panda::checker { class ETSBigIntType : public ETSObjectType { public: - explicit ETSBigIntType(ArenaAllocator *allocator, [[maybe_unused]] ETSObjectType *super) + explicit ETSBigIntType(ThreadSafeArenaAllocator *allocator, [[maybe_unused]] ETSObjectType *super) : ETSObjectType(allocator, "", compiler::Signatures::BUILTIN_BIGINT, nullptr, ETSObjectFlags::CLASS | ETSObjectFlags::BUILTIN_BIGINT | ETSObjectFlags::RESOLVED_SUPER) { SetSuperType(super); } - explicit ETSBigIntType(ArenaAllocator *allocator, ETSObjectType *super, TypeRelation *relation, + explicit ETSBigIntType(ThreadSafeArenaAllocator *allocator, ETSObjectType *super, TypeRelation *relation, util::StringView value) : ETSObjectType( allocator, "", compiler::Signatures::BUILTIN_BIGINT, diff --git a/ets2panda/checker/types/ets/etsDynamicType.h b/ets2panda/checker/types/ets/etsDynamicType.h index eea79b4fb92a6ea1b1275bdfc17aa8c1a845ad9c..9506417407b68e4c8be22b2d007eb016fcb407bc 100644 --- a/ets2panda/checker/types/ets/etsDynamicType.h +++ b/ets2panda/checker/types/ets/etsDynamicType.h @@ -28,7 +28,8 @@ class ETSDynamicType : public ETSObjectType { static constexpr auto RELATION = 2; public: - explicit ETSDynamicType(ArenaAllocator *allocator, std::tuple label, + explicit ETSDynamicType(ThreadSafeArenaAllocator *allocator, + std::tuple label, std::tuple info, bool hasDecl) : ETSObjectType(allocator, std::get(label), std::get(label), std::make_tuple(std::get(info), std::get(info) | ETSObjectFlags::DYNAMIC, diff --git a/ets2panda/checker/types/ets/etsEnumType.cpp b/ets2panda/checker/types/ets/etsEnumType.cpp index 6f9d01f6b45d762054a97d76bac60eb47ef19322..61d23b7cbf94ef87d12a88cce69cb24207f4cb97 100644 --- a/ets2panda/checker/types/ets/etsEnumType.cpp +++ b/ets2panda/checker/types/ets/etsEnumType.cpp @@ -27,7 +27,9 @@ bool ETSStringEnumType::AssignmentSource(TypeRelation *relation, Type *target) result = true; } else if (target->IsETSStringType()) { result = true; - relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + if (relation->GetNode() != nullptr) { + relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + } } else if (target->IsETSUnionType()) { auto &unionConstituentTypes = target->AsETSUnionType()->ConstituentTypes(); for (auto *constituentType : unionConstituentTypes) { @@ -72,7 +74,8 @@ bool ETSIntEnumType::AssignmentSource(TypeRelation *relation, Type *target) { bool result = false; if (target->IsETSObjectType()) { - if (target->AsETSObjectType()->IsGlobalETSObjectType()) { + if (target->AsETSObjectType()->IsGlobalETSObjectType() || + target->AsETSObjectType()->Name() == compiler::Signatures::NUMERIC) { result = true; } else if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC)) { result = true; diff --git a/ets2panda/checker/types/ets/etsEnumType.h b/ets2panda/checker/types/ets/etsEnumType.h index a5c6bdf33d7a3e767413365b6105f75f9114285b..99e5b34528f8275ab16deaa3690158817ea64ae0 100644 --- a/ets2panda/checker/types/ets/etsEnumType.h +++ b/ets2panda/checker/types/ets/etsEnumType.h @@ -24,7 +24,7 @@ namespace ark::es2panda::checker { class ETSEnumType : public ETSObjectType { public: - explicit ETSEnumType(ArenaAllocator *allocator, util::StringView name, util::StringView internalName, + explicit ETSEnumType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView internalName, ir::AstNode *declNode, TypeRelation *relation) : ETSObjectType(allocator, name, internalName, std::make_tuple(declNode, ETSObjectFlags::CLASS | ETSObjectFlags::ENUM_OBJECT, relation)) @@ -49,7 +49,7 @@ public: class ETSIntEnumType : public ETSEnumType { public: - explicit ETSIntEnumType(ArenaAllocator *allocator, util::StringView name, util::StringView internalName, + explicit ETSIntEnumType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView internalName, ir::AstNode *declNode, TypeRelation *relation) : ETSEnumType(allocator, name, internalName, declNode, relation) { @@ -70,8 +70,8 @@ public: class ETSStringEnumType : public ETSEnumType { public: - explicit ETSStringEnumType(ArenaAllocator *allocator, util::StringView name, util::StringView internalName, - ir::AstNode *declNode, TypeRelation *relation) + explicit ETSStringEnumType(ThreadSafeArenaAllocator *allocator, util::StringView name, + util::StringView internalName, ir::AstNode *declNode, TypeRelation *relation) : ETSEnumType(allocator, name, internalName, declNode, relation) { AddTypeFlag(checker::TypeFlag::ETS_STRING_ENUM); diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index a5a07c1729a7b6eb50f05440fe61b102ff04daef..6ee38c66621147d016e917a5dc352869b3df7035 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -15,6 +15,7 @@ #include "checker/ETSchecker.h" #include "checker/types/globalTypesHolder.h" +#include "compiler/lowering/phase.h" namespace ark::es2panda::checker { @@ -22,8 +23,8 @@ ETSFunctionType::ETSFunctionType([[maybe_unused]] ETSChecker *checker, util::Str ArenaVector &&signatures) : Type(TypeFlag::FUNCTION | TypeFlag::ETS_METHOD), callSignatures_(std::move(signatures)), - extensionFunctionSigs_(ArenaVector(checker->Allocator()->Adapter())), - extensionAccessorSigs_(ArenaVector(checker->Allocator()->Adapter())), + extensionFunctionSigs_(ArenaVector(checker->ProgramAllocator()->Adapter())), + extensionAccessorSigs_(ArenaVector(checker->ProgramAllocator()->Adapter())), name_(name) { auto flag = TypeFlag::NONE; @@ -41,9 +42,9 @@ ETSFunctionType::ETSFunctionType([[maybe_unused]] ETSChecker *checker, util::Str ETSFunctionType::ETSFunctionType(ETSChecker *checker, Signature *signature) : Type(TypeFlag::FUNCTION), - callSignatures_({{signature->ToArrowSignature(checker)}, checker->Allocator()->Adapter()}), - extensionFunctionSigs_(ArenaVector(checker->Allocator()->Adapter())), - extensionAccessorSigs_(ArenaVector(checker->Allocator()->Adapter())), + callSignatures_({{signature->ToArrowSignature(checker)}, checker->ProgramAllocator()->Adapter()}), + extensionFunctionSigs_(ArenaVector(checker->ProgramAllocator()->Adapter())), + extensionAccessorSigs_(ArenaVector(checker->ProgramAllocator()->Adapter())), name_(""), assemblerName_(checker->GlobalBuiltinFunctionType(signature->MinArgCount(), signature->HasRestParameter()) ->AsETSObjectType() @@ -73,8 +74,8 @@ static ETSObjectType *FunctionTypeToFunctionalInterfaceType(ETSChecker *checker, if (signature->RestVar() != nullptr) { auto *functionN = checker->GlobalBuiltinFunctionType(arity, true)->AsETSObjectType(); auto *substitution = checker->NewSubstitution(); - substitution->emplace(functionN->TypeArguments()[0]->AsETSTypeParameter(), - checker->MaybeBoxType(signature->RestVar()->TsType()->AsETSArrayType()->ElementType())); + auto *elementType = checker->GetElementTypeOfArray(signature->RestVar()->TsType()); + substitution->emplace(functionN->TypeArguments()[0]->AsETSTypeParameter(), checker->MaybeBoxType(elementType)); return functionN->Substitute(checker->Relation(), substitution, true, isExtensionHack); } @@ -104,11 +105,16 @@ static ETSObjectType *FunctionTypeToFunctionalInterfaceType(ETSChecker *checker, ETSObjectType *ETSFunctionType::ArrowToFunctionalInterface(ETSChecker *checker) { - auto &cached = arrowToFuncInterface_; - if (LIKELY(cached != nullptr)) { - return cached; + auto &cached = compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker()->GetArrowToFuncInterfaces(); + + auto found = cached.find(this); + if (LIKELY(found != cached.end())) { + return found->second; } - return cached = FunctionTypeToFunctionalInterfaceType(checker, ArrowSignature(), ArrowSignature()->MinArgCount()); + return cached + .emplace(this, + FunctionTypeToFunctionalInterfaceType(checker, ArrowSignature(), ArrowSignature()->MinArgCount())) + .first->second; } ETSObjectType *ETSFunctionType::ArrowToFunctionalInterfaceDesiredArity(ETSChecker *checker, size_t arity) @@ -121,13 +127,15 @@ ETSObjectType *ETSFunctionType::ArrowToFunctionalInterfaceDesiredArity(ETSChecke ETSFunctionType *ETSFunctionType::MethodToArrow(ETSChecker *checker) { - auto &cached = invokeToArrowSignature_; - if (LIKELY(cached != nullptr)) { - return cached; + auto &cached = compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker()->GetInvokeToArrowSignatures(); + + auto found = cached.find(this); + if (LIKELY(found != cached.end())) { + return found->second; } ES2PANDA_ASSERT(!IsETSArrowType() && CallSignatures().size() == 1); - return cached = checker->CreateETSArrowType(CallSignatures()[0]); + return cached.emplace(this, checker->CreateETSArrowType(CallSignatures()[0])).first->second; } void ETSFunctionType::AddCallSignature(Signature *signature) @@ -292,7 +300,7 @@ ETSFunctionType *ETSFunctionType::Substitute(TypeRelation *relation, const Subst { if (substitution != nullptr && !substitution->empty()) { auto *const checker = relation->GetChecker()->AsETSChecker(); - auto *const allocator = checker->Allocator(); + auto *const allocator = checker->ProgramAllocator(); auto signatures = ArenaVector(allocator->Adapter()); bool anyChange = false; @@ -332,8 +340,11 @@ void ETSFunctionType::CastTarget(TypeRelation *relation, Type *source) relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); return; } - - relation->Result(relation->InCastingContext()); + if (relation->InCastingContext() && relation->IsSupertypeOf(source, this)) { + relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); + return; + } + relation->Result(false); } void ETSFunctionType::IsSubtypeOf(TypeRelation *relation, Type *target) diff --git a/ets2panda/checker/types/ets/etsFunctionType.h b/ets2panda/checker/types/ets/etsFunctionType.h index f59b65c709b186655a85fb231952f2884b628baa..14eea128aac6824708397918277d2d9520ad4547 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.h +++ b/ets2panda/checker/types/ets/etsFunctionType.h @@ -165,8 +165,6 @@ private: ArenaVector extensionAccessorSigs_; util::StringView const name_; util::StringView const assemblerName_; - ETSFunctionType *invokeToArrowSignature_ {}; - ETSObjectType *arrowToFuncInterface_ {}; Signature *helperSignature_ {}; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsNeverType.cpp b/ets2panda/checker/types/ets/etsNeverType.cpp index e6fa4f3806db7b714a20035be823f3450bffd459..0b5401c3ba54c9e81c5e0428d85d081a23493238 100644 --- a/ets2panda/checker/types/ets/etsNeverType.cpp +++ b/ets2panda/checker/types/ets/etsNeverType.cpp @@ -22,7 +22,7 @@ namespace ark::es2panda::checker { void ETSNeverType::Identical(TypeRelation *relation, Type *other) { - relation->Result(other->IsNeverType()); + relation->Result(other->IsETSNeverType()); } void ETSNeverType::AssignmentTarget(TypeRelation *relation, Type *source) diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 6a85627d835bbfebb4dc97145babd4ad33613f7c..61a6db0141bf8e1c7eeb777481cebbc09b8bac23 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -18,6 +18,11 @@ #include "checker/ETSchecker.h" #include "checker/ets/conversion.h" #include "checker/types/globalTypesHolder.h" +#include "checker/types/ets/etsAsyncFuncReturnType.h" +#include "checker/types/ets/etsEnumType.h" +#include "checker/types/ets/etsDynamicFunctionType.h" +#include "compiler/lowering/phase.h" +#include "ir/statements/annotationDeclaration.h" namespace ark::es2panda::checker { @@ -146,11 +151,18 @@ bool ETSObjectType::IsDescendantOf(const ETSObjectType *ascendant) const return this->SuperType()->IsDescendantOf(ascendant); } +static bool HasAccessor(const PropertySearchFlags &flags, const ETSFunctionType *funcType) +{ + if ((flags & (PropertySearchFlags::IS_GETTER | PropertySearchFlags::IS_SETTER)) != 0) { + return true; + } + return funcType->HasTypeFlag(TypeFlag::GETTER) || funcType->HasTypeFlag(TypeFlag::SETTER); +} + static void UpdateDeclarationForGetterSetter(varbinder::LocalVariable *res, const ETSFunctionType *funcType, const PropertySearchFlags &flags) { - if ((flags & (PropertySearchFlags::IS_GETTER | PropertySearchFlags::IS_SETTER)) == 0 || - res->Declaration() != nullptr) { + if (!HasAccessor(flags, funcType) || res->Declaration() != nullptr) { return; } auto var = funcType->CallSignatures().front()->OwnerVar(); @@ -196,27 +208,41 @@ ETSFunctionType *ETSObjectType::CreateMethodTypeForProp(const util::StringView & return GetRelation()->GetChecker()->AsETSChecker()->CreateETSMethodType(name, {{}, Allocator()->Adapter()}); } +static void AddSignature(std::vector &signatures, PropertySearchFlags flags, ETSChecker *checker, + varbinder::LocalVariable *found) +{ + for (auto *it : found->TsType()->AsETSFunctionType()->CallSignatures()) { + if (std::find(signatures.begin(), signatures.end(), it) != signatures.end()) { + continue; + } + if (((flags & PropertySearchFlags::IGNORE_ABSTRACT) != 0) && it->HasSignatureFlag(SignatureFlags::ABSTRACT)) { + continue; + } + if (std::any_of(signatures.begin(), signatures.end(), [&it, &checker](auto sig) { + return checker->AreOverrideCompatible(sig, it) && + it->Owner()->HasObjectFlag(ETSObjectFlags::INTERFACE) && + (checker->Relation()->IsSupertypeOf(it->Owner(), sig->Owner()) || + !sig->Owner()->HasObjectFlag(ETSObjectFlags::INTERFACE)); + })) { + continue; + } + // Issue: #18720 + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) + signatures.emplace_back(it); + } +} + varbinder::LocalVariable *ETSObjectType::CollectSignaturesForSyntheticType(std::vector &signatures, const util::StringView &name, PropertySearchFlags flags) const { - auto const addSignature = [&signatures, flags](varbinder::LocalVariable *found) -> void { - for (auto *it : found->TsType()->AsETSFunctionType()->CallSignatures()) { - if (((flags & PropertySearchFlags::IGNORE_ABSTRACT) != 0) && - it->HasSignatureFlag(SignatureFlags::ABSTRACT)) { - continue; - } - // Issue: #18720 - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - signatures.push_back(&*it); - } - }; + auto *checker = GetRelation()->GetChecker()->AsETSChecker(); if ((flags & PropertySearchFlags::SEARCH_STATIC_METHOD) != 0) { if (auto *found = GetOwnProperty(name); found != nullptr && !found->TsType()->IsTypeError()) { ES2PANDA_ASSERT(found->TsType()->IsETSFunctionType()); - addSignature(found); + AddSignature(signatures, flags, checker, found); } } @@ -224,14 +250,28 @@ varbinder::LocalVariable *ETSObjectType::CollectSignaturesForSyntheticType(std:: if (auto *found = GetOwnProperty(name); found != nullptr && !found->TsType()->IsTypeError()) { ES2PANDA_ASSERT(found->TsType()->IsETSFunctionType()); - addSignature(found); + AddSignature(signatures, flags, checker, found); } } if (superType_ != nullptr && ((flags & PropertySearchFlags::SEARCH_IN_BASE) != 0)) { - return superType_->CollectSignaturesForSyntheticType(signatures, name, flags); + superType_->CollectSignaturesForSyntheticType(signatures, name, flags); } + ArenaVector interfaces(Allocator()->Adapter()); + checker->GetInterfacesOfClass(const_cast(this), interfaces); + + for (auto *const &interface : interfaces) { + if (interface != nullptr && ((flags & PropertySearchFlags::SEARCH_IN_INTERFACES) != 0) && + !this->IsPartial()) { // NOTE: issue 24548 + if (auto *found = + interface->GetProperty(name, flags | PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION); + found != nullptr && !found->TsType()->IsTypeError()) { + ES2PANDA_ASSERT(found->TsType()->IsETSFunctionType()); + AddSignature(signatures, flags, checker, found); + } + } + } return nullptr; } @@ -306,20 +346,40 @@ std::vector ETSObjectType::Fields() const std::vector ETSObjectType::ForeignProperties() const { std::vector foreignProps; - std::unordered_set ownProps; + + // spec 9.3: all names in static and, separately, non-static class declaration scopes must be unique. + std::unordered_set ownInstanceProps; + std::unordered_set ownStaticProps; EnsurePropertiesInstantiated(); - ownProps.reserve(properties_.size()); + ownInstanceProps.reserve(properties_.size()); + ownStaticProps.reserve(properties_.size()); for (const auto *prop : GetAllProperties()) { - ownProps.insert(prop->Name()); + if (prop->HasFlag(varbinder::VariableFlags::STATIC)) { + ownStaticProps.insert(prop->Name()); + } else { + ownInstanceProps.insert(prop->Name()); + } } - std::map allProps {}; - Iterate([&allProps](const varbinder::LocalVariable *var) { allProps.emplace(var->Name(), var); }); + std::map allInstanceProps {}; + std::map allStaticProps {}; + Iterate([&allInstanceProps, &allStaticProps](const varbinder::LocalVariable *var) { + if (var->HasFlag(varbinder::VariableFlags::STATIC)) { + allStaticProps.emplace(var->Name(), var); + } else { + allInstanceProps.emplace(var->Name(), var); + } + }); - for (const auto &[name, var] : allProps) { - if (ownProps.find(name) == ownProps.end()) { + for (const auto &[name, var] : allInstanceProps) { + if (ownInstanceProps.find(name) == ownInstanceProps.end()) { + foreignProps.push_back(var); + } + } + for (const auto &[name, var] : allStaticProps) { + if (ownStaticProps.find(name) == ownStaticProps.end()) { foreignProps.push_back(var); } } @@ -800,6 +860,7 @@ void ETSObjectType::IsGenericSupertypeOf(TypeRelation *relation, ETSObjectType * Type *ETSObjectType::AsSuper(Checker *checker, varbinder::Variable *sourceVar) { + checker = GetETSChecker(); if (sourceVar == nullptr) { return nullptr; } @@ -863,9 +924,10 @@ varbinder::LocalVariable *ETSObjectType::CopyProperty(varbinder::LocalVariable * return copiedProp; } -Type *ETSObjectType::Instantiate(ArenaAllocator *const allocator, TypeRelation *const relation, +Type *ETSObjectType::Instantiate(ArenaAllocator *const allocator, TypeRelation *relation, GlobalTypesHolder *const globalTypes) { + relation = relation_; auto *const checker = relation->GetChecker()->AsETSChecker(); std::lock_guard guard {*checker->Mutex()}; auto *const base = GetOriginalBaseType(); @@ -980,19 +1042,26 @@ void ETSObjectType::SetCopiedTypeProperties(TypeRelation *const relation, ETSObj copiedType->RemoveObjectFlag(ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS | ETSObjectFlags::INCOMPLETE_INSTANTIATION | ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY); copiedType->SetVariable(variable_); - copiedType->SetBaseType(base); + + // #25295 Need to do some refactor on baseType for partial + if (IsPartial() && HasObjectFlag(ETSObjectFlags::INTERFACE)) { + copiedType->SetBaseType(this); + } else { + copiedType->SetBaseType(base); + } auto const &baseTypeParams = base->TypeArguments(); copiedType->effectiveSubstitution_ = ComputeEffectiveSubstitution(relation, baseTypeParams, newTypeArgs); copiedType->SetTypeArguments(std::move(newTypeArgs)); + ES2PANDA_ASSERT(relation); copiedType->relation_ = relation; } -void ETSObjectType::UpdateTypeProperty(checker::ETSChecker *checker, varbinder::LocalVariable *const prop, - PropertyType fieldType, PropertyProcesser const &func) +void ETSObjectType::UpdateTypeProperty(varbinder::LocalVariable *const prop, PropertyType fieldType, + PropertyProcesser const &func) { - auto const propType = prop->Declaration()->Node()->Check(checker); + auto const propType = prop->Declaration()->Node()->Check(GetETSChecker()); auto *const propCopy = func(prop, propType); if (fieldType == PropertyType::INSTANCE_FIELD) { @@ -1004,36 +1073,128 @@ void ETSObjectType::UpdateTypeProperty(checker::ETSChecker *checker, varbinder:: } } -void ETSObjectType::UpdateTypeProperties(checker::ETSChecker *checker, PropertyProcesser const &func) +void ETSObjectType::UpdateTypeProperties(PropertyProcesser const &func) { AddTypeFlag(TypeFlag::READONLY); for (auto const &prop : InstanceFields()) { - UpdateTypeProperty(checker, prop.second, PropertyType::INSTANCE_FIELD, func); + UpdateTypeProperty(prop.second, PropertyType::INSTANCE_FIELD, func); } for (auto const &prop : StaticFields()) { - UpdateTypeProperty(checker, prop.second, PropertyType::STATIC_FIELD, func); + UpdateTypeProperty(prop.second, PropertyType::STATIC_FIELD, func); } if (SuperType() != nullptr) { - auto *const superProp = SuperType()->Clone(checker)->AsETSObjectType(); - superProp->UpdateTypeProperties(checker, func); + auto *const superProp = + SuperType() + ->Instantiate(allocator_, relation_, relation_->GetChecker()->GetGlobalTypesHolder()) + ->AsETSObjectType(); + superProp->UpdateTypeProperties(func); SetSuperType(superProp); } } +static util::StringView GetHashFromSubstitution(const Substitution *substitution, const bool extensionFuncFlag, + ArenaAllocator *allocator) +{ + std::vector fields; + for (auto [k, v] : *substitution) { + std::stringstream ss; + k->ToString(ss, true); + ss << ":"; + v->ToString(ss, true); + // NOTE (mmartin): change bare address to something more appropriate unique representation + ss << ":" << k << ":" << v; + fields.push_back(ss.str()); + } + std::sort(fields.begin(), fields.end()); + + std::stringstream ss; + for (auto &fstr : fields) { + ss << fstr; + ss << ";"; + } + + if (extensionFuncFlag) { + ss << "extensionFunctionType;"; + } + return util::UString(ss.str(), allocator).View(); +} + +static std::pair GetObjectTypeDeclNames(ir::AstNode *node) +{ + if (node->IsClassDefinition()) { + return {node->AsClassDefinition()->Ident()->Name(), node->AsClassDefinition()->InternalName()}; + } + if (node->IsTSInterfaceDeclaration()) { + return {node->AsTSInterfaceDeclaration()->Id()->Name(), node->AsTSInterfaceDeclaration()->InternalName()}; + } + return {node->AsAnnotationDeclaration()->GetBaseName()->Name(), node->AsAnnotationDeclaration()->InternalName()}; +} + +static std::tuple CheckForDynamicLang(ir::AstNode *declNode, util::StringView assemblerName) +{ + Language lang(Language::Id::ETS); + bool hasDecl = false; + + if (declNode->IsClassDefinition()) { + auto *clsDef = declNode->AsClassDefinition(); + lang = clsDef->Language(); + hasDecl = clsDef->IsDeclare(); + } + + if (declNode->IsTSInterfaceDeclaration()) { + auto *ifaceDecl = declNode->AsTSInterfaceDeclaration(); + lang = ifaceDecl->Language(); + hasDecl = ifaceDecl->IsDeclare(); + } + + auto res = compiler::Signatures::Dynamic::LanguageFromType(assemblerName.Utf8()); + if (res) { + lang = *res; + } + + return std::make_tuple(lang, hasDecl); +} + +ETSObjectType *ETSObjectType::CreateETSObjectType(ir::AstNode *declNode, ETSObjectFlags flags) +{ + auto const [name, internalName] = GetObjectTypeDeclNames(declNode); + + if (declNode->IsClassDefinition() && (declNode->AsClassDefinition()->IsEnumTransformed())) { + if (declNode->AsClassDefinition()->IsIntEnumTransformed()) { + return Allocator()->New(Allocator(), name, internalName, declNode, GetRelation()); + } + ES2PANDA_ASSERT(declNode->AsClassDefinition()->IsStringEnumTransformed()); + return Allocator()->New(Allocator(), name, internalName, declNode, GetRelation()); + } + + if (auto [lang, hasDecl] = CheckForDynamicLang(declNode, internalName); lang.IsDynamic()) { + return Allocator()->New(Allocator(), std::make_tuple(name, internalName, lang), + std::make_tuple(declNode, flags, GetRelation()), hasDecl); + } + + if (internalName == compiler::Signatures::BUILTIN_ARRAY) { + return Allocator()->New(Allocator(), name, + std::make_tuple(declNode, flags, GetRelation())); + } + + return Allocator()->New(Allocator(), name, internalName, + std::make_tuple(declNode, flags, GetRelation())); +} + // #22951: remove isExtensionFunctionType flag ETSObjectType *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution, bool cache, bool isExtensionFunctionType) { + relation = relation_; if (substitution == nullptr || substitution->empty()) { return this; } - auto *const checker = relation->GetChecker()->AsETSChecker(); auto *base = GetOriginalBaseType(); - ArenaVector newTypeArgs {checker->Allocator()->Adapter()}; + ArenaVector newTypeArgs {allocator_->Adapter()}; const bool anyChange = SubstituteTypeArgs(relation, newTypeArgs, substitution); // Lambda types can capture type params in their bodies, normal classes cannot. // NOTE: gogabr. determine precise conditions where we do not need to copy. @@ -1042,7 +1203,7 @@ ETSObjectType *ETSObjectType::Substitute(TypeRelation *relation, const Substitut return this; } - const util::StringView hash = checker->GetHashFromSubstitution(substitution, isExtensionFunctionType); + const util::StringView hash = GetHashFromSubstitution(substitution, isExtensionFunctionType, allocator_); if (cache) { if (auto *inst = GetInstantiatedType(hash); inst != nullptr) { return inst; @@ -1054,14 +1215,15 @@ ETSObjectType *ETSObjectType::Substitute(TypeRelation *relation, const Substitut } relation->IncreaseTypeRecursionCount(base); - auto *const copiedType = checker->CreateETSObjectType(declNode_, flags_); + auto *const copiedType = CreateETSObjectType(declNode_, flags_); SetCopiedTypeProperties(relation, copiedType, std::move(newTypeArgs), base); if (isExtensionFunctionType) { copiedType->AddObjectFlag(checker::ETSObjectFlags::EXTENSION_FUNCTION); } if (cache) { - GetInstantiationMap().try_emplace(hash, copiedType); + ES2PANDA_ASSERT(copiedType->GetRelation()); + InsertInstantiationMap(hash, copiedType); } if (superType_ != nullptr) { @@ -1101,6 +1263,11 @@ ETSObjectType *ETSObjectType::SubstituteArguments(TypeRelation *relation, ArenaV return Substitute(relation, substitution); } +ETSChecker *ETSObjectType::GetETSChecker() +{ + return relation_->GetChecker()->AsETSChecker(); +} + void ETSObjectType::InstantiateProperties() const { ES2PANDA_ASSERT(relation_ != nullptr); @@ -1299,4 +1466,40 @@ void ETSObjectType::CheckVarianceRecursively(TypeRelation *relation, VarianceFla } } +ETSObjectType *ETSObjectType::GetInstantiatedType(util::StringView hash) +{ + auto &instantiationMap = + compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker()->GetObjectInstantiationMap(); + auto found = instantiationMap.find(this); + if (found == instantiationMap.end()) { + return nullptr; + } + + auto found2 = instantiationMap.at(this).find(hash); + if (found2 == instantiationMap.at(this).end()) { + return nullptr; + } + + return found2->second; +} + +void ETSObjectType::InsertInstantiationMap(const util::StringView &key, ETSObjectType *value) +{ + auto &instantiationMap = + compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker()->GetObjectInstantiationMap(); + if (instantiationMap.find(this) == instantiationMap.end()) { + ArenaUnorderedMap instantiation( + compiler::GetPhaseManager()->Context()->GetChecker()->AsETSChecker()->Allocator()->Adapter()); + instantiation.emplace(key, value); + instantiationMap.emplace(this, instantiation); + } + compiler::GetPhaseManager() + ->Context() + ->GetChecker() + ->AsETSChecker() + ->GetObjectInstantiationMap() + .at(this) + .try_emplace(key, value); +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 9a174689dd7925c03ca8557b5caf2c2a044d2338..20e5811f3d0d524919f40930e1c89e2a437532b2 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -16,6 +16,10 @@ #ifndef ES2PANDA_COMPILER_CHECKER_TYPES_ETS_OBJECT_TYPE_H #define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_OBJECT_TYPE_H +#include +#include + +#include "checker/checker.h" #include "checker/types/type.h" #include "checker/types/ets/etsObjectTypeConstants.h" #include "checker/types/signature.h" @@ -37,14 +41,14 @@ public: using PropertyTraverser = std::function; using PropertyHolder = std::array(PropertyType::COUNT)>; - explicit ETSObjectType(ArenaAllocator *allocator, util::StringView name, util::StringView internalName, + explicit ETSObjectType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView internalName, ir::AstNode *declNode, ETSObjectFlags flags) : ETSObjectType(allocator, name, internalName, std::make_tuple(declNode, flags, nullptr), std::make_index_sequence(PropertyType::COUNT)> {}) { } - explicit ETSObjectType(ArenaAllocator *allocator, util::StringView name, util::StringView internalName, + explicit ETSObjectType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView internalName, std::tuple info) : ETSObjectType(allocator, name, internalName, info, std::make_index_sequence(PropertyType::COUNT)> {}) @@ -70,6 +74,8 @@ public: } } + ETSChecker *GetETSChecker(); + void SetSuperType(ETSObjectType *super) { superType_ = super; @@ -92,6 +98,7 @@ public: void SetRelation(TypeRelation *relation) { + ES2PANDA_ASSERT(relation); relation_ = relation; } @@ -158,7 +165,7 @@ public: return interfaces_; } - ArenaVector &Interfaces() + const ArenaVector &Interfaces() { return interfaces_; } @@ -276,15 +283,7 @@ public: return static_cast(flags_ & ETSObjectFlags::UNBOXABLE_TYPE); } - ETSObjectType *GetInstantiatedType(util::StringView hash) - { - auto found = instantiationMap_.find(hash); - if (found != instantiationMap_.end()) { - return found->second; - } - - return nullptr; - } + ETSObjectType *GetInstantiatedType(util::StringView hash); varbinder::Scope *GetTypeArgumentScope() const { @@ -295,10 +294,7 @@ public: return typeParams->Scope(); } - InstantiationMap &GetInstantiationMap() - { - return instantiationMap_; - } + void InsertInstantiationMap(const util::StringView &key, ETSObjectType *value); template varbinder::LocalVariable *GetOwnProperty(const util::StringView &name) const @@ -361,7 +357,7 @@ public: const util::StringView &name, PropertySearchFlags flags) const; bool CheckIdenticalFlags(ETSObjectType *other) const; - + ETSObjectType *CreateETSObjectType(ir::AstNode *declNode, ETSObjectFlags flags); void Iterate(const PropertyTraverser &cb) const; void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; @@ -369,7 +365,7 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; bool IsBoxedPrimitive() const; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - void UpdateTypeProperties(checker::ETSChecker *checker, PropertyProcesser const &func); + void UpdateTypeProperties(PropertyProcesser const &func); ETSObjectType *Substitute(TypeRelation *relation, const Substitution *substitution) override; ETSObjectType *Substitute(TypeRelation *relation, const Substitution *substitution, bool cache, bool isExtensionFunctionType = false); @@ -392,7 +388,7 @@ public: const ArenaVector &ReExports() const; bool IsSameBasedGeneric(TypeRelation *relation, Type const *other) const; - ArenaAllocator *Allocator() const + ThreadSafeArenaAllocator *Allocator() const { return allocator_; } @@ -414,7 +410,7 @@ protected: private: template - explicit ETSObjectType(ArenaAllocator *allocator, util::StringView name, util::StringView assemblerName, + explicit ETSObjectType(ThreadSafeArenaAllocator *allocator, util::StringView name, util::StringView assemblerName, std::tuple info, [[maybe_unused]] std::index_sequence s) : Type(TypeFlag::ETS_OBJECT), @@ -426,7 +422,6 @@ private: reExports_(allocator->Adapter()), reExportAlias_(allocator->Adapter()), flags_(std::get(info)), - instantiationMap_(allocator->Adapter()), typeArguments_(allocator->Adapter()), relation_(std::get(info)), constructSignatures_(allocator->Adapter()), @@ -448,7 +443,7 @@ private: void IdenticalUptoTypeArguments(TypeRelation *relation, Type *other); void SubstitutePartialTypes(TypeRelation *relation, Type *other); void IsGenericSupertypeOf(TypeRelation *relation, ETSObjectType *source); - void UpdateTypeProperty(checker::ETSChecker *checker, varbinder::LocalVariable *const prop, PropertyType fieldType, + void UpdateTypeProperty(varbinder::LocalVariable *const prop, PropertyType fieldType, PropertyProcesser const &func); varbinder::LocalVariable *SearchFieldsDecls(const util::StringView &name, PropertySearchFlags flags) const; @@ -464,7 +459,7 @@ private: ir::TSTypeParameterDeclaration *GetTypeParams() const; - ArenaAllocator *const allocator_; + ThreadSafeArenaAllocator *const allocator_; util::StringView const name_; util::StringView const internalName_; ir::AstNode *const declNode_; @@ -472,7 +467,6 @@ private: ArenaVector reExports_; ArenaMap reExportAlias_; ETSObjectFlags flags_; - InstantiationMap instantiationMap_; ArenaVector typeArguments_; ETSObjectType *superType_ {}; ETSObjectType *enclosingType_ {}; diff --git a/ets2panda/checker/types/ets/etsObjectTypeConstants.h b/ets2panda/checker/types/ets/etsObjectTypeConstants.h index a0582dd23555b9b1c3485716724ea03c0557a966..0a51f2f1d6a1393d49d722194d834fdc8992eb7e 100644 --- a/ets2panda/checker/types/ets/etsObjectTypeConstants.h +++ b/ets2panda/checker/types/ets/etsObjectTypeConstants.h @@ -54,9 +54,12 @@ enum class ETSObjectFlags : std::uint64_t { BUILTIN_LONG = 1U << 29U, BUILTIN_FLOAT = 1U << 30U, BUILTIN_DOUBLE = 1U << 31U, + BUILTIN_ARRAY = 1ULL << 32U, - ENUM_OBJECT = 1ULL << 32U, - EXTENSION_FUNCTION = 1ULL << 33U, + ENUM_OBJECT = 1ULL << 33U, + EXTENSION_FUNCTION = 1ULL << 34U, + + FUNCTIONAL_REFERENCE = 1ULL << 35U, BUILTIN_NUMERIC = BUILTIN_BYTE | BUILTIN_SHORT | BUILTIN_INT | BUILTIN_LONG | BUILTIN_FLOAT | BUILTIN_DOUBLE, // Complete set includes null|undefined|Object diff --git a/ets2panda/checker/types/ets/etsResizableArrayType.cpp b/ets2panda/checker/types/ets/etsResizableArrayType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..25fcd72aba950af51699942f1241bbfff595af9a --- /dev/null +++ b/ets2panda/checker/types/ets/etsResizableArrayType.cpp @@ -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. + */ + +#include "etsResizableArrayType.h" + +namespace ark::es2panda::checker { + +ETSResizableArrayType *ETSResizableArrayType::Substitute(TypeRelation *relation, const Substitution *substitution) +{ + auto copiedType = ETSObjectType::Substitute(relation, substitution)->AsETSResizableArrayType(); + element_ = TypeArguments()[0]; + return copiedType; +} + +} // namespace ark::es2panda::checker \ No newline at end of file diff --git a/ets2panda/checker/types/ets/etsResizableArrayType.h b/ets2panda/checker/types/ets/etsResizableArrayType.h new file mode 100644 index 0000000000000000000000000000000000000000..1301e726931f457b658e626b915696d2f01a50d1 --- /dev/null +++ b/ets2panda/checker/types/ets/etsResizableArrayType.h @@ -0,0 +1,85 @@ +/* + * 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 ES2PANDA_COMPILER_CHECKER_TYPES_ETS_RESIZABLE_ARRAY_TYPE_H +#define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_RESIZABLE_ARRAY_TYPE_H + +#include "checker/types/ets/etsObjectType.h" +#include "checker/types/ets/etsObjectTypeConstants.h" + +namespace ark::es2panda::checker { + +class ETSResizableArrayType : public ETSObjectType { +public: + explicit ETSResizableArrayType(ThreadSafeArenaAllocator *allocator, ETSObjectType *super) + : ETSObjectType(allocator, "", compiler::Signatures::BUILTIN_ARRAY, nullptr, + ETSObjectFlags::CLASS | ETSObjectFlags::BUILTIN_ARRAY | ETSObjectFlags::RESOLVED_SUPER), + element_(nullptr) + { + SetSuperType(super); + } + + explicit ETSResizableArrayType(ThreadSafeArenaAllocator *allocator, util::StringView name, + std::tuple info) + : ETSObjectType(allocator, name, compiler::Signatures::BUILTIN_ARRAY, info), element_(nullptr) + { + } + + explicit ETSResizableArrayType(ThreadSafeArenaAllocator *allocator, ETSObjectType *super, TypeRelation *relation, + Type *element) + : ETSObjectType( + allocator, "", compiler::Signatures::BUILTIN_ARRAY, + std::make_tuple(nullptr, + ETSObjectFlags::CLASS | ETSObjectFlags::BUILTIN_ARRAY | ETSObjectFlags::RESOLVED_SUPER, + relation)), + element_(element) + { + SetSuperType(super); + variable_ = super->Variable(); + } + + NO_COPY_SEMANTIC(ETSResizableArrayType); + NO_MOVE_SEMANTIC(ETSResizableArrayType); + + ETSResizableArrayType() = delete; + ~ETSResizableArrayType() override = default; + + Type *ElementType() + { + if (element_ == nullptr) { + element_ = TypeArguments()[0]; + } + return element_; + } + + const Type *ElementType() const + { + return TypeArguments()[0]; + } + + void SetElementType(Type *element) + { + element_ = element; + } + + ETSResizableArrayType *Substitute(TypeRelation *relation, const Substitution *substitution) override; + +private: + Type *element_; +}; + +} // namespace ark::es2panda::checker + +#endif \ No newline at end of file diff --git a/ets2panda/checker/types/ets/etsStringType.cpp b/ets2panda/checker/types/ets/etsStringType.cpp index 648af3cc0137a144315bc3974bc6f456b31ed8b4..1a3c8ba2cc94ec1fc7ea2c58a07b1c419137e8dc 100644 --- a/ets2panda/checker/types/ets/etsStringType.cpp +++ b/ets2panda/checker/types/ets/etsStringType.cpp @@ -40,17 +40,7 @@ void ETSStringType::Identical(TypeRelation *relation, Type *other) bool ETSStringType::AssignmentSource(TypeRelation *relation, Type *target) { - auto node = relation->GetNode(); - if ((relation->InAssignmentContext() || relation->ApplyStringToChar()) && IsConvertibleTo(target)) { - node->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOX_TO_CHAR); - if (target->IsETSObjectType()) { - node->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR); - } - relation->Result(true); - } else { - relation->Result(target->IsETSStringType() && AreStringTypesAssignable(this, target)); - } - + relation->Result(target->IsETSStringType() && AreStringTypesAssignable(this, target)); return relation->IsTrue(); } @@ -85,14 +75,4 @@ void ETSStringType::IsSubtypeOf(TypeRelation *relation, Type *source) relation->IsSupertypeOf(source, checker->GlobalBuiltinETSStringType()); } -bool ETSStringType::IsConvertibleTo(Type const *to) const -{ - const bool targetIsChar = - to->IsCharType() || - // ETSObjectType is used in arrow function expression call. - (to->IsETSObjectType() && to->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)); - - return targetIsChar && IsConstantType() && value_.IsConvertibleToChar(); -} - } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsStringType.h b/ets2panda/checker/types/ets/etsStringType.h index 2e47f48eea53295796b17ada5234f95891e6c5ae..513f4deb5271c35793f4e8f6c8abe1f26795142d 100644 --- a/ets2panda/checker/types/ets/etsStringType.h +++ b/ets2panda/checker/types/ets/etsStringType.h @@ -21,14 +21,14 @@ namespace ark::es2panda::checker { class ETSStringType : public ETSObjectType { public: - explicit ETSStringType(ArenaAllocator *allocator, ETSObjectType *super) + explicit ETSStringType(ThreadSafeArenaAllocator *allocator, ETSObjectType *super) : ETSObjectType(allocator, "", compiler::Signatures::BUILTIN_STRING, nullptr, ETSObjectFlags::CLASS | ETSObjectFlags::STRING | ETSObjectFlags::RESOLVED_SUPER) { SetSuperType(super); } - explicit ETSStringType(ArenaAllocator *allocator, ETSObjectType *super, TypeRelation *relation) + explicit ETSStringType(ThreadSafeArenaAllocator *allocator, ETSObjectType *super, TypeRelation *relation) : ETSObjectType(allocator, "", compiler::Signatures::BUILTIN_STRING, std::make_tuple(nullptr, ETSObjectFlags::CLASS | ETSObjectFlags::STRING | ETSObjectFlags::RESOLVED_SUPER, @@ -37,7 +37,7 @@ public: SetSuperType(super); } - explicit ETSStringType(ArenaAllocator *allocator, ETSObjectType *super, TypeRelation *relation, + explicit ETSStringType(ThreadSafeArenaAllocator *allocator, ETSObjectType *super, TypeRelation *relation, util::StringView value) : ETSObjectType(allocator, "", compiler::Signatures::BUILTIN_STRING, std::make_tuple(nullptr, @@ -81,8 +81,6 @@ public: return {IsConstantType(), IsConstantType() ? (GetValue().Length() != 0) : false}; } - bool IsConvertibleTo(Type const *to) const; - private: util::StringView value_ {}; }; diff --git a/ets2panda/checker/types/ets/etsTupleType.cpp b/ets2panda/checker/types/ets/etsTupleType.cpp index 60b2c20e27f725cb6e7442bb613426d8a400ec07..cd7ffe68c14f04c04178eefcbc94aa10f0534a01 100644 --- a/ets2panda/checker/types/ets/etsTupleType.cpp +++ b/ets2panda/checker/types/ets/etsTupleType.cpp @@ -41,22 +41,26 @@ void ETSTupleType::ToString(std::stringstream &ss, bool precise) const void ETSTupleType::ToAssemblerType(std::stringstream &ss) const { - GetHolderArrayType()->ToAssemblerType(ss); -} - -void ETSTupleType::ToAssemblerTypeWithRank(std::stringstream &ss) const -{ - GetHolderArrayType()->ToAssemblerTypeWithRank(ss); + wrapperType_->ToAssemblerType(ss); } void ETSTupleType::ToDebugInfoType(std::stringstream &ss) const { - GetHolderArrayType()->ToDebugInfoType(ss); -} + if (HasTypeFlag(TypeFlag::READONLY)) { + ss << "readonly "; + } -uint32_t ETSTupleType::Rank() const -{ - return GetHolderArrayType()->Rank(); + ss << "["; + + for (auto it = typeList_.begin(); it != typeList_.end(); it++) { + (*it)->ToDebugInfoType(ss); + + if (std::next(it) != typeList_.end()) { + ss << ", "; + } + } + + ss << "]"; } Type *ETSTupleType::GetTypeAtIndex(const TupleSizeType index) const @@ -65,6 +69,20 @@ Type *ETSTupleType::GetTypeAtIndex(const TupleSizeType index) const return GetTupleTypesList().at(index); } +bool ETSTupleType::CheckElementsIdentical(TypeRelation *relation, const ETSTupleType *other) const +{ + if (GetTupleSize() != other->GetTupleSize()) { + return false; + } + + for (TupleSizeType idx = 0; idx < GetTupleSize(); ++idx) { + if (!relation->IsIdenticalTo(GetTypeAtIndex(idx), other->GetTypeAtIndex(idx))) { + return false; + } + } + return true; +} + void ETSTupleType::Identical([[maybe_unused]] TypeRelation *const relation, Type *const other) { if (!other->IsETSTupleType()) { @@ -73,15 +91,14 @@ void ETSTupleType::Identical([[maybe_unused]] TypeRelation *const relation, Type const auto *const otherTuple = other->AsETSTupleType(); - if (GetTupleSize() != otherTuple->GetTupleSize()) { + if (HasTypeFlag(TypeFlag::READONLY) != other->HasTypeFlag(TypeFlag::READONLY)) { + relation->Result(false); return; } - for (TupleSizeType idx = 0; idx < GetTupleSize(); ++idx) { - if (!relation->IsIdenticalTo(GetTypeAtIndex(idx), otherTuple->GetTypeAtIndex(idx))) { - relation->Result(false); - return; - } + if (!CheckElementsIdentical(relation, otherTuple)) { + relation->Result(false); + return; } relation->Result(true); @@ -98,41 +115,21 @@ bool ETSTupleType::AssignmentSource(TypeRelation *const relation, Type *const ta void ETSTupleType::AssignmentTarget(TypeRelation *const relation, Type *const source) { - if (source->HasTypeFlag(TypeFlag::READONLY)) { - relation->Result(false); - return; - } - - if (!source->IsETSTupleType()) { - return; - } - - const auto *const sourceTuple = source->AsETSTupleType(); - if (sourceTuple->GetTupleSize() != GetTupleSize()) { - return; - } - - for (TupleSizeType idx = 0; idx < GetTupleSize(); ++idx) { - if (!relation->IsIdenticalTo(GetTypeAtIndex(idx), sourceTuple->GetTypeAtIndex(idx))) { - return; - } + if (!source->HasTypeFlag(TypeFlag::READONLY) && source->IsETSTupleType()) { + source->AsETSTupleType()->IsSubtypeOf(relation, this); } - - relation->Result(true); } Type *ETSTupleType::Substitute(TypeRelation *relation, const Substitution *substitution) { auto *const checker = relation->GetChecker()->AsETSChecker(); - ArenaVector newTypeList(checker->Allocator()->Adapter()); + ArenaVector newTypeList(checker->ProgramAllocator()->Adapter()); for (auto *const tupleTypeListElement : GetTupleTypesList()) { newTypeList.emplace_back(tupleTypeListElement->Substitute(relation, substitution)); } - auto *newElementType = ir::ETSTuple::GetHolderTypeForTuple(checker, newTypeList); - auto *holderArrayType = checker->CreateETSArrayType(newElementType, HasTypeFlag(TypeFlag::READONLY)); - return checker->Allocator()->New(std::move(newTypeList), newElementType, holderArrayType); + return checker->ProgramAllocator()->New(checker, std::move(newTypeList)); } void ETSTupleType::IsSubtypeOf(TypeRelation *const relation, Type *target) @@ -141,12 +138,15 @@ void ETSTupleType::IsSubtypeOf(TypeRelation *const relation, Type *target) relation->Result(true); return; } + if (target->IsETSTupleType()) { + if (!HasTypeFlag(TypeFlag::READONLY) && CheckElementsIdentical(relation, target->AsETSTupleType())) { + relation->Result(true); + } + } } void ETSTupleType::Cast(TypeRelation *const relation, Type *const target) { - // NOTE(mmartin): Might be not the correct casting rules, as these aren't defined yet - if (!(target->IsETSTupleType() || target->IsETSArrayType())) { conversion::Forbidden(relation); return; @@ -194,11 +194,8 @@ void ETSTupleType::Cast(TypeRelation *const relation, Type *const target) Type *ETSTupleType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[maybe_unused]] TypeRelation *relation, [[maybe_unused]] GlobalTypesHolder *globalTypes) { - auto *const instantiatedLubType = GetLubType()->Instantiate(allocator, relation, globalTypes); - auto *const instantiatedArrayType = - GetHolderArrayType()->Instantiate(allocator, relation, globalTypes)->AsETSArrayType(); - auto *const tupleType = - allocator->New(GetTupleTypesList(), instantiatedLubType, instantiatedArrayType); + auto *const checker = relation->GetChecker()->AsETSChecker(); + auto *const tupleType = allocator->New(checker, GetTupleTypesList()); tupleType->typeFlags_ = typeFlags_; return tupleType; } @@ -206,7 +203,7 @@ Type *ETSTupleType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[ma void ETSTupleType::CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) { for (auto const &ctype : typeList_) { - relation->CheckVarianceRecursively(ctype, relation->TransferVariant(varianceFlag, VarianceFlag::COVARIANT)); + relation->CheckVarianceRecursively(ctype, relation->TransferVariant(varianceFlag, VarianceFlag::INVARIANT)); } } diff --git a/ets2panda/checker/types/ets/etsTupleType.h b/ets2panda/checker/types/ets/etsTupleType.h index 73b85a888b3f5adfc9e9e26188ec1b597da764f1..53418a226c933ef7bd6fe24e38d68bfc3ba130f4 100644 --- a/ets2panda/checker/types/ets/etsTupleType.h +++ b/ets2panda/checker/types/ets/etsTupleType.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_COMPILER_CHECKER_TYPES_ETS_TUPLE_TYPE_H #define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_TUPLE_TYPE_H +#include "checker/ETSchecker.h" #include "checker/types/type.h" namespace ark::es2panda::checker { @@ -24,49 +25,17 @@ class ETSTupleType : public Type { using TupleSizeType = std::size_t; public: - explicit ETSTupleType(ArenaAllocator *const allocator, Type *const lubType, ETSArrayType *const holderArrayType) - : Type(checker::TypeFlag::ETS_TUPLE), - typeList_(allocator->Adapter()), - lubType_(lubType), - holderArrayType_(holderArrayType) - { - typeFlags_ |= TypeFlag::ETS_TUPLE; - } - - explicit ETSTupleType(ArenaAllocator *const allocator, const TupleSizeType size, Type *const lubType, - ETSArrayType *const holderArrayType) - : Type(checker::TypeFlag::ETS_TUPLE), - typeList_(allocator->Adapter()), - lubType_(lubType), - holderArrayType_(holderArrayType), - size_(size) - { - typeFlags_ |= TypeFlag::ETS_TUPLE; - } - - explicit ETSTupleType(const ArenaVector &typeList, Type *const lubType, ETSArrayType *const holderArrayType) + explicit ETSTupleType(ETSChecker *checker, const ArenaVector &typeList) : Type(checker::TypeFlag::ETS_TUPLE), typeList_(typeList), - lubType_(lubType), - holderArrayType_(holderArrayType), - size_(typeList.size()) + wrapperType_(checker->GlobalBuiltinTupleType(typeList_.size())->AsETSObjectType()) { typeFlags_ |= TypeFlag::ETS_TUPLE; } - [[nodiscard]] Type *GetLubType() const - { - return lubType_; - } - [[nodiscard]] TupleSizeType GetTupleSize() const { - return size_; - } - - [[nodiscard]] ETSArrayType *GetHolderArrayType() const - { - return holderArrayType_; + return typeList_.size(); } [[nodiscard]] ArenaVector const &GetTupleTypesList() const @@ -79,6 +48,11 @@ public: return {false, false}; } + [[nodiscard]] ETSObjectType *GetWrapperType() const + { + return wrapperType_; + } + [[nodiscard]] Type *GetTypeAtIndex(TupleSizeType index) const; void ToString(std::stringstream &ss, bool precise) const override; @@ -93,15 +67,13 @@ public: void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; void ToAssemblerType(std::stringstream &ss) const override; - void ToAssemblerTypeWithRank(std::stringstream &ss) const override; void ToDebugInfoType(std::stringstream &ss) const override; - uint32_t Rank() const override; private: - ArenaVector const typeList_; - Type *const lubType_ {}; - ETSArrayType *const holderArrayType_ {}; - TupleSizeType size_ {0}; + bool CheckElementsIdentical(TypeRelation *relation, const ETSTupleType *other) const; + + const ArenaVector typeList_; + ETSObjectType *wrapperType_; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsTypeParameter.cpp b/ets2panda/checker/types/ets/etsTypeParameter.cpp index dc06935a79578f716e4b1d3ca4a9ed605d3492ab..518a42441bc1d0493b3a90a4a549052fdf48b3b9 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.cpp +++ b/ets2panda/checker/types/ets/etsTypeParameter.cpp @@ -101,25 +101,22 @@ void ETSTypeParameter::CheckVarianceRecursively([[maybe_unused]] TypeRelation *r } if (varianceFlag == VarianceFlag::INVARIANT) { - relation->GetChecker()->LogTypeError({"Type Parameter '", declNode_->Name()->Name(), "' is declared as", - declNode_->IsOut() ? " 'out'" : " 'in'", - " but occurs in 'invariant' position."}, - relation->GetNode()->Start()); + relation->GetChecker()->LogError(diagnostic::VARIANT_PARAM_INVARIAN_USE, + {declNode_->Name()->Name(), declNode_->IsOut() ? " 'out'" : " 'in'"}, + relation->GetNode()->Start()); relation->Result(false); return; } if (varianceFlag == VarianceFlag::COVARIANT && !declNode_->IsOut()) { - relation->GetChecker()->LogTypeError( - {"Type Parameter '", declNode_->Name()->Name(), "' is declared as 'in' but occurs in 'out' position."}, - relation->GetNode()->Start()); + relation->GetChecker()->LogError(diagnostic::VARIANCE_TPARAM_IN_OUT, {declNode_->Name()->Name()}, + relation->GetNode()->Start()); relation->Result(false); } if (varianceFlag == VarianceFlag::CONTRAVARIANT && !declNode_->IsIn()) { - relation->GetChecker()->LogTypeError( - {"Type Parameter '", declNode_->Name()->Name(), "' is declared as 'out' but occurs in 'in' position."}, - relation->GetNode()->Start()); + relation->GetChecker()->LogError(diagnostic::VARIANCE_TPARAM_OUT_IN, {declNode_->Name()->Name()}, + relation->GetNode()->Start()); relation->Result(false); } } diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index 4c4167db9623390eae108ccb6a1bdf3e3ada68a0..2bbdf54442f4f6e4e746f7b52b6a3795a33aedc4 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -14,9 +14,10 @@ */ #include +#include "etsObjectType.h" #include "etsUnionType.h" - #include "checker/ets/conversion.h" +#include "checker/types/ets/etsTupleType.h" #include "checker/types/globalTypesHolder.h" #include "checker/ETSchecker.h" @@ -140,7 +141,12 @@ void ETSUnionType::RelationTarget(TypeRelation *relation, Type *source, RelFN co if (std::any_of(constituentTypes_.begin(), constituentTypes_.end(), [relation, refsource, relFn](auto *t) { return relFn(relation, refsource, t); })) { if (refsource != source) { - relation->GetNode()->SetBoxingUnboxingFlags(checker->GetBoxingFlag(refsource)); + // Some nodes can have both boxing and unboxing flags set. When applying them, first the unboxing happens + // (then a possible primitive conversion), and boxing at last. + // NOTE (smartin): when boxing/unboxing is moved to a lowering, review this part of the code + const auto mergedBoxingFlags = + relation->GetNode()->GetBoxingUnboxingFlags() | checker->GetBoxingFlag(refsource); + relation->GetNode()->SetBoxingUnboxingFlags(mergedBoxingFlags); } relation->Result(true); return; @@ -372,6 +378,25 @@ bool ETSUnionType::IsAssignableType(checker::Type *sourceType) const noexcept return false; } +checker::Type *ETSUnionType::HandleNumericPrecedence( + checker::ETSChecker *checker, checker::ETSObjectType *objectType, checker::Type *sourceType, + std::map &numericTypes) const noexcept +{ + auto const sourceId = + (objectType != nullptr) ? ETSObjectType::GetPrecedence(checker, objectType) : Type::GetPrecedence(sourceType); + if (sourceId > 0U) { + for (auto const [id, type] : numericTypes) { + if (id >= sourceId) { + return type; + } + } + if (sourceType->IsConstantType() && !numericTypes.empty()) { + return numericTypes.begin()->second; + } + } + return nullptr; +} + // NOTE! When calling this method we assume that 'AssignmentTarget(...)' check was passes successfully, // thus the required assignable type always exists. checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, checker::Type *sourceType) const noexcept @@ -380,31 +405,37 @@ checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, che return sourceType; } - auto *objectType = sourceType->IsETSObjectType() ? sourceType->AsETSObjectType() : nullptr; - if (objectType != nullptr && (!objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE) || - objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_STRING))) { - // NOTE: here wo don't cast the actual type to possible base type using in the union, but use it as is! - return sourceType; - } - + auto *objectType = sourceType->IsETSObjectType() ? sourceType->AsETSObjectType() + : sourceType->IsETSTupleType() ? sourceType->AsETSTupleType()->GetWrapperType() + : nullptr; std::map numericTypes {}; bool const isBool = objectType != nullptr ? objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN) : sourceType->HasTypeFlag(TypeFlag::ETS_BOOLEAN); bool const isChar = objectType != nullptr ? objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR) : sourceType->HasTypeFlag(TypeFlag::CHAR); + + if (objectType != nullptr) { + if (objectType->IsETSResizableArrayType() || sourceType->IsETSTupleType()) { + checker::Type *assignableType = GetAssignableBuiltinType(checker, objectType, isBool, isChar, numericTypes); + // NOTE: For array and tuple types, they may be readonly, so we cannot simply use the it + if (assignableType != nullptr && assignableType->HasTypeFlag(TypeFlag::READONLY)) { + return assignableType; + } + } + if ((!objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE) || + objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_STRING))) { + // NOTE: here wo don't cast the actual type to possible base type using in the union, but use it as is! + return sourceType; + } + } + if (checker::Type *assignableType = GetAssignableBuiltinType(checker, objectType, isBool, isChar, numericTypes); assignableType != nullptr) { return assignableType; } - if (auto const sourceId = - objectType != nullptr ? ETSObjectType::GetPrecedence(checker, objectType) : Type::GetPrecedence(sourceType); - sourceId > 0U) { - for (auto const [id, type] : numericTypes) { - if (id >= sourceId) { - return type; - } - } + if (auto *assignableType = HandleNumericPrecedence(checker, objectType, sourceType, numericTypes)) { + return assignableType; } for (auto *constituentType : constituentTypes_) { @@ -423,11 +454,12 @@ checker::Type *ETSUnionType::GetAssignableBuiltinType( checker::Type *assignableType = nullptr; for (auto *constituentType : constituentTypes_) { - if (!constituentType->IsETSObjectType()) { + if (!constituentType->IsETSObjectType() && !constituentType->IsETSTupleType()) { continue; } - auto *const type = constituentType->AsETSObjectType(); + auto *const type = constituentType->IsETSTupleType() ? constituentType->AsETSTupleType()->GetWrapperType() + : constituentType->AsETSObjectType(); if (type->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN)) { if (isBool) { assignableType = constituentType; diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index d38376a8f827c8faddfbaa7e779b88bcd65226e3..12ae980aec9d686f2561d43f4309aec0d3710229 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -74,6 +74,9 @@ public: return std::all_of(constituentTypes_.cbegin(), constituentTypes_.cend(), p); } + checker::Type *HandleNumericPrecedence(checker::ETSChecker *checker, checker::ETSObjectType *objectType, + checker::Type *sourceType, + std::map &numericTypes) const noexcept; [[nodiscard]] checker::Type *GetAssignableType(ETSChecker *checker, checker::Type *sourceType) const noexcept; [[nodiscard]] std::pair GetComplimentaryType(ETSChecker *checker, checker::Type *sourceType); diff --git a/ets2panda/checker/types/globalTypesHolder.cpp b/ets2panda/checker/types/globalTypesHolder.cpp index 841df6f07678a2753875151509054e5d86cd9817..784aa977a409c2561d3418a1ec74d7eb7821fb44 100644 --- a/ets2panda/checker/types/globalTypesHolder.cpp +++ b/ets2panda/checker/types/globalTypesHolder.cpp @@ -63,6 +63,7 @@ void GlobalTypesHolder::AddETSEscompatLayer() builtinNameMappings_.emplace("NullPointerError", GlobalTypeId::ETS_NULL_POINTER_ERROR_BUILTIN); builtinNameMappings_.emplace("UncaughtExceptionError", GlobalTypeId::ETS_UNCAUGHT_EXCEPTION_ERROR_BUILTIN); builtinNameMappings_.emplace("Map", GlobalTypeId::ETS_MAP_BUILTIN); + builtinNameMappings_.emplace("Record", GlobalTypeId::ETS_RECORD_BUILTIN); builtinNameMappings_.emplace("RegExp", GlobalTypeId::ETS_REGEXP_BUILTIN); builtinNameMappings_.emplace("Set", GlobalTypeId::ETS_SET_BUILTIN); } @@ -86,6 +87,19 @@ void GlobalTypesHolder::AddFunctionTypes(ArenaAllocator *allocator) builtinNameMappings_.emplace("LambdaN", GlobalTypeId::ETS_FUNCTIONN_CLASS); } +void GlobalTypesHolder::AddTupleTypes(ArenaAllocator *allocator) +{ + auto addTypes = [this, allocator](const std::string &name, GlobalTypeId from, GlobalTypeId to) { + for (size_t id = static_cast(from), nargs = 0; id <= static_cast(to); id++, nargs++) { + builtinNameMappings_.emplace(util::UString(name + std::to_string(nargs), allocator).View(), + static_cast(id)); + } + }; + + addTypes("Tuple", GlobalTypeId::ETS_TUPLE0_CLASS, GlobalTypeId::ETS_TUPLE16_CLASS); + builtinNameMappings_.emplace("TupleN", GlobalTypeId::ETS_TUPLEN_CLASS); +} + void GlobalTypesHolder::AddTSSpecificTypes(ArenaAllocator *allocator) { globalTypes_[static_cast(GlobalTypeId::NUMBER)] = allocator->New(); @@ -201,6 +215,9 @@ GlobalTypesHolder::GlobalTypesHolder(ArenaAllocator *allocator) // Function types AddFunctionTypes(allocator); + // Tuple types + AddTupleTypes(allocator); + // ETS interop js specific types builtinNameMappings_.emplace("JSRuntime", GlobalTypeId::ETS_INTEROP_JSRUNTIME_BUILTIN); builtinNameMappings_.emplace("JSValue", GlobalTypeId::ETS_INTEROP_JSVALUE_BUILTIN); @@ -471,6 +488,11 @@ Type *GlobalTypesHolder::GlobalMapBuiltinType() return globalTypes_.at(static_cast(GlobalTypeId::ETS_MAP_BUILTIN)); } +Type *GlobalTypesHolder::GlobalRecordBuiltinType() +{ + return globalTypes_.at(static_cast(GlobalTypeId::ETS_RECORD_BUILTIN)); +} + Type *GlobalTypesHolder::GlobalErrorBuiltinType() { return globalTypes_.at(static_cast(GlobalTypeId::ETS_ERROR_BUILTIN)); @@ -665,6 +687,19 @@ Type *GlobalTypesHolder::GlobalLambdaBuiltinType(size_t nargs, bool hasRest) return globalTypes_.at(static_cast(GlobalTypeId::ETS_LAMBDAN_CLASS)); } +size_t GlobalTypesHolder::VariadicTupleTypeThreshold() +{ + return static_cast(GlobalTypeId::ETS_TUPLEN_CLASS) - static_cast(GlobalTypeId::ETS_TUPLE0_CLASS); +} + +Type *GlobalTypesHolder::GlobalTupleBuiltinType(size_t nargs) +{ + const auto tupleClassIdPos = nargs < VariadicTupleTypeThreshold() + ? static_cast(GlobalTypeId::ETS_TUPLE0_CLASS) + nargs + : static_cast(GlobalTypeId::ETS_TUPLEN_CLASS); + return globalTypes_.at(tupleClassIdPos); +} + Type *GlobalTypesHolder::GlobalTypeError() { return globalTypes_.at(static_cast(GlobalTypeId::TYPE_ERROR)); diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index 5d5344d99f9d91d19e1b95c61054c732dc7da4cf..2242097f8d854483c454b3d2ab6f24672ae1840c 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -75,6 +75,7 @@ enum class GlobalTypeId : std::size_t { ETS_INTEGRAL_BUILTIN, ETS_LONG_BUILTIN, ETS_MAP_BUILTIN, + ETS_RECORD_BUILTIN, ETS_ERROR_BUILTIN, ETS_RUNTIME_BUILTIN, ETS_RUNTIME_LINKER_BUILTIN, @@ -97,6 +98,7 @@ enum class GlobalTypeId : std::size_t { ETS_FUNCTION_BUILTIN, ETS_REGEXP_BUILTIN, ETS_ARRAY_BUILTIN, + ETS_ARRAY, ETS_INTEROP_JSRUNTIME_BUILTIN, ETS_INTEROP_JSVALUE_BUILTIN, ETS_BOX_BUILTIN, @@ -185,6 +187,25 @@ enum class GlobalTypeId : std::size_t { ETS_LAMBDAR15_CLASS, ETS_LAMBDAR16_CLASS, + ETS_TUPLE0_CLASS, + ETS_TUPLE1_CLASS, + ETS_TUPLE2_CLASS, + ETS_TUPLE3_CLASS, + ETS_TUPLE4_CLASS, + ETS_TUPLE5_CLASS, + ETS_TUPLE6_CLASS, + ETS_TUPLE7_CLASS, + ETS_TUPLE8_CLASS, + ETS_TUPLE9_CLASS, + ETS_TUPLE10_CLASS, + ETS_TUPLE11_CLASS, + ETS_TUPLE12_CLASS, + ETS_TUPLE13_CLASS, + ETS_TUPLE14_CLASS, + ETS_TUPLE15_CLASS, + ETS_TUPLE16_CLASS, + ETS_TUPLEN_CLASS, + TYPE_ERROR, COUNT, @@ -205,6 +226,7 @@ public: void AddEtsSpecificBuiltinTypes(); void AddTSSpecificTypes(ArenaAllocator *allocator); void AddFunctionTypes(ArenaAllocator *allocator); + void AddTupleTypes(ArenaAllocator *allocator); // TS specific types Type *GlobalNumberType(); @@ -292,6 +314,10 @@ public: Type *GlobalFunctionBuiltinType(size_t nargs, bool hasRest); Type *GlobalLambdaBuiltinType(size_t nargs, bool hasRest); + // Tuple types + Type *GlobalTupleBuiltinType(size_t nargs); + size_t VariadicTupleTypeThreshold(); + // ETS escompat layer Type *GlobalArrayBuiltinType(); Type *GlobalAssertionErrorBuiltinType(); @@ -299,6 +325,7 @@ public: Type *GlobalNullPointerErrorBuiltinType(); Type *GlobalUncaughtExceptionErrorBuiltinType(); Type *GlobalMapBuiltinType(); + Type *GlobalRecordBuiltinType(); Type *GlobalRegExpBuiltinType(); Type *GlobalSetBuiltinType(); diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index 34b2d8a74e3ada647e58b00c84a1ff81b9940f23..5ced79c41120e511b5f411031ffe5a045c8275b0 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -32,7 +32,7 @@ Signature *Signature::Substitute(TypeRelation *relation, const Substitution *sub return this; } auto *checker = relation->GetChecker()->AsETSChecker(); - auto *allocator = checker->Allocator(); + auto *allocator = checker->ProgramAllocator(); bool anyChange = false; SignatureInfo *newSigInfo = allocator->New(allocator); @@ -287,7 +287,7 @@ void Signature::AssignmentTarget([[maybe_unused]] TypeRelation *relation, [[mayb Signature *Signature::ToArrowSignature(ETSChecker *checker) { - auto *allocator = checker->Allocator(); + auto *allocator = checker->ProgramAllocator(); auto *sigInfo = allocator->New(signatureInfo_, allocator); for (auto param : sigInfo->params) { param->SetTsType(checker->MaybeBoxType(param->TsType())); diff --git a/ets2panda/checker/types/type.cpp b/ets2panda/checker/types/type.cpp index b3cb8780497aac7fb57002db6d8332c71d9f69e4..e03343c7f1ef1a1375d60dc812c4a3a7297b51ab 100644 --- a/ets2panda/checker/types/type.cpp +++ b/ets2panda/checker/types/type.cpp @@ -22,6 +22,13 @@ namespace ark::es2panda::checker { +std::mutex Type::idLock_ {}; + +bool Type::IsETSResizableArrayType() const +{ + return IsETSObjectType() && AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_ARRAY); +} + bool Type::IsETSStringType() const { return IsETSObjectType() && AsETSObjectType()->HasObjectFlag(ETSObjectFlags::STRING); @@ -136,7 +143,7 @@ Type *Type::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[maybe_unus Type *Type::Clone(Checker *const checker) { - return Instantiate(checker->Allocator(), checker->Relation(), checker->GetGlobalTypesHolder()); + return Instantiate(checker->ProgramAllocator(), checker->Relation(), checker->GetGlobalTypesHolder()); } Type *Type::Substitute([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] const Substitution *substitution) diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index 423ad7b5c565e68d786506c28da9f94879624ece..1104cada5f540782858ce5ef1b0b7de8f17639d6 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_COMPILER_CHECKER_TYPES_TYPE_H #define ES2PANDA_COMPILER_CHECKER_TYPES_TYPE_H +#include #include "generated/signatures.h" #include "checker/types/typeMapping.h" #include "checker/types/typeRelation.h" @@ -42,6 +43,7 @@ TYPE_MAPPING(DECLARE_TYPENAMES) #undef DECLARE_TYPENAMES class ETSStringType; class ETSBigIntType; +class ETSResizableArrayType; using Substitution = ArenaMap; @@ -49,6 +51,7 @@ class Type { public: explicit Type(TypeFlag flag) : typeFlags_(flag) { + std::lock_guard lock(idLock_); static uint64_t typeId = 0; id_ = ++typeId; } @@ -57,6 +60,7 @@ public: NO_MOVE_SEMANTIC(Type); virtual ~Type() = default; + static std::mutex idLock_; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define TYPE_IS_CHECKS(typeFlag, typeName) \ @@ -87,6 +91,7 @@ public: TYPE_MAPPING(TYPE_AS_CASTS) #undef TYPE_AS_CASTS + bool IsETSResizableArrayType() const; bool IsETSStringType() const; bool IsETSCharType() const; bool IsETSBigIntType() const; @@ -97,7 +102,6 @@ public: bool IsETSAsyncFuncReturnType() const; bool IsETSUnboxableObject() const; bool IsETSPrimitiveOrEnumType() const; - bool IsETSResizableArrayType() const; bool PossiblyETSNull() const; bool PossiblyETSUndefined() const; @@ -127,6 +131,18 @@ public: return reinterpret_cast(this); } + ETSResizableArrayType *AsETSResizableArrayType() + { + ES2PANDA_ASSERT(IsETSResizableArrayType()); + return reinterpret_cast(this); + } + + const ETSResizableArrayType *AsETSResizableArrayType() const + { + ES2PANDA_ASSERT(IsETSResizableArrayType()); + return reinterpret_cast(this); + } + bool IsETSDynamicType() const { return IsETSObjectType() && HasTypeFlag(TypeFlag::ETS_DYNAMIC_FLAG); diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index 88ed2fd9516c47f518516359e6ac4a37f25cede4..965d2172bb0dc4ed33260bd727d8d2f127523260 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -23,7 +23,7 @@ namespace ark::es2panda::checker { ArenaAllocator *TypeRelation::Allocator() { - return checker_->Allocator(); + return checker_->ProgramAllocator(); } RelationResult TypeRelation::CacheLookup(const Type *source, const Type *target, const RelationHolder &holder, @@ -33,6 +33,9 @@ RelationResult TypeRelation::CacheLookup(const Type *source, const Type *target, return result_; } + ES2PANDA_ASSERT(source != nullptr); + ES2PANDA_ASSERT(target != nullptr); + RelationKey relationKey {source->Id(), target->Id()}; auto res = holder.cached.find(relationKey); if (res == holder.cached.end()) { @@ -237,6 +240,10 @@ bool TypeRelation::IsSupertypeOf(Type *super, Type *sub) return Result(true); } + if (sub == nullptr) { + return false; + } + result_ = CacheLookup(super, sub, checker_->SupertypeResults(), RelationType::SUPERTYPE); if (result_ == RelationResult::CACHE_MISS) { if (IsIdenticalTo(super, sub)) { @@ -275,13 +282,14 @@ VarianceFlag TypeRelation::TransferVariant(VarianceFlag variance, VarianceFlag p return variance == VarianceFlag::CONTRAVARIANT ? VarianceFlag::COVARIANT : VarianceFlag::CONTRAVARIANT; } -void TypeRelation::RaiseError(const std::string &errMsg, const lexer::SourcePosition &loc) const +void TypeRelation::RaiseError(const diagnostic::DiagnosticKind &kind, const lexer::SourcePosition &loc) const { - checker_->LogTypeError(errMsg, loc); + RaiseError(kind, {}, loc); } -void TypeRelation::RaiseError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &loc) const +void TypeRelation::RaiseError(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams &list, + const lexer::SourcePosition &loc) const { - checker_->LogTypeError(list, loc); + checker_->LogError(kind, list, loc); } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index 489132498b96b8cea31058d19fe3654da1c928ba..6e1ad8cb6d6263e8ac6152029fc6261e7b0cb80b 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_COMPILER_CHECKER_TYPES_TYPE_RELATION_H #define ES2PANDA_COMPILER_CHECKER_TYPES_TYPE_RELATION_H +#include #include "lexer/token/sourceLocation.h" #include "generated/tokenType.h" #include "util/ustring.h" @@ -62,7 +63,6 @@ enum class TypeRelationFlag : uint32_t { NO_THROW_GENERIC_TYPEALIAS = 1U << 24U, OVERRIDING_CONTEXT = 1U << 25U, IGNORE_REST_PARAM = 1U << 26U, - STRING_TO_CHAR = 1U << 27U, ASSIGNMENT_CONTEXT = WIDENING | BOXING | UNBOXING, BRIDGE_CHECK = OVERRIDING_CONTEXT | IGNORE_TYPE_PARAMETERS | NO_RETURN_TYPE_CHECK, @@ -111,11 +111,18 @@ public: RelationType type; }; -using RelationMap = std::unordered_map; +using RelationMap = ArenaUnorderedMap; class RelationHolder { public: + RelationHolder(ThreadSafeArenaAllocator *allocator, RelationType relationType) + : cached(allocator->Adapter()), type(relationType) + { + } + + // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) RelationMap cached; + // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) RelationType type {}; }; @@ -156,11 +163,6 @@ public: return (flags_ & TypeRelationFlag::UNBOXING) != 0; } - bool ApplyStringToChar() const - { - return (flags_ & TypeRelationFlag::STRING_TO_CHAR) != 0; - } - bool NoReturnTypeCheck() const { return (flags_ & TypeRelationFlag::NO_RETURN_TYPE_CHECK) != 0; @@ -234,6 +236,11 @@ public: return checker_; } + void SetChecker(Checker *checker) + { + checker_ = checker; + } + ir::Expression *GetNode() const { return node_; @@ -246,6 +253,7 @@ public: void IncreaseTypeRecursionCount(Type *const type) { + std::lock_guard lock(mtx_); if (const auto foundType = instantiationRecursionMap_.find(type); foundType != instantiationRecursionMap_.end()) { foundType->second += 1; @@ -262,12 +270,14 @@ public: // possible to reference the correct types of it's members and methods. 2 is possibly enough, because if we // chain expressions, every one of them will be rechecked separately, thus allowing another 2 recursion. constexpr auto MAX_RECURSIVE_TYPE_INST = 2; + std::lock_guard lock(mtx_); const auto foundType = instantiationRecursionMap_.find(type); return foundType == instantiationRecursionMap_.end() ? true : (foundType->second < MAX_RECURSIVE_TYPE_INST); } void DecreaseTypeRecursionCount(Type *const type) { + std::lock_guard lock(mtx_); const auto foundType = instantiationRecursionMap_.find(type); if (foundType == instantiationRecursionMap_.end()) { return; @@ -303,8 +313,10 @@ public: bool SignatureIsSupertypeOf(Signature *super, Signature *sub); bool CheckVarianceRecursively(Type *type, VarianceFlag varianceFlag); VarianceFlag TransferVariant(VarianceFlag variance, VarianceFlag posVariance); - void RaiseError(const std::string &errMsg, const lexer::SourcePosition &loc) const; - void RaiseError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &loc) const; + + 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) @@ -341,6 +353,7 @@ private: RelationResult CacheLookup(const Type *source, const Type *target, const RelationHolder &holder, RelationType type) const; + std::mutex mtx_; Checker *checker_; RelationResult result_ {}; TypeRelationFlag flags_ {}; diff --git a/ets2panda/compiler/base/condition.cpp b/ets2panda/compiler/base/condition.cpp index 30e6aca479779a6c6b0981a3e86039180049f2e8..c8a7d0de4dbbc06d728f934d25c777bec1edc21a 100644 --- a/ets2panda/compiler/base/condition.cpp +++ b/ets2panda/compiler/base/condition.cpp @@ -99,33 +99,6 @@ void Condition::Compile(PandaGen *pg, const ir::Expression *expr, Label *falseLa pg->BranchIfFalse(expr, falseLabel); } -Condition::Result Condition::CheckConstantExpr(ETSGen *etsg, const ir::Expression *expr) -{ - const auto resultingExpression = [](const ir::Expression *e) { - if (e->IsBinaryExpression() && e->AsBinaryExpression()->IsLogicalExtended()) { - return e->AsBinaryExpression()->Result(); - } - if (e->IsAssignmentExpression() && e->AsAssignmentExpression()->IsLogicalExtended()) { - return e->AsAssignmentExpression()->Result(); - } - return e; - }(expr); - if (resultingExpression == nullptr) { - return Result::UNKNOWN; - } - - if (etsg->Checker()->IsNullLikeOrVoidExpression(resultingExpression)) { - return Result::CONST_FALSE; - } - - auto exprRes = resultingExpression->TsType()->ResolveConditionExpr(); - if (std::get<0>(exprRes)) { - return std::get<1>(exprRes) ? Result::CONST_TRUE : Result::CONST_FALSE; - } - - return Result::UNKNOWN; -} - bool Condition::CompileBinaryExprForBigInt(ETSGen *etsg, const ir::BinaryExpression *expr, Label *falseLabel) { if ((expr->Left()->TsType() == nullptr) || (expr->Right()->TsType() == nullptr)) { diff --git a/ets2panda/compiler/base/condition.h b/ets2panda/compiler/base/condition.h index c1ad2a21f593b89d89bbe00eba8975997862c5d0..1c86f17396717f53cf5c1176e3898e2e6ed2024e 100644 --- a/ets2panda/compiler/base/condition.h +++ b/ets2panda/compiler/base/condition.h @@ -35,7 +35,6 @@ public: static void Compile(PandaGen *pg, const ir::Expression *expr, Label *falseLabel); static void Compile(ETSGen *etsg, const ir::Expression *expr, Label *falseLabel); - static Result CheckConstantExpr(ETSGen *etsg, const ir::Expression *expr); private: static bool CompileBinaryExpr(PandaGen *pg, const ir::BinaryExpression *binExpr, Label *falseLabel); diff --git a/ets2panda/compiler/base/lreference.cpp b/ets2panda/compiler/base/lreference.cpp index 48bab0c0d66c81d5f0161ccf41a6e29cfaaa55ba..240aa09bd3fbad7c3e11dc67fa5826635b15e745 100644 --- a/ets2panda/compiler/base/lreference.cpp +++ b/ets2panda/compiler/base/lreference.cpp @@ -287,11 +287,19 @@ void ETSLReference::SetValueComputed(const ir::MemberExpression *memberExpr) con } if (objectType->IsETSTupleType()) { - etsg_->StoreTupleElement(Node(), baseReg_, propReg_, objectType->AsETSTupleType()->GetLubType()); - } else { - etsg_->StoreArrayElement(Node(), baseReg_, propReg_, - etsg_->GetVRegType(baseReg_)->AsETSArrayType()->ElementType()); + ES2PANDA_ASSERT(memberExpr->GetTupleIndexValue().has_value()); + + std::size_t indexValue = *memberExpr->GetTupleIndexValue(); + etsg_->StoreTupleElement(Node(), baseReg_, objectType->AsETSTupleType()->GetTypeAtIndex(indexValue), + indexValue); + return; } + + ES2PANDA_ASSERT(objectType->IsETSArrayType() || objectType->IsETSResizableArrayType()); + auto vRegtype = etsg_->GetVRegType(baseReg_); + auto *elementType = vRegtype->IsETSArrayType() ? vRegtype->AsETSArrayType()->ElementType() + : vRegtype->AsETSResizableArrayType()->ElementType(); + etsg_->StoreArrayElement(Node(), baseReg_, propReg_, elementType); } void ETSLReference::SetValueGetterSetter(const ir::MemberExpression *memberExpr) const @@ -303,6 +311,8 @@ void ETSLReference::SetValueGetterSetter(const ir::MemberExpression *memberExpr) if (sig->Function()->IsStatic()) { etsg_->CallExact(Node(), sig->InternalName(), argReg); + } else if (memberExpr->Object()->IsSuperExpression()) { + etsg_->CallExact(Node(), sig->InternalName(), baseReg_, argReg); } else { etsg_->CallVirtual(Node(), sig, baseReg_, argReg); } @@ -316,9 +326,7 @@ void ETSLReference::SetValue() const } const auto *const memberExpr = Node()->AsMemberExpression(); - const auto *const memberExprTsType = memberExpr->Object()->TsType()->IsETSTupleType() - ? memberExpr->Object()->TsType()->AsETSTupleType()->GetLubType() - : memberExpr->TsType(); + const auto *const memberExprTsType = memberExpr->TsType(); if (!memberExpr->IsIgnoreBox()) { etsg_->ApplyConversion(Node(), memberExprTsType); diff --git a/ets2panda/compiler/core/ASTCompiler.h b/ets2panda/compiler/core/ASTCompiler.h index b77041400054c38a324ddd7fca26fcff8ad1b0c6..d7925c2f4429ed3b8775ea8fc5a2fb778b2330b6 100644 --- a/ets2panda/compiler/core/ASTCompiler.h +++ b/ets2panda/compiler/core/ASTCompiler.h @@ -38,7 +38,6 @@ #include "ir/ets/etsClassLiteral.h" #include "ir/ets/etsFunctionType.h" #include "ir/ets/etsImportDeclaration.h" -#include "ir/ets/etsLaunchExpression.h" #include "ir/ets/etsNewArrayInstanceExpression.h" #include "ir/ets/etsNewClassInstanceExpression.h" #include "ir/ets/etsNewMultiDimArrayInstanceExpression.h" diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index f4a79941ec001f8e4254e1fce5fca118f667059b..86ee12f811a1febfbb0dbf9396155fea1018198d 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -59,10 +59,8 @@ void ETSCompiler::Compile(const ir::ClassProperty *st) const if (st->Value() == nullptr) { etsg->LoadDefaultValue(st, st->TsType()); } else { - if (!etsg->TryLoadConstantExpression(st->Value())) { - st->Value()->Compile(etsg); - etsg->ApplyConversion(st->Value(), st->TsType()); - } + st->Value()->Compile(etsg); + etsg->ApplyConversion(st->Value(), st->TsType()); st->Value()->SetBoxingUnboxingFlags(flags); } @@ -106,39 +104,6 @@ void ETSCompiler::Compile(const ir::ETSFunctionType *node) const etsg->LoadAccumulatorPoison(node, node->TsType()); } -void ETSCompiler::Compile([[maybe_unused]] const ir::ETSLaunchExpression *expr) const -{ -#ifdef PANDA_WITH_ETS - ETSGen *etsg = GetETSGen(); - compiler::RegScope rs(etsg); - compiler::VReg calleeReg = etsg->AllocReg(); - checker::Signature *signature = expr->expr_->Signature(); - bool isStatic = signature->HasSignatureFlag(checker::SignatureFlags::STATIC); - if (expr->expr_->Callee()->IsIdentifier()) { - if (!isStatic) { - etsg->LoadThis(expr->expr_); - etsg->StoreAccumulator(expr, calleeReg); - } - } else if (expr->expr_->Callee()->IsMemberExpression()) { - if (!isStatic) { - expr->expr_->Callee()->AsMemberExpression()->Object()->Compile(etsg); - etsg->StoreAccumulator(expr, calleeReg); - } - } else { - expr->expr_->Callee()->Compile(etsg); - etsg->StoreAccumulator(expr, calleeReg); - } - - if (isStatic) { - etsg->LaunchExact(expr, signature, expr->expr_->Arguments()); - } else { - etsg->LaunchVirtual(expr, signature, calleeReg, expr->expr_->Arguments()); - } - - etsg->SetAccumulatorType(expr->TsType()); -#endif // PANDA_WITH_ETS -} - void ETSCompiler::Compile(const ir::ETSNewArrayInstanceExpression *expr) const { ETSGen *etsg = GetETSGen(); @@ -228,7 +193,8 @@ static void CreateDynamicObject(const ir::AstNode *node, compiler::ETSGen *etsg, static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::ETSNewClassInstanceExpression *expr) { - if (expr->GetSignature()->RestVar() != nullptr) { + if (expr->GetSignature()->RestVar() != nullptr && (expr->GetSignature()->RestVar()->TsType()->IsETSArrayType() || + expr->GetSignature()->RestVar()->TsType()->IsETSTupleType())) { std::size_t const argumentCount = expr->GetArguments().size(); std::size_t const parameterCount = expr->GetSignature()->Params().size(); ES2PANDA_ASSERT(argumentCount >= parameterCount); @@ -238,7 +204,7 @@ static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::E if (i < argumentCount && expr->GetArguments()[i]->IsSpreadElement()) { arguments[i] = expr->GetArguments()[i]->AsSpreadElement()->Argument(); - } else { + } else if (!expr->GetSignature()->RestVar()->TsType()->IsETSTupleType()) { ArenaVector elements(checker->Allocator()->Adapter()); for (; i < argumentCount; ++i) { elements.emplace_back(expr->GetArguments()[i]); @@ -279,6 +245,8 @@ static void HandleUnionTypeInForOf(compiler::ETSGen *etsg, checker::Type const * if (countReg == nullptr) { if (currentType->IsETSArrayType()) { etsg->LoadArrayLength(st, unionReg); + } else if (currentType->IsETSResizableArrayType()) { + etsg->LoadResizableArrayLength(st); } else { etsg->LoadStringLength(st); } @@ -286,6 +254,8 @@ static void HandleUnionTypeInForOf(compiler::ETSGen *etsg, checker::Type const * if (currentType->IsETSArrayType()) { etsg->LoadAccumulator(st, *countReg); etsg->LoadArrayElement(st, unionReg); + } else if (currentType->IsETSResizableArrayType()) { + etsg->LoadResizableArrayElement(st, unionReg, *countReg); } else { etsg->LoadStringChar(st, unionReg, *countReg); // NOTE(vpukhov): #20510 use a single unboxing convertor @@ -369,42 +339,46 @@ void ETSCompiler::Compile([[maybe_unused]] const ir::ETSWildcardType *node) cons ES2PANDA_UNREACHABLE(); } -void ETSCompiler::Compile(const ir::ArrayExpression *expr) const +void ETSCompiler::CompileTupleCreation(const ir::ArrayExpression *tupleInitializer) const +{ + ETSGen *etsg = GetETSGen(); + + etsg->InitObject(tupleInitializer, + tupleInitializer->TsType()->AsETSTupleType()->GetWrapperType()->ConstructSignatures().front(), + tupleInitializer->Elements()); + etsg->SetAccumulatorType(tupleInitializer->TsType()); +} + +void ETSCompiler::CompileArrayCreation(const ir::ArrayExpression *expr) const { ETSGen *etsg = GetETSGen(); - const compiler::RegScope rs(etsg); const auto arr = etsg->AllocReg(); const auto dim = etsg->AllocReg(); - const auto *const arrayExprType = - expr->TsType()->IsETSTupleType() ? expr->TsType()->AsETSTupleType()->GetHolderArrayType() : expr->TsType(); + const auto *const arrayExprType = expr->TsType(); const compiler::TargetTypeContext ttctx(etsg, etsg->Checker()->GlobalIntType()); etsg->LoadAccumulatorInt(expr, static_cast(expr->Elements().size())); etsg->StoreAccumulator(expr, dim); - etsg->NewArray(expr, arr, dim, arrayExprType); + etsg->NewArray(expr, arr, dim, expr->TsType()); const auto indexReg = etsg->AllocReg(); + auto const *const elementType = arrayExprType->AsETSArrayType()->ElementType(); + for (std::uint32_t i = 0; i < expr->Elements().size(); ++i) { const auto *const expression = expr->Elements()[i]; etsg->LoadAccumulatorInt(expr, i); etsg->StoreAccumulator(expr, indexReg); - const compiler::TargetTypeContext ttctx2(etsg, arrayExprType->AsETSArrayType()->ElementType()); - if (!etsg->TryLoadConstantExpression(expression)) { - expression->Compile(etsg); - } - - etsg->ApplyConversion(expression, nullptr); - etsg->ApplyConversion(expression); + const compiler::TargetTypeContext ttctx2(etsg, elementType); + expression->Compile(etsg); + etsg->ApplyConversion(expression, elementType); if (expression->TsType()->IsETSArrayType()) { etsg->StoreArrayElement(expr, arr, indexReg, expression->TsType()); - } else if (expr->TsType()->IsETSTupleType()) { - etsg->StoreTupleElement(expr, arr, indexReg, expr->TsType()->AsETSTupleType()->GetLubType()); } else { - etsg->StoreArrayElement(expr, arr, indexReg, expr->TsType()->AsETSArrayType()->ElementType()); + etsg->StoreArrayElement(expr, arr, indexReg, arrayExprType->AsETSArrayType()->ElementType()); } } @@ -412,12 +386,24 @@ void ETSCompiler::Compile(const ir::ArrayExpression *expr) const ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), arrayExprType)); } +void ETSCompiler::Compile(const ir::ArrayExpression *expr) const +{ + ETSGen *etsg = GetETSGen(); + const compiler::RegScope rs(etsg); + + if (expr->TsType()->IsETSTupleType()) { + CompileTupleCreation(expr); + } else { + CompileArrayCreation(expr); + } +} + void ETSCompiler::Compile(const ir::AssignmentExpression *expr) const { ETSGen *etsg = GetETSGen(); // All other operations are handled in OpAssignmentLowering ES2PANDA_ASSERT(expr->OperatorType() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - auto *const exprType = expr->TsType(); + const auto *const exprType = expr->TsType(); compiler::RegScope rs(etsg); auto lref = compiler::ETSLReference::Create(etsg, expr->Left(), false); @@ -637,10 +623,6 @@ void ETSCompiler::Compile(const ir::BinaryExpression *expr) const return; } - if (etsg->TryLoadConstantExpression(expr)) { - return; - } - if (expr->IsLogical()) { CompileLogical(etsg, expr); return; @@ -671,7 +653,8 @@ void ETSCompiler::Compile(const ir::BinaryExpression *expr) const static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::CallExpression *expr, checker::Signature *signature) { - if (signature->RestVar() != nullptr) { + if (signature->RestVar() != nullptr && + (signature->RestVar()->TsType()->IsETSArrayType() || signature->RestVar()->TsType()->IsETSTupleType())) { std::size_t const argumentCount = expr->Arguments().size(); std::size_t const parameterCount = signature->Params().size(); ES2PANDA_ASSERT(argumentCount >= parameterCount); @@ -684,7 +667,7 @@ static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::C } else if (i < argumentCount && expr->Arguments()[i]->IsTSAsExpression() && expr->Arguments()[i]->AsTSAsExpression()->Expr()->Type() == ir::AstNodeType::SPREAD_ELEMENT) { arguments[i] = expr->Arguments()[i]->AsTSAsExpression()->Expr()->AsSpreadElement()->Argument(); - } else { + } else if (!signature->RestVar()->TsType()->IsETSTupleType()) { ArenaVector elements(checker->Allocator()->Adapter()); for (; i < argumentCount; ++i) { elements.emplace_back(expr->Arguments()[i]); @@ -758,9 +741,19 @@ void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calle } if (signature->HasSignatureFlag(checker::SignatureFlags::STATIC)) { etsg->CallExact(expr, expr->Signature(), expr->Arguments()); - } else if ((expr->Callee()->IsMemberExpression() && - expr->Callee()->AsMemberExpression()->Object()->IsSuperExpression())) { - etsg->CallExact(expr, signature, calleeReg, expr->Arguments()); + } else if (expr->Callee()->IsMemberExpression()) { + auto me = expr->Callee()->AsMemberExpression(); + auto obj = me->Object(); + if (obj->IsSuperExpression()) { + etsg->CallExact(expr, signature, calleeReg, expr->Arguments()); + // 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())->IsETSUnionType())) { + etsg->CallByName(expr, signature, calleeReg, expr->Arguments()); + } else { + etsg->CallVirtual(expr, signature, calleeReg, expr->Arguments()); + } } else { etsg->CallVirtual(expr, signature, calleeReg, expr->Arguments()); } @@ -855,11 +848,23 @@ void ETSCompiler::Compile(const ir::Identifier *expr) const if (!etsg->Checker()->AsETSChecker()->Relation()->IsSupertypeOf(smartType, etsg->GetAccumulatorType())) { etsg->CastToReftype(expr, smartType, false); } + } else if (smartType->IsETSPrimitiveType()) { + etsg->ApplyConversionCast(expr, smartType); } - etsg->SetAccumulatorType(smartType); } +static void LoadETSDynamicTypeFromMemberExpr(compiler::ETSGen *etsg, const ir::MemberExpression *expr, + compiler::VReg objReg) +{ + if (etsg->Checker()->AsETSChecker()->Relation()->IsSupertypeOf(etsg->Checker()->GlobalBuiltinETSStringType(), + expr->Property()->TsType())) { + etsg->LoadPropertyDynamic(expr, expr->TsType(), objReg, expr->Property()); + } else { + etsg->LoadElementDynamic(expr, objReg); + } +} + bool ETSCompiler::CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpression *expr) { if (!expr->IsComputed()) { @@ -880,18 +885,16 @@ bool ETSCompiler::CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpres auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); - if (objectType->IsETSDynamicType()) { - if (etsg->Checker()->AsETSChecker()->Relation()->IsSupertypeOf(etsg->Checker()->GlobalBuiltinETSStringType(), - expr->Property()->TsType())) { - etsg->LoadPropertyDynamic(expr, expr->TsType(), objReg, expr->Property()); - } else { - etsg->LoadElementDynamic(expr, objReg); - } - } else if (objectType->IsETSArrayType()) { - etsg->LoadArrayElement(expr, objReg); + if (objectType->IsETSTupleType()) { + ES2PANDA_ASSERT(expr->GetTupleIndexValue().has_value()); + auto indexValue = *expr->GetTupleIndexValue(); + auto *tupleElementType = objectType->AsETSTupleType()->GetTypeAtIndex(indexValue); + etsg->LoadTupleElement(expr, objReg, tupleElementType, indexValue); + } else if (objectType->IsETSDynamicType()) { + LoadETSDynamicTypeFromMemberExpr(etsg, expr, objReg); } else { - ES2PANDA_ASSERT(objectType->IsETSTupleType()); - etsg->LoadTupleElement(expr, objReg); + ES2PANDA_ASSERT(objectType->IsETSArrayType()); + etsg->LoadArrayElement(expr, objReg); } etsg->GuardUncheckedType(expr, expr->UncheckedType(), expr->TsType()); @@ -972,24 +975,25 @@ bool ETSCompiler::HandleArrayTypeLengthProperty(const ir::MemberExpression *expr bool ETSCompiler::HandleStaticProperties(const ir::MemberExpression *expr, ETSGen *etsg) const { - auto &propName = expr->PropVar()->Name(); - auto const *const variable = expr->PropVar(); - if (checker::ETSChecker::IsVariableStatic(variable)) { + if (auto const *const variable = expr->PropVar(); checker::ETSChecker::IsVariableStatic(variable)) { auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); - if (expr->PropVar()->TsType()->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { - checker::Signature *sig = variable->TsType()->AsETSFunctionType()->FindGetter(); + if (auto const *const varType = variable->TsType(); varType->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { + checker::Signature *sig = varType->AsETSFunctionType()->FindGetter(); etsg->CallExact(expr, sig->InternalName()); etsg->SetAccumulatorType(expr->TsType()); - return true; + } else { + util::StringView const fullName = + etsg->FormClassPropReference(expr->Object()->TsType()->AsETSObjectType(), variable->Name()); + etsg->LoadStaticProperty(expr, varType, fullName); + etsg->ApplyConversion(expr, expr->TsType()); } - util::StringView fullName = etsg->FormClassPropReference(expr->Object()->TsType()->AsETSObjectType(), propName); - etsg->LoadStaticProperty(expr, expr->TsType(), fullName); - ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), expr->TsType())); + return true; } + return false; } @@ -1088,16 +1092,13 @@ void ETSCompiler::Compile([[maybe_unused]] const ir::TypeofExpression *expr) con void ETSCompiler::Compile(const ir::UnaryExpression *expr) const { ETSGen *etsg = GetETSGen(); - auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); + auto ttctx = compiler::TargetTypeContext(etsg, expr->Argument()->TsType()); - if (!etsg->TryLoadConstantExpression(expr->Argument())) { - expr->Argument()->Compile(etsg); - } - - etsg->ApplyConversion(expr->Argument(), nullptr); - etsg->ApplyCast(expr->Argument(), expr->TsType()); + expr->Argument()->Compile(etsg); + etsg->ApplyConversion(expr->Argument(), expr->Argument()->TsType()); etsg->Unary(expr, expr->OperatorType()); + etsg->ApplyConversion(expr, expr->TsType()); ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), expr->TsType())); } @@ -1255,7 +1256,8 @@ void ETSCompiler::Compile(const ir::ForOfStatement *st) const compiler::LocalRegScope declRegScope(etsg, st->Scope()->DeclScope()->InitScope()); checker::Type const *const exprType = st->Right()->TsType(); - ES2PANDA_ASSERT(exprType->IsETSArrayType() || exprType->IsETSStringType() || exprType->IsETSUnionType()); + ES2PANDA_ASSERT(exprType->IsETSResizableArrayType() || exprType->IsETSArrayType() || exprType->IsETSStringType() || + exprType->IsETSUnionType()); st->Right()->Compile(etsg); compiler::VReg objReg = etsg->AllocReg(); @@ -1337,20 +1339,6 @@ void ETSCompiler::Compile(const ir::ForUpdateStatement *st) const void ETSCompiler::Compile(const ir::IfStatement *st) const { ETSGen *etsg = GetETSGen(); - auto res = compiler::Condition::CheckConstantExpr(etsg, st->Test()); - if (res == compiler::Condition::Result::CONST_TRUE) { - st->Test()->Compile(etsg); - st->Consequent()->Compile(etsg); - return; - } - - if (res == compiler::Condition::Result::CONST_FALSE) { - st->Test()->Compile(etsg); - if (st->Alternate() != nullptr) { - st->Alternate()->Compile(etsg); - } - return; - } auto *consequentEnd = etsg->AllocLabel(); compiler::Label *statementEnd = consequentEnd; @@ -1387,8 +1375,9 @@ void ETSCompiler::Compile(const ir::ReturnStatement *st) const ETSGen *etsg = GetETSGen(); bool isAsyncImpl = st->IsAsyncImplReturn(); + auto *const argument = st->Argument(); - if (st->Argument() == nullptr) { + if (argument == nullptr) { if (etsg->ExtendWithFinalizer(st->Parent(), st)) { return; } @@ -1408,27 +1397,26 @@ void ETSCompiler::Compile(const ir::ReturnStatement *st) const return; } - if (st->Argument()->IsCallExpression() && - st->Argument()->AsCallExpression()->Signature()->ReturnType()->IsETSVoidType()) { - st->Argument()->Compile(etsg); + if (argument->IsCallExpression() && argument->AsCallExpression()->Signature()->ReturnType()->IsETSVoidType()) { + argument->Compile(etsg); - if (isAsyncImpl) { - etsg->LoadAccumulatorUndefined(st); + if (etsg->ReturnType()->IsETSVoidType()) { + if (isAsyncImpl) { + etsg->LoadAccumulatorUndefined(st); + etsg->ReturnAcc(st); + } else { + etsg->EmitReturnVoid(st); + } + } else { + etsg->LoadDefaultValue(st, etsg->ReturnType()); etsg->ReturnAcc(st); - return; } - - etsg->EmitReturnVoid(st); return; } auto ttctx = compiler::TargetTypeContext(etsg, etsg->ReturnType()); - - if (!etsg->TryLoadConstantExpression(st->Argument())) { - st->Argument()->Compile(etsg); - } - - etsg->ApplyConversion(st->Argument(), st->ReturnType()); + argument->Compile(etsg); + etsg->ApplyConversion(argument, etsg->ReturnType()); if (etsg->ExtendWithFinalizer(st->Parent(), st)) { return; @@ -1534,10 +1522,8 @@ void ETSCompiler::Compile(const ir::VariableDeclarator *st) const auto ttctx = compiler::TargetTypeContext(etsg, st->TsType()); if (st->Init() != nullptr) { - if (!etsg->TryLoadConstantExpression(st->Init())) { - st->Init()->Compile(etsg); - etsg->ApplyConversion(st->Init(), nullptr); - } + st->Init()->Compile(etsg); + etsg->ApplyConversion(st->Init(), st->Id()->AsIdentifier()->Variable()->TsType()); } else { etsg->LoadDefaultValue(st, st->Id()->AsIdentifier()->Variable()->TsType()); } @@ -1696,13 +1682,11 @@ void ETSCompiler::CompileCast(const ir::TSAsExpression *expr) const void ETSCompiler::Compile(const ir::TSAsExpression *expr) const { ETSGen *etsg = GetETSGen(); - auto ttctx = compiler::TargetTypeContext(etsg, nullptr); - if (!etsg->TryLoadConstantExpression(expr->Expr())) { - expr->Expr()->Compile(etsg); - } + expr->Expr()->Compile(etsg); const auto *const targetType = etsg->Checker()->GetApparentType(expr->TsType()); + auto ttctx = compiler::TargetTypeContext(etsg, nullptr); if ((expr->Expr()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U) { etsg->ApplyUnboxingConversion(expr->Expr()); } diff --git a/ets2panda/compiler/core/ETSCompiler.h b/ets2panda/compiler/core/ETSCompiler.h index 466212c55003262488704040044f83ab96988a3c..94cd1e8f35b8cdbe204d965a029984772d864185 100644 --- a/ets2panda/compiler/core/ETSCompiler.h +++ b/ets2panda/compiler/core/ETSCompiler.h @@ -42,6 +42,8 @@ private: void EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, checker::Signature *signature) const; bool HandleArrayTypeLengthProperty(const ir::MemberExpression *expr, ETSGen *etsg) const; bool HandleStaticProperties(const ir::MemberExpression *expr, ETSGen *etsg) const; + void CompileArrayCreation(const ir::ArrayExpression *expr) const; + void CompileTupleCreation(const ir::ArrayExpression *tupleInitializer) const; static bool CompileComputed(compiler::ETSGen *etsg, const ir::MemberExpression *expr); diff --git a/ets2panda/compiler/core/ETSCompilerUnrechable.cpp b/ets2panda/compiler/core/ETSCompilerUnrechable.cpp index 3f3908e8206d4f92de117ae319809c813e6dc108..edcf0a2205a199f8fffcfa611f29d53ae946bcee 100644 --- a/ets2panda/compiler/core/ETSCompilerUnrechable.cpp +++ b/ets2panda/compiler/core/ETSCompilerUnrechable.cpp @@ -117,6 +117,11 @@ void ETSCompiler::Compile([[maybe_unused]] const ir::ETSStructDeclaration *node) ES2PANDA_UNREACHABLE(); } +void ETSCompiler::Compile([[maybe_unused]] const ir::ETSNonNullishTypeNode *node) const +{ + ES2PANDA_UNREACHABLE(); +} + void ETSCompiler::Compile([[maybe_unused]] const ir::ETSNullType *node) const { ES2PANDA_UNREACHABLE(); diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index a1b21ec2c32eacb65e8c5ed2774cb3bf6f346949..004427936cbf08ea19c6b7e32214e490ddf3bf18 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -97,7 +97,7 @@ void ETSGen::CompileAndCheck(const ir::Expression *expr) const checker::ETSChecker *ETSGen::Checker() const noexcept { - return Context()->checker->AsETSChecker(); + return Context()->GetChecker()->AsETSChecker(); } const varbinder::ETSBinder *ETSGen::VarBinder() const noexcept @@ -781,39 +781,16 @@ void ETSGen::IsInstanceDynamic(const ir::BinaryExpression *const node, const VRe SetAccumulatorType(Checker()->GlobalETSBooleanType()); } -void ETSGen::TestIsInstanceConstant(const ir::AstNode *node, Label *ifTrue, VReg srcReg, checker::Type const *target) -{ - if (!target->IsConstantType()) { - return; - } - RegScope rs(this); - VReg rhs = AllocReg(); - auto ifNotEquals = AllocLabel(); - - LoadAccumulator(node, srcReg); - LoadConstantObject(node->AsExpression(), target); - StoreAccumulator(node, rhs); - EmitEtsEquals(node, srcReg, rhs); - BranchIfFalse(node, ifNotEquals); - BranchIfTrue(node, ifTrue); - SetLabel(node, ifNotEquals); - SetAccumulatorType(nullptr); -} - // 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 = AppStorage.link('PropA'); + * link1.set(a); + * @param cs: for search PAG node in SubscribedAbstractProperty + * @param cid: for search PAG node in SubscribedAbstractProperty + * @returns StorageType enum + */ + private getStorageType(storageName: string, cs: CallSite | DynCallSite, cid: ContextID): StorageType { + switch (storageName) { + case 'AppStorage': + return StorageType.APP_STORAGE; + case 'SubscribedAbstractProperty': { + let calleeBaseLocal = (cs.callStmt.getInvokeExpr() as ArkInstanceInvokeExpr).getBase(); + let calleeBaseLocalNode = this.pag.getOrNewNode(cid, calleeBaseLocal) as PagLocalNode; + if (calleeBaseLocalNode.isStorageLinked()) { + let storage = calleeBaseLocalNode.getStorage(); + + return storage.StorageType!; + } + return StorageType.Undefined; + } + default: + return StorageType.Undefined; + } + } + + /**\ + * ArkNewExpr, ArkNewArrayExpr, function ptr, globalThis + */ + private stmtIsCreateAddressObj(stmt: ArkAssignStmt): boolean { + let lhOp = stmt.getLeftOp(); + let rhOp = stmt.getRightOp(); + if ( + rhOp instanceof ArkNewExpr || + rhOp instanceof ArkNewArrayExpr || + (lhOp instanceof Local && + ((rhOp instanceof Local && rhOp.getType() instanceof FunctionType && rhOp.getDeclaringStmt() === null) || + (rhOp instanceof AbstractFieldRef && rhOp.getType() instanceof FunctionType))) || + (rhOp instanceof Local && rhOp.getName() === GLOBAL_THIS_NAME && rhOp.getDeclaringStmt() == null) + ) { + return true; + } + + // TODO: add other Address Obj creation + // like static object + return false; + } + + private stmtIsCopyKind(stmt: ArkAssignStmt): boolean { + let lhOp = stmt.getLeftOp(); + let rhOp = stmt.getRightOp(); + + let condition: boolean = + (lhOp instanceof Local && + (rhOp instanceof Local || rhOp instanceof ArkParameterRef || rhOp instanceof ArkThisRef || rhOp instanceof ArkStaticFieldRef)) || + (lhOp instanceof ArkStaticFieldRef && rhOp instanceof Local); + + if (condition) { + return true; + } + return false; + } + + private stmtIsWriteKind(stmt: ArkAssignStmt): boolean { + let lhOp = stmt.getLeftOp(); + let rhOp = stmt.getRightOp(); + + if (rhOp instanceof Local && (lhOp instanceof ArkInstanceFieldRef || lhOp instanceof ArkArrayRef)) { + return true; + } + return false; + } + + private stmtIsReadKind(stmt: ArkAssignStmt): boolean { + let lhOp = stmt.getLeftOp(); + let rhOp = stmt.getRightOp(); + + if (lhOp instanceof Local && (rhOp instanceof ArkInstanceFieldRef || rhOp instanceof ArkArrayRef)) { + return true; + } + return false; + } + + public addToDynamicCallSite(funcPag: FuncPag, cs: DynCallSite): void { + funcPag.addDynamicCallSite(cs); + this.pagStat.numDynamicCall++; + + logger.trace('[add dynamic callsite] ' + cs.callStmt.toString() + ': ' + cs.callStmt.getCfg()?.getDeclaringMethod().getSignature().toString()); + } + + public setPtForNode(node: NodeID, pts: IPtsCollection | undefined): void { + if (!pts) { + return; + } + + (this.pag.getNode(node) as PagNode).setPointTo(pts); + } + + public getRealThisLocal(input: Local, funcId: FuncID): Local { + if (input.getName() !== 'this') { + return input; + } + let real = input; + + let f = this.cg.getArkMethodByFuncID(funcId); + f + ?.getCfg() + ?.getStmts() + .forEach(s => { + if (s instanceof ArkAssignStmt && s.getLeftOp() instanceof Local) { + if ((s.getLeftOp() as Local).getName() === 'this') { + real = s.getLeftOp() as Local; + return; + } + } + }); + return real; + } + + public doStat(): void { + this.pagStat.numTotalNode = this.pag.getNodeNum(); + } + + public printStat(): void { + this.pagStat.printStat(); + } + + public getStat(): string { + return this.pagStat.getStat(); + } + + public getUnhandledFuncs(): FuncID[] { + let handledFuncs = this.getHandledFuncs(); + let unhandleFuncs = Array.from(this.cg.getNodesIter()) + .filter(f => !handledFuncs.includes(f.getID())) + .map(f => f.getID()); + return unhandleFuncs; + } + + public getHandledFuncs(): FuncID[] { + return Array.from(this.funcPags.keys()); + } + + /** + * build export edge in internal func pag + * @param value: Value that need to check if it is from import/export + * @param originValue: if Value if InstanceFieldRef, the base will be passed to `value` recursively, + * fieldRef will be passed to `originValue` + */ + private handleValueFromExternalScope(value: Value, funcID: FuncID, originValue?: Value): void { + if (value instanceof Local) { + if (value.getDeclaringStmt() || value.getName() === 'this') { + // not from external scope + return; + } + + if (!value.getType()) { + return; + } + + let srcLocal = this.getSourceValueFromExternalScope(value, funcID); + + if (srcLocal) { + // if `value` is from field base, use origin value(fieldRef) instead + this.addInterFuncEdge(srcLocal, originValue ?? value, funcID); + } + } else if (value instanceof ArkInstanceFieldRef) { + let base = value.getBase(); + if (base) { + this.handleValueFromExternalScope(base, funcID, value); + } + } + } + + private addInterFuncEdge(src: Local, dst: Value, funcID: FuncID): void { + this.interFuncPags = this.interFuncPags ?? new Map(); + let interFuncPag = this.interFuncPags.get(funcID) ?? new InterFuncPag(); + // Export a local + // Add a InterProcedural edge + if (dst instanceof Local) { + let e: InterProceduralEdge = { + src: src, + dst: dst, + kind: PagEdgeKind.InterProceduralCopy, + }; + interFuncPag.addToInterProceduralEdgeSet(e); + this.addExportVariableMap(src, dst as Local); + } else if (dst instanceof ArkInstanceFieldRef) { + // record the export base use + this.addExportVariableMap(src, dst.getBase()); + } + this.interFuncPags.set(funcID, interFuncPag); + + // Put the function which the src belongs to to worklist + let srcFunc = src.getDeclaringStmt()?.getCfg().getDeclaringMethod(); + if (srcFunc) { + let srcFuncID = this.cg.getCallGraphNodeByMethod(srcFunc.getSignature()).getID(); + let cid = this.ctx.getNewContextID(srcFuncID); + let csFuncID = new CSFuncID(cid, srcFuncID); + this.buildFuncPagAndAddToWorklist(csFuncID); + } + // Extend other types of src here + } + + private getSourceValueFromExternalScope(value: Local, funcID: FuncID): Local | undefined { + let sourceValue; + + sourceValue = this.getDefaultMethodSourceValue(value, funcID); + if (!sourceValue) { + sourceValue = this.getExportSourceValue(value, funcID); + } + + return sourceValue; + } + + private getDefaultMethodSourceValue(value: Local, funcID: FuncID): Local | undefined { + // namespace check + let arkMethod = this.cg.getArkMethodByFuncID(funcID); + if (!arkMethod) { + return undefined; + } + + let declaringNameSpace = arkMethod.getDeclaringArkClass().getDeclaringArkNamespace(); + while (declaringNameSpace) { + let nameSpaceLocals = declaringNameSpace.getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals() ?? new Map(); + if (nameSpaceLocals.has(value.getName())) { + return nameSpaceLocals.get(value.getName()); + } + + declaringNameSpace = declaringNameSpace.getDeclaringArkNamespace() ?? undefined; + } + + // file check + let declaringFile = arkMethod.getDeclaringArkFile(); + let fileLocals = declaringFile.getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals() ?? new Map(); + if (!fileLocals.has(value.getName())) { + return undefined; + } + + return fileLocals.get(value.getName()); + } + + private getExportSourceValue(value: Local, funcID: FuncID): Local | undefined { + let curMethod = this.cg.getArkMethodByFuncID(funcID); + if (!curMethod) { + return undefined; + } + + let curFile = curMethod.getDeclaringArkFile(); + let impInfo = curFile.getImportInfoBy(value.getName()); + if (!impInfo) { + return undefined; + } + + let exportSource = impInfo.getLazyExportInfo(); + if (!exportSource) { + return undefined; + } + + let exportSouceValue = exportSource.getArkExport(); + if (exportSouceValue instanceof Local) { + return exportSouceValue; + } + return undefined; + } + + private addExportVariableMap(src: Local, dst: Local): void { + let exportMap: Local[] = this.externalScopeVariableMap.get(src) ?? []; + if (!exportMap.includes(dst)) { + exportMap.push(dst); + this.externalScopeVariableMap.set(src, exportMap); + } + } + + public getExportVariableMap(src: Local): Local[] { + return this.externalScopeVariableMap.get(src) ?? []; + } + + /// Add inter-procedural Pag Nodes and Edges + public addEdgesFromInterFuncPag(interFuncPag: InterFuncPag, cid: ContextID): boolean { + let edges = interFuncPag.getInterProceduralEdges(); + if (edges.size === 0) { + return false; + } + + for (let e of edges) { + // Existing local exported nodes -> ExportNode + let exportLocal = e.src; + let dstPagNode = this.getOrNewPagNode(cid, e.dst); + + // get export local node in all cid + let existingNodes = this.pag.getNodesByValue(exportLocal); + existingNodes?.forEach(n => { + this.pag.addPagEdge(this.pag.getNode(n)! as PagNode, dstPagNode, e.kind); + this.retriggerNodesList.add(n); + }); + } + + return true; + } + + public getRetriggerNodes(): NodeID[] { + let retriggerNodes = Array.from(this.retriggerNodesList); + this.retriggerNodesList.clear(); + return retriggerNodes; + } + + public addUpdatedNode(nodeID: NodeID, diffPT: IPtsCollection): void { + let ptaConfig = PointerAnalysisConfig.getInstance(); + let updatedNode = this.updatedNodesThisRound.get(nodeID) ?? new ptaConfig.ptsCollectionCtor(); + updatedNode.union(diffPT); + this.updatedNodesThisRound.set(nodeID, updatedNode); + } + + public getUpdatedNodes(): Map> { + return this.updatedNodesThisRound; + } + + public resetUpdatedNodes(): void { + this.updatedNodesThisRound.clear(); + } + + private transferArrayValues(method: ArkMethod, arrayLocal: Value): Local[] { + if (!(arrayLocal instanceof Local) || !(arrayLocal.getType() instanceof ArrayType)) { + return []; + } + + /** + * TODO: get array element values + * need to resolve multi dimension array + */ + const usedValuesInArray = arrayLocal.getUsedStmts().flatMap(stmt => { + if (stmt instanceof ArkAssignStmt) { + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local) { + return rightOp; + } + } + return []; + }); + + return usedValuesInArray; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysis.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysis.ts new file mode 100644 index 0000000000000000000000000000000000000000..902a05b902faa419cf511850bd2ccc1871a915fc --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysis.ts @@ -0,0 +1,673 @@ +/* + * 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. + */ + +import { Scene } from '../../Scene'; +import { Value } from '../../core/base/Value'; +import { NodeID } from '../../core/graph/BaseExplicitGraph'; +import path from 'path'; +import * as fs from 'fs'; +import { CallGraph, CallGraphNode, CallSite, DynCallSite, FuncID } from '../model/CallGraph'; +import { AbstractAnalysis } from '../algorithm/AbstractAnalysis'; +import { ClassType, Type, UnknownType } from '../../core/base/Type'; +import { CallGraphBuilder } from '../model/builder/CallGraphBuilder'; +import { Stmt } from '../../core/base/Stmt'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { DummyMainCreater } from '../../core/common/DummyMainCreater'; +import { PTAStat } from '../common/Statistics'; +import { Pag, PagNode, PagEdgeKind, PagEdge, PagLocalNode, PagGlobalThisNode, PagArrayNode } from './Pag'; +import { PagBuilder } from './PagBuilder'; +import { PointerAnalysisConfig, PtaAnalysisScale } from './PointerAnalysisConfig'; +import { DiffPTData, IPtsCollection } from './PtsDS'; +import { Local } from '../../core/base/Local'; +import { ArkMethod } from '../../core/model/ArkMethod'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'PTA'); + +export class PointerAnalysis extends AbstractAnalysis { + private pag: Pag; + private pagBuilder: PagBuilder; + private ptd: DiffPTData>; + private entries!: FuncID[]; + private worklist!: NodeID[]; + // record all updated nodes + private ptaStat: PTAStat; + private typeDiffMap!: Map>; + private config: PointerAnalysisConfig; + + constructor(p: Pag, cg: CallGraph, s: Scene, config: PointerAnalysisConfig) { + super(s); + this.pag = p; + this.cg = cg; + this.ptd = new DiffPTData>(config.ptsCollectionCtor); + this.pagBuilder = new PagBuilder(this.pag, this.cg, s, config.kLimit, config.analysisScale); + this.cgBuilder = new CallGraphBuilder(this.cg, s); + this.ptaStat = new PTAStat(this); + this.config = config; + } + + static pointerAnalysisForWholeProject(projectScene: Scene, config?: PointerAnalysisConfig): PointerAnalysis { + let cg = new CallGraph(projectScene); + let cgBuilder = new CallGraphBuilder(cg, projectScene); + cgBuilder.buildDirectCallGraphForScene(); + let pag = new Pag(); + if (!config) { + config = PointerAnalysisConfig.create(1, 'out/', false, false); + } + + const dummyMainCreator = new DummyMainCreater(projectScene); + dummyMainCreator.createDummyMain(); + const dummyMainMethod = dummyMainCreator.getDummyMain(); + cgBuilder.buildDirectCallGraph([dummyMainMethod]); + + let dummyMainMethodID = cg.getCallGraphNodeByMethod(dummyMainMethod.getSignature()).getID(); + cg.setDummyMainFuncID(dummyMainMethodID); + + let pta = new PointerAnalysis(pag, cg, projectScene, config); + pta.setEntries([dummyMainMethodID]); + pta.start(); + return pta; + } + + static pointerAnalysisForMethod(s: Scene, method: ArkMethod, config?: PointerAnalysisConfig): PointerAnalysis { + let cg = new CallGraph(s); + let cgBuilder = new CallGraphBuilder(cg, s); + cgBuilder.buildDirectCallGraphForScene(); + let pag = new Pag(); + if (!config) { + config = PointerAnalysisConfig.create(1, 'out/', false, false); + } + + let entryMethodID = cg.getCallGraphNodeByMethod(method.getSignature()).getID(); + let pta = new PointerAnalysis(pag, cg, s, config); + pta.setEntries([entryMethodID]); + pta.start(); + return pta; + } + + protected init(): void { + logger.warn(`========== Init Pointer Analysis ==========`); + // start statistics + this.ptaStat.startStat(); + // build funcPag with entries + this.pagBuilder.buildForEntries(this.entries); + if (this.config.dotDump) { + this.pag.dump(path.join(this.config.outputDirectory, 'ptaInit_pag.dot')); + this.cg.dump(path.join(this.config.outputDirectory, 'cg_init.dot')); + } + } + + public start(): void { + this.init(); + this.solveConstraint(); + this.postProcess(); + } + + private postProcess(): void { + this.ptaStat.endStat(); + this.pagBuilder.doStat(); + this.cg.printStat(); + this.pagBuilder.printStat(); + this.ptaStat.printStat(); + if (this.config.dotDump) { + this.pag.dump(path.join(this.config.outputDirectory, 'ptaEnd_pag.dot')); + this.cg.dump(path.join(this.config.outputDirectory, 'cgEnd.dot')); + } + + if (this.config.unhandledFuncDump) { + this.dumpUnhandledFunctions(); + } + } + + public getPTD(): DiffPTData> { + return this.ptd; + } + + public getStat(): string { + let ret: string = this.cg.getStat(); + ret += '\n' + this.pagBuilder.getStat(); + ret += '\n' + this.ptaStat.getStat(); + + return ret; + } + + protected preProcessMethod(funcID: FuncID): CallSite[] { + // do nothing + return []; + } + + public setEntries(fIds: FuncID[]): void { + this.entries = fIds; + } + + private solveConstraint(): void { + this.worklist = []; + logger.warn(`========== Pointer Analysis Start ==========`); + this.initWorklist(); + let reanalyzer: boolean = true; + + while (reanalyzer) { + this.ptaStat.iterTimes++; + logger.warn(`========== Pointer Analysis Round ${this.ptaStat.iterTimes} ==========`); + + // do pointer transfer + this.solveWorklist(); + // process dynamic call + if (this.config.analysisScale === PtaAnalysisScale.WholeProgram || this.ptaStat.iterTimes === 1) { + reanalyzer = this.onTheFlyDynamicCallSolve(); + } else { + reanalyzer = false; + } + if (this.config.dotDump) { + this.pag.dump(path.join(this.config.outputDirectory, `pta_pag_itor#${this.ptaStat.iterTimes}.dot`)); + } + } + } + + /** + * get newly added Address Edge, and add them to initial WorkList + */ + private initWorklist(): boolean { + let changed: boolean = false; + this.addToReanalyze(this.pagBuilder.getRetriggerNodes()); + for (let e of this.pag.getAddrEdges()) { + this.ptaStat.numProcessedAddr++; + + let { src, dst } = e.getEndPoints(); + this.ptd.addPts(dst, src); + if (this.pag.getNode(src) instanceof PagGlobalThisNode) { + // readd globalThis heapObj into workList + this.ptd.addPts(src, src); + this.worklist.push(src); + } + + this.worklist.push(dst); + changed = true; + } + this.pag.resetAddrEdges(); + return changed; + } + + private solveWorklist(): boolean { + while (this.worklist.length > 0) { + let node = this.worklist.shift() as NodeID; + this.processNode(node); + } + + return true; + } + + private processNode(nodeId: NodeID): boolean { + this.handleThis(nodeId); + this.handleLoadWrite(nodeId); + this.handleCopy(nodeId); + this.handlePt(nodeId); + + this.detectTypeDiff(nodeId); + return true; + } + + private handleCopy(nodeID: NodeID): boolean { + let node = this.pag.getNode(nodeID) as PagNode; + node.getOutgoingCopyEdges()?.forEach(copyEdge => { + this.propagate(copyEdge); + this.ptaStat.numProcessedCopy++; + }); + + return true; + } + + private handleLoadWrite(nodeID: NodeID): boolean { + let node = this.pag.getNode(nodeID) as PagNode; + let nodeValue = node.getValue(); + let diffPts = this.ptd.getDiffPts(nodeID); + if (!diffPts || diffPts.count() === 0) { + return false; + } + + // get related field node with current node's value + let instanceFieldNodeMap = this.pag.getNodesByBaseValue(nodeValue) ?? new Map(); + // get intra procedural field node by exportMap + let intraProceduralFieldNodeMap = new Map(); + + if (nodeValue instanceof Local) { + this.pagBuilder.getExportVariableMap(nodeValue).forEach(dst => { + let temp = this.pag.getNodesByBaseValue(dst) ?? new Map(); + intraProceduralFieldNodeMap = this.mergeInstanceFieldMap(instanceFieldNodeMap, temp); + }); + } + + instanceFieldNodeMap!.forEach((nodeIDs, cid) => { + // TODO: check cid + // cid === -1 will escape the check, mainly for globalThis + let baseCid = node.getCid(); + if (baseCid !== -1 && cid !== baseCid) { + return; + } + nodeIDs.forEach((nodeID: number) => { + // get abstract field node + let fieldNode = this.pag.getNode(nodeID) as PagNode; + + this.handleFieldInEdges(fieldNode, diffPts!); + this.handleFieldOutEdges(fieldNode, diffPts!); + }); + }); + + // without cid check, because closure and export is under different cid + intraProceduralFieldNodeMap!.forEach(nodeIDs => { + nodeIDs.forEach((nodeID: number) => { + // get abstract field node + let fieldNode = this.pag.getNode(nodeID) as PagNode; + + this.handleFieldInEdges(fieldNode, diffPts!); + this.handleFieldOutEdges(fieldNode, diffPts!); + }); + }); + + return true; + } + + private handleFieldInEdges(fieldNode: PagNode, diffPts: IPtsCollection): void { + fieldNode.getIncomingEdge().forEach(edge => { + if (edge.getKind() !== PagEdgeKind.Write) { + return; + } + let srcNode = edge.getSrcNode() as PagNode; + this.ptaStat.numProcessedWrite++; + for (let pt of diffPts!) { + // filter pt + // clone the real field node with abstract field node + let dstNode; + if (fieldNode instanceof PagArrayNode) { + dstNode = this.pag.getOrClonePagContainerFieldNode(pt, fieldNode); + } else { + dstNode = this.pag.getOrClonePagFieldNode(fieldNode, pt); + } + if (!(dstNode && this.pag.addPagEdge(srcNode, dstNode!, PagEdgeKind.Copy))) { + continue; + } + + this.ptaStat.numRealWrite++; + + if (this.ptd.resetElem(srcNode.getID())) { + this.worklist.push(srcNode.getID()); + } + } + }); + } + + private handleFieldOutEdges(fieldNode: PagNode, diffPts: IPtsCollection): void { + fieldNode.getOutgoingEdges().forEach(edge => { + if (edge.getKind() !== PagEdgeKind.Load) { + return; + } + let dstNode = edge.getDstNode() as PagNode; + this.ptaStat.numProcessedLoad++; + for (let pt of diffPts!) { + let srcNode; + if (fieldNode instanceof PagArrayNode) { + srcNode = this.pag.getOrClonePagContainerFieldNode(pt, fieldNode); + } else { + srcNode = this.pag.getOrClonePagFieldNode(fieldNode, pt); + } + if (!(srcNode && this.pag.addPagEdge(srcNode!, dstNode, PagEdgeKind.Copy))) { + continue; + } + + this.ptaStat.numRealLoad++; + + // TODO: if field is used before initialzed, newSrc node has no diff pts + if (this.ptd.resetElem(srcNode.getID())) { + this.worklist.push(srcNode.getID()); + } + } + }); + } + + /** + * If current node is a base of a called method, pointer in this node will be transfered into `this` Local in method + */ + private handleThis(nodeID: NodeID): boolean { + let node = this.pag.getNode(nodeID) as PagNode; + node.getOutgoingThisEdges()?.forEach(thisEdge => { + this.propagate(thisEdge); + this.ptaStat.numProcessedThis++; + }); + + return true; + } + + private handlePt(nodeID: NodeID): void { + let realDiff = this.ptd.calculateDiff(nodeID, nodeID); + + if (realDiff.count() !== 0) { + // record the updated nodes + this.pagBuilder.addUpdatedNode(nodeID, realDiff); + } + this.ptd.flush(nodeID); + this.pagBuilder.setPtForNode(nodeID, this.ptd.getPropaPts(nodeID)); + } + + private propagate(edge: PagEdge): boolean { + let changed: boolean = false; + let { src, dst } = edge.getEndPoints(); + let diffPts = this.ptd.getDiffPts(src); + if (!diffPts) { + return changed; + } + let realDiffPts = this.ptd.calculateDiff(src, dst); + + for (let pt of realDiffPts) { + changed = this.ptd.addPts(dst, pt) || changed; + } + + if (changed) { + this.worklist.push(dst); + } + + return changed; + } + + /** + * 1. 记录被更新的节点(记录cid, nodeid) + * 2. ( PAGLocalNode记录callsite(cid, value唯一)),通过1种的nodeID查询Node,拿到Callsite + * 3. 在addDynamicCall里对传入指针过滤(已处理指针和未处理指针) + */ + private onTheFlyDynamicCallSolve(): boolean { + let changed: boolean = false; + let processedCallSites: Set = new Set(); + this.pagBuilder.getUpdatedNodes().forEach((pts, nodeID) => { + let node = this.pag.getNode(nodeID) as PagNode; + + if (!(node instanceof PagLocalNode)) { + logger.warn(`node ${nodeID} is not local node, value: ${node.getValue()}`); + return; + } + + changed = this.processDynCallSite(node, pts, processedCallSites) || changed; + changed = this.processUnknownCallSite(node, pts) || changed; + }); + this.pagBuilder.resetUpdatedNodes(); + let srcNodes = this.pagBuilder.handleUnprocessedCallSites(processedCallSites); + changed = this.addToReanalyze(srcNodes) || changed; + + changed = this.pagBuilder.handleReachable() || changed; + changed = this.initWorklist() || changed; + return changed; + } + + private processDynCallSite(node: PagLocalNode, pts: IPtsCollection, processedCallSites: Set): boolean { + let changed: boolean = false; + let dynCallSites = node.getRelatedDynCallSites(); + + if (!dynCallSites && !node.isSdkParam()) { + logger.warn(`node ${node.getID()} has no related dynamic call site`); + return changed; + } + + logger.info(`[process dynamic callsite] node ${node.getID()}`); + dynCallSites.forEach(dynCallsite => { + for (let pt of pts) { + let srcNodes = this.pagBuilder.addDynamicCallEdge(dynCallsite, pt, node.getCid()); + changed = this.addToReanalyze(srcNodes) || changed; + } + processedCallSites.add(dynCallsite); + }); + + return changed; + } + + private processUnknownCallSite(node: PagLocalNode, pts: IPtsCollection): boolean { + let changed: boolean = false; + let unknownCallSites = node.getRelatedUnknownCallSites(); + + if (!unknownCallSites) { + logger.warn(`node ${node.getID()} has no related unknown call site`); + return changed; + } + + logger.info(`[process unknown callsite] node ${node.getID()}`); + unknownCallSites.forEach(unknownCallSite => { + for (let pt of pts) { + let srcNodes = this.pagBuilder.addDynamicCallEdge(unknownCallSite, pt, node.getCid()); + changed = this.addToReanalyze(srcNodes) || changed; + } + }); + + return changed; + } + + private addToReanalyze(startNodes: NodeID[]): boolean { + let flag = false; + for (let node of startNodes) { + if (!this.worklist.includes(node) && this.ptd.resetElem(node)) { + this.worklist.push(node); + flag = true; + } + } + return flag; + } + + /** + * compare interface + */ + public noAlias(leftValue: Value, rightValue: Value): boolean { + let leftValueNodes = this.pag.getNodesByValue(leftValue)?.values()!; + let rightValueNodes = this.pag.getNodesByValue(rightValue)?.values()!; + + let leftValuePts: Set = new Set(); + let rightValuePts: Set = new Set(); + + for (let nodeID of leftValueNodes) { + let node = this.pag.getNode(nodeID) as PagNode; + for (let pt of node.getPointTo()) { + leftValuePts.add(pt); + } + } + + for (let nodeID of rightValueNodes) { + let node = this.pag.getNode(nodeID) as PagNode; + for (let pt of node.getPointTo()) { + rightValuePts.add(pt); + } + } + + if (leftValuePts.size > rightValuePts.size) { + [leftValuePts, rightValuePts] = [rightValuePts, leftValuePts]; + } + + for (const elem of leftValuePts) { + if (rightValuePts.has(elem)) { + return false; + } + } + + // no alias + return true; + } + + public mayAlias(leftValue: Value, rightValue: Value): boolean { + return !this.noAlias(leftValue, rightValue); + } + + public getRelatedNodes(value: Value): Set { + let valueNodes = this.pag.getNodesByValue(value); + let relatedAllNodes: Set = new Set(); + let workListNodes: NodeID[] = []; + let processedNodes: Set = new Set(); + + if (valueNodes) { + for (const nodeID of valueNodes.values()) { + workListNodes.push(nodeID); + } + } + + while (workListNodes.length !== 0) { + let valueNodeID: NodeID = workListNodes.shift()!; + if (processedNodes.has(valueNodeID)) { + continue; + } + + this.processRelatedNode(valueNodeID, workListNodes, processedNodes); + } + + processedNodes.forEach(nodeID => { + let valueNode = this.pag.getNode(nodeID) as PagNode; + relatedAllNodes.add(valueNode.getValue()); + }); + + return relatedAllNodes; + } + + private processRelatedNode(valueNodeID: NodeID, workListNodes: NodeID[], processedNodes: Set): void { + let valueNode = this.pag.getNode(valueNodeID) as PagNode; + + this.addIncomingEdgesToWorkList(valueNode, workListNodes, processedNodes); + this.addOutgoingEdgesToWorkList(valueNode, workListNodes, processedNodes); + + processedNodes.add(valueNodeID); + } + + private addIncomingEdgesToWorkList(valueNode: PagNode, workListNodes: NodeID[], processedNodes: Set): void { + let inCopyEdges = valueNode.getIncomingCopyEdges(); + let inThisEdges = valueNode.getIncomingThisEdges(); + let combinedEdges = new Set([...(inCopyEdges ?? []), ...(inThisEdges ?? [])]); + if (combinedEdges) { + combinedEdges.forEach(edge => { + let srcID = edge.getSrcID(); + if (!processedNodes.has(srcID)) { + workListNodes.push(srcID); + } + }); + } + } + + private addOutgoingEdgesToWorkList(valueNode: PagNode, workListNodes: NodeID[], processedNodes: Set): void { + let outCopyEdges = valueNode.getOutgoingCopyEdges(); + let outThisEdges = valueNode.getOutgoingThisEdges(); + let combinedEdges = new Set([...(outCopyEdges ?? []), ...(outThisEdges ?? [])]); + if (combinedEdges) { + combinedEdges.forEach(edge => { + let dstID = edge.getDstID(); + if (!processedNodes.has(dstID)) { + workListNodes.push(dstID); + } + }); + } + } + + private detectTypeDiff(nodeId: NodeID): void { + if (this.config.detectTypeDiff === false) { + return; + } + + this.typeDiffMap = this.typeDiffMap ?? new Map(); + let node = this.pag.getNode(nodeId) as PagNode; + + let value = node.getValue(); + let origType = node.getValue().getType(); + // TODO: union type + if (!(origType instanceof ClassType || origType instanceof UnknownType)) { + return; + } + + let findSameType = false; + let pts = node.getPointTo(); + if (pts.count() === 0) { + return; + } + + for (let pt of pts) { + let ptNode = this.pag.getNode(pt) as PagNode; + let type = ptNode.getValue().getType(); + if (type.toString() !== origType.toString()) { + let diffSet = this.typeDiffMap.get(value) ?? new Set(); + this.typeDiffMap.set(value, diffSet); + if (!diffSet.has(type)) { + diffSet.add(type); + } + } else { + findSameType = true; + } + } + + // If find pts to original type, + // need add original type back since it is a correct type + let diffSet = this.typeDiffMap.get(value); + if (diffSet && findSameType) { + diffSet.add(origType); + } + } + + public getTypeDiffMap(): Map> { + return this.typeDiffMap ?? new Map(); + } + + protected resolveCall(sourceMethod: NodeID, invokeStmt: Stmt): CallSite[] { + return []; + } + + public getUnhandledFuncs(): FuncID[] { + return this.pagBuilder.getUnhandledFuncs(); + } + + public getHandledFuncs(): FuncID[] { + return this.pagBuilder.getHandledFuncs(); + } + + public getPTAConfig(): PointerAnalysisConfig { + return this.config; + } + + private dumpUnhandledFunctions(): void { + const filePath = path.join(this.config.outputDirectory, 'PtaUnhandledFunctionList.txt'); + fs.access(filePath, fs.constants.F_OK, err => { + if (!err) { + fs.truncate(filePath, 0, err => { + err && logger.error('Error to truncate file ', err); + }); + } + + let updatedContent: string = ''; + this.getUnhandledFuncs().forEach(funcID => { + let cgNode = this.cg.getNode(funcID); + if ((cgNode as CallGraphNode).isSdkMethod()) { + return; + } + + let f = this.cg.getArkMethodByFuncID(funcID); + if (f) { + updatedContent += f.getSignature().toString() + '\n'; + } + }); + + fs.writeFile(filePath, updatedContent, 'utf8', err => { + if (err) { + logger.error('Error to write file', err); + } + }); + }); + } + + public mergeInstanceFieldMap(src: Map, dst: Map): Map { + dst.forEach((value, key) => { + if (src.has(key)) { + src.set(key, [...src.get(key)!, ...value]); + } else { + src.set(key, value); + } + }); + return src; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..1e68c981db8221514da887c76692e267a90cbe2f --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts @@ -0,0 +1,101 @@ +/* + * 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. + */ + +import * as fs from 'fs'; +import { createPtsCollectionCtor, IPtsCollection, PtsCollectionType } from './PtsDS'; +import { NodeID } from '../../core/graph/BaseExplicitGraph'; + +export enum PtaAnalysisScale { + WholeProgram = 0, + MethodLevel = 1, +} + +export class PointerAnalysisConfig { + private static instance: PointerAnalysisConfig; + + public kLimit: number; + public outputDirectory: string; + public detectTypeDiff: boolean; + public dotDump: boolean; + public unhandledFuncDump: boolean; + public analysisScale: PtaAnalysisScale; + public ptsCollectionType: PtsCollectionType; + public ptsCollectionCtor: new () => IPtsCollection; + + /* + * Note: DO NOT use `new PointerAnalysisConfig` to initialize ptaconfig + * Use PointerAnalysisConfig.create() for singleton pattern + */ + constructor( + kLimit: number, + outputDirectory: string, + detectTypeDiff: boolean = false, + dotDump: boolean = false, + unhandledFuncDump: boolean = false, + analysisScale: PtaAnalysisScale = PtaAnalysisScale.WholeProgram, + ptsCoType = PtsCollectionType.Set + ) { + if (kLimit > 5) { + throw new Error('K Limit too large'); + } + this.kLimit = kLimit; + this.outputDirectory = outputDirectory; + this.detectTypeDiff = detectTypeDiff; + this.dotDump = dotDump; + this.unhandledFuncDump = unhandledFuncDump; + this.analysisScale = analysisScale; + this.ptsCollectionType = ptsCoType; + this.ptsCollectionCtor = createPtsCollectionCtor(ptsCoType); + + if (!fs.existsSync(outputDirectory)) { + fs.mkdirSync(outputDirectory, { recursive: true }); + } + } + + /* + * Create Singleton instance + * The instance can be created multi-times and be overwrited + */ + public static create( + kLimit: number, + outputDirectory: string, + detectTypeDiff: boolean = false, + dotDump: boolean = false, + unhandledFuncDump: boolean = false, + analysisScale: PtaAnalysisScale = PtaAnalysisScale.WholeProgram, + ptsCoType = PtsCollectionType.Set + ): PointerAnalysisConfig { + PointerAnalysisConfig.instance = new PointerAnalysisConfig( + kLimit, + outputDirectory, + detectTypeDiff, + dotDump, + unhandledFuncDump, + analysisScale, + ptsCoType + ); + return PointerAnalysisConfig.instance; + } + + /* + * Get Singleton instance + */ + public static getInstance(): PointerAnalysisConfig { + if (!PointerAnalysisConfig.instance) { + throw new Error('PTA config: instance is not existing'); + } + return PointerAnalysisConfig.instance; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PtsDS.ts b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PtsDS.ts new file mode 100644 index 0000000000000000000000000000000000000000..492d6c99ecd407b1955cb8ba6e2acd80cabf95c3 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/callgraph/pointerAnalysis/PtsDS.ts @@ -0,0 +1,376 @@ +/* + * 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. + */ + +import { SparseBitVector } from '../../utils/SparseBitVector'; + +type Idx = number; +export interface IPtsCollection { + contains(elem: T): boolean; + insert(elem: T): boolean; + remove(elem: T): boolean; + clone(): this; + union(other: this): boolean; + subtract(other: this): boolean; + clear(): void; + count(): number; + isEmpty(): boolean; + superset(other: this): boolean; + intersect(other: this): boolean; + getProtoPtsSet(): any; + [Symbol.iterator](): IterableIterator; +} + +/* + * Return PtsSet or PtsBV 's constructor by input type + */ +export function createPtsCollectionCtor(type: PtsCollectionType): new () => IPtsCollection { + if (type === PtsCollectionType.Set) { + return PtsSet; + } else if (type === PtsCollectionType.BitVector) { + return PtsBV; + } + throw new Error(`Unsupported pts collection type: ${type}`); +} + +/* + * A simple set to store pts data + */ +export class PtsSet implements IPtsCollection { + pts: Set; + + constructor() { + this.pts = new Set(); + } + + contains(elem: T): boolean { + return this.pts.has(elem); + } + + insert(elem: T): boolean { + if (this.pts.has(elem)) { + return false; + } + this.pts.add(elem); + return true; + } + + remove(elem: T): boolean { + if (!this.pts.has(elem)) { + return false; + } + this.pts.delete(elem); + return true; + } + + clone(): this { + let clonedSet = new PtsSet(); + clonedSet.pts = new Set(this.pts); + // TODO: need validate + return clonedSet as this; + } + + union(other: this): boolean { + let changed = false; + for (const elem of other.pts) { + changed = this.insert(elem) || changed; + } + return changed; + } + + subtract(other: this): boolean { + let changed = false; + for (const elem of other.pts) { + changed = this.remove(elem) || changed; + } + + return changed; + } + + clear(): void { + this.pts.clear(); + } + + count(): number { + return this.pts.size; + } + + isEmpty(): boolean { + return this.pts.size === 0; + } + + // If current collection is a super set of other + superset(other: this): boolean { + for (const elem of other.pts) { + if (!this.pts.has(elem)) { + return false; + } + } + return true; + } + + // If current collection is intersect with other + intersect(other: this): boolean { + for (const elem of other.pts) { + if (this.pts.has(elem)) { + return true; + } + } + return false; + } + + getProtoPtsSet(): Set { + return this.pts; + } + + [Symbol.iterator](): IterableIterator { + return this.pts[Symbol.iterator](); + } +} + +export class PtsBV implements IPtsCollection { + pts: SparseBitVector; + + constructor() { + this.pts = new SparseBitVector(); + } + + contains(elem: T): boolean { + return this.pts.test(elem); + } + + insert(elem: T): boolean { + this.pts.set(elem); + return true; + } + + remove(elem: T): boolean { + this.pts.reset(elem); + return true; + } + + clone(): this { + let cloned = new PtsBV(); + cloned.pts = this.pts.clone(); + return cloned as this; + } + + union(other: this): boolean { + return this.pts.unionWith(other.pts); + } + + subtract(other: this): boolean { + return this.pts.subtractWith(other.pts); + } + + clear(): void { + this.pts.clear(); + } + + count(): number { + return this.pts.count(); + } + + isEmpty(): boolean { + return this.pts.isEmpty(); + } + + // If current collection is a super set of other + superset(other: this): boolean { + for (const elem of other.pts) { + if (!this.pts.test(elem)) { + return false; + } + } + return true; + } + + // If current collection is intersect with other + intersect(other: this): boolean { + for (const elem of other.pts) { + if (this.pts.test(elem)) { + return true; + } + } + return false; + } + + getProtoPtsSet(): SparseBitVector { + return this.pts; + } + + [Symbol.iterator](): IterableIterator { + return this.pts[Symbol.iterator]() as IterableIterator; + } +} + +export enum PtsCollectionType { + Set, + BitVector, +} +export class DiffPTData> { + private diffPtsMap: Map; + private propaPtsMap: Map; + + constructor(private DSCreator: new () => DS) { + this.diffPtsMap = new Map(); + this.propaPtsMap = new Map(); + } + + clear(): void { + this.diffPtsMap.clear(); + this.propaPtsMap.clear(); + } + + addPts(v: K, elem: D): boolean { + let propa = this.propaPtsMap.get(v); + if (propa && propa.contains(elem)) { + return false; + } + let diff = this.diffPtsMap.get(v) || new this.DSCreator(); + this.diffPtsMap.set(v, diff); + return diff.insert(elem); + } + + resetElem(v: K): boolean { + let propa = this.propaPtsMap.get(v); + if (propa) { + this.diffPtsMap.set(v, propa.clone()); + return true; + } + return false; + } + + unionDiffPts(dstv: K, srcv: K): boolean { + if (dstv === srcv) { + return false; + } + let changed = false; + let diff = this.diffPtsMap.get(srcv); + if (diff) { + let srcDs = diff.clone(); + changed = this.unionPtsTo(dstv, srcDs); + } + return changed; + } + + unionPts(dstv: K, srcv: K): boolean { + if (dstv === srcv) { + return false; + } + let changed = false; + let diff = this.diffPtsMap.get(srcv); + if (diff) { + let srcDs = diff.clone(); + changed = this.unionPtsTo(dstv, srcDs); + } + let propa = this.propaPtsMap.get(srcv); + if (propa) { + let srcDs = propa.clone(); + changed = this.unionPtsTo(dstv, srcDs) || changed; + } + return changed; + } + + unionPtsTo(dstv: K, srcDs: DS): boolean { + let diff = this.diffPtsMap.get(dstv) || new this.DSCreator(); + let propa = this.propaPtsMap.get(dstv) || new this.DSCreator(); + let newSet = srcDs.clone(); + newSet.subtract(propa); + let changed = diff.union(newSet); + this.diffPtsMap.set(dstv, diff); + return changed; + } + + removePtsElem(v: K, elem: D): boolean { + let removedFromDiff = this.diffPtsMap.get(v)?.remove(elem) ?? false; + let removedFromPropa = this.propaPtsMap.get(v)?.remove(elem) ?? false; + return removedFromDiff || removedFromPropa; + } + + getDiffPts(v: K): DS | undefined { + return this.diffPtsMap.get(v); + } + + getMutDiffPts(v: K): DS | undefined { + if (!this.diffPtsMap.has(v)) { + this.diffPtsMap.set(v, new this.DSCreator()); + } + return this.diffPtsMap.get(v); + } + + getPropaPts(v: K): DS | undefined { + return this.propaPtsMap.get(v); + } + + getAllPropaPts(): Map { + return this.propaPtsMap; + } + + getPropaPtsMut(v: K): DS { + if (!this.propaPtsMap.has(v)) { + this.propaPtsMap.set(v, new this.DSCreator()); + } + return this.propaPtsMap.get(v)!; + } + + flush(v: K): void { + if (!this.diffPtsMap.has(v)) { + return; + } + let diff = this.diffPtsMap.get(v)!; + let propa = this.getPropaPtsMut(v); + // do not clear origin propa, only copy the pt and add it to diff + propa.union(diff); + diff.clear(); + } + + clearPts(v: K): void { + let diff = this.diffPtsMap.get(v); + if (diff) { + diff.clear(); + } + let propa = this.propaPtsMap.get(v); + if (propa) { + propa.clear(); + } + } + + clearDiffPts(v: K): void { + let diff = this.diffPtsMap.get(v); + if (diff) { + diff.clear(); + } + } + + clearPropaPts(v: K): void { + let propa = this.propaPtsMap.get(v); + if (propa) { + propa.clear(); + } + } + + calculateDiff(src: K, dst: K): DS { + let srcDiff = this.diffPtsMap.get(src)!; + let dstPropa = this.propaPtsMap.get(dst); + if (!dstPropa) { + return srcDiff.clone(); + } + + let result = srcDiff.clone(); + + result.subtract(dstPropa); + return result; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Constant.ts b/ets2panda/linter/arkanalyzer/src/core/base/Constant.ts new file mode 100644 index 0000000000000000000000000000000000000000..cc7da1df70180d6a6d9b7df638fde0c7dedb7e7e --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Constant.ts @@ -0,0 +1,120 @@ +/* + * 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. + */ + +import { BigIntType, BooleanType, NullType, NumberType, StringType, Type, UndefinedType } from './Type'; +import { Value } from './Value'; +import { NULL_KEYWORD, UNDEFINED_KEYWORD } from '../common/TSConst'; + +/** + * @category core/base + */ +export class Constant implements Value { + private readonly value: string; + private readonly type: Type; + + constructor(value: string, type: Type) { + this.value = value; + this.type = type; + } + + /** + * Returns the constant's value as a **string**. + * @returns The constant's value. + */ + public getValue(): string { + return this.value; + } + + public getUses(): Value[] { + return []; + } + + /** + * Returns the type of this constant. + * @returns The type of this constant. + */ + public getType(): Type { + return this.type; + } + + /** + * Get a string of constant value in Constant. + * @returns The string of constant value. + */ + public toString(): string { + let str = ''; + if (this.type instanceof StringType) { + str = "'" + this.value + "'"; + } else { + str = this.value; + } + return str; + } +} + +export class BooleanConstant extends Constant { + private static readonly FALSE = new BooleanConstant(false); + private static readonly TRUE = new BooleanConstant(true); + + constructor(value: boolean) { + super(value.toString(), BooleanType.getInstance()); + } + + public static getInstance(value: boolean): NullConstant { + return value ? this.TRUE : this.FALSE; + } +} + +export class NumberConstant extends Constant { + constructor(value: number) { + super(value.toString(), NumberType.getInstance()); + } +} + +export class BigIntConstant extends Constant { + constructor(value: bigint) { + super(value.toString(), BigIntType.getInstance()); + } +} + +export class StringConstant extends Constant { + constructor(value: string) { + super(value.toString(), StringType.getInstance()); + } +} + +export class NullConstant extends Constant { + private static readonly INSTANCE = new NullConstant(); + + constructor() { + super(NULL_KEYWORD, NullType.getInstance()); + } + + public static getInstance(): NullConstant { + return this.INSTANCE; + } +} + +export class UndefinedConstant extends Constant { + private static readonly INSTANCE = new UndefinedConstant(); + + constructor() { + super(UNDEFINED_KEYWORD, UndefinedType.getInstance()); + } + + public static getInstance(): UndefinedConstant { + return this.INSTANCE; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Decorator.ts b/ets2panda/linter/arkanalyzer/src/core/base/Decorator.ts new file mode 100644 index 0000000000000000000000000000000000000000..f53d1f78bd00abdcf67027620245b4d449be8312 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Decorator.ts @@ -0,0 +1,44 @@ +/* + * 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. + */ + +/** + * @category core/base + */ +export class Decorator { + kind: string; + content: string = ''; + param: string = ''; + constructor(name: string) { + this.kind = name; + } + public getKind(): string { + return this.kind; + } + public setContent(content: string): void { + this.content = content; + } + public getContent(): string { + return this.content; + } + public setParam(param: string): void { + this.param = param; + } + public getParam(): string { + return this.param; + } + public toString(): string { + return `@${this.content}`; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/DefUseChain.ts b/ets2panda/linter/arkanalyzer/src/core/base/DefUseChain.ts new file mode 100644 index 0000000000000000000000000000000000000000..8c4bd3ce97560ddde6183f16408d8a445e33d3e3 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/DefUseChain.ts @@ -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. + */ + +import { Value } from './Value'; +import { Stmt } from './Stmt'; + +export class DefUseChain { + value: Value; + def: Stmt; + use: Stmt; + constructor(value: Value, def: Stmt, use: Stmt) { + this.value = value; + this.def = def; + this.use = use; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Expr.ts b/ets2panda/linter/arkanalyzer/src/core/base/Expr.ts new file mode 100644 index 0000000000000000000000000000000000000000..dcf4695331ac437403e3d04b0ce248b533806264 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Expr.ts @@ -0,0 +1,1138 @@ +/* + * 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. + */ + +import { TypeInference } from '../common/TypeInference'; +import { BasicBlock } from '../graph/BasicBlock'; +import { MethodSignature } from '../model/ArkSignature'; +import { Local } from './Local'; +import { + AliasType, + ArrayType, + BigIntType, + BooleanType, + ClassType, + FunctionType, + NullType, + NumberType, + StringType, + Type, + UnclearReferenceType, + UndefinedType, + UnionType, + UnknownType, +} from './Type'; +import { Value } from './Value'; +import { AbstractFieldRef, AbstractRef, ArkInstanceFieldRef, ArkStaticFieldRef } from './Ref'; +import { EMPTY_STRING, ValueUtil } from '../common/ValueUtil'; +import { ArkMethod } from '../model/ArkMethod'; +import { UNKNOWN_FILE_NAME } from '../common/Const'; +import { IRInference } from '../common/IRInference'; +import { ImportInfo } from '../model/ArkImport'; +import { ArkClass } from '../model/ArkClass'; +import { ArkField } from '../model/ArkField'; + +/** + * @category core/base/expr + */ +export abstract class AbstractExpr implements Value { + abstract getUses(): Value[]; + + abstract getType(): Type; + + abstract toString(): string; + + public inferType(arkMethod: ArkMethod): AbstractExpr { + return this; + } +} + +export abstract class AbstractInvokeExpr extends AbstractExpr { + private methodSignature: MethodSignature; + private args: Value[]; + private realGenericTypes?: Type[]; //新增 + + constructor(methodSignature: MethodSignature, args: Value[], realGenericTypes?: Type[]) { + super(); + this.methodSignature = methodSignature; + this.args = args; + this.realGenericTypes = realGenericTypes; + } + + /** + * Get method Signature. The method signature is consist of ClassSignature and MethodSubSignature. + * It is the unique flag of a method. It is usually used to compose a expression string in ArkIRTransformer. + * @returns The class method signature, such as ArkStaticInvokeExpr. + * @example + * 1. 3AC information composed of getMethodSignature (). + + ```typescript + let strs: string[] = []; + strs.push('staticinvoke <'); + strs.push(this.getMethodSignature().toString()); + strs.push('>('); + ``` + */ + public getMethodSignature(): MethodSignature { + return this.methodSignature; + } + + public setMethodSignature(newMethodSignature: MethodSignature): void { + this.methodSignature = newMethodSignature; + } + + /** + * Returns an argument used in the expression according to its index. + * @param index - the index of the argument. + * @returns An argument used in the expression. + */ + public getArg(index: number): Value { + return this.args[index]; + } + + /** + * Returns an **array** of arguments used in the expression. + * @returns An **array** of arguments used in the expression. + * @example + * 1. get args number. + + ```typescript + const argsNum = expr.getArgs().length; + if (argsNum < 5) { + ... ... + } + ``` + + 2. iterate arg based on expression + + ```typescript + for (const arg of this.getArgs()) { + strs.push(arg.toString()); + strs.push(', '); + } + ``` + */ + public getArgs(): Value[] { + return this.args; + } + + public setArgs(newArgs: Value[]): void { + this.args = newArgs; + } + + public getType(): Type { + const type = this.methodSignature.getType(); + if (this.realGenericTypes) { + return TypeInference.replaceTypeWithReal(type, this.realGenericTypes); + } + return type; + } + + public getRealGenericTypes(): Type[] | undefined { + return this.realGenericTypes; + } + + public setRealGenericTypes(realTypes: Type[] | undefined): void { + if (realTypes) { + this.realGenericTypes = realTypes; + } + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(...this.args); + for (const arg of this.args) { + uses.push(...arg.getUses()); + } + return uses; + } +} + +export class ArkInstanceInvokeExpr extends AbstractInvokeExpr { + private base: Local; + + constructor(base: Local, methodSignature: MethodSignature, args: Value[], realGenericTypes?: Type[]) { + super(methodSignature, args, realGenericTypes); + this.base = base; + } + + /** + * Returns the local of the instance of invoke expression. + * @returns The local of the invoke expression's instance.. + */ + public getBase(): Local { + return this.base; + } + + public setBase(newBase: Local): void { + this.base = newBase; + } + + /** + * Returns an **array** of values used in this invoke expression, + * including all arguments and values each arguments used. + * For {@link ArkInstanceInvokeExpr}, the return also contains the caller base and uses of base. + * @returns An **array** of arguments used in the invoke expression. + */ + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.base); + uses.push(...this.base.getUses()); + uses.push(...this.getArgs()); + for (const arg of this.getArgs()) { + uses.push(...arg.getUses()); + } + return uses; + } + + public toString(): string { + let strs: string[] = []; + strs.push('instanceinvoke '); + strs.push(this.base.toString()); + strs.push('.<'); + strs.push(this.getMethodSignature().toString()); + strs.push('>('); + if (this.getArgs().length > 0) { + for (const arg of this.getArgs()) { + strs.push(arg.toString()); + strs.push(', '); + } + strs.pop(); + } + strs.push(')'); + return strs.join(''); + } + + public inferType(arkMethod: ArkMethod): AbstractInvokeExpr { + return IRInference.inferInstanceInvokeExpr(this, arkMethod); + } +} + +export class ArkStaticInvokeExpr extends AbstractInvokeExpr { + constructor(methodSignature: MethodSignature, args: Value[], realGenericTypes?: Type[]) { + super(methodSignature, args, realGenericTypes); + } + + public toString(): string { + let strs: string[] = []; + strs.push('staticinvoke <'); + strs.push(this.getMethodSignature().toString()); + strs.push('>('); + if (this.getArgs().length > 0) { + for (const arg of this.getArgs()) { + strs.push(arg.toString()); + strs.push(', '); + } + strs.pop(); + } + strs.push(')'); + return strs.join(''); + } + + public inferType(arkMethod: ArkMethod): AbstractInvokeExpr { + return IRInference.inferStaticInvokeExpr(this, arkMethod); + } +} + +/** + * 1. Local PtrInvokeExpr + * + * ```typescript + * func foo():void { + * } + * let ptr = foo; + * ptr(); + * ``` + * 2. FieldRef PtrInvokeExpr + * + * ```typescript + * class A { + * b:()=> void() + * } + * new A().b() + * ``` + */ +export class ArkPtrInvokeExpr extends AbstractInvokeExpr { + private funPtr: Local | AbstractFieldRef; + + constructor(methodSignature: MethodSignature, ptr: Local | AbstractFieldRef, args: Value[], realGenericTypes?: Type[]) { + super(methodSignature, args, realGenericTypes); + this.funPtr = ptr; + } + + public setFunPtrLocal(ptr: Local | AbstractFieldRef): void { + this.funPtr = ptr; + } + + public getFuncPtrLocal(): Local | AbstractFieldRef { + return this.funPtr; + } + + public toString(): string { + let strs: string[] = []; + strs.push('ptrinvoke <'); + let ptrName: string = ''; + if (this.funPtr instanceof Local) { + ptrName = this.funPtr.getName(); + } else if (this.funPtr instanceof ArkInstanceFieldRef) { + ptrName = this.funPtr.getBase().getName() + '.' + this.funPtr.getFieldName(); + } else if (this.funPtr instanceof ArkStaticFieldRef) { + ptrName = this.funPtr.getFieldName(); + } + strs.push(this.getMethodSignature().toString(ptrName)); + strs.push('>('); + if (this.getArgs().length > 0) { + for (const arg of this.getArgs()) { + strs.push(arg.toString()); + strs.push(', '); + } + strs.pop(); + } + strs.push(')'); + return strs.join(''); + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.getFuncPtrLocal()); + uses.push(...this.getArgs()); + for (const arg of this.getArgs()) { + uses.push(...arg.getUses()); + } + return uses; + } +} + +export class ArkNewExpr extends AbstractExpr { + private classType: ClassType; + + constructor(classType: ClassType) { + super(); + this.classType = classType; + } + + public getClassType(): ClassType { + return this.classType; + } + + public getUses(): Value[] { + return []; + } + + public getType(): Type { + return this.classType; + } + + public toString(): string { + return 'new ' + this.classType; + } + + public inferType(arkMethod: ArkMethod): ArkNewExpr { + const classSignature = this.classType.getClassSignature(); + if (classSignature.getDeclaringFileSignature().getFileName() === UNKNOWN_FILE_NAME) { + const className = classSignature.getClassName(); + let type = TypeInference.inferUnclearRefName(className, arkMethod.getDeclaringArkClass()); + if (type && type instanceof ClassType) { + let realGenericTypes = this.classType.getRealGenericTypes(); + this.classType = realGenericTypes ? new ClassType(type.getClassSignature(), realGenericTypes) : type; + } + } + return this; + } +} + +export class ArkNewArrayExpr extends AbstractExpr { + private baseType: Type; + private size: Value; + + private fromLiteral: boolean; + + constructor(baseType: Type, size: Value, fromLiteral: boolean = false) { + super(); + this.baseType = baseType; + this.size = size; + this.fromLiteral = fromLiteral; + } + + public getSize(): Value { + return this.size; + } + + public setSize(newSize: Value): void { + this.size = newSize; + } + + public getType(): ArrayType { + return new ArrayType(this.baseType, 1); + } + + public getBaseType(): Type { + return this.baseType; + } + + public setBaseType(newType: Type): void { + this.baseType = newType; + } + + public isFromLiteral(): boolean { + return this.fromLiteral; + } + + public inferType(arkMethod: ArkMethod): ArkNewArrayExpr { + const type = TypeInference.inferUnclearedType(this.baseType, arkMethod.getDeclaringArkClass()); + if (type) { + this.baseType = type; + } + return this; + } + + public getUses(): Value[] { + let uses: Value[] = [this.size]; + uses.push(...this.size.getUses()); + return uses; + } + + public toString(): string { + return 'newarray (' + this.baseType + ')[' + this.size + ']'; + } +} + +export class ArkDeleteExpr extends AbstractExpr { + private field: AbstractFieldRef; + + constructor(field: AbstractFieldRef) { + super(); + this.field = field; + } + + public getField(): AbstractFieldRef { + return this.field; + } + + public setField(newField: AbstractFieldRef): void { + this.field = newField; + } + + public getType(): Type { + return BooleanType.getInstance(); + } + + public getUses(): Value[] { + const uses: Value[] = []; + uses.push(this.field); + uses.push(...this.field.getUses()); + return uses; + } + + public toString(): string { + return 'delete ' + this.field; + } +} + +export class ArkAwaitExpr extends AbstractExpr { + private promise: Value; + + constructor(promise: Value) { + super(); + this.promise = promise; + } + + public getPromise(): Value { + return this.promise; + } + + public setPromise(newPromise: Value): void { + this.promise = newPromise; + } + + public getType(): Type { + const type = this.promise.getType(); + if (type instanceof UnclearReferenceType) { + return type.getGenericTypes()[0]; + } else if (type instanceof ClassType) { + return type.getRealGenericTypes()?.[0] ?? type; + } + return type; + } + + public inferType(arkMethod: ArkMethod): ArkAwaitExpr { + TypeInference.inferValueType(this.promise, arkMethod); + return this; + } + + public getUses(): Value[] { + const uses: Value[] = []; + uses.push(this.promise); + uses.push(...this.promise.getUses()); + return uses; + } + + public toString(): string { + const str = 'await ' + this.promise; + return str; + } +} + +export class ArkYieldExpr extends AbstractExpr { + private yieldValue: Value; + + constructor(yieldValue: Value) { + super(); + this.yieldValue = yieldValue; + } + + public getYieldValue(): Value { + return this.yieldValue; + } + + public setYieldValue(newYieldValue: Value): void { + this.yieldValue = newYieldValue; + } + + public getType(): Type { + return this.yieldValue.getType(); + } + + public getUses(): Value[] { + const uses: Value[] = []; + uses.push(this.yieldValue); + uses.push(...this.yieldValue.getUses()); + return uses; + } + + public toString(): string { + const str = 'yield ' + this.yieldValue; + return str; + } +} + +export enum NormalBinaryOperator { + // TODO: unfold it + NullishCoalescing = '??', + + // arithmetic + Exponentiation = '**', + Division = '/', + Addition = '+', + Subtraction = '-', + Multiplication = '*', + Remainder = '%', + + // shift + LeftShift = '<<', + RightShift = '>>', + UnsignedRightShift = '>>>', + + // Bitwise + BitwiseAnd = '&', + BitwiseOr = '|', + BitwiseXor = '^', + + // Logical + LogicalAnd = '&&', + LogicalOr = '||', +} + +export enum RelationalBinaryOperator { + LessThan = '<', + LessThanOrEqual = '<=', + GreaterThan = '>', + GreaterThanOrEqual = '>=', + Equality = '==', + InEquality = '!=', + StrictEquality = '===', + StrictInequality = '!==', + isPropertyOf = 'in', +} + +export type BinaryOperator = NormalBinaryOperator | RelationalBinaryOperator; + +// 二元运算表达式 +export abstract class AbstractBinopExpr extends AbstractExpr { + protected op1: Value; + protected op2: Value; + protected operator: BinaryOperator; + + protected type!: Type; + + constructor(op1: Value, op2: Value, operator: BinaryOperator) { + super(); + this.op1 = op1; + this.op2 = op2; + this.operator = operator; + } + + /** + * Returns the first operand in the binary operation expression. + * For example, the first operand in `a + b;` is `a`. + * @returns The first operand in the binary operation expression. + */ + public getOp1(): Value { + return this.op1; + } + + public setOp1(newOp1: Value): void { + this.op1 = newOp1; + } + + /** + * Returns the second operand in the binary operation expression. + * For example, the second operand in `a + b;` is `b`. + * @returns The second operand in the binary operation expression. + */ + public getOp2(): Value { + return this.op2; + } + + public setOp2(newOp2: Value): void { + this.op2 = newOp2; + } + + /** + * Get the binary operator from the statement. + * The binary operator can be divided into two categories, + * one is the normal binary operator and the other is relational binary operator. + * @returns The binary operator from the statement. + * @example + ```typescript + if (expr instanceof AbstractBinopExpr) { + let op1: Value = expr.getOp1(); + let op2: Value = expr.getOp2(); + let operator: string = expr.getOperator(); + ... ... + } + ``` + */ + public getOperator(): BinaryOperator { + return this.operator; + } + + public getType(): Type { + if (!this.type) { + this.setType(); + } + return this.type; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.op1); + uses.push(...this.op1.getUses()); + uses.push(this.op2); + uses.push(...this.op2.getUses()); + return uses; + } + + public toString(): string { + return this.op1 + ' ' + this.operator + ' ' + this.op2; + } + + protected inferOpType(op: Value, arkMethod: ArkMethod): void { + if (op instanceof AbstractExpr || op instanceof AbstractRef) { + TypeInference.inferValueType(op, arkMethod); + } + } + + protected setType(): void { + let op1Type = this.op1.getType(); + let op2Type = this.op2.getType(); + if (op1Type instanceof UnionType) { + op1Type = op1Type.getCurrType(); + } + if (op2Type instanceof UnionType) { + op2Type = op2Type.getCurrType(); + } + let type = UnknownType.getInstance(); + switch (this.operator) { + case '+': + if (op1Type === StringType.getInstance() || op2Type === StringType.getInstance()) { + type = StringType.getInstance(); + } + if (op1Type === NumberType.getInstance() && op2Type === NumberType.getInstance()) { + type = NumberType.getInstance(); + } + if (op1Type === BigIntType.getInstance() && op2Type === BigIntType.getInstance()) { + type = BigIntType.getInstance(); + } + break; + case '-': + case '*': + case '/': + case '%': + if (op1Type === NumberType.getInstance() && op2Type === NumberType.getInstance()) { + type = NumberType.getInstance(); + } + if (op1Type === BigIntType.getInstance() && op2Type === BigIntType.getInstance()) { + type = BigIntType.getInstance(); + } + break; + case '!=': + case '!==': + case '<': + case '>': + case '<=': + case '>=': + case '&&': + case '||': + case '==': + case '===': + case 'in': + type = BooleanType.getInstance(); + break; + case '&': + case '|': + case '^': + case '<<': + case '>>': + if (op1Type === BigIntType.getInstance() && op2Type === BigIntType.getInstance()) { + type = BigIntType.getInstance(); + } + case '>>>': + if (op1Type === NumberType.getInstance() && op2Type === NumberType.getInstance()) { + type = NumberType.getInstance(); + } + break; + case '??': + if (op1Type === UnknownType.getInstance() || op1Type === UndefinedType.getInstance() || op1Type === NullType.getInstance()) { + type = op2Type; + } else { + type = op1Type; + } + break; + default: + } + this.type = type; + } + + public inferType(arkMethod: ArkMethod): AbstractBinopExpr { + this.inferOpType(this.op1, arkMethod); + this.inferOpType(this.op2, arkMethod); + this.setType(); + return this; + } +} + +export class ArkConditionExpr extends AbstractBinopExpr { + constructor(op1: Value, op2: Value, operator: RelationalBinaryOperator) { + super(op1, op2, operator); + } + + public inferType(arkMethod: ArkMethod): ArkConditionExpr { + this.inferOpType(this.op1, arkMethod); + const op1Type = this.op1.getType(); + if (this.operator === RelationalBinaryOperator.InEquality && this.op2 === ValueUtil.getOrCreateNumberConst(0)) { + if (op1Type instanceof StringType) { + this.op2 = ValueUtil.createStringConst(EMPTY_STRING); + } else if (op1Type instanceof BooleanType) { + this.op2 = ValueUtil.getBooleanConstant(false); + } else if (op1Type instanceof ClassType) { + this.op2 = ValueUtil.getUndefinedConst(); + } + } else { + this.inferOpType(this.getOp2(), arkMethod); + } + this.type = BooleanType.getInstance(); + return this; + } +} + +export class ArkNormalBinopExpr extends AbstractBinopExpr { + constructor(op1: Value, op2: Value, operator: NormalBinaryOperator) { + super(op1, op2, operator); + } +} + +export class ArkTypeOfExpr extends AbstractExpr { + private op: Value; + + constructor(op: Value) { + super(); + this.op = op; + } + + public getOp(): Value { + return this.op; + } + + public setOp(newOp: Value): void { + this.op = newOp; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.op); + uses.push(...this.op.getUses()); + return uses; + } + + public getType(): Type { + return this.op.getType(); + } + + public toString(): string { + return 'typeof ' + this.op; + } + + public inferType(arkMethod: ArkMethod): AbstractExpr { + if (this.op instanceof AbstractRef || this.op instanceof AbstractExpr) { + this.op.inferType(arkMethod); + } + return this; + } +} + +export class ArkInstanceOfExpr extends AbstractExpr { + private op: Value; + private checkType: Type; + + constructor(op: Value, checkType: Type) { + super(); + this.op = op; + this.checkType = checkType; + } + + public getOp(): Value { + return this.op; + } + + public setOp(newOp: Value): void { + this.op = newOp; + } + + public getCheckType(): Type { + return this.checkType; + } + + public getType(): Type { + return BooleanType.getInstance(); + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.op); + uses.push(...this.op.getUses()); + return uses; + } + + public toString(): string { + return this.op + ' instanceof ' + this.checkType; + } + + public inferType(arkMethod: ArkMethod): AbstractExpr { + TypeInference.inferValueType(this.op, arkMethod); + if (TypeInference.isUnclearType(this.checkType)) { + const newType = TypeInference.inferUnclearedType(this.checkType, arkMethod.getDeclaringArkClass()); + if (newType) { + this.checkType = newType; + } + } + return this; + } +} + +// 类型转换 +export class ArkCastExpr extends AbstractExpr { + private op: Value; + private type: Type; + + constructor(op: Value, type: Type) { + super(); + this.op = op; + this.type = type; + } + + public getOp(): Value { + return this.op; + } + + public setOp(newOp: Value): void { + this.op = newOp; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.op); + uses.push(...this.op.getUses()); + return uses; + } + + public getType(): Type { + return this.type; + } + + public inferType(arkMethod: ArkMethod): AbstractExpr { + if (TypeInference.isUnclearType(this.getType())) { + const type = TypeInference.inferUnclearedType(this.type, arkMethod.getDeclaringArkClass()) ?? this.op.getType(); + if (type !== undefined && !TypeInference.isUnclearType(type)) { + this.type = type; + IRInference.inferRightWithSdkType(type, this.op.getType(), arkMethod.getDeclaringArkClass()); + } + } + return this; + } + + public toString(): string { + return '<' + this.type + '>' + this.op; + } +} + +export class ArkPhiExpr extends AbstractExpr { + private args: Local[]; + private argToBlock: Map; + + constructor() { + super(); + this.args = []; + this.argToBlock = new Map(); + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(...this.args); + return uses; + } + + public getArgs(): Local[] { + return this.args; + } + + public setArgs(args: Local[]): void { + this.args = args; + } + + public getArgToBlock(): Map { + return this.argToBlock; + } + + public setArgToBlock(argToBlock: Map): void { + this.argToBlock = argToBlock; + } + + public getType(): Type { + return this.args[0].getType(); + } + + public toString(): string { + let strs: string[] = []; + strs.push('phi('); + if (this.args.length > 0) { + for (const arg of this.args) { + strs.push(arg.toString()); + strs.push(', '); + } + strs.pop(); + } + strs.push(')'); + return strs.join(''); + } +} + +export enum UnaryOperator { + Neg = '-', + BitwiseNot = '~', + LogicalNot = '!', +} + +// unary operation expression +export class ArkUnopExpr extends AbstractExpr { + private op: Value; + private operator: UnaryOperator; + + constructor(op: Value, operator: UnaryOperator) { + super(); + this.op = op; + this.operator = operator; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.op); + uses.push(...this.op.getUses()); + return uses; + } + + public getOp(): Value { + return this.op; + } + + public setOp(newOp: Value): void { + this.op = newOp; + } + + public getType(): Type { + return this.op.getType(); + } + + /** + * Get the unary operator from the statement, such as `-`,`~`,`!`. + * @returns the unary operator of a statement. + */ + public getOperator(): UnaryOperator { + return this.operator; + } + + public toString(): string { + return this.operator + this.op; + } +} + +export type AliasTypeOriginalModel = Type | ImportInfo | Local | ArkClass | ArkMethod | ArkField; + +/** + * Expression of the right hand of the type alias definition statement. + * @category core/base/expr + * @extends AbstractExpr + * @example + ```typescript + let a: number = 123; + type ABC = typeof a; + ``` + * The AliasTypeExpr of the previous statement is with local 'a' as the 'originalObject' and 'transferWithTypeOf' is true. + * + * The Following case: import type with no clause name is not supported now, + * whose 'originalObject' is {@link ImportInfo} with 'null' 'lazyExportInfo'. + ```typescript + let a = typeof import('./abc'); + ``` + */ +export class AliasTypeExpr extends AbstractExpr { + private originalObject: AliasTypeOriginalModel; + private readonly transferWithTypeOf: boolean = false; + private realGenericTypes?: Type[]; + + constructor(originalObject: AliasTypeOriginalModel, transferWithTypeOf?: boolean) { + super(); + this.originalObject = originalObject; + if (transferWithTypeOf !== undefined) { + this.transferWithTypeOf = transferWithTypeOf; + } + } + + public getOriginalObject(): AliasTypeOriginalModel { + return this.originalObject; + } + + public setOriginalObject(object: AliasTypeOriginalModel): void { + this.originalObject = object; + } + + public getTransferWithTypeOf(): boolean { + return this.transferWithTypeOf; + } + + public setRealGenericTypes(realGenericTypes: Type[]): void { + this.realGenericTypes = realGenericTypes; + } + + public getRealGenericTypes(): Type[] | undefined { + return this.realGenericTypes; + } + + public getType(): Type { + function getTypeOfImportInfo(importInfo: ImportInfo): Type { + const arkExport = importInfo.getLazyExportInfo()?.getArkExport(); + if (arkExport) { + return TypeInference.parseArkExport2Type(arkExport) ?? UnknownType.getInstance(); + } + return UnknownType.getInstance(); + } + + const operator = this.getOriginalObject(); + if (!this.getTransferWithTypeOf()) { + if (operator instanceof Type) { + return TypeInference.replaceTypeWithReal(operator, this.getRealGenericTypes()); + } + if (operator instanceof ImportInfo) { + return getTypeOfImportInfo(operator); + } + if (operator instanceof ArkClass) { + return TypeInference.replaceTypeWithReal(new ClassType(operator.getSignature(), operator.getGenericsTypes()), this.getRealGenericTypes()); + } + return UnknownType.getInstance(); + } + + if (operator instanceof ImportInfo) { + return getTypeOfImportInfo(operator); + } + if (operator instanceof Local || operator instanceof ArkField) { + return operator.getType(); + } + if (operator instanceof ArkClass) { + return TypeInference.replaceTypeWithReal(new ClassType(operator.getSignature(), operator.getGenericsTypes()), this.getRealGenericTypes()); + } + if (operator instanceof ArkMethod) { + return TypeInference.replaceTypeWithReal(new FunctionType(operator.getSignature(), operator.getGenericTypes()), this.getRealGenericTypes()); + } + return UnknownType.getInstance(); + } + + public inferType(arkMethod: ArkMethod): AbstractExpr { + return IRInference.inferAliasTypeExpr(this, arkMethod); + } + + /** + * Returns all used values which mainly used for def-use chain analysis. + * @returns Always returns empty array because her is the alias type definition which has no relationship with value flow. + */ + public getUses(): Value[] { + return []; + } + + public toString(): string { + let typeOf = ''; + if (this.getTransferWithTypeOf()) { + typeOf = 'typeof '; + } + + const typeObject = this.getOriginalObject(); + if (typeObject instanceof AliasType && this.getRealGenericTypes()) { + return `${typeOf}${typeObject.getSignature().toString()}<${this.getRealGenericTypes()!.join(',')}>`; + } + if (typeObject instanceof Type) { + return `${typeOf}${typeObject.getTypeString()}`; + } + if (typeObject instanceof ImportInfo) { + let res = `${typeOf}import('${typeObject.getFrom()}')`; + if (typeObject.getImportClauseName() !== '') { + res = `${res}.${typeObject.getImportClauseName()}`; + } + return res; + } + if (typeObject instanceof Local) { + return `${typeOf}${typeObject.toString()}`; + } + if (typeObject instanceof ArkClass || typeObject instanceof ArkMethod) { + let res = `${typeOf}${typeObject.getSignature().toString()}`; + if (this.getRealGenericTypes() && typeObject instanceof ArkClass) { + res += `<${this.getRealGenericTypes()!.join(',')}>`; + } else if (this.getRealGenericTypes() && typeObject instanceof ArkMethod) { + const genericTypes = this.getRealGenericTypes()!.join(','); + res = res.replace('(', `<${genericTypes}>(`).replace(/\([^)]*\)/g, `(${genericTypes})`); + } + return res; + } + return `${typeOf}${typeObject.getName()}`; + } + + public static isAliasTypeOriginalModel(object: any): object is AliasTypeOriginalModel { + return ( + object instanceof Type || + object instanceof ImportInfo || + object instanceof Local || + object instanceof ArkClass || + object instanceof ArkMethod || + object instanceof ArkField + ); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Local.ts b/ets2panda/linter/arkanalyzer/src/core/base/Local.ts new file mode 100644 index 0000000000000000000000000000000000000000..aa4fbebdf0597b1972cea69e7fcdb70bba21b64b --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Local.ts @@ -0,0 +1,216 @@ +/* + * 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. + */ + +import { Stmt } from './Stmt'; +import { ClassType, Type, UnknownType } from './Type'; +import { Value } from './Value'; +import { TypeInference } from '../common/TypeInference'; +import { ArkExport, ExportType } from '../model/ArkExport'; +import { ClassSignature, LocalSignature, MethodSignature } from '../model/ArkSignature'; +import { ArkSignatureBuilder } from '../model/builder/ArkSignatureBuilder'; +import { UNKNOWN_METHOD_NAME } from '../common/Const'; +import { ModifierType } from '../model/ArkBaseModel'; +import { ArkMethod } from '../model/ArkMethod'; +import { ModelUtils } from '../common/ModelUtils'; +import { THIS_NAME } from '../common/TSConst'; + +/** + * @category core/base + */ +export class Local implements Value, ArkExport { + private name: string; + private type: Type; + + private originalValue: Value | null; + + private declaringStmt: Stmt | null; + private usedStmts: Stmt[]; + private signature?: LocalSignature; + private constFlag?: boolean; + + constructor(name: string, type: Type = UnknownType.getInstance()) { + this.name = name; + this.type = type; + + this.originalValue = null; + this.declaringStmt = null; + this.usedStmts = []; + } + + public inferType(arkMethod: ArkMethod): Local { + if (this.name === THIS_NAME && this.type instanceof UnknownType) { + const declaringArkClass = arkMethod.getDeclaringArkClass(); + this.type = new ClassType(declaringArkClass.getSignature(), declaringArkClass.getRealTypes()); + } else if (TypeInference.isUnclearType(this.type)) { + const type = TypeInference.inferBaseType(this.name, arkMethod.getDeclaringArkClass()) ?? ModelUtils.findDeclaredLocal(this, arkMethod)?.getType(); + if (type) { + this.type = type; + } + } + return this; + } + + /** + * Returns the name of local value. + * @returns The name of local value. + * @example + * 1. get the name of local value. + + ```typescript + arkClass.getDefaultArkMethod()?.getBody().getLocals().forEach(local => { + const arkField = new ArkField(); + arkField.setFieldType(ArkField.DEFAULT_ARK_Field); + arkField.setDeclaringClass(defaultClass); + arkField.setType(local.getType()); + arkField.setName(local.getName()); + arkField.genSignature(); + defaultClass.addField(arkField); + }); + ``` + */ + public getName(): string { + return this.name; + } + + public setName(name: string): void { + this.name = name; + } + + /** + * Returns the type of this local. + * @returns The type of this local. + */ + public getType(): Type { + return this.type; + } + + public setType(newType: Type): void { + this.type = newType; + } + + public getOriginalValue(): Value | null { + return this.originalValue; + } + + public setOriginalValue(originalValue: Value): void { + this.originalValue = originalValue; + } + + /** + * Returns the declaring statement, which may also be a **null**. + * For example, if the code snippet in a function is `let dd = cc + 5;` where `cc` is a **number** + * and `dd` is not defined before, then the declaring statemet of local `dd`: + * - its **string** text is "dd = cc + 5". + * - the **strings** of right operand and left operand are "cc + 5" and "dd", respectively. + * - three values are used in this statement: `cc + 5` (i.e., a normal binary operation expression), `cc` (a local), and `5` (a constant), respectively. + * @returns The declaring statement (maybe a **null**) of the local. + * @example + * 1. get the statement that defines the local for the first time. + + ```typescript + let stmt = local.getDeclaringStmt(); + if (stmt !== null) { + ... + } + ``` + */ + public getDeclaringStmt(): Stmt | null { + return this.declaringStmt; + } + + public setDeclaringStmt(declaringStmt: Stmt): void { + this.declaringStmt = declaringStmt; + } + + /** + * Returns an **array** of values which are contained in this local. + * @returns An **array** of values used by this local. + */ + public getUses(): Value[] { + return []; + } + + public addUsedStmt(usedStmt: Stmt): void { + this.usedStmts.push(usedStmt); + } + + /** + * Returns an array of statements used by the local, i.e., the statements in which the local participate. + * For example, if the code snippet is `let dd = cc + 5;` where `cc` is a local and `cc` only appears once, + * then the length of **array** returned is 1 and `Stmts[0]` will be same as the example described + * in the `Local.getDeclaringStmt()`. + * @returns An array of statements used by the local. + */ + public getUsedStmts(): Stmt[] { + return this.usedStmts; + } + + /** + * Get a string of local name in Local + * @returns The string of local name. + * @example + * 1. get a name string. + + ```typescript + for (const value of stmt.getUses()) { + const name = value.toString(); + ... + } + ``` + */ + public toString(): string { + return this.getName(); + } + + public getExportType(): ExportType { + return ExportType.LOCAL; + } + + public getModifiers(): number { + return 0; + } + + public containsModifier(modifierType: ModifierType): boolean { + if (modifierType === ModifierType.CONST) { + return this.getConstFlag(); + } + return false; + } + + public getSignature(): LocalSignature { + return ( + this.signature ?? + new LocalSignature( + this.name, + new MethodSignature(ClassSignature.DEFAULT, ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(UNKNOWN_METHOD_NAME)) + ) + ); + } + + public setSignature(signature: LocalSignature): void { + this.signature = signature; + } + + public getConstFlag(): boolean { + if (!this.constFlag) { + return false; + } + return this.constFlag; + } + + public setConstFlag(newConstFlag: boolean): void { + this.constFlag = newConstFlag; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Position.ts b/ets2panda/linter/arkanalyzer/src/core/base/Position.ts new file mode 100644 index 0000000000000000000000000000000000000000..2e1087b4cd50e2cc45a1de95c66e9f2948f2738d --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Position.ts @@ -0,0 +1,147 @@ +/* + * 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. + */ + +import ts from 'ohos-typescript'; + +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'Position'); + +const LOW_BITS_SIZE = 16; +const LOW_BITS_MASK = 0xffff; +const HIGH_BITS_MASK = 0xffff0000; +const MIN_NUMBER = 0; +const MAX_NUMBER = 0xffff; +const INVALID_LINE = -1; + +export type LineCol = number; + +export function setLine(lineCol: LineCol, lineNo: number): LineCol { + if (lineNo < MIN_NUMBER) { + lineNo = MIN_NUMBER; + } + if (lineNo > MAX_NUMBER) { + logger.warn(`setLine overflow ${lineNo}`); + lineNo = MAX_NUMBER; + } + + return (lineNo << LOW_BITS_SIZE) | (lineCol & LOW_BITS_MASK); +} + +export function setCol(lineCol: LineCol, colNo: number): LineCol { + if (colNo < MIN_NUMBER) { + colNo = MIN_NUMBER; + } + if (colNo > MAX_NUMBER) { + logger.warn(`setCol overflow ${colNo}`); + colNo = MAX_NUMBER; + } + + return (lineCol & HIGH_BITS_MASK) | colNo; +} + +export function setLineCol(lineNo: number, colNo: number): LineCol { + let lineCol: LineCol = 0; + lineCol = setLine(lineCol, lineNo); + lineCol = setCol(lineCol, colNo); + return lineCol; +} + +export function getLineNo(lineCol: LineCol): number { + let line = lineCol >>> LOW_BITS_SIZE; + if (line === MIN_NUMBER) { + return INVALID_LINE; + } + return line; +} + +export function getColNo(lineCol: LineCol): number { + let col = lineCol & LOW_BITS_MASK; + if (col === MIN_NUMBER) { + return INVALID_LINE; + } + return col; +} + +/** + * @category core/base + */ +export class LineColPosition { + private readonly lineCol: LineCol; + + public static readonly DEFAULT: LineColPosition = new LineColPosition(INVALID_LINE, INVALID_LINE); + + constructor(lineNo: number, colNo: number) { + this.lineCol = setLineCol(lineNo, colNo); + } + + public getLineNo(): number { + return getLineNo(this.lineCol); + } + + public getColNo(): number { + return getColNo(this.lineCol); + } + + public static buildFromNode(node: ts.Node, sourceFile: ts.SourceFile): LineColPosition { + let { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)); + // line start from 1. + return new LineColPosition(line + 1, character + 1); + } +} + +export class FullPosition { + private readonly first: LineCol; + private readonly last: LineCol; + + public static readonly DEFAULT: FullPosition = new FullPosition(INVALID_LINE, INVALID_LINE, INVALID_LINE, INVALID_LINE); + + constructor(firstLine: number, firstCol: number, lastLine: number, lastCol: number) { + this.first = setLineCol(firstLine, firstCol); + this.last = setLineCol(lastLine, lastCol); + } + + public getFirstLine(): number { + return getLineNo(this.first); + } + + public getLastLine(): number { + return getLineNo(this.last); + } + + public getFirstCol(): number { + return getColNo(this.first); + } + + public getLastCol(): number { + return getColNo(this.last); + } + + public static buildFromNode(node: ts.Node, sourceFile: ts.SourceFile): FullPosition { + const { line: startLine, character: startCharacter } = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)); + const { line: endLine, character: endCharacter } = ts.getLineAndCharacterOfPosition(sourceFile, node.getEnd()); + + // line start from 1 + return new FullPosition(startLine + 1, startCharacter + 1, endLine + 1, endCharacter + 1); + } + + public static merge(leftMostPosition: FullPosition, rightMostPosition: FullPosition): FullPosition { + return new FullPosition( + leftMostPosition.getFirstLine(), + leftMostPosition.getFirstCol(), + rightMostPosition.getLastLine(), + rightMostPosition.getLastCol() + ); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Ref.ts b/ets2panda/linter/arkanalyzer/src/core/base/Ref.ts new file mode 100644 index 0000000000000000000000000000000000000000..66e13f6d9066fb175a34c775831b846cc07591c8 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Ref.ts @@ -0,0 +1,412 @@ +/* + * 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. + */ + +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { FieldSignature } from '../model/ArkSignature'; +import { Local } from './Local'; +import { ArrayType, ClassType, LexicalEnvType, Type, UnknownType } from './Type'; +import { Value } from './Value'; +import { TypeInference } from '../common/TypeInference'; +import { ArkMethod } from '../model/ArkMethod'; +import { Stmt } from './Stmt'; +import { IRInference } from '../common/IRInference'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'Ref'); + +/** + * @category core/base/ref + */ +export abstract class AbstractRef implements Value { + abstract getUses(): Value[]; + + abstract getType(): Type; + + public inferType(arkMethod: ArkMethod): AbstractRef { + return this; + } +} + +export class ArkArrayRef extends AbstractRef { + private base: Local; // 数组变量 + private index: Value; // 索引 + + constructor(base: Local, index: Value) { + super(); + this.base = base; + this.index = index; + } + + /** + * Returns the base of this array reference. Array reference refers to access to array elements. + * Array references usually consist of an local variable and an index. + * For example, `a[i]` is a typical array reference, where `a` is the base (i.e., local variable) + * pointing to the actual memory location where the array is stored + * and `i` is the index indicating access to the `i-th` element from array `a`. + * @returns the base of this array reference. + * @example + * 1. Get the base and the specific elements. + + ```typescript + // Create an array + let myArray: number[] = [10, 20, 30, 40]; + // Create an ArrayRef object representing a reference to myArray[2] + let arrayRef = new ArkArrayRef(myArray, 2); + // Use the getBase() method to get the base of the array + let baseArray = arrayRef.getBase(); + + console.log("Base array:", baseArray); // Output: Base array: [10, 20, 30, 40] + + // Use baseArray and obeject index of ArrayRef to access to specific array elements + let element = baseArray[arrayRef.index]; + console.log("Element at index", arrayRef.index, ":", element); // Output: Element at index 2 : 30 + ``` + */ + public getBase(): Local { + return this.base; + } + + public setBase(newBase: Local): void { + this.base = newBase; + } + + /** + * Returns the index of this array reference. + * In TypeScript, an array reference means that the variable stores + * the memory address of the array rather than the actual data of the array. + * @returns The index of this array reference. + */ + public getIndex(): Value { + return this.index; + } + + public setIndex(newIndex: Value): void { + this.index = newIndex; + } + + public getType(): Type { + let baseType = TypeInference.replaceTypeWithReal(this.base.getType()); + if (baseType instanceof ArrayType) { + return baseType.getBaseType(); + } else { + logger.warn(`the type of base in ArrayRef is not ArrayType`); + return UnknownType.getInstance(); + } + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.base); + uses.push(...this.base.getUses()); + uses.push(this.index); + uses.push(...this.index.getUses()); + return uses; + } + + public toString(): string { + return this.base + '[' + this.index + ']'; + } +} + +export abstract class AbstractFieldRef extends AbstractRef { + private fieldSignature: FieldSignature; + + constructor(fieldSignature: FieldSignature) { + super(); + this.fieldSignature = fieldSignature; + } + + /** + * Returns the the field name as a **string**. + * @returns The the field name. + */ + public getFieldName(): string { + return this.fieldSignature.getFieldName(); + } + + /** + * Returns a field signature, which consists of a class signature, + * a **string** field name, and a **boolean** label indicating whether it is static or not. + * @returns The field signature. + * @example + * 1. Compare two Fields + + ```typescript + const fieldSignature = new FieldSignature(); + fieldSignature.setFieldName(...); + const fieldRef = new ArkInstanceFieldRef(baseValue as Local, fieldSignature); + ... + if (fieldRef.getFieldSignature().getFieldName() === + targetField.getFieldSignature().getFieldName()) { + ... + } + ``` + */ + public getFieldSignature(): FieldSignature { + return this.fieldSignature; + } + + public setFieldSignature(newFieldSignature: FieldSignature): void { + this.fieldSignature = newFieldSignature; + } + + public getType(): Type { + return this.fieldSignature.getType(); + } +} + +export class ArkInstanceFieldRef extends AbstractFieldRef { + private base: Local; // which obj this field belong to + + constructor(base: Local, fieldSignature: FieldSignature) { + super(fieldSignature); + this.base = base; + } + + /** + * Returns the local of field, showing which object this field belongs to. + * A {@link Local} consists of : + * - Name: the **string** name of local value, e.g., "$temp0". + * - Type: the type of value. + * @returns The object that the field belongs to. + * @example + * 1. Get a base. + + ```typescript + if (expr instanceof ArkInstanceFieldRef) { + ... + let base = expr.getBase(); + if (base.getName() == 'this') { + ... + } + ... + } + ``` + */ + public getBase(): Local { + return this.base; + } + + public setBase(newBase: Local): void { + this.base = newBase; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.base); + uses.push(...this.base.getUses()); + return uses; + } + + public toString(): string { + return this.base.toString() + '.<' + this.getFieldSignature() + '>'; + } + + public inferType(arkMethod: ArkMethod): AbstractRef { + return IRInference.inferFieldRef(this, arkMethod); + } +} + +export class ArkStaticFieldRef extends AbstractFieldRef { + constructor(fieldSignature: FieldSignature) { + super(fieldSignature); + } + + public getUses(): Value[] { + return []; + } + + public toString(): string { + return this.getFieldSignature().toString(); + } +} + +export class ArkParameterRef extends AbstractRef { + private index: number; + private paramType: Type; + + constructor(index: number, paramType: Type) { + super(); + this.index = index; + this.paramType = paramType; + } + + public getIndex(): number { + return this.index; + } + + public setIndex(index: number): void { + this.index = index; + } + + public getType(): Type { + return this.paramType; + } + + public setType(newType: Type): void { + this.paramType = newType; + } + + public inferType(arkMethod: ArkMethod): AbstractRef { + return IRInference.inferParameterRef(this, arkMethod); + } + + public getUses(): Value[] { + return []; + } + + public toString(): string { + return 'parameter' + this.index + ': ' + this.paramType; + } +} + +export class ArkThisRef extends AbstractRef { + private type: ClassType; + + constructor(type: ClassType) { + super(); + this.type = type; + } + + public getType(): ClassType { + return this.type; + } + + public getUses(): Value[] { + return []; + } + + public toString(): string { + return 'this: ' + this.type; + } +} + +export class ArkCaughtExceptionRef extends AbstractRef { + private type: Type; + + constructor(type: Type) { + super(); + this.type = type; + } + + public getType(): Type { + return this.type; + } + + public getUses(): Value[] { + return []; + } + + public toString(): string { + return 'caughtexception: ' + this.type; + } +} + +export class GlobalRef extends AbstractRef { + private name: string; + private ref: Value | null; + private usedStmts: Stmt[]; + + constructor(name: string, ref?: Value) { + super(); + this.name = name; + this.ref = ref ?? null; + this.usedStmts = []; + } + + public getName(): string { + return this.name; + } + + public getUses(): Value[] { + return this.ref?.getUses() || []; + } + + public getType(): Type { + return this.ref?.getType() || UnknownType.getInstance(); + } + + public getRef(): Value | null { + return this.ref || null; + } + + public setRef(value: Value): void { + this.ref = value; + } + + public getUsedStmts(): Stmt[] { + return this.usedStmts; + } + + public addUsedStmts(usedStmts: Stmt | Stmt[]): void { + if (usedStmts instanceof Stmt) { + this.usedStmts.push(usedStmts); + } else { + usedStmts.forEach(stmt => this.usedStmts.push(stmt)); + } + } + + public toString(): string { + return this.getName(); + } +} + +export class ClosureFieldRef extends AbstractRef { + private base: Local; + private fieldName: string; + private type: Type; + + constructor(base: Local, fieldName: string, type: Type) { + super(); + this.base = base; + this.fieldName = fieldName; + this.type = type; + } + + public getUses(): Value[] { + return []; + } + + public getBase(): Local { + return this.base; + } + + public getType(): Type { + return this.type; + } + + public getFieldName(): string { + return this.fieldName; + } + + public toString(): string { + return this.base.toString() + '.' + this.getFieldName(); + } + + public inferType(arkMethod: ArkMethod): AbstractRef { + if (TypeInference.isUnclearType(this.type)) { + let type: Type | undefined = this.base.getType(); + if (type instanceof LexicalEnvType) { + type = type + .getClosures() + .find(c => c.getName() === this.fieldName) + ?.getType(); + } + if (type && !TypeInference.isUnclearType(type)) { + this.type = type; + } + } + return this; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Stmt.ts b/ets2panda/linter/arkanalyzer/src/core/base/Stmt.ts new file mode 100644 index 0000000000000000000000000000000000000000..6d792a826efa2f61369902bcb3473b8594914f86 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Stmt.ts @@ -0,0 +1,603 @@ +/* + * 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. + */ + +import { StmtUseReplacer } from '../common/StmtUseReplacer'; +import { Cfg } from '../graph/Cfg'; +import { AbstractExpr, AbstractInvokeExpr, AliasTypeExpr, ArkConditionExpr } from './Expr'; +import { AbstractFieldRef, ArkArrayRef } from './Ref'; +import { Value } from './Value'; +import { FullPosition, LineColPosition } from './Position'; +import { ArkMetadata, ArkMetadataKind, ArkMetadataType } from '../model/ArkMetadata'; +import { StmtDefReplacer } from '../common/StmtDefReplacer'; +import { IRUtils } from '../common/IRUtils'; +import { AliasType, ArrayType, IntersectionType, TupleType, Type, UnionType } from './Type'; +import { ModifierType } from '../model/ArkBaseModel'; +import { AbstractTypeExpr } from './TypeExpr'; + +/** + * @category core/base/stmt + */ +export abstract class Stmt { + protected text?: string; // just for debug + protected originalText?: string; + protected originalPosition: LineColPosition = LineColPosition.DEFAULT; + protected cfg!: Cfg; + protected operandOriginalPositions?: FullPosition[]; // operandOriginalPositions correspond with + // def and uses one by one + metadata?: ArkMetadata; + + public getMetadata(kind: ArkMetadataKind): ArkMetadataType | undefined { + return this.metadata?.getMetadata(kind); + } + + public setMetadata(kind: ArkMetadataKind, value: ArkMetadataType): void { + if (!this.metadata) { + this.metadata = new ArkMetadata(); + } + return this.metadata?.setMetadata(kind, value); + } + + /** Return a list of values which are uesd in this statement */ + public getUses(): Value[] { + return []; + } + + public replaceUse(oldUse: Value, newUse: Value): void { + const stmtUseReplacer = new StmtUseReplacer(oldUse, newUse); + stmtUseReplacer.caseStmt(this); + } + + /** + * Return the definition which is uesd in this statement. Generally, the definition is the left value of `=` in + * 3AC. For example, the definition in 3AC of `value = parameter0: @project-1/sample-1.ets: AnonymousClass-0` is + * `value`, and the definition in `$temp0 = staticinvoke <@_ProjectName/_FileName: xxx.create()>()` is `\$temp0`. + * @returns The definition in 3AC (may be a **null**). + * @example + * 1. get the def in stmt. + ```typescript + for (const block of this.blocks) { + for (const stmt of block.getStmts()) { + const defValue = stmt.getDef(); + ... + } + } + ``` + */ + public getDef(): Value | null { + return null; + } + + public replaceDef(oldDef: Value, newDef: Value): void { + const stmtDefReplacer = new StmtDefReplacer(oldDef, newDef); + stmtDefReplacer.caseStmt(this); + } + + public getDefAndUses(): Value[] { + const defAndUses: Value[] = []; + const def = this.getDef(); + if (def) { + defAndUses.push(def); + } + defAndUses.push(...this.getUses()); + return defAndUses; + } + + /** + * Get the CFG (i.e., control flow graph) of an {@link ArkBody} in which the statement is. + * A CFG contains a set of basic blocks and statements corresponding to each basic block. + * Note that, "source code" and "three-address" are two types of {@link Stmt} in ArkAnalyzer. + * Source code {@link Stmt} represents the statement of ets/ts source code, while three-address code {@link Stmt} + * represents the statement after it has been converted into three-address code. Since the source code {@link + * Stmt} does not save its CFG reference, it returns **null**, while the `getCfg()` of the third address code + * {@link Stmt} will return its CFG reference. + * @returns The CFG (i.e., control flow graph) of an {@link ArkBody} in which the statement is. + * @example + * 1. get the ArkFile based on stmt. + ```typescript + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + ``` + 2. get the ArkMethod based on stmt. + ```typescript + let sourceMethod: ArkMethod = stmt.getCfg()?.getDeclaringMethod(); + ``` + */ + public getCfg(): Cfg { + return this.cfg; + } + + public setCfg(cfg: Cfg): void { + this.cfg = cfg; + } + + /** + * Return true if the following statement may not execute after this statement. + * The ArkIfStmt and ArkGotoStmt will return true. + */ + public isBranch(): boolean { + return false; + } + + /** Return the number of statements which this statement may go to */ + public getExpectedSuccessorCount(): number { + return 1; + } + + public containsInvokeExpr(): boolean { + for (const use of this.getUses()) { + if (use instanceof AbstractInvokeExpr) { + return true; + } + } + return false; + } + + /** + * Returns the method's invocation expression (including method signature and its arguments) + * in the current statement. An **undefined** will be returned if there is no method used in this statement. + * @returns the method's invocation expression from the statement. An **undefined** will be returned if there is + * no method can be found in this statement. + * @example + * 1. get invoke expr based on stmt. + ```typescript + let invoke = stmt.getInvokeExpr(); + ``` + */ + public getInvokeExpr(): AbstractInvokeExpr | undefined { + for (const use of this.getUses()) { + if (use instanceof AbstractInvokeExpr) { + return use as AbstractInvokeExpr; + } + } + return undefined; + } + + /** + * Returns an array of expressions in the statement. + * @returns An array of expressions in the statement. + * @example + * 1. Traverse expression of statement. + + ```typescript + for (const expr of stmt.getExprs()) { + ... + } + ``` + */ + public getExprs(): AbstractExpr[] { + let exprs: AbstractExpr[] = []; + for (const use of this.getUses()) { + if (use instanceof AbstractExpr) { + exprs.push(use); + } + } + return exprs; + } + + public getTypeExprs(): AbstractTypeExpr[] { + let typeExprs: AbstractTypeExpr[] = []; + for (const value of this.getDefAndUses()) { + const valueType = value.getType(); + if (valueType instanceof AbstractTypeExpr) { + typeExprs.push(valueType); + } + } + return typeExprs; + } + + public containsArrayRef(): boolean { + for (const use of this.getUses()) { + if (use instanceof ArkArrayRef) { + return true; + } + } + if (this.getDef() instanceof ArkArrayRef) { + return true; + } + return false; + } + + public getArrayRef(): ArkArrayRef | undefined { + for (const use of this.getUses()) { + if (use instanceof ArkArrayRef) { + return use as ArkArrayRef; + } + } + + if (this.getDef() instanceof ArkArrayRef) { + return undefined; + } + + return undefined; + } + + public containsFieldRef(): boolean { + for (const use of this.getUses()) { + if (use instanceof AbstractFieldRef) { + return true; + } + } + + if (this.getDef() instanceof AbstractFieldRef) { + return true; + } + return false; + } + + public getFieldRef(): AbstractFieldRef | undefined { + for (const use of this.getUses()) { + if (use instanceof AbstractFieldRef) { + return use as AbstractFieldRef; + } + } + if (this.getDef() instanceof AbstractFieldRef) { + return undefined; + } + return undefined; + } + + public setOriginPositionInfo(originPositionInfo: LineColPosition): void { + this.originalPosition = originPositionInfo; + } + + /** + * Returns the original position of the statement. + * The position consists of two parts: line number and column number. + * In the source file, the former (i.e., line number) indicates which line the statement is in, + * and the latter (i.e., column number) indicates the position of the statement in the line. + * The position is described as `LineColPosition(lineNo,colNum)` in ArkAnalyzer, + * and its default value is LineColPosition(-1,-1). + * @returns The original location of the statement. + * @example + * 1. Get the stmt position info to make some condition judgements. + ```typescript + for (const stmt of stmts) { + if (stmt.getOriginPositionInfo().getLineNo() === -1) { + stmt.setOriginPositionInfo(originalStmt.getOriginPositionInfo()); + this.stmtToOriginalStmt.set(stmt, originalStmt); + } + } + ``` + */ + public getOriginPositionInfo(): LineColPosition { + return this.originalPosition; + } + + abstract toString(): string; + + public setText(text: string): void { + this.text = text; + } + + public setOriginalText(originalText: string): void { + this.originalText = originalText; + } + + public getOriginalText(): string | undefined { + return this.originalText; + } + + public setOperandOriginalPositions(operandOriginalPositions: FullPosition[]): void { + this.operandOriginalPositions = operandOriginalPositions; + } + + public getOperandOriginalPositions(): FullPosition[] | undefined { + return this.operandOriginalPositions; + } + + public getOperandOriginalPosition(indexOrOperand: number | Value): FullPosition | null { + let index: number = -1; + if (typeof indexOrOperand !== 'number') { + index = IRUtils.findOperandIdx(this, indexOrOperand); + } else { + index = indexOrOperand; + } + + if (!this.operandOriginalPositions || index < 0 || index > this.operandOriginalPositions.length) { + return null; + } + return this.operandOriginalPositions[index]; + } +} + +export class ArkAssignStmt extends Stmt { + private leftOp: Value; + private rightOp: Value; + + constructor(leftOp: Value, rightOp: Value) { + super(); + this.leftOp = leftOp; + this.rightOp = rightOp; + } + + /** + * Returns the left operand of the assigning statement. + * @returns The left operand of the assigning statement. + * @example + * 1. If the statement is `a=b;`, the right operand is `a`; if the statement is `dd = cc + 5;`, the right operand + * is `cc`. + */ + public getLeftOp(): Value { + return this.leftOp; + } + + public setLeftOp(newLeftOp: Value): void { + this.leftOp = newLeftOp; + } + + /** + * Returns the right operand of the assigning statement. + * @returns The right operand of the assigning statement. + * @example + * 1. If the statement is `a=b;`, the right operand is `b`; if the statement is `dd = cc + 5;`, the right operand + * is `cc + 5`. + * 2. Get the rightOp from stmt. + ```typescript + const rightOp = stmt.getRightOp(); + ``` + */ + public getRightOp(): Value { + return this.rightOp; + } + + public setRightOp(rightOp: Value): void { + this.rightOp = rightOp; + } + + public toString(): string { + const str = this.getLeftOp() + ' = ' + this.getRightOp(); + return str; + } + + public getDef(): Value | null { + return this.leftOp; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(...this.leftOp.getUses()); + uses.push(this.rightOp); + uses.push(...this.rightOp.getUses()); + return uses; + } +} + +export class ArkInvokeStmt extends Stmt { + private invokeExpr: AbstractInvokeExpr; + + constructor(invokeExpr: AbstractInvokeExpr) { + super(); + this.invokeExpr = invokeExpr; + } + + public replaceInvokeExpr(newExpr: AbstractInvokeExpr): void { + this.invokeExpr = newExpr; + } + + public getInvokeExpr(): AbstractInvokeExpr { + return this.invokeExpr; + } + + public toString(): string { + const str = this.invokeExpr.toString(); + return str; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.invokeExpr); + uses.push(...this.invokeExpr.getUses()); + return uses; + } +} + +export class ArkIfStmt extends Stmt { + private conditionExpr: ArkConditionExpr; + + constructor(conditionExpr: ArkConditionExpr) { + super(); + this.conditionExpr = conditionExpr; + } + + /** + * The condition expression consisit of two values as operands and one binary operator as operator. + * The operator can indicate the relation between the two values, e.g., `<`, `<=`,`>`, `>=`, `==`, `!=`, `===`, + * `!==`. + * @returns a condition expression. + * @example + * 1. When a statement is `if (a > b)`, the operands are `a` and `b`, the operator is `<`. Therefore, the condition + * expression is `a > b`. + * 2. get a conditon expr from a condition statement. + ```typescript + let expr = (this.original as ArkIfStmt).getConditionExpr(); + ``` + */ + public getConditionExpr(): ArkConditionExpr { + return this.conditionExpr; + } + + public setConditionExpr(newConditionExpr: ArkConditionExpr): void { + this.conditionExpr = newConditionExpr; + } + + public isBranch(): boolean { + return true; + } + + public getExpectedSuccessorCount(): number { + return 2; + } + + public toString(): string { + const str = 'if ' + this.conditionExpr; + return str; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.conditionExpr); + uses.push(...this.conditionExpr.getUses()); + return uses; + } +} + +export class ArkReturnStmt extends Stmt { + private op: Value; + + constructor(op: Value) { + super(); + this.op = op; + } + + public getExpectedSuccessorCount(): number { + return 0; + } + + public getOp(): Value { + return this.op; + } + + public setReturnValue(returnValue: Value): void { + this.op = returnValue; + } + + public toString(): string { + const str = 'return ' + this.op; + return str; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.op); + uses.push(...this.op.getUses()); + return uses; + } +} + +export class ArkReturnVoidStmt extends Stmt { + constructor() { + super(); + } + + public getExpectedSuccessorCount(): number { + return 0; + } + + public toString(): string { + const str = 'return'; + return str; + } +} + +export class ArkThrowStmt extends Stmt { + private op: Value; + + constructor(op: Value) { + super(); + this.op = op; + } + + public getOp(): Value { + return this.op; + } + + public setOp(newOp: Value): void { + this.op = newOp; + } + + public toString(): string { + const str = 'throw ' + this.op; + return str; + } + + public getUses(): Value[] { + let uses: Value[] = []; + uses.push(this.op); + uses.push(...this.op.getUses()); + return uses; + } +} + +/** + * Statement of type alias definition combines with the left hand as {@link AliasType} and right hand as {@link AliasTypeExpr}. + * @category core/base/stmt + * @extends Stmt + * @example + ```typescript + type A = string; + type B = import('./abc').TypeB; + + let c = 123; + declare type C = typeof c; + ``` + */ +export class ArkAliasTypeDefineStmt extends Stmt { + private aliasType: AliasType; + private aliasTypeExpr: AliasTypeExpr; + + constructor(aliasType: AliasType, typeAliasExpr: AliasTypeExpr) { + super(); + this.aliasType = aliasType; + this.aliasTypeExpr = typeAliasExpr; + } + + public getAliasType(): AliasType { + return this.aliasType; + } + + public getAliasTypeExpr(): AliasTypeExpr { + return this.aliasTypeExpr; + } + + public getAliasName(): string { + return this.getAliasType().getName(); + } + + public toString(): string { + let str = `type ${this.getAliasType().toString()} = ${this.getAliasTypeExpr().toString()}`; + if (this.getAliasType().containsModifier(ModifierType.DECLARE)) { + str = 'declare ' + str; + } + if (this.getAliasType().containsModifier(ModifierType.EXPORT)) { + str = 'export ' + str; + } + return str; + } + + public getExprs(): AliasTypeExpr[] { + return [this.getAliasTypeExpr()]; + } + + public getTypeExprs(): AbstractTypeExpr[] { + function getTypeExprsInType(originalObject: Type): AbstractTypeExpr[] { + let typeExprs: AbstractTypeExpr[] = []; + if (originalObject instanceof AbstractTypeExpr) { + typeExprs.push(originalObject); + } else if (originalObject instanceof ArrayType) { + typeExprs.push(...getTypeExprsInType(originalObject.getBaseType())); + } else if (originalObject instanceof UnionType || originalObject instanceof IntersectionType || originalObject instanceof TupleType) { + for (const member of originalObject.getTypes()) { + typeExprs.push(...getTypeExprsInType(member)); + } + } + return typeExprs; + } + + const originalObject = this.getAliasTypeExpr().getOriginalObject(); + if (originalObject instanceof Type) { + return getTypeExprsInType(originalObject); + } + return []; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Trap.ts b/ets2panda/linter/arkanalyzer/src/core/base/Trap.ts new file mode 100644 index 0000000000000000000000000000000000000000..62237fe0e906615939e38d3fcfa1c67ef3d3bc59 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Trap.ts @@ -0,0 +1,34 @@ +/* + * 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. + */ + +import { BasicBlock } from '../graph/BasicBlock'; + +export class Trap { + private readonly tryBlocks: BasicBlock[]; + private readonly catchBlocks: BasicBlock[]; + + constructor(tryBlocks: BasicBlock[], catchBlocks: BasicBlock[]) { + this.tryBlocks = tryBlocks; + this.catchBlocks = catchBlocks; + } + + public getTryBlocks(): BasicBlock[] { + return this.tryBlocks; + } + + public getCatchBlocks(): BasicBlock[] { + return this.catchBlocks; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Type.ts b/ets2panda/linter/arkanalyzer/src/core/base/Type.ts new file mode 100644 index 0000000000000000000000000000000000000000..16987467749ac00a493ec3f00132d789c8f123b2 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Type.ts @@ -0,0 +1,818 @@ +/* + * 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. + */ + +import { AliasTypeSignature, ClassSignature, FieldSignature, MethodSignature, NamespaceSignature } from '../model/ArkSignature'; +import { ArkExport, ExportType } from '../model/ArkExport'; +import { MODIFIER_TYPE_MASK, ModifierType } from '../model/ArkBaseModel'; +import { + ANY_KEYWORD, + BIGINT_KEYWORD, + BOOLEAN_KEYWORD, + NEVER_KEYWORD, + NULL_KEYWORD, + NUMBER_KEYWORD, + STRING_KEYWORD, + UNDEFINED_KEYWORD, + UNKNOWN_KEYWORD, + VOID_KEYWORD, +} from '../common/TSConst'; +import { Local } from './Local'; +import { Constant } from './Constant'; + +/** + * @category core/base/type + */ +export abstract class Type { + toString(): string { + return this.getTypeString(); + } + + abstract getTypeString(): string; +} + +/** + * any type + * @category core/base/type + */ +export class AnyType extends Type { + private static readonly INSTANCE = new AnyType(); + + public static getInstance(): AnyType { + return this.INSTANCE; + } + + private constructor() { + super(); + } + + public getTypeString(): string { + return ANY_KEYWORD; + } +} + +/** + * unknown type + * @category core/base/type + */ +export class UnknownType extends Type { + private static readonly INSTANCE = new UnknownType(); + + public static getInstance(): UnknownType { + return this.INSTANCE; + } + + private constructor() { + super(); + } + + public getTypeString(): string { + return UNKNOWN_KEYWORD; + } +} + +/** + * unclear type + * @category core/base/type + */ +export class UnclearReferenceType extends Type { + private name: string; + private genericTypes: Type[]; + + constructor(name: string, genericTypes: Type[] = []) { + super(); + this.name = name; + this.genericTypes = genericTypes; + } + + public getName(): string { + return this.name; + } + + public getGenericTypes(): Type[] { + return this.genericTypes; + } + + public getTypeString(): string { + let str = this.name; + if (this.genericTypes.length > 0) { + str += '<' + this.genericTypes.join(',') + '>'; + } + return str; + } +} + +/** + * primitive type + * @category core/base/type + */ +export abstract class PrimitiveType extends Type { + private name: string; + + constructor(name: string) { + super(); + this.name = name; + } + + public getName(): string { + return this.name; + } + + public getTypeString(): string { + return this.name; + } +} + +export class BooleanType extends PrimitiveType { + private static readonly INSTANCE = new BooleanType(); + + private constructor() { + super(BOOLEAN_KEYWORD); + } + + public static getInstance(): BooleanType { + return this.INSTANCE; + } +} + +export class NumberType extends PrimitiveType { + private static readonly INSTANCE = new NumberType(); + + private constructor() { + super(NUMBER_KEYWORD); + } + + public static getInstance(): NumberType { + return this.INSTANCE; + } +} + +/** + * bigint type + * @category core/base/type + */ +export class BigIntType extends PrimitiveType { + private static readonly INSTANCE = new BigIntType(); + + private constructor() { + super(BIGINT_KEYWORD); + } + + public static getInstance(): BigIntType { + return this.INSTANCE; + } +} + +export class StringType extends PrimitiveType { + private static readonly INSTANCE = new StringType(); + + private constructor() { + super(STRING_KEYWORD); + } + + public static getInstance(): StringType { + return this.INSTANCE; + } +} + +/** + * null type + * @category core/base/type + */ +export class NullType extends PrimitiveType { + private static readonly INSTANCE = new NullType(); + + public static getInstance(): NullType { + return this.INSTANCE; + } + + private constructor() { + super(NULL_KEYWORD); + } +} + +/** + * undefined type + * @category core/base/type + */ +export class UndefinedType extends PrimitiveType { + private static readonly INSTANCE = new UndefinedType(); + + public static getInstance(): UndefinedType { + return this.INSTANCE; + } + + private constructor() { + super(UNDEFINED_KEYWORD); + } +} + +/** + * literal type + * @category core/base/type + */ +export class LiteralType extends PrimitiveType { + public static readonly TRUE = new LiteralType(true); + public static readonly FALSE = new LiteralType(false); + + private literalName: string | number | boolean; + + constructor(literalName: string | number | boolean) { + super('literal'); + this.literalName = literalName; + } + + public getLiteralName(): string | number | boolean { + return this.literalName; + } + + public getTypeString(): string { + return this.literalName.toString(); + } +} + +/** + * union type + * @category core/base/type + */ +export class UnionType extends Type { + private types: Type[]; + private currType: Type; // The true type of the value at this time + constructor(types: Type[], currType: Type = UnknownType.getInstance()) { + super(); + this.types = [...types]; + this.currType = currType; + } + + public getTypes(): Type[] { + return this.types; + } + + public getCurrType(): Type { + return this.currType; + } + + public setCurrType(newType: Type): void { + this.currType = newType; + } + + public getTypeString(): string { + let typesString: string[] = []; + this.getTypes().forEach(t => { + if (t instanceof UnionType || t instanceof IntersectionType) { + typesString.push(`(${t.toString()})`); + } else { + typesString.push(t.toString()); + } + }); + return typesString.join('|'); + } + + // TODO: Need to remove this function because of IntersectionType has been added. + public flatType(): Type[] { + const result: Type[] = []; + this.types.forEach(t => { + if (t instanceof UnionType) { + t.flatType().forEach(e => result.push(e)); + } else { + result.push(t); + } + }); + return result; + } +} + +/** + * intersection type + * @category core/base/type + */ +export class IntersectionType extends Type { + private types: Type[]; + + constructor(types: Type[]) { + super(); + this.types = [...types]; + } + + public getTypes(): Type[] { + return this.types; + } + + public getTypeString(): string { + let typesString: string[] = []; + this.getTypes().forEach(t => { + if (t instanceof UnionType || t instanceof IntersectionType) { + typesString.push(`(${t.toString()})`); + } else { + typesString.push(t.toString()); + } + }); + return typesString.join('&'); + } +} + +/** + * types for function void return type + * @category core/base/type + */ +export class VoidType extends Type { + private static readonly INSTANCE = new VoidType(); + + public static getInstance(): VoidType { + return this.INSTANCE; + } + + private constructor() { + super(); + } + + public getTypeString(): string { + return VOID_KEYWORD; + } +} + +export class NeverType extends Type { + private static readonly INSTANCE = new NeverType(); + + public static getInstance(): NeverType { + return this.INSTANCE; + } + + private constructor() { + super(); + } + + public getTypeString(): string { + return NEVER_KEYWORD; + } +} + +/** + * function type + * @category core/base/type + */ +export class FunctionType extends Type { + private methodSignature: MethodSignature; + private realGenericTypes?: Type[]; + + constructor(methodSignature: MethodSignature, realGenericTypes?: Type[]) { + super(); + this.methodSignature = methodSignature; + this.realGenericTypes = realGenericTypes; + } + + public getMethodSignature(): MethodSignature { + return this.methodSignature; + } + + public getRealGenericTypes(): Type[] | undefined { + return this.realGenericTypes; + } + + public getTypeString(): string { + return this.methodSignature.toString(); + } +} + +/** + * types for closures which is a special FunctionType with a lexical env + * @category core/base/type + */ +export class ClosureType extends FunctionType { + private lexicalEnv: LexicalEnvType; + + constructor(lexicalEnv: LexicalEnvType, methodSignature: MethodSignature, realGenericTypes?: Type[]) { + super(methodSignature, realGenericTypes); + this.lexicalEnv = lexicalEnv; + } + + public getLexicalEnv(): LexicalEnvType { + return this.lexicalEnv; + } + + public getTypeString(): string { + return 'closures: ' + super.getTypeString(); + } +} + +/** + * type of an object + * @category core/base/type + */ +export class ClassType extends Type { + private classSignature: ClassSignature; + private realGenericTypes?: Type[]; + + constructor(classSignature: ClassSignature, realGenericTypes?: Type[]) { + super(); + this.classSignature = classSignature; + this.realGenericTypes = realGenericTypes; + } + + public getClassSignature(): ClassSignature { + return this.classSignature; + } + + public setClassSignature(newClassSignature: ClassSignature): void { + this.classSignature = newClassSignature; + } + + public getRealGenericTypes(): Type[] | undefined { + return this.realGenericTypes; + } + + public setRealGenericTypes(types: Type[] | undefined): void { + this.realGenericTypes = types; + } + + public getTypeString(): string { + let temp = this.classSignature.toString(); + let generic = this.realGenericTypes?.join(','); + if (generic) { + temp += `<${generic}>`; + } + return temp; + } +} + +/** + * Array type + * @category core/base/type + * @extends Type + * @example + ```typescript + // baseType is number, dimension is 1, readonlyFlag is true + let a: readonly number[] = [1, 2, 3]; + + // baseType is number, dimension is 1, readonlyFlag is undefined + let a: number[] = [1, 2, 3]; + ``` + */ +export class ArrayType extends Type { + private baseType: Type; + private dimension: number; + private readonlyFlag?: boolean; + + constructor(baseType: Type, dimension: number) { + super(); + this.baseType = baseType; + this.dimension = dimension; + } + + /** + * Returns the base type of this array, such as `Any`, `Unknown`, `TypeParameter`, etc. + * @returns The base type of array. + */ + public getBaseType(): Type { + return this.baseType; + } + + public setBaseType(newType: Type): void { + this.baseType = newType; + } + + public getDimension(): number { + return this.dimension; + } + + public setReadonlyFlag(readonlyFlag: boolean): void { + this.readonlyFlag = readonlyFlag; + } + + public getReadonlyFlag(): boolean | undefined { + return this.readonlyFlag; + } + + public getTypeString(): string { + const strs: string[] = []; + if (this.getReadonlyFlag()) { + strs.push('readonly '); + } + if (this.baseType instanceof UnionType || this.baseType instanceof IntersectionType) { + strs.push('(' + this.baseType.toString() + ')'); + } else if (this.baseType) { + strs.push(this.baseType.toString()); + } + for (let i = 0; i < this.dimension; i++) { + strs.push('[]'); + } + return strs.join(''); + } +} + +/** + * Tuple type + * @category core/base/type + * @extends Type + * @example + ```typescript + // types are number and string, dimension is 1, readonlyFlag is true + let a: readonly number[] = [1, 2, 3]; + + // baseType is number, dimension is 1, readonlyFlag is undefined + let a: number[] = [1, 2, 3]; + ``` + */ +export class TupleType extends Type { + private types: Type[]; + private readonlyFlag?: boolean; + + constructor(types: Type[]) { + super(); + this.types = types; + } + + public getTypes(): Type[] { + return this.types; + } + + public setReadonlyFlag(readonlyFlag: boolean): void { + this.readonlyFlag = readonlyFlag; + } + + public getReadonlyFlag(): boolean | undefined { + return this.readonlyFlag; + } + + public getTypeString(): string { + if (this.getReadonlyFlag()) { + return 'readonly [' + this.types.join(', ') + ']'; + } + return '[' + this.types.join(', ') + ']'; + } +} + +/** + * alias type + * @category core/base/type + * @extends Type + * @example + ```typescript + // alias type A is defined without any genericTypes (undefined) or realGenericTypes (undefined) + type A = number; + + // alias type B is defined with genericTypes but not instance with realGenericTypes (undefined) + type B = T[]; + + // alias type could also be defined with another instance generic type such as aliaType, FunctionType and ClassType + // genericTypes and realGenericTypes of C are both undefined + // originalType of C is an instance of B with genericTypes [T] and realGenericTypes [numberType] + type C = B; + ``` + */ +export class AliasType extends Type implements ArkExport { + private originalType: Type; + private name: string; + private signature: AliasTypeSignature; + protected modifiers?: number; + private genericTypes?: GenericType[]; + private realGenericTypes?: Type[]; + + constructor(name: string, originalType: Type, signature: AliasTypeSignature, genericTypes?: GenericType[]) { + super(); + this.name = name; + this.originalType = originalType; + this.signature = signature; + this.genericTypes = genericTypes; + } + + public getName(): string { + return this.name; + } + + public setOriginalType(type: Type): void { + this.originalType = type; + } + + public getOriginalType(): Type { + return this.originalType; + } + + public getTypeString(): string { + let res = this.getSignature().toString(); + let generic = this.getRealGenericTypes()?.join(',') ?? this.getGenericTypes()?.join(','); + if (generic) { + res += `<${generic}>`; + } + return res; + } + + public getExportType(): ExportType { + return ExportType.TYPE; + } + + public getModifiers(): number { + if (!this.modifiers) { + return 0; + } + return this.modifiers; + } + + public containsModifier(modifierType: ModifierType): boolean { + if (!this.modifiers) { + return false; + } + + return (this.modifiers & modifierType) === modifierType; + } + + public setModifiers(modifiers: number): void { + if (modifiers !== 0) { + this.modifiers = modifiers; + } + } + + public addModifier(modifier: ModifierType | number): void { + this.modifiers = this.getModifiers() | modifier; + } + + public removeModifier(modifier: ModifierType): void { + if (!this.modifiers) { + return; + } + this.modifiers &= MODIFIER_TYPE_MASK ^ modifier; + } + + public getSignature(): AliasTypeSignature { + return this.signature; + } + + public setGenericTypes(genericTypes: GenericType[]): void { + this.genericTypes = genericTypes; + } + + public getGenericTypes(): GenericType[] | undefined { + return this.genericTypes; + } + + public setRealGenericTypes(realGenericTypes: Type[]): void { + this.realGenericTypes = realGenericTypes; + } + + public getRealGenericTypes(): Type[] | undefined { + return this.realGenericTypes; + } +} + +export class GenericType extends Type { + private name: string; + private defaultType?: Type; + private constraint?: Type; + private index: number = 0; + + constructor(name: string, defaultType?: Type, constraint?: Type) { + super(); + this.name = name; + this.defaultType = defaultType; + this.constraint = constraint; + } + + public getName(): string { + return this.name; + } + + public getDefaultType(): Type | undefined { + return this.defaultType; + } + + public setDefaultType(type: Type): void { + this.defaultType = type; + } + + public getConstraint(): Type | undefined { + return this.constraint; + } + + public setConstraint(type: Type): void { + this.constraint = type; + } + + public setIndex(index: number): void { + this.index = index; + } + + public getIndex(): number { + return this.index ?? 0; + } + + public getTypeString(): string { + let str = this.name; + if (this.constraint) { + str += ' extends ' + this.constraint.toString(); + } + if (this.defaultType) { + str += ' = ' + this.defaultType.toString(); + } + return str; + } +} + +export abstract class AnnotationType extends Type { + private originType: string; + + protected constructor(originType: string) { + super(); + this.originType = originType; + } + + public getOriginType(): string { + return this.originType; + } + + public getTypeString(): string { + return this.originType; + } +} + +export class AnnotationNamespaceType extends AnnotationType { + private namespaceSignature: NamespaceSignature = NamespaceSignature.DEFAULT; + + public static getInstance(signature: NamespaceSignature): AnnotationNamespaceType { + const type = new AnnotationNamespaceType(signature.getNamespaceName()); + type.setNamespaceSignature(signature); + return type; + } + + public getNamespaceSignature(): NamespaceSignature { + return this.namespaceSignature; + } + + public setNamespaceSignature(signature: NamespaceSignature): void { + this.namespaceSignature = signature; + } + + constructor(originType: string) { + super(originType); + } + + public getOriginType(): string { + return super.getOriginType(); + } +} + +export class AnnotationTypeQueryType extends AnnotationType { + constructor(originType: string) { + super(originType); + } +} + +export class LexicalEnvType extends Type { + private nestedMethodSignature: MethodSignature; + private closures: Local[] = []; + + constructor(nestedMethod: MethodSignature, closures?: Local[]) { + super(); + this.nestedMethodSignature = nestedMethod; + this.closures = closures ?? this.closures; + } + + public getNestedMethod(): MethodSignature { + return this.nestedMethodSignature; + } + + public getClosures(): Local[] { + return this.closures; + } + + public addClosure(closure: Local): void { + this.closures.push(closure); + } + + public getTypeString(): string { + return `[${this.getClosures().join(', ')}]`; + } +} + +export class EnumValueType extends Type { + private signature: FieldSignature; + private constant?: Constant; + + constructor(signature: FieldSignature, constant?: Constant) { + super(); + this.signature = signature; + this.constant = constant; + } + + public getFieldSignature(): FieldSignature { + return this.signature; + } + + public getConstant(): Constant | undefined { + return this.constant; + } + + public getTypeString(): string { + return this.signature.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/TypeExpr.ts b/ets2panda/linter/arkanalyzer/src/core/base/TypeExpr.ts new file mode 100644 index 0000000000000000000000000000000000000000..8995083feb1acc7689742832e041f1cd7a9408f7 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/TypeExpr.ts @@ -0,0 +1,178 @@ +/* + * 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 { Value } from './Value'; +import { ArkMethod } from '../model/ArkMethod'; +import { IntersectionType, Type, UnionType, UnknownType } from './Type'; +import { IRInference } from '../common/IRInference'; +import { ArkBaseModel } from '../model/ArkBaseModel'; +import { ModelUtils } from '../common/ModelUtils'; +import { ArkClass } from '../model/ArkClass'; + +/** + * abstract type expr represents the type operations of types or values. + * AbstractTypeExpr is different from AbstractExpr. + * @category core/base/typeExpr + * @extends Type + * @example + * ```typescript + * let a = number; + * type A = typeof a; + * let b: keyof typeof a; + * ``` + */ +export abstract class AbstractTypeExpr extends Type { + abstract getUses(): Value[]; + + abstract getType(): Type; + + public inferType(arkMethod: ArkMethod): void { + return; + } +} + +/** + * typeQuery type expr represents the get type of value with typeof. + * @category core/base/typeExpr + * @extends AbstractTypeExpr + * @example + ```typescript + // opValue is a and type A is number + let a = number; + type A = typeof a; + ``` + */ + +export class TypeQueryExpr extends AbstractTypeExpr { + private opValue: Value | ArkBaseModel; + private genericTypes?: Type[]; + + constructor(opValue: Value | ArkBaseModel, generateTypes?: Type[]) { + super(); + this.opValue = opValue; + this.genericTypes = generateTypes; + } + + public setOpValue(opValue: Value | ArkBaseModel): void { + this.opValue = opValue; + } + + public getOpValue(): Value | ArkBaseModel { + return this.opValue; + } + + public setGenerateTypes(types: Type[]): void { + this.genericTypes = types; + } + + public getGenerateTypes(): Type[] | undefined { + return this.genericTypes; + } + + public addGenericType(gType: Type): void { + if (!this.genericTypes) { + this.genericTypes = []; + } + this.genericTypes.push(gType); + } + + public getUses(): Value[] { + const opValue = this.getOpValue(); + if (opValue instanceof ArkBaseModel) { + return []; + } + let uses: Value[] = []; + uses.push(opValue); + uses.push(...opValue.getUses()); + return uses; + } + + public getType(): Type { + const opValue = this.getOpValue(); + if (opValue instanceof ArkBaseModel) { + return ModelUtils.parseArkBaseModel2Type(opValue) ?? UnknownType.getInstance(); + } + return opValue.getType(); + } + + public getTypeString(): string { + const opValue = this.getOpValue(); + const gTypes = this.getGenerateTypes(); + const genericStr = gTypes && gTypes.length > 0 ? `<${gTypes.join(',')}>` : ''; + if (opValue instanceof ArkClass || opValue instanceof ArkMethod) { + return `typeof ${opValue.getSignature().toString()}${genericStr}`; + } + return `typeof ${opValue.toString()}${genericStr}`; + } + + public inferType(arkMethod: ArkMethod): void { + IRInference.inferTypeQueryExpr(this, arkMethod); + } +} + +/** + * keyof type expr represents the type operator with keyof. + * It should be an internal expr. + * the final type should be transferred to union type, unless it cannot find out all types within the union type. + * @category core/base/typeExpr + * @extends AbstractTypeExpr + * @example + ```typescript + // opType is {a: 1, b: 2} and type of A is KeyofTypeExpr, which can be transferred to union type {'a', 'b'} + type A = keyof {a: 1, b: 2}; + + // opType is number and type of B is KeyofTypeExpr, which can be transferred to union type "toString" | "toFixed" | "toExponential" | ... + type B = keyof number; + ``` + */ +export class KeyofTypeExpr extends AbstractTypeExpr { + private opType: Type; + + constructor(opType: Type) { + super(); + this.opType = opType; + } + + public getOpType(): Type { + return this.opType; + } + + public setOpType(opType: Type): void { + this.opType = opType; + } + + public getUses(): Value[] { + let uses: Value[] = []; + if (this.getOpType() instanceof TypeQueryExpr) { + uses.push(...(this.getOpType() as TypeQueryExpr).getUses()); + } + return uses; + } + + public getType(): Type { + return this; + } + + public getTypeString(): string { + if (this.getOpType() instanceof UnionType || this.getOpType() instanceof IntersectionType) { + return `keyof (${this.getOpType().toString()})`; + } + return `keyof ${this.getOpType().toString()}`; + } + + public inferType(arkMethod: ArkMethod): void { + IRInference.inferKeyofTypeExpr(this, arkMethod); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/base/Value.ts b/ets2panda/linter/arkanalyzer/src/core/base/Value.ts new file mode 100644 index 0000000000000000000000000000000000000000..abeb8acba8897d3c8e364559b317bed16918a77e --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/base/Value.ts @@ -0,0 +1,49 @@ +/* + * 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. + */ + +import { Type } from './Type'; + +/** + * @category core/base + */ +export interface Value { + /** + * Return a list of values which are contained in this {@link Value}. + * Value is a core interface in ArkAnalyzer, which may represent any value or expression. + * @returns An **array** of values used by this value. + */ + getUses(): Value[]; + + /** + * Return the type of this value. The interface is encapsulated in {@link Value}. + * The `Type` is defined in type.ts, such as **Any**, **Unknown**, **TypeParameter**, + * **UnclearReference**, **Primitive**, **Number**, **String**, etc. + * @returns The type of this value. + * @example + * 1. In the declaration statement, determine the left-value type and right-value type. + + ```typescript + let leftValue:Value; + let rightValue:Value; + ... + if (leftValue.getType() instanceof UnknownType && + !(rightValue.getType() instanceof UnknownType) && + !(rightValue.getType() instanceof UndefinedType)) { + ... + } + ``` + */ + getType(): Type; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ArkError.ts b/ets2panda/linter/arkanalyzer/src/core/common/ArkError.ts new file mode 100644 index 0000000000000000000000000000000000000000..effb281a6e4f22c55a634c735e4dffefd1801ba0 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/ArkError.ts @@ -0,0 +1,30 @@ +/* + * 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. + */ + +export enum ArkErrorCode { + OK = 0, + CLASS_INSTANCE_FIELD_UNDEFINDED = -1, + BB_MORE_THAN_ONE_BRANCH_RET_STMT = -2, + BB_BRANCH_RET_STMT_NOT_AT_END = -3, + CFG_NOT_FOUND_START_BLOCK = -4, + CFG_HAS_UNREACHABLE_BLOCK = -5, + METHOD_SIGNATURE_UNDEFINED = -6, + METHOD_SIGNATURE_LINE_UNMATCHED = -7, +} + +export interface ArkError { + errCode: ArkErrorCode; + errMsg?: string; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ArkIRTransformer.ts b/ets2panda/linter/arkanalyzer/src/core/common/ArkIRTransformer.ts new file mode 100644 index 0000000000000000000000000000000000000000..31f9ecf635744368612a3a08b551ecca62c1b4a5 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/ArkIRTransformer.ts @@ -0,0 +1,822 @@ +/* + * 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. + */ + +import { + AbstractInvokeExpr, + AliasTypeExpr, + ArkCastExpr, + ArkConditionExpr, + ArkInstanceInvokeExpr, + ArkStaticInvokeExpr, + BinaryOperator, + NormalBinaryOperator, + RelationalBinaryOperator, + UnaryOperator, +} from '../base/Expr'; +import { ArkCaughtExceptionRef, ArkInstanceFieldRef, ArkParameterRef, ArkThisRef, GlobalRef } from '../base/Ref'; +import { Value } from '../base/Value'; +import * as ts from 'ohos-typescript'; +import { Local } from '../base/Local'; +import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, ArkThrowStmt, Stmt } from '../base/Stmt'; +import { AliasType, BooleanType, ClassType, Type, UnclearReferenceType, UnknownType, VoidType } from '../base/Type'; +import { ValueUtil } from './ValueUtil'; +import { AliasTypeSignature, ClassSignature, FieldSignature, MethodSignature, MethodSubSignature } from '../model/ArkSignature'; + +import { IRUtils } from './IRUtils'; +import { ArkMethod } from '../model/ArkMethod'; +import { buildArkMethodFromArkClass } from '../model/builder/ArkMethodBuilder'; +import { ArkSignatureBuilder } from '../model/builder/ArkSignatureBuilder'; +import { COMPONENT_BRANCH_FUNCTION, COMPONENT_CREATE_FUNCTION, COMPONENT_IF, COMPONENT_POP_FUNCTION, COMPONENT_REPEAT } from './EtsConst'; +import { FullPosition, LineColPosition } from '../base/Position'; +import { ModelUtils } from './ModelUtils'; +import { Builtin } from './Builtin'; +import { DEFAULT, PROMISE } from './TSConst'; +import { buildGenericType, buildModifiers, buildTypeParameters } from '../model/builder/builderUtils'; +import { ArkValueTransformer } from './ArkValueTransformer'; +import { ImportInfo } from '../model/ArkImport'; +import { TypeInference } from './TypeInference'; +import { AbstractTypeExpr } from '../base/TypeExpr'; +import { buildNormalArkClassFromArkMethod } from '../model/builder/ArkClassBuilder'; +import { ArkClass } from '../model/ArkClass'; +import { ModifierType } from '../model/ArkBaseModel'; + +export type ValueAndStmts = { + value: Value; + valueOriginalPositions: FullPosition[]; // original positions of value and its uses + stmts: Stmt[]; +}; + +export class DummyStmt extends Stmt { + constructor(text: string) { + super(); + this.text = text; + } + + public toString(): string { + return this.text!; + } +} + +export class ArkIRTransformer { + public static readonly DUMMY_LOOP_INITIALIZER_STMT = 'LoopInitializer'; + public static readonly DUMMY_CONDITIONAL_OPERATOR = 'ConditionalOperator'; + public static readonly DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT = ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR + 'IfTrue'; + public static readonly DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT = ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR + 'IfFalse'; + public static readonly DUMMY_CONDITIONAL_OPERATOR_END_STMT = ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR + 'End'; + + private sourceFile: ts.SourceFile; + private declaringMethod: ArkMethod; + private inBuilderMethod = false; + private builderMethodContextFlag = false; + private stmtsHaveOriginalText: Set = new Set(); + private arkValueTransformer: ArkValueTransformer; + + constructor(sourceFile: ts.SourceFile, declaringMethod: ArkMethod) { + this.sourceFile = sourceFile; + this.declaringMethod = declaringMethod; + this.inBuilderMethod = ModelUtils.isArkUIBuilderMethod(declaringMethod); + this.arkValueTransformer = new ArkValueTransformer(this, sourceFile, this.declaringMethod); + } + + public getLocals(): Set { + return this.arkValueTransformer.getLocals(); + } + + public getGlobals(): Map | null { + return this.arkValueTransformer.getGlobals(); + } + + public getThisLocal(): Local { + return this.arkValueTransformer.getThisLocal(); + } + + public getAliasTypeMap(): Map { + return this.arkValueTransformer.getAliasTypeMap(); + } + + public prebuildStmts(): Stmt[] { + const stmts: Stmt[] = []; + let index = 0; + for (const methodParameter of this.declaringMethod.getParameters()) { + const parameterRef = new ArkParameterRef(index, methodParameter.getType()); + stmts.push(new ArkAssignStmt(this.arkValueTransformer.addNewLocal(methodParameter.getName(), parameterRef.getType()), parameterRef)); + index++; + } + + const thisRef = new ArkThisRef(this.arkValueTransformer.getThisLocal().getType() as ClassType); + stmts.push(new ArkAssignStmt(this.arkValueTransformer.getThisLocal(), thisRef)); + return stmts; + } + + public tsNodeToStmts(node: ts.Node): Stmt[] { + let stmts: Stmt[] = []; + if (ts.isExpressionStatement(node)) { + stmts = this.expressionStatementToStmts(node); + } else if (ts.isTypeAliasDeclaration(node)) { + stmts = this.typeAliasDeclarationToStmts(node); + } else if (ts.isBlock(node)) { + stmts = this.blockToStmts(node); + } else if (ts.isForStatement(node)) { + stmts = this.forStatementToStmts(node); + } else if (ts.isForInStatement(node) || ts.isForOfStatement(node)) { + stmts = this.rangeForStatementToStmts(node); + } else if (ts.isWhileStatement(node)) { + stmts = this.whileStatementToStmts(node); + } else if (ts.isDoStatement(node)) { + stmts = this.doStatementToStmts(node); + } else if (ts.isVariableStatement(node)) { + stmts = this.variableStatementToStmts(node); + } else if (ts.isVariableDeclarationList(node)) { + stmts = this.variableDeclarationListToStmts(node); + } else if (ts.isIfStatement(node)) { + stmts = this.ifStatementToStmts(node); + } else if (ts.isBreakStatement(node) || ts.isContinueStatement(node)) { + stmts = this.gotoStatementToStmts(node); + } else if (ts.isThrowStatement(node)) { + stmts = this.throwStatementToStmts(node); + } else if (ts.isCatchClause(node)) { + stmts = this.catchClauseToStmts(node); + } else if (ts.isReturnStatement(node)) { + stmts = this.returnStatementToStmts(node); + } else if (ts.isFunctionDeclaration(node)) { + stmts = this.functionDeclarationToStmts(node); + } else if (ts.isExportAssignment(node)) { + stmts = this.expressionInExportToStmts(node.expression); + } else if (ts.isClassDeclaration(node)) { + stmts = this.classDeclarationToStmts(node); + } + + this.mapStmtsToTsStmt(stmts, node); + if (stmts.length > 0) { + IRUtils.setComments(stmts[0], node, this.sourceFile, this.declaringMethod.getDeclaringArkFile().getScene().getOptions()); + } + return stmts; + } + + public tsNodeToValueAndStmts(node: ts.Node): ValueAndStmts { + return this.arkValueTransformer.tsNodeToValueAndStmts(node); + } + + private functionDeclarationToStmts(functionDeclarationNode: ts.FunctionDeclaration): Stmt[] { + const declaringClass = this.declaringMethod.getDeclaringArkClass(); + const arkMethod = new ArkMethod(); + if (this.builderMethodContextFlag) { + ModelUtils.implicitArkUIBuilderMethods.add(arkMethod); + } + buildArkMethodFromArkClass(functionDeclarationNode, declaringClass, arkMethod, this.sourceFile, this.declaringMethod); + return []; + } + + private classDeclarationToStmts(node: ts.ClassDeclaration): Stmt[] { + const cls = new ArkClass(); + const declaringArkNamespace = this.declaringMethod.getDeclaringArkClass().getDeclaringArkNamespace(); + if (declaringArkNamespace) { + cls.setDeclaringArkNamespace(declaringArkNamespace); + } + cls.setDeclaringArkFile(this.declaringMethod.getDeclaringArkFile()); + buildNormalArkClassFromArkMethod(node, cls, this.sourceFile, this.declaringMethod); + return []; + } + + private returnStatementToStmts(returnStatement: ts.ReturnStatement): Stmt[] { + const stmts: Stmt[] = []; + if (returnStatement.expression) { + let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(returnStatement.expression); + exprStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(exprValue)) { + ({ value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.generateAssignStmtForValue(exprValue, exprPositions)); + exprStmts.forEach(stmt => stmts.push(stmt)); + } + const returnStmt = new ArkReturnStmt(exprValue); + returnStmt.setOperandOriginalPositions(exprPositions); + stmts.push(returnStmt); + if (this.declaringMethod.getSubSignature().getReturnType() instanceof UnknownType) { + this.declaringMethod.getSubSignature().setReturnType(exprValue.getType()); + } + return stmts; + } + stmts.push(new ArkReturnVoidStmt()); + if (this.declaringMethod.getSubSignature().getReturnType() instanceof UnknownType) { + if (this.declaringMethod.containsModifier(ModifierType.ASYNC)) { + const promise = this.declaringMethod.getDeclaringArkFile().getScene().getSdkGlobal(PROMISE); + if (promise instanceof ArkClass) { + this.declaringMethod.getSubSignature().setReturnType(new ClassType(promise.getSignature())); + } else { + this.declaringMethod.getSubSignature().setReturnType(new UnclearReferenceType(PROMISE, [VoidType.getInstance()])); + } + } else { + this.declaringMethod.getSubSignature().setReturnType(VoidType.getInstance()); + } + } + return stmts; + } + + private blockToStmts(block: ts.Block): Stmt[] { + const stmts: Stmt[] = []; + for (const statement of block.statements) { + this.tsNodeToStmts(statement).forEach(stmt => stmts.push(stmt)); + } + return stmts; + } + + private expressionStatementToStmts(expressionStatement: ts.ExpressionStatement): Stmt[] { + const exprNode = expressionStatement.expression; + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts(exprNode); + if (exprValue instanceof AbstractInvokeExpr) { + this.addInvokeStmts(exprValue, exprPositions, stmts); + } else if (this.shouldGenerateExtraAssignStmt(exprNode)) { + const { stmts: exprStmts } = this.generateAssignStmtForValue(exprValue, exprPositions); + exprStmts.forEach(stmt => stmts.push(stmt)); + } + return stmts; + } + + private addInvokeStmts(invokeExpr: AbstractInvokeExpr, exprPositions: FullPosition[], stmts: Stmt[]): void { + const invokeStmt = new ArkInvokeStmt(invokeExpr); + invokeStmt.setOperandOriginalPositions(exprPositions); + stmts.push(invokeStmt); + + let hasRepeat: boolean = false; + for (const stmt of stmts) { + if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof ArkStaticInvokeExpr) { + const rightOp = stmt.getRightOp() as ArkStaticInvokeExpr; + if (rightOp.getMethodSignature().getMethodSubSignature().getMethodName() === COMPONENT_REPEAT) { + const createMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName( + COMPONENT_REPEAT, + COMPONENT_CREATE_FUNCTION + ); + const createInvokeExpr = new ArkStaticInvokeExpr(createMethodSignature, rightOp.getArgs()); + stmt.setRightOp(createInvokeExpr); + hasRepeat = true; + } + } + } + if (hasRepeat) { + const popMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(COMPONENT_REPEAT, COMPONENT_POP_FUNCTION); + const popInvokeExpr = new ArkStaticInvokeExpr(popMethodSignature, []); + const popInvokeStmt = new ArkInvokeStmt(popInvokeExpr); + stmts.push(popInvokeStmt); + } + } + + private shouldGenerateExtraAssignStmt(expression: ts.Expression): boolean { + if (ts.isParenthesizedExpression(expression)) { + return this.shouldGenerateExtraAssignStmt(expression.expression); + } + if ( + (ts.isBinaryExpression(expression) && + (expression.operatorToken.kind === ts.SyntaxKind.FirstAssignment || + ArkValueTransformer.isCompoundAssignmentOperator(expression.operatorToken.kind))) || + ts.isEtsComponentExpression(expression) || + ts.isVoidExpression(expression) || + ts.isNewExpression(expression) || + ts.isCallExpression(expression) || + (ts.isPrefixUnaryExpression(expression) && + (expression.operator === ts.SyntaxKind.PlusPlusToken || expression.operator === ts.SyntaxKind.MinusMinusToken)) || + (ts.isPostfixUnaryExpression(expression) && + (expression.operator === ts.SyntaxKind.PlusPlusToken || expression.operator === ts.SyntaxKind.MinusMinusToken)) + ) { + return false; + } + + return true; + } + + private typeAliasDeclarationToStmts(typeAliasDeclaration: ts.TypeAliasDeclaration): Stmt[] { + const aliasName = typeAliasDeclaration.name.text; + const rightOp = typeAliasDeclaration.type; + let rightType = this.arkValueTransformer.resolveTypeNode(rightOp); + if (rightType instanceof AbstractTypeExpr) { + rightType = rightType.getType(); + } + + const aliasType = new AliasType(aliasName, rightType, new AliasTypeSignature(aliasName, this.declaringMethod.getSignature())); + if (typeAliasDeclaration.typeParameters) { + const genericTypes = buildTypeParameters(typeAliasDeclaration.typeParameters, this.sourceFile, this.declaringMethod); + aliasType.setGenericTypes(genericTypes); + aliasType.setOriginalType(buildGenericType(rightType, aliasType)); + rightType = aliasType.getOriginalType(); + } + + let expr = this.generateAliasTypeExpr(rightOp, aliasType); + + if ((ts.isTypeQueryNode(rightOp) || ts.isTypeReferenceNode(rightOp)) && rightOp.typeArguments) { + let realGenericTypes: Type[] = []; + rightOp.typeArguments.forEach(typeArgument => { + realGenericTypes.push(this.arkValueTransformer.resolveTypeNode(typeArgument)); + }); + expr.setRealGenericTypes(realGenericTypes); + } + + const modifiers = typeAliasDeclaration.modifiers ? buildModifiers(typeAliasDeclaration) : 0; + aliasType.setModifiers(modifiers); + + const aliasTypeDefineStmt = new ArkAliasTypeDefineStmt(aliasType, expr); + const leftPosition = FullPosition.buildFromNode(typeAliasDeclaration.name, this.sourceFile); + const rightPosition = FullPosition.buildFromNode(rightOp, this.sourceFile); + const operandOriginalPositions = [leftPosition, rightPosition]; + aliasTypeDefineStmt.setOperandOriginalPositions(operandOriginalPositions); + + this.getAliasTypeMap().set(aliasName, [aliasType, aliasTypeDefineStmt]); + + return [aliasTypeDefineStmt]; + } + + private generateAliasTypeExpr(rightOp: ts.TypeNode, aliasType: AliasType): AliasTypeExpr { + let rightType = aliasType.getOriginalType(); + let expr: AliasTypeExpr; + if (ts.isImportTypeNode(rightOp)) { + expr = this.resolveImportTypeNode(rightOp); + const typeObject = expr.getOriginalObject(); + if (typeObject instanceof ImportInfo && typeObject.getLazyExportInfo() !== null) { + const arkExport = typeObject.getLazyExportInfo()!.getArkExport(); + rightType = TypeInference.parseArkExport2Type(arkExport) ?? UnknownType.getInstance(); + aliasType.setOriginalType(rightType); + } + } else if (ts.isTypeQueryNode(rightOp)) { + const localName = rightOp.exprName.getText(this.sourceFile); + const originalLocal = Array.from(this.arkValueTransformer.getLocals()).find(local => local.getName() === localName); + if (originalLocal === undefined || rightType instanceof UnclearReferenceType) { + expr = new AliasTypeExpr(new Local(localName, rightType), true); + } else { + expr = new AliasTypeExpr(originalLocal, true); + } + } else if (ts.isTypeReferenceNode(rightOp)) { + // For type A = B stmt and B is also an alias type with the same scope of A, + // rightType here is AliasType with real generic type number. + // The originalObject in expr should be the object without real generic type, so try to find it in this scope. + if (rightType instanceof AliasType) { + const existAliasType = this.getAliasTypeMap().get(rightType.getName()); + if (existAliasType) { + expr = new AliasTypeExpr(existAliasType[0], false); + } else { + expr = new AliasTypeExpr(rightType, false); + } + } else { + expr = new AliasTypeExpr(rightType, false); + } + } else { + expr = new AliasTypeExpr(rightType, false); + + // 对于type A = {x:1, y:2}语句,当前阶段即可精确获取ClassType类型,需找到对应的ArkClass作为originalObject + // 对于其他情况此处为UnclearReferenceTye并由类型推导进行查找和处理 + if (rightType instanceof ClassType) { + const classObject = ModelUtils.getClassWithName(rightType.getClassSignature().getClassName(), this.declaringMethod.getDeclaringArkClass()); + if (classObject) { + expr.setOriginalObject(classObject); + } + } + } + return expr; + } + + private resolveImportTypeNode(importTypeNode: ts.ImportTypeNode): AliasTypeExpr { + const importType = 'typeAliasDefine'; + let importFrom = ''; + let importClauseName = ''; + + if (ts.isLiteralTypeNode(importTypeNode.argument)) { + if (ts.isStringLiteral(importTypeNode.argument.literal)) { + importFrom = importTypeNode.argument.literal.text; + } + } + + const importQualifier = importTypeNode.qualifier; + if (importQualifier !== undefined) { + importClauseName = importQualifier.getText(this.sourceFile); + } + + let importInfo = new ImportInfo(); + importInfo.build(importClauseName, importType, importFrom, LineColPosition.buildFromNode(importTypeNode, this.sourceFile), 0); + importInfo.setDeclaringArkFile(this.declaringMethod.getDeclaringArkFile()); + + // Function getLazyExportInfo will automatically try to infer the export info if it's undefined at the beginning. + importInfo.getLazyExportInfo(); + return new AliasTypeExpr(importInfo, importTypeNode.isTypeOf); + } + + public switchStatementToValueAndStmts(switchStatement: ts.SwitchStatement): ValueAndStmts[] { + const valueAndStmtsOfSwitchAndCases: ValueAndStmts[] = []; + const exprStmts: Stmt[] = []; + let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprTempStmts } = this.tsNodeToValueAndStmts(switchStatement.expression); + exprTempStmts.forEach(stmt => exprStmts.push(stmt)); + if (IRUtils.moreThanOneAddress(exprValue)) { + ({ value: exprValue, valueOriginalPositions: exprPositions, stmts: exprTempStmts } = this.generateAssignStmtForValue(exprValue, exprPositions)); + exprTempStmts.forEach(stmt => exprStmts.push(stmt)); + } + valueAndStmtsOfSwitchAndCases.push({ + value: exprValue, + valueOriginalPositions: exprPositions, + stmts: exprStmts, + }); + + for (const clause of switchStatement.caseBlock.clauses) { + if (ts.isCaseClause(clause)) { + const clauseStmts: Stmt[] = []; + let { value: clauseValue, valueOriginalPositions: clausePositions, stmts: clauseTempStmts } = this.tsNodeToValueAndStmts(clause.expression); + clauseTempStmts.forEach(stmt => clauseStmts.push(stmt)); + if (IRUtils.moreThanOneAddress(clauseValue)) { + ({ + value: clauseValue, + valueOriginalPositions: clausePositions, + stmts: clauseTempStmts, + } = this.generateAssignStmtForValue(clauseValue, clausePositions)); + clauseTempStmts.forEach(stmt => clauseStmts.push(stmt)); + } + valueAndStmtsOfSwitchAndCases.push({ + value: clauseValue, + valueOriginalPositions: clausePositions, + stmts: clauseStmts, + }); + } + } + return valueAndStmtsOfSwitchAndCases; + } + + private forStatementToStmts(forStatement: ts.ForStatement): Stmt[] { + const stmts: Stmt[] = []; + if (forStatement.initializer) { + this.tsNodeToValueAndStmts(forStatement.initializer).stmts.forEach(stmt => stmts.push(stmt)); + } + const dummyInitializerStmt = new DummyStmt(ArkIRTransformer.DUMMY_LOOP_INITIALIZER_STMT); + stmts.push(dummyInitializerStmt); + + if (forStatement.condition) { + const { value: conditionValue, stmts: conditionStmts } = this.arkValueTransformer.conditionToValueAndStmts(forStatement.condition); + conditionStmts.forEach(stmt => stmts.push(stmt)); + stmts.push(new ArkIfStmt(conditionValue as ArkConditionExpr)); + } else { + // The omitted condition always evaluates to true. + const trueConstant = ValueUtil.getBooleanConstant(true); + const conditionExpr = new ArkConditionExpr(trueConstant, trueConstant, RelationalBinaryOperator.Equality); + stmts.push(new ArkIfStmt(conditionExpr)); + } + if (forStatement.incrementor) { + this.tsNodeToValueAndStmts(forStatement.incrementor).stmts.forEach(stmt => stmts.push(stmt)); + } + return stmts; + } + + private rangeForStatementToStmts(forOfStatement: ts.ForOfStatement | ts.ForInStatement): Stmt[] { + const stmts: Stmt[] = []; + let { value: iterableValue, valueOriginalPositions: iterablePositions, stmts: iterableStmts } = this.tsNodeToValueAndStmts(forOfStatement.expression); + iterableStmts.forEach(stmt => stmts.push(stmt)); + if (!(iterableValue instanceof Local)) { + ({ + value: iterableValue, + valueOriginalPositions: iterablePositions, + stmts: iterableStmts, + } = this.generateAssignStmtForValue(iterableValue, iterablePositions)); + iterableStmts.forEach(stmt => stmts.push(stmt)); + } + const iteratorMethodSubSignature = new MethodSubSignature(Builtin.ITERATOR_FUNCTION, [], Builtin.ITERATOR_CLASS_TYPE); + const iteratorMethodSignature = new MethodSignature(ClassSignature.DEFAULT, iteratorMethodSubSignature); + const iteratorInvokeExpr = new ArkInstanceInvokeExpr(iterableValue as Local, iteratorMethodSignature, []); + const iteratorInvokeExprPositions = [iterablePositions[0], ...iterablePositions]; + const { + value: iterator, + valueOriginalPositions: iteratorPositions, + stmts: iteratorStmts, + } = this.generateAssignStmtForValue(iteratorInvokeExpr, iteratorInvokeExprPositions); + iteratorStmts.forEach(stmt => stmts.push(stmt)); + (iterator as Local).setType(Builtin.ITERATOR_CLASS_TYPE); + + const nextMethodSubSignature = new MethodSubSignature(Builtin.ITERATOR_NEXT, [], Builtin.ITERATOR_RESULT_CLASS_TYPE); + const nextMethodSignature = new MethodSignature(ClassSignature.DEFAULT, nextMethodSubSignature); + const iteratorNextInvokeExpr = new ArkInstanceInvokeExpr(iterator as Local, nextMethodSignature, []); + const iteratorNextInvokeExprPositions = [iteratorPositions[0], ...iteratorPositions]; + const { + value: iteratorResult, + valueOriginalPositions: iteratorResultPositions, + stmts: iteratorResultStmts, + } = this.generateAssignStmtForValue(iteratorNextInvokeExpr, iteratorNextInvokeExprPositions); + iteratorResultStmts.forEach(stmt => stmts.push(stmt)); + (iteratorResult as Local).setType(Builtin.ITERATOR_RESULT_CLASS_TYPE); + const doneFieldSignature = new FieldSignature(Builtin.ITERATOR_RESULT_DONE, Builtin.ITERATOR_RESULT_CLASS_SIGNATURE, BooleanType.getInstance(), false); + const doneFieldRef = new ArkInstanceFieldRef(iteratorResult as Local, doneFieldSignature); + const doneFieldRefPositions = [iteratorResultPositions[0], ...iteratorResultPositions]; + const { + value: doneFlag, + valueOriginalPositions: doneFlagPositions, + stmts: doneFlagStmts, + } = this.generateAssignStmtForValue(doneFieldRef, doneFieldRefPositions); + doneFlagStmts.forEach(stmt => stmts.push(stmt)); + (doneFlag as Local).setType(BooleanType.getInstance()); + const conditionExpr = new ArkConditionExpr(doneFlag, ValueUtil.getBooleanConstant(true), RelationalBinaryOperator.Equality); + const conditionExprPositions = [doneFlagPositions[0], ...doneFlagPositions, FullPosition.DEFAULT]; + const ifStmt = new ArkIfStmt(conditionExpr); + ifStmt.setOperandOriginalPositions(conditionExprPositions); + stmts.push(ifStmt); + + const valueFieldSignature = new FieldSignature( + Builtin.ITERATOR_RESULT_VALUE, + Builtin.ITERATOR_RESULT_CLASS_SIGNATURE, + UnknownType.getInstance(), + false + ); + const valueFieldRef = new ArkInstanceFieldRef(iteratorResult as Local, valueFieldSignature); + const valueFieldRefPositions = [iteratorResultPositions[0], ...iteratorResultPositions]; + const { + value: yieldValue, + valueOriginalPositions: yieldValuePositions, + stmts: yieldValueStmts, + } = this.generateAssignStmtForValue(valueFieldRef, valueFieldRefPositions); + yieldValueStmts.forEach(stmt => stmts.push(stmt)); + + const castExpr = new ArkCastExpr(yieldValue, UnknownType.getInstance()); + const castExprPositions = [yieldValuePositions[0], ...yieldValuePositions]; + const initializerNode = forOfStatement.initializer; + if (ts.isVariableDeclarationList(initializerNode)) { + const isConst = (initializerNode.flags & ts.NodeFlags.Const) !== 0; + const { + value: initValue, + valueOriginalPositions: initOriPos, + stmts: initStmts, + } = this.arkValueTransformer.variableDeclarationToValueAndStmts(initializerNode.declarations[0], isConst, false); + const assignStmt = new ArkAssignStmt(initValue, castExpr); + assignStmt.setOperandOriginalPositions([...initOriPos, ...castExprPositions]); + stmts.push(assignStmt); + initStmts.forEach(stmt => stmts.push(stmt)); + } else { + // initializer maybe an expression + const { value: initValue, valueOriginalPositions: initOriPos, stmts: initStmts } = this.tsNodeToValueAndStmts(initializerNode); + const assignStmt = new ArkAssignStmt(initValue, castExpr); + assignStmt.setOperandOriginalPositions([...initOriPos, ...castExprPositions]); + initStmts.forEach(stmt => stmts.push(stmt)); + stmts.push(assignStmt); + } + return stmts; + } + + private whileStatementToStmts(whileStatement: ts.WhileStatement): Stmt[] { + const stmts: Stmt[] = []; + const dummyInitializerStmt = new DummyStmt(ArkIRTransformer.DUMMY_LOOP_INITIALIZER_STMT); + stmts.push(dummyInitializerStmt); + + const { value: conditionExpr, stmts: conditionStmts } = this.arkValueTransformer.conditionToValueAndStmts(whileStatement.expression); + conditionStmts.forEach(stmt => stmts.push(stmt)); + stmts.push(new ArkIfStmt(conditionExpr as ArkConditionExpr)); + return stmts; + } + + private doStatementToStmts(doStatement: ts.DoStatement): Stmt[] { + const stmts: Stmt[] = []; + const { value: conditionExpr, stmts: conditionStmts } = this.arkValueTransformer.conditionToValueAndStmts(doStatement.expression); + conditionStmts.forEach(stmt => stmts.push(stmt)); + stmts.push(new ArkIfStmt(conditionExpr as ArkConditionExpr)); + return stmts; + } + + private variableStatementToStmts(variableStatement: ts.VariableStatement): Stmt[] { + return this.variableDeclarationListToStmts(variableStatement.declarationList); + } + + private variableDeclarationListToStmts(variableDeclarationList: ts.VariableDeclarationList): Stmt[] { + return this.arkValueTransformer.variableDeclarationListToValueAndStmts(variableDeclarationList).stmts; + } + + private ifStatementToStmts(ifStatement: ts.IfStatement): Stmt[] { + const stmts: Stmt[] = []; + if (this.inBuilderMethod) { + const { + value: conditionExpr, + valueOriginalPositions: conditionExprPositions, + stmts: conditionStmts, + } = this.arkValueTransformer.conditionToValueAndStmts(ifStatement.expression); + conditionStmts.forEach(stmt => stmts.push(stmt)); + const createMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(COMPONENT_IF, COMPONENT_CREATE_FUNCTION); + const { + value: conditionLocal, + valueOriginalPositions: conditionLocalPositions, + stmts: assignConditionStmts, + } = this.generateAssignStmtForValue(conditionExpr, conditionExprPositions); + assignConditionStmts.forEach(stmt => stmts.push(stmt)); + const createInvokeExpr = new ArkStaticInvokeExpr(createMethodSignature, [conditionLocal]); + const createInvokeExprPositions = [conditionLocalPositions[0], ...conditionLocalPositions]; + const { stmts: createStmts } = this.generateAssignStmtForValue(createInvokeExpr, createInvokeExprPositions); + createStmts.forEach(stmt => stmts.push(stmt)); + const branchMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(COMPONENT_IF, COMPONENT_BRANCH_FUNCTION); + const branchInvokeExpr = new ArkStaticInvokeExpr(branchMethodSignature, [ValueUtil.getOrCreateNumberConst(0)]); + const branchInvokeExprPositions = [conditionLocalPositions[0], FullPosition.DEFAULT]; + const branchInvokeStmt = new ArkInvokeStmt(branchInvokeExpr); + branchInvokeStmt.setOperandOriginalPositions(branchInvokeExprPositions); + stmts.push(branchInvokeStmt); + this.tsNodeToStmts(ifStatement.thenStatement).forEach(stmt => stmts.push(stmt)); + if (ifStatement.elseStatement) { + const branchElseMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(COMPONENT_IF, COMPONENT_BRANCH_FUNCTION); + const branchElseInvokeExpr = new ArkStaticInvokeExpr(branchElseMethodSignature, [ValueUtil.getOrCreateNumberConst(1)]); + const branchElseInvokeExprPositions = [FullPosition.buildFromNode(ifStatement.elseStatement, this.sourceFile), FullPosition.DEFAULT]; + const branchElseInvokeStmt = new ArkInvokeStmt(branchElseInvokeExpr); + branchElseInvokeStmt.setOperandOriginalPositions(branchElseInvokeExprPositions); + stmts.push(branchElseInvokeStmt); + + this.tsNodeToStmts(ifStatement.elseStatement).forEach(stmt => stmts.push(stmt)); + } + const popMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(COMPONENT_IF, COMPONENT_POP_FUNCTION); + const popInvokeExpr = new ArkStaticInvokeExpr(popMethodSignature, []); + const popInvokeStmt = new ArkInvokeStmt(popInvokeExpr); + stmts.push(popInvokeStmt); + } else { + const { + value: conditionExpr, + valueOriginalPositions: conditionExprPositions, + stmts: conditionStmts, + } = this.arkValueTransformer.conditionToValueAndStmts(ifStatement.expression); + conditionStmts.forEach(stmt => stmts.push(stmt)); + const ifStmt = new ArkIfStmt(conditionExpr as ArkConditionExpr); + ifStmt.setOperandOriginalPositions(conditionExprPositions); + stmts.push(ifStmt); + } + return stmts; + } + + private gotoStatementToStmts(gotoStatement: ts.BreakStatement | ts.ContinueStatement): Stmt[] { + return []; + } + + private throwStatementToStmts(throwStatement: ts.ThrowStatement): Stmt[] { + const stmts: Stmt[] = []; + const { value: throwValue, valueOriginalPositions: throwValuePositions, stmts: throwStmts } = this.tsNodeToValueAndStmts(throwStatement.expression); + throwStmts.forEach(stmt => stmts.push(stmt)); + const throwStmt = new ArkThrowStmt(throwValue); + throwStmt.setOperandOriginalPositions(throwValuePositions); + stmts.push(throwStmt); + return stmts; + } + + private catchClauseToStmts(catchClause: ts.CatchClause): Stmt[] { + const stmts: Stmt[] = []; + if (catchClause.variableDeclaration) { + const { + value: catchValue, + valueOriginalPositions: catchOriPos, + stmts: catchStmts, + } = this.arkValueTransformer.variableDeclarationToValueAndStmts(catchClause.variableDeclaration, false, false); + const caughtExceptionRef = new ArkCaughtExceptionRef(UnknownType.getInstance()); + const assignStmt = new ArkAssignStmt(catchValue, caughtExceptionRef); + assignStmt.setOperandOriginalPositions(catchOriPos); + stmts.push(assignStmt); + catchStmts.forEach(stmt => stmts.push(stmt)); + } + return stmts; + } + + private expressionInExportToStmts(expression: ts.Node): Stmt[] { + if (ts.isNewExpression(expression) || ts.isObjectLiteralExpression(expression)) { + return this.newClassInExportToStmts(expression); + } + return []; + } + + private newClassInExportToStmts(expression: ts.NewExpression | ts.ObjectLiteralExpression): Stmt[] { + let stmts: Stmt[] = []; + let { value: rightValue, valueOriginalPositions: rightPositions, stmts: rightStmts } = this.tsNodeToValueAndStmts(expression); + rightStmts.forEach(stmt => stmts.push(stmt)); + let leftValue = this.arkValueTransformer.addNewLocal(DEFAULT); + let leftPositions = rightPositions; + const assignStmt = new ArkAssignStmt(leftValue, rightValue); + assignStmt.setOperandOriginalPositions([...leftPositions, ...rightPositions]); + stmts.push(assignStmt); + return stmts; + } + + public mapStmtsToTsStmt(stmts: Stmt[], node: ts.Node): void { + for (const stmt of stmts) { + if (!this.stmtsHaveOriginalText.has(stmt)) { + this.stmtsHaveOriginalText.add(stmt); + stmt.setOriginPositionInfo(LineColPosition.buildFromNode(node, this.sourceFile)); + stmt.setOriginalText(node.getText(this.sourceFile)); + } + } + } + + public static tokenToUnaryOperator(token: ts.SyntaxKind): UnaryOperator | null { + switch (token) { + case ts.SyntaxKind.MinusToken: + return UnaryOperator.Neg; + case ts.SyntaxKind.TildeToken: + return UnaryOperator.BitwiseNot; + case ts.SyntaxKind.ExclamationToken: + return UnaryOperator.LogicalNot; + default: + } + return null; + } + + public static tokenToBinaryOperator(token: ts.SyntaxKind): BinaryOperator | null { + switch (token) { + case ts.SyntaxKind.QuestionQuestionToken: + return NormalBinaryOperator.NullishCoalescing; + case ts.SyntaxKind.AsteriskAsteriskToken: + return NormalBinaryOperator.Exponentiation; + case ts.SyntaxKind.SlashToken: + return NormalBinaryOperator.Division; + case ts.SyntaxKind.PlusToken: + return NormalBinaryOperator.Addition; + case ts.SyntaxKind.MinusToken: + return NormalBinaryOperator.Subtraction; + case ts.SyntaxKind.AsteriskToken: + return NormalBinaryOperator.Multiplication; + case ts.SyntaxKind.PercentToken: + return NormalBinaryOperator.Remainder; + case ts.SyntaxKind.LessThanLessThanToken: + return NormalBinaryOperator.LeftShift; + case ts.SyntaxKind.GreaterThanGreaterThanToken: + return NormalBinaryOperator.RightShift; + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + return NormalBinaryOperator.UnsignedRightShift; + case ts.SyntaxKind.AmpersandToken: + return NormalBinaryOperator.BitwiseAnd; + case ts.SyntaxKind.BarToken: + return NormalBinaryOperator.BitwiseOr; + case ts.SyntaxKind.CaretToken: + return NormalBinaryOperator.BitwiseXor; + case ts.SyntaxKind.AmpersandAmpersandToken: + return NormalBinaryOperator.LogicalAnd; + case ts.SyntaxKind.BarBarToken: + return NormalBinaryOperator.LogicalOr; + case ts.SyntaxKind.LessThanToken: + return RelationalBinaryOperator.LessThan; + case ts.SyntaxKind.LessThanEqualsToken: + return RelationalBinaryOperator.LessThanOrEqual; + case ts.SyntaxKind.GreaterThanToken: + return RelationalBinaryOperator.GreaterThan; + case ts.SyntaxKind.GreaterThanEqualsToken: + return RelationalBinaryOperator.GreaterThanOrEqual; + case ts.SyntaxKind.EqualsEqualsToken: + return RelationalBinaryOperator.Equality; + case ts.SyntaxKind.ExclamationEqualsToken: + return RelationalBinaryOperator.InEquality; + case ts.SyntaxKind.EqualsEqualsEqualsToken: + return RelationalBinaryOperator.StrictEquality; + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + return RelationalBinaryOperator.StrictInequality; + default: + } + return null; + } + + public generateAssignStmtForValue(value: Value, valueOriginalPositions: FullPosition[]): ValueAndStmts { + const leftOp = this.arkValueTransformer.generateTempLocal(value.getType()); + const leftOpPosition = valueOriginalPositions[0]; + const assignStmt = new ArkAssignStmt(leftOp, value); + assignStmt.setOperandOriginalPositions([leftOpPosition, ...valueOriginalPositions]); + return { + value: leftOp, + valueOriginalPositions: [leftOpPosition], + stmts: [assignStmt], + }; + } + + public generateIfStmtForValues( + leftValue: Value, + leftOpOriginalPositions: FullPosition[], + rightValue: Value, + rightOpOriginalPositions: FullPosition[] + ): Stmt[] { + const stmts: Stmt[] = []; + if (IRUtils.moreThanOneAddress(leftValue)) { + const { + value: tempLeftValue, + valueOriginalPositions: tempLeftPositions, + stmts: leftStmts, + } = this.generateAssignStmtForValue(leftValue, leftOpOriginalPositions); + leftStmts.forEach(stmt => stmts.push(stmt)); + leftValue = tempLeftValue; + leftOpOriginalPositions = tempLeftPositions; + } + if (IRUtils.moreThanOneAddress(rightValue)) { + const { + value: tempRightValue, + valueOriginalPositions: tempRightPositions, + stmts: rightStmts, + } = this.generateAssignStmtForValue(rightValue, rightOpOriginalPositions); + rightStmts.forEach(stmt => stmts.push(stmt)); + rightValue = tempRightValue; + rightOpOriginalPositions = tempRightPositions; + } + + const conditionExpr = new ArkConditionExpr(leftValue, rightValue, RelationalBinaryOperator.Equality); + const conditionPositions = [...leftOpOriginalPositions, ...rightOpOriginalPositions]; + const ifStmt = new ArkIfStmt(conditionExpr); + ifStmt.setOperandOriginalPositions([...conditionPositions]); + stmts.push(ifStmt); + return stmts; + } + + public setBuilderMethodContextFlag(builderMethodContextFlag: boolean): void { + this.builderMethodContextFlag = builderMethodContextFlag; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ArkValueTransformer.ts b/ets2panda/linter/arkanalyzer/src/core/common/ArkValueTransformer.ts new file mode 100644 index 0000000000000000000000000000000000000000..75d86894287526553dc8e0e7a656d10f280cc4da --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/ArkValueTransformer.ts @@ -0,0 +1,1999 @@ +/* + * 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. + */ + +import * as ts from 'ohos-typescript'; +import { Local } from '../base/Local'; +import { FullPosition } from '../base/Position'; +import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, Stmt } from '../base/Stmt'; +import { + AbstractBinopExpr, + ArkAwaitExpr, + ArkCastExpr, + ArkConditionExpr, + ArkDeleteExpr, + ArkInstanceInvokeExpr, + ArkInstanceOfExpr, + ArkNewArrayExpr, + ArkNewExpr, + ArkNormalBinopExpr, + ArkPtrInvokeExpr, + ArkStaticInvokeExpr, + ArkTypeOfExpr, + ArkUnopExpr, + ArkYieldExpr, + BinaryOperator, + NormalBinaryOperator, + RelationalBinaryOperator, +} from '../base/Expr'; +import { ArkClass } from '../model/ArkClass'; +import { buildNormalArkClassFromArkFile, buildNormalArkClassFromArkNamespace } from '../model/builder/ArkClassBuilder'; +import { + AliasType, + AnyType, + ArrayType, + BigIntType, + BooleanType, + ClassType, + FunctionType, + IntersectionType, + LiteralType, + NeverType, + NullType, + NumberType, + StringType, + TupleType, + Type, + UnclearReferenceType, + UndefinedType, + UnionType, + UnknownType, + VoidType, +} from '../base/Type'; +import { ArkSignatureBuilder } from '../model/builder/ArkSignatureBuilder'; +import { CONSTRUCTOR_NAME, THIS_NAME } from './TSConst'; +import { ClassSignature, FieldSignature, MethodSignature } from '../model/ArkSignature'; +import { Value } from '../base/Value'; +import { + COMPONENT_CREATE_FUNCTION, + COMPONENT_CUSTOMVIEW, + COMPONENT_FOR_EACH, + COMPONENT_LAZY_FOR_EACH, + COMPONENT_POP_FUNCTION, + isEtsSystemComponent, +} from './EtsConst'; +import { ValueUtil } from './ValueUtil'; +import { IRUtils } from './IRUtils'; +import { AbstractFieldRef, ArkArrayRef, ArkInstanceFieldRef, ArkStaticFieldRef, GlobalRef } from '../base/Ref'; +import { ModelUtils } from './ModelUtils'; +import { ArkMethod } from '../model/ArkMethod'; +import { buildArkMethodFromArkClass } from '../model/builder/ArkMethodBuilder'; +import { Builtin } from './Builtin'; +import { Constant } from '../base/Constant'; +import { TEMP_LOCAL_PREFIX } from './Const'; +import { ArkIRTransformer, DummyStmt, ValueAndStmts } from './ArkIRTransformer'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { TypeInference } from './TypeInference'; +import { KeyofTypeExpr, TypeQueryExpr } from '../base/TypeExpr'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkValueTransformer'); + +export class ArkValueTransformer { + private conditionalOperatorNo: number = 0; + private tempLocalNo: number = 0; + private sourceFile: ts.SourceFile; + private locals: Map = new Map(); + private globals?: Map; + private thisLocal: Local; + private declaringMethod: ArkMethod; + private arkIRTransformer: ArkIRTransformer; + private aliasTypeMap: Map = new Map(); + private builderMethodContextFlag = false; + + constructor(arkIRTransformer: ArkIRTransformer, sourceFile: ts.SourceFile, declaringMethod: ArkMethod) { + this.arkIRTransformer = arkIRTransformer; + this.sourceFile = sourceFile; + this.thisLocal = new Local(THIS_NAME, declaringMethod.getDeclaringArkClass().getSignature().getType()); + this.locals.set(this.thisLocal.getName(), this.thisLocal); + this.declaringMethod = declaringMethod; + } + + public getLocals(): Set { + return new Set(this.locals.values()); + } + + public getThisLocal(): Local { + return this.thisLocal; + } + + public getAliasTypeMap(): Map { + return this.aliasTypeMap; + } + + public addNewLocal(localName: string, localType: Type = UnknownType.getInstance()): Local { + let local = new Local(localName, localType); + this.locals.set(localName, local); + return local; + } + + public getGlobals(): Map | null { + return this.globals ?? null; + } + + private addNewGlobal(name: string, ref?: Value): GlobalRef { + let globalRef = new GlobalRef(name, ref); + this.globals = this.globals ?? new Map(); + this.globals.set(name, globalRef); + return globalRef; + } + + public tsNodeToValueAndStmts(node: ts.Node): ValueAndStmts { + if (ts.isBinaryExpression(node)) { + return this.binaryExpressionToValueAndStmts(node); + } else if (ts.isCallExpression(node)) { + return this.callExpressionToValueAndStmts(node); + } else if (ts.isVariableDeclarationList(node)) { + return this.variableDeclarationListToValueAndStmts(node); + } else if (ts.isIdentifier(node)) { + return this.identifierToValueAndStmts(node); + } else if (ts.isPropertyAccessExpression(node)) { + return this.propertyAccessExpressionToValue(node); + } else if (ts.isPrefixUnaryExpression(node)) { + return this.prefixUnaryExpressionToValueAndStmts(node); + } else if (ts.isPostfixUnaryExpression(node)) { + return this.postfixUnaryExpressionToValueAndStmts(node); + } else if (ts.isTemplateExpression(node)) { + return this.templateExpressionToValueAndStmts(node); + } else if (ts.isTaggedTemplateExpression(node)) { + return this.taggedTemplateExpressionToValueAndStmts(node); + } else if (ts.isAwaitExpression(node)) { + return this.awaitExpressionToValueAndStmts(node); + } else if (ts.isYieldExpression(node)) { + return this.yieldExpressionToValueAndStmts(node); + } else if (ts.isDeleteExpression(node)) { + return this.deleteExpressionToValueAndStmts(node); + } else if (ts.isVoidExpression(node)) { + return this.voidExpressionToValueAndStmts(node); + } else if (ts.isElementAccessExpression(node)) { + return this.elementAccessExpressionToValueAndStmts(node); + } else if (ts.isNewExpression(node)) { + return this.newExpressionToValueAndStmts(node); + } else if (ts.isParenthesizedExpression(node)) { + return this.parenthesizedExpressionToValueAndStmts(node); + } else if (ts.isAsExpression(node)) { + return this.asExpressionToValueAndStmts(node); + } else if (ts.isNonNullExpression(node)) { + return this.nonNullExpressionToValueAndStmts(node); + } else if (ts.isTypeAssertionExpression(node)) { + return this.typeAssertionToValueAndStmts(node); + } else if (ts.isTypeOfExpression(node)) { + return this.typeOfExpressionToValueAndStmts(node); + } else if (ts.isArrayLiteralExpression(node)) { + return this.arrayLiteralExpressionToValueAndStmts(node); + } else if (this.isLiteralNode(node)) { + return this.literalNodeToValueAndStmts(node) as ValueAndStmts; + } else if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) { + return this.callableNodeToValueAndStmts(node); + } else if (ts.isClassExpression(node)) { + return this.classExpressionToValueAndStmts(node); + } else if (ts.isEtsComponentExpression(node)) { + return this.etsComponentExpressionToValueAndStmts(node); + } else if (ts.isObjectLiteralExpression(node)) { + return this.objectLiteralExpresionToValueAndStmts(node); + } else if (node.kind === ts.SyntaxKind.ThisKeyword) { + return this.thisExpressionToValueAndStmts(node as ts.ThisExpression); + } else if (ts.isConditionalExpression(node)) { + return this.conditionalExpressionToValueAndStmts(node); + } + + return { + value: new Local(node.getText(this.sourceFile)), + valueOriginalPositions: [FullPosition.buildFromNode(node, this.sourceFile)], + stmts: [], + }; + } + + private tsNodeToSingleAddressValueAndStmts(node: ts.Node): ValueAndStmts { + const allStmts: Stmt[] = []; + let { value, valueOriginalPositions, stmts } = this.tsNodeToValueAndStmts(node); + stmts.forEach(stmt => allStmts.push(stmt)); + if (IRUtils.moreThanOneAddress(value)) { + ({ value, valueOriginalPositions, stmts } = this.arkIRTransformer.generateAssignStmtForValue(value, valueOriginalPositions)); + stmts.forEach(stmt => allStmts.push(stmt)); + } + return { value, valueOriginalPositions, stmts: allStmts }; + } + + private thisExpressionToValueAndStmts(thisExpression: ts.ThisExpression): ValueAndStmts { + return { + value: this.getThisLocal(), + valueOriginalPositions: [FullPosition.buildFromNode(thisExpression, this.sourceFile)], + stmts: [], + }; + } + + private conditionalExpressionToValueAndStmts(conditionalExpression: ts.ConditionalExpression): ValueAndStmts { + const stmts: Stmt[] = []; + const currConditionalOperatorIndex = this.conditionalOperatorNo++; + const { + value: conditionValue, + valueOriginalPositions: conditionPositions, + stmts: conditionStmts, + } = this.conditionToValueAndStmts(conditionalExpression.condition); + conditionStmts.forEach(stmt => stmts.push(stmt)); + const ifStmt = new ArkIfStmt(conditionValue as ArkConditionExpr); + ifStmt.setOperandOriginalPositions(conditionPositions); + stmts.push(ifStmt); + + stmts.push(new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT + currConditionalOperatorIndex)); + const { + value: whenTrueValue, + valueOriginalPositions: whenTruePositions, + stmts: whenTrueStmts, + } = this.tsNodeToValueAndStmts(conditionalExpression.whenTrue); + whenTrueStmts.forEach(stmt => stmts.push(stmt)); + const resultLocal = this.generateTempLocal(); + const assignStmtWhenTrue = new ArkAssignStmt(resultLocal, whenTrueValue); + const resultLocalPosition: FullPosition[] = [whenTruePositions[0]]; + assignStmtWhenTrue.setOperandOriginalPositions([...resultLocalPosition, ...whenTruePositions]); + stmts.push(assignStmtWhenTrue); + + stmts.push(new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT + currConditionalOperatorIndex)); + const { + value: whenFalseValue, + valueOriginalPositions: whenFalsePositions, + stmts: whenFalseStmts, + } = this.tsNodeToValueAndStmts(conditionalExpression.whenFalse); + whenFalseStmts.forEach(stmt => stmts.push(stmt)); + const assignStmt = new ArkAssignStmt(resultLocal, whenFalseValue); + assignStmt.setOperandOriginalPositions([...resultLocalPosition, ...whenFalsePositions]); + stmts.push(assignStmt); + stmts.push(new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT + currConditionalOperatorIndex)); + return { + value: resultLocal, + valueOriginalPositions: resultLocalPosition, + stmts: stmts, + }; + } + + private objectLiteralExpresionToValueAndStmts(objectLiteralExpression: ts.ObjectLiteralExpression): ValueAndStmts { + const declaringArkClass = this.declaringMethod.getDeclaringArkClass(); + const declaringArkNamespace = declaringArkClass.getDeclaringArkNamespace(); + const anonymousClass = new ArkClass(); + if (declaringArkNamespace) { + buildNormalArkClassFromArkNamespace(objectLiteralExpression, declaringArkNamespace, anonymousClass, this.sourceFile, this.declaringMethod); + declaringArkNamespace.addArkClass(anonymousClass); + } else { + const declaringArkFile = declaringArkClass.getDeclaringArkFile(); + buildNormalArkClassFromArkFile(objectLiteralExpression, declaringArkFile, anonymousClass, this.sourceFile, this.declaringMethod); + declaringArkFile.addArkClass(anonymousClass); + } + + const objectLiteralExpressionPosition = FullPosition.buildFromNode(objectLiteralExpression, this.sourceFile); + const stmts: Stmt[] = []; + const anonymousClassSignature = anonymousClass.getSignature(); + const anonymousClassType = new ClassType(anonymousClassSignature); + const newExpr = new ArkNewExpr(anonymousClassType); + const { + value: newExprLocal, + valueOriginalPositions: newExprLocalPositions, + stmts: newExprStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, [objectLiteralExpressionPosition]); + newExprStmts.forEach(stmt => stmts.push(stmt)); + + const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(CONSTRUCTOR_NAME); + const constructorMethodSignature = new MethodSignature(anonymousClassSignature, constructorMethodSubSignature); + const constructorInvokeExpr = new ArkInstanceInvokeExpr(newExprLocal as Local, constructorMethodSignature, []); + const constructorInvokeExprPositions = [objectLiteralExpressionPosition, ...newExprLocalPositions]; + const constructorInvokeStmt = new ArkInvokeStmt(constructorInvokeExpr); + constructorInvokeStmt.setOperandOriginalPositions(constructorInvokeExprPositions); + stmts.push(constructorInvokeStmt); + return { + value: newExprLocal, + valueOriginalPositions: newExprLocalPositions, + stmts: stmts, + }; + } + + private generateSystemComponentStmt( + componentName: string, + args: Value[], + argPositionsAllFlat: FullPosition[], + componentExpression: ts.EtsComponentExpression | ts.CallExpression, + currStmts: Stmt[] + ): ValueAndStmts { + const stmts: Stmt[] = [...currStmts]; + const componentExpressionPosition = FullPosition.buildFromNode(componentExpression, this.sourceFile); + const { + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: componentStmts, + } = this.generateComponentCreationStmts(componentName, args, componentExpressionPosition, argPositionsAllFlat); + componentStmts.forEach(stmt => stmts.push(stmt)); + + if (ts.isEtsComponentExpression(componentExpression) && componentExpression.body) { + for (const statement of componentExpression.body.statements) { + this.arkIRTransformer.tsNodeToStmts(statement).forEach(stmt => stmts.push(stmt)); + } + } + stmts.push(this.generateComponentPopStmts(componentName, componentExpressionPosition)); + return { + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: stmts, + }; + } + + private generateCustomViewStmt( + componentName: string, + args: Value[], + argPositionsAllFlat: FullPosition[], + componentExpression: ts.EtsComponentExpression | ts.CallExpression, + currStmts: Stmt[] + ): ValueAndStmts { + const stmts: Stmt[] = [...currStmts]; + const componentExpressionPosition = FullPosition.buildFromNode(componentExpression, this.sourceFile); + const classSignature = ArkSignatureBuilder.buildClassSignatureFromClassName(componentName); + const classType = new ClassType(classSignature); + const newExpr = new ArkNewExpr(classType); + const { + value: newExprLocal, + valueOriginalPositions: newExprPositions, + stmts: newExprStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, [componentExpressionPosition]); + newExprStmts.forEach(stmt => stmts.push(stmt)); + const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(CONSTRUCTOR_NAME); + const constructorMethodSignature = new MethodSignature(classSignature, constructorMethodSubSignature); + const instanceInvokeExpr = new ArkInstanceInvokeExpr(newExprLocal as Local, constructorMethodSignature, args); + const instanceInvokeExprPositions = [componentExpressionPosition, ...newExprPositions, ...argPositionsAllFlat]; + const instanceInvokeStmt = new ArkInvokeStmt(instanceInvokeExpr); + instanceInvokeStmt.setOperandOriginalPositions(instanceInvokeExprPositions); + stmts.push(instanceInvokeStmt); + const createViewArgs = [newExprLocal]; + const createViewArgPositionsAll = [newExprPositions]; + if (ts.isEtsComponentExpression(componentExpression) && componentExpression.body) { + const anonymous = ts.factory.createArrowFunction([], [], [], undefined, undefined, componentExpression.body); + // @ts-expect-error: add pos info for the created ArrowFunction + anonymous.pos = componentExpression.body.pos; + // @ts-expect-error: add end info for the created ArrowFunction + anonymous.end = componentExpression.body.end; + const { value: builderMethod, valueOriginalPositions: builderMethodPositions } = this.callableNodeToValueAndStmts(anonymous); + createViewArgs.push(builderMethod); + createViewArgPositionsAll.push(builderMethodPositions); + } + const { + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: componentStmts, + } = this.generateComponentCreationStmts(COMPONENT_CUSTOMVIEW, createViewArgs, componentExpressionPosition, createViewArgPositionsAll.flat()); + componentStmts.forEach(stmt => stmts.push(stmt)); + stmts.push(this.generateComponentPopStmts(COMPONENT_CUSTOMVIEW, componentExpressionPosition)); + return { + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: stmts, + }; + } + + private generateComponentCreationStmts( + componentName: string, + createArgs: Value[], + componentExpressionPosition: FullPosition, + createArgsPositionsAllFlat: FullPosition[] + ): ValueAndStmts { + const createMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(componentName, COMPONENT_CREATE_FUNCTION); + const createInvokeExpr = new ArkStaticInvokeExpr(createMethodSignature, createArgs); + const createInvokeExprPositions = [componentExpressionPosition, ...createArgsPositionsAllFlat]; + const { + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: componentStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(createInvokeExpr, createInvokeExprPositions); + return { + value: componentValue, + valueOriginalPositions: componentPositions, + stmts: componentStmts, + }; + } + + private generateComponentPopStmts(componentName: string, componentExpressionPosition: FullPosition): Stmt { + const popMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(componentName, COMPONENT_POP_FUNCTION); + const popInvokeExpr = new ArkStaticInvokeExpr(popMethodSignature, []); + const popInvokeExprPositions = [componentExpressionPosition]; + const popInvokeStmt = new ArkInvokeStmt(popInvokeExpr); + popInvokeStmt.setOperandOriginalPositions(popInvokeExprPositions); + return popInvokeStmt; + } + + private etsComponentExpressionToValueAndStmts(etsComponentExpression: ts.EtsComponentExpression): ValueAndStmts { + const stmts: Stmt[] = []; + const componentName = (etsComponentExpression.expression as ts.Identifier).text; + const { args: args, argPositions: argPositions } = this.parseArguments(stmts, etsComponentExpression.arguments); + if (isEtsSystemComponent(componentName)) { + return this.generateSystemComponentStmt(componentName, args, argPositions, etsComponentExpression, stmts); + } + return this.generateCustomViewStmt(componentName, args, argPositions, etsComponentExpression, stmts); + } + + private classExpressionToValueAndStmts(classExpression: ts.ClassExpression): ValueAndStmts { + const declaringArkClass = this.declaringMethod.getDeclaringArkClass(); + const declaringArkNamespace = declaringArkClass.getDeclaringArkNamespace(); + const newClass = new ArkClass(); + if (declaringArkNamespace) { + buildNormalArkClassFromArkNamespace(classExpression, declaringArkNamespace, newClass, this.sourceFile, this.declaringMethod); + declaringArkNamespace.addArkClass(newClass); + } else { + const declaringArkFile = declaringArkClass.getDeclaringArkFile(); + buildNormalArkClassFromArkFile(classExpression, declaringArkFile, newClass, this.sourceFile, this.declaringMethod); + declaringArkFile.addArkClass(newClass); + } + const classValue = this.addNewLocal(newClass.getName(), new ClassType(newClass.getSignature())); + return { + value: classValue, + valueOriginalPositions: [FullPosition.buildFromNode(classExpression, this.sourceFile)], + stmts: [], + }; + } + + private templateExpressionToValueAndStmts(templateExpression: ts.TemplateExpression): ValueAndStmts { + const { stmts, stringTextValues, placeholderValues, stringTextPositions, placeholderPositions } = this.collectTemplateValues(templateExpression); + + const { placeholderStringLocals, placeholderStringLocalPositions, newStmts } = this.processTemplatePlaceholders( + placeholderValues, + placeholderPositions, + stmts + ); + + return this.combineTemplateParts(stringTextValues, stringTextPositions, placeholderStringLocals, placeholderStringLocalPositions, newStmts); + } + + private processTemplatePlaceholders( + placeholderValues: Value[], + placeholderPositions: FullPosition[], + currStmts: Stmt[] + ): { + placeholderStringLocals: Local[]; + placeholderStringLocalPositions: FullPosition[]; + newStmts: Stmt[]; + } { + const placeholderStringLocals: Local[] = []; + const placeholderStringLocalPositions: FullPosition[] = []; + const newStmts: Stmt[] = [...currStmts]; + + for (let i = 0; i < placeholderValues.length; i++) { + let placeholderValue = placeholderValues[i]; + let placeholderPosition: FullPosition[] = [placeholderPositions[i]]; + let placeholderStmts: Stmt[] = []; + + if (!(placeholderValue instanceof Local)) { + ({ + value: placeholderValue, + valueOriginalPositions: placeholderPosition, + stmts: placeholderStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(placeholderValue, placeholderPosition)); + } + + placeholderStmts.forEach(stmt => newStmts.push(stmt)); + const toStringExpr = new ArkInstanceInvokeExpr(placeholderValue as Local, Builtin.TO_STRING_METHOD_SIGNATURE, []); + const toStringExprPosition: FullPosition[] = [placeholderPosition[0], placeholderPosition[0]]; + const { + value: placeholderStringLocal, + valueOriginalPositions: placeholderStringPositions, + stmts: toStringStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(toStringExpr, toStringExprPosition); + placeholderStringLocals.push(placeholderStringLocal as Local); + placeholderStringLocalPositions.push(placeholderStringPositions[0]); + toStringStmts.forEach(stmt => newStmts.push(stmt)); + } + + return { + placeholderStringLocals, + placeholderStringLocalPositions, + newStmts, + }; + } + + private combineTemplateParts( + stringTextValues: Value[], + stringTextPositions: FullPosition[], + placeholderStringLocals: Local[], + placeholderStringLocalPositions: FullPosition[], + currStmts: Stmt[] + ): ValueAndStmts { + const templateParts: Value[] = []; + const templatePartPositions: FullPosition[] = []; + + for (let i = 0; i < placeholderStringLocals.length; i++) { + if (stringTextValues[i] !== ValueUtil.EMPTY_STRING_CONSTANT) { + templateParts.push(stringTextValues[i]); + templatePartPositions.push(stringTextPositions[i]); + } + templateParts.push(placeholderStringLocals[i]); + templatePartPositions.push(placeholderStringLocalPositions[i]); + } + + if (stringTextValues[stringTextValues.length - 1] !== ValueUtil.EMPTY_STRING_CONSTANT) { + templateParts.push(stringTextValues[stringTextValues.length - 1]); + templatePartPositions.push(stringTextPositions[stringTextPositions.length - 1]); + } + + let currTemplateResult: Value = templateParts[0]; + let currTemplateResultPosition: FullPosition = templatePartPositions[0]; + const finalStmts: Stmt[] = [...currStmts]; + + for (let i = 1; i < templateParts.length; i++) { + const nextTemplatePartPosition = templatePartPositions[i]; + const normalBinopExpr = new ArkNormalBinopExpr(currTemplateResult, templateParts[i], NormalBinaryOperator.Addition); + const normalBinopExprPositions = [ + FullPosition.merge(currTemplateResultPosition, nextTemplatePartPosition), + currTemplateResultPosition, + nextTemplatePartPosition, + ]; + const { + value: combinationValue, + valueOriginalPositions: combinationValuePositions, + stmts: combinationStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(normalBinopExpr, normalBinopExprPositions); + combinationStmts.forEach(stmt => finalStmts.push(stmt)); + currTemplateResult = combinationValue; + currTemplateResultPosition = combinationValuePositions[0]; + } + + return { + value: currTemplateResult, + valueOriginalPositions: [currTemplateResultPosition], + stmts: finalStmts, + }; + } + + private taggedTemplateExpressionToValueAndStmts(taggedTemplateExpression: ts.TaggedTemplateExpression): ValueAndStmts { + const { stmts, stringTextValues, placeholderValues, stringTextPositions, placeholderPositions } = this.collectTemplateValues( + taggedTemplateExpression.template + ); + const stringTextBaseType = StringType.getInstance(); + const stringTextArrayLen = stringTextValues.length; + const stringTextArrayLenValue = ValueUtil.getOrCreateNumberConst(stringTextArrayLen); + const stringTextArrayLenPosition = FullPosition.DEFAULT; + const { + value: templateObjectLocal, + valueOriginalPositions: templateObjectLocalPositions, + stmts: templateObjectStmts, + } = this.generateArrayExprAndStmts( + stringTextBaseType, + stringTextArrayLenValue, + stringTextArrayLenPosition, + stringTextArrayLen, + stringTextValues, + stringTextPositions, + stmts, + FullPosition.DEFAULT, + true + ); + + const placeholderBaseType = AnyType.getInstance(); + const placeholdersArrayLen = placeholderValues.length; + const placeholdersArrayLenValue = ValueUtil.getOrCreateNumberConst(placeholdersArrayLen); + const placeholdersArrayLenPosition = FullPosition.DEFAULT; + const { + value: placeholdersLocal, + valueOriginalPositions: placeholdersLocalPositions, + stmts: placeholdersStmts, + } = this.generateArrayExprAndStmts( + placeholderBaseType, + placeholdersArrayLenValue, + placeholdersArrayLenPosition, + placeholdersArrayLen, + placeholderValues, + placeholderPositions, + templateObjectStmts, + FullPosition.DEFAULT, + true + ); + + const taggedFuncArgus = { + realGenericTypes: undefined, + args: [templateObjectLocal, placeholdersLocal], + argPositions: [templateObjectLocalPositions[0], placeholdersLocalPositions[0]], + }; + return this.generateInvokeValueAndStmts(taggedTemplateExpression.tag, taggedFuncArgus, placeholdersStmts, taggedTemplateExpression); + } + + private collectTemplateValues(templateLiteral: ts.TemplateLiteral): { + stmts: Stmt[]; + stringTextValues: Value[]; + placeholderValues: Value[]; + stringTextPositions: FullPosition[]; + placeholderPositions: FullPosition[]; + } { + const stmts: Stmt[] = []; + if (ts.isNoSubstitutionTemplateLiteral(templateLiteral)) { + const templateLiteralString = templateLiteral.getText(this.sourceFile); + return { + stmts: [], + stringTextValues: [ValueUtil.createStringConst(templateLiteralString)], + placeholderValues: [], + stringTextPositions: [FullPosition.buildFromNode(templateLiteral, this.sourceFile)], + placeholderPositions: [], + }; + } + const head = templateLiteral.head; + const stringTextValues: Value[] = [ValueUtil.createStringConst(head.rawText || '')]; + const placeholderValues: Value[] = []; + const stringTextPositions: FullPosition[] = [FullPosition.buildFromNode(head, this.sourceFile)]; + const placeholderPositions: FullPosition[] = []; + for (const templateSpan of templateLiteral.templateSpans) { + let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(templateSpan.expression); + exprStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(exprValue)) { + ({ + value: exprValue, + valueOriginalPositions: exprPositions, + stmts: exprStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions)); + exprStmts.forEach(stmt => stmts.push(stmt)); + } + placeholderValues.push(exprValue); + placeholderPositions.push(exprPositions[0]); + stringTextPositions.push(FullPosition.buildFromNode(templateSpan.literal, this.sourceFile)); + stringTextValues.push(ValueUtil.createStringConst(templateSpan.literal.rawText || '')); + } + return { + stmts, + stringTextValues, + placeholderValues, + stringTextPositions, + placeholderPositions, + }; + } + + private identifierToValueAndStmts(identifier: ts.Identifier, variableDefFlag: boolean = false): ValueAndStmts { + let identifierValue: Value; + let identifierPositions = [FullPosition.buildFromNode(identifier, this.sourceFile)]; + if (identifier.text === UndefinedType.getInstance().getName()) { + identifierValue = ValueUtil.getUndefinedConst(); + } else { + if (variableDefFlag) { + identifierValue = this.addNewLocal(identifier.text); + } else { + identifierValue = this.getOrCreateLocal(identifier.text); + } + } + return { + value: identifierValue, + valueOriginalPositions: identifierPositions, + stmts: [], + }; + } + + private propertyAccessExpressionToValue(propertyAccessExpression: ts.PropertyAccessExpression): ValueAndStmts { + const stmts: Stmt[] = []; + let { value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = this.tsNodeToValueAndStmts(propertyAccessExpression.expression); + baseStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(baseValue)) { + ({ + value: baseValue, + valueOriginalPositions: basePositions, + stmts: baseStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions)); + baseStmts.forEach(stmt => stmts.push(stmt)); + } + if (!(baseValue instanceof Local)) { + ({ + value: baseValue, + valueOriginalPositions: basePositions, + stmts: baseStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions)); + baseStmts.forEach(stmt => stmts.push(stmt)); + } + + const fieldRefPositions = [FullPosition.buildFromNode(propertyAccessExpression, this.sourceFile), ...basePositions]; + + // this if for the case: const obj: Object = Object.create(Object.prototype); + if (baseValue instanceof Local && baseValue.getName() === Builtin.OBJECT) { + this.locals.delete(baseValue.getName()); + const fieldSignature = new FieldSignature( + propertyAccessExpression.name.getText(this.sourceFile), + Builtin.OBJECT_CLASS_SIGNATURE, + UnknownType.getInstance(), + true + ); + const fieldRef = new ArkStaticFieldRef(fieldSignature); + return { + value: fieldRef, + valueOriginalPositions: fieldRefPositions, + stmts: stmts, + }; + } + + let fieldSignature: FieldSignature; + if (baseValue instanceof Local && baseValue.getType() instanceof ClassType) { + fieldSignature = new FieldSignature( + propertyAccessExpression.name.getText(this.sourceFile), + (baseValue.getType() as ClassType).getClassSignature(), + UnknownType.getInstance() + ); + } else { + fieldSignature = ArkSignatureBuilder.buildFieldSignatureFromFieldName(propertyAccessExpression.name.getText(this.sourceFile)); + } + const fieldRef = new ArkInstanceFieldRef(baseValue as Local, fieldSignature); + + return { + value: fieldRef, + valueOriginalPositions: fieldRefPositions, + stmts: stmts, + }; + } + + private elementAccessExpressionToValueAndStmts(elementAccessExpression: ts.ElementAccessExpression): ValueAndStmts { + const stmts: Stmt[] = []; + let { value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = this.tsNodeToValueAndStmts(elementAccessExpression.expression); + baseStmts.forEach(stmt => stmts.push(stmt)); + if (!(baseValue instanceof Local)) { + ({ + value: baseValue, + valueOriginalPositions: basePositions, + stmts: baseStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions)); + baseStmts.forEach(stmt => stmts.push(stmt)); + } + let { + value: argumentValue, + valueOriginalPositions: arguPositions, + stmts: argumentStmts, + } = this.tsNodeToValueAndStmts(elementAccessExpression.argumentExpression); + argumentStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(argumentValue)) { + ({ + value: argumentValue, + valueOriginalPositions: arguPositions, + stmts: argumentStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(argumentValue, arguPositions)); + argumentStmts.forEach(stmt => stmts.push(stmt)); + } + + let elementAccessExpr: Value; + if (baseValue.getType() instanceof ArrayType) { + elementAccessExpr = new ArkArrayRef(baseValue as Local, argumentValue); + } else { + // TODO: deal with ArkStaticFieldRef + const fieldSignature = ArkSignatureBuilder.buildFieldSignatureFromFieldName(argumentValue.toString()); + elementAccessExpr = new ArkInstanceFieldRef(baseValue as Local, fieldSignature); + } + // reserve positions for field name + const exprPositions = [FullPosition.buildFromNode(elementAccessExpression, this.sourceFile), ...basePositions, ...arguPositions]; + return { + value: elementAccessExpr, + valueOriginalPositions: exprPositions, + stmts: stmts, + }; + } + + private callExpressionToValueAndStmts(callExpression: ts.CallExpression): ValueAndStmts { + const stmts: Stmt[] = []; + const argus = this.parseArgumentsOfCallExpression(stmts, callExpression); + return this.generateInvokeValueAndStmts(callExpression.expression, argus, stmts, callExpression); + } + + private generateInvokeValueAndStmts( + functionNameNode: ts.LeftHandSideExpression, + argus: { + realGenericTypes: Type[] | undefined; + args: Value[]; + argPositions: FullPosition[]; + }, + currStmts: Stmt[], + callExpression: ts.CallExpression | ts.TaggedTemplateExpression + ): ValueAndStmts { + const stmts: Stmt[] = [...currStmts]; + let { value: callerValue, valueOriginalPositions: callerPositions, stmts: callerStmts } = this.tsNodeToValueAndStmts(functionNameNode); + callerStmts.forEach(stmt => stmts.push(stmt)); + + let invokeValue: Value; + let invokeValuePositions: FullPosition[] = [FullPosition.buildFromNode(callExpression, this.sourceFile)]; + const { args, argPositions, realGenericTypes } = argus; + if (callerValue instanceof AbstractFieldRef) { + let methodSignature: MethodSignature; + const declareSignature = callerValue.getFieldSignature().getDeclaringSignature(); + if (declareSignature instanceof ClassSignature) { + methodSignature = new MethodSignature(declareSignature, ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(callerValue.getFieldName())); + } else { + methodSignature = ArkSignatureBuilder.buildMethodSignatureFromMethodName(callerValue.getFieldName()); + } + if (callerValue instanceof ArkInstanceFieldRef) { + invokeValue = new ArkInstanceInvokeExpr(callerValue.getBase(), methodSignature, args, realGenericTypes); + invokeValuePositions.push(...callerPositions.slice(1)); + } else { + invokeValue = new ArkStaticInvokeExpr(methodSignature, args, realGenericTypes); + } + } else if (callerValue instanceof Local) { + const callerName = callerValue.getName(); + let classSignature = ArkSignatureBuilder.buildClassSignatureFromClassName(callerName); + let cls = ModelUtils.getClass(this.declaringMethod, classSignature); + if (cls?.hasComponentDecorator() && ts.isCallExpression(callExpression)) { + return this.generateCustomViewStmt(callerName, args, argPositions, callExpression, stmts); + } else if ((callerName === COMPONENT_FOR_EACH || callerName === COMPONENT_LAZY_FOR_EACH) && ts.isCallExpression(callExpression)) { + // foreach/lazyforeach will be parsed as ts.callExpression + return this.generateSystemComponentStmt(callerName, args, argPositions, callExpression, stmts); + } + const methodSignature = ArkSignatureBuilder.buildMethodSignatureFromMethodName(callerName); + if (callerValue.getType() instanceof FunctionType) { + invokeValue = new ArkPtrInvokeExpr(methodSignature, callerValue, args, realGenericTypes); + } else { + invokeValue = new ArkStaticInvokeExpr(methodSignature, args, realGenericTypes); + } + } else { + ({ + value: callerValue, + valueOriginalPositions: callerPositions, + stmts: callerStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(callerValue, callerPositions)); + callerStmts.forEach(stmt => stmts.push(stmt)); + const methodSignature = ArkSignatureBuilder.buildMethodSignatureFromMethodName((callerValue as Local).getName()); + invokeValue = new ArkStaticInvokeExpr(methodSignature, args, realGenericTypes); + } + invokeValuePositions.push(...argPositions); + return { + value: invokeValue, + valueOriginalPositions: invokeValuePositions, + stmts: stmts, + }; + } + + private parseArgumentsOfCallExpression( + currStmts: Stmt[], + callExpression: ts.CallExpression + ): { + realGenericTypes: Type[] | undefined; + args: Value[]; + argPositions: FullPosition[]; + } { + let realGenericTypes: Type[] | undefined; + if (callExpression.typeArguments) { + realGenericTypes = []; + callExpression.typeArguments.forEach(typeArgument => { + realGenericTypes!.push(this.resolveTypeNode(typeArgument)); + }); + } + + let builderMethodIndexes: Set | undefined; + if (ts.isIdentifier(callExpression.expression)) { + const callerName = callExpression.expression.text; + if (callerName === COMPONENT_FOR_EACH || callerName === COMPONENT_LAZY_FOR_EACH) { + builderMethodIndexes = new Set([1]); + } + } + const { args: args, argPositions: argPositions } = this.parseArguments(currStmts, callExpression.arguments, builderMethodIndexes); + return { + realGenericTypes: realGenericTypes, + args: args, + argPositions: argPositions, + }; + } + + private parseArguments( + currStmts: Stmt[], + argumentNodes?: ts.NodeArray, + builderMethodIndexes?: Set + ): { + args: Value[]; + argPositions: FullPosition[]; + } { + const args: Value[] = []; + const argPositions: FullPosition[] = []; + if (argumentNodes) { + for (let i = 0; i < argumentNodes.length; i++) { + const argument = argumentNodes[i]; + const prevBuilderMethodContextFlag = this.builderMethodContextFlag; + if (builderMethodIndexes?.has(i)) { + this.builderMethodContextFlag = true; + this.arkIRTransformer.setBuilderMethodContextFlag(true); + } + let { value: argValue, valueOriginalPositions: argPositionsSingle, stmts: argStmts } = this.tsNodeToValueAndStmts(argument); + this.builderMethodContextFlag = prevBuilderMethodContextFlag; + this.arkIRTransformer.setBuilderMethodContextFlag(prevBuilderMethodContextFlag); + argStmts.forEach(s => currStmts.push(s)); + if (IRUtils.moreThanOneAddress(argValue)) { + ({ + value: argValue, + valueOriginalPositions: argPositionsSingle, + stmts: argStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(argValue, argPositionsSingle)); + argStmts.forEach(s => currStmts.push(s)); + } + args.push(argValue); + argPositions.push(argPositionsSingle[0]); + } + } + return { args: args, argPositions: argPositions }; + } + + private callableNodeToValueAndStmts(callableNode: ts.ArrowFunction | ts.FunctionExpression): ValueAndStmts { + const declaringClass = this.declaringMethod.getDeclaringArkClass(); + const arrowArkMethod = new ArkMethod(); + if (this.builderMethodContextFlag) { + ModelUtils.implicitArkUIBuilderMethods.add(arrowArkMethod); + } + buildArkMethodFromArkClass(callableNode, declaringClass, arrowArkMethod, this.sourceFile, this.declaringMethod); + + const callableType = new FunctionType(arrowArkMethod.getSignature()); + const callableValue = this.addNewLocal(arrowArkMethod.getName(), callableType); + return { + value: callableValue, + valueOriginalPositions: [FullPosition.buildFromNode(callableNode, this.sourceFile)], + stmts: [], + }; + } + + private newExpressionToValueAndStmts(newExpression: ts.NewExpression): ValueAndStmts { + let className = ''; + if (ts.isClassExpression(newExpression.expression) && newExpression.expression.name) { + className = newExpression.expression.name.text; + } else { + className = newExpression.expression.getText(this.sourceFile); + } + if (className === Builtin.ARRAY) { + return this.newArrayExpressionToValueAndStmts(newExpression); + } + + const stmts: Stmt[] = []; + let realGenericTypes: Type[] | undefined; + if (newExpression.typeArguments) { + realGenericTypes = []; + newExpression.typeArguments.forEach(typeArgument => { + realGenericTypes!.push(this.resolveTypeNode(typeArgument)); + }); + } + + let classSignature = ArkSignatureBuilder.buildClassSignatureFromClassName(className); + let classType = new ClassType(classSignature, realGenericTypes); + if (className === Builtin.OBJECT) { + classSignature = Builtin.OBJECT_CLASS_SIGNATURE; + classType = Builtin.OBJECT_CLASS_TYPE; + } + + const newExpr = new ArkNewExpr(classType); + const { + value: newLocal, + valueOriginalPositions: newLocalPositions, + stmts: newExprStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, [FullPosition.buildFromNode(newExpression, this.sourceFile)]); + newExprStmts.forEach(stmt => stmts.push(stmt)); + + const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(CONSTRUCTOR_NAME); + const constructorMethodSignature = new MethodSignature(classSignature, constructorMethodSubSignature); + + const { args: argValues, argPositions: argPositions } = this.parseArguments(stmts, newExpression.arguments); + const instanceInvokeExpr = new ArkInstanceInvokeExpr(newLocal as Local, constructorMethodSignature, argValues); + const instanceInvokeExprPositions = [newLocalPositions[0], ...newLocalPositions, ...argPositions]; + const invokeStmt = new ArkInvokeStmt(instanceInvokeExpr); + invokeStmt.setOperandOriginalPositions(instanceInvokeExprPositions); + stmts.push(invokeStmt); + return { + value: newLocal, + valueOriginalPositions: newLocalPositions, + stmts: stmts, + }; + } + + private newArrayExpressionToValueAndStmts(newArrayExpression: ts.NewExpression): ValueAndStmts { + let baseType: Type = UnknownType.getInstance(); + if (newArrayExpression.typeArguments && newArrayExpression.typeArguments.length > 0) { + const argumentType = this.resolveTypeNode(newArrayExpression.typeArguments[0]); + if (!(argumentType instanceof AnyType || argumentType instanceof UnknownType)) { + baseType = argumentType; + } + } + const stmts: Stmt[] = []; + const { args: argumentValues, argPositions: argPositions } = this.parseArguments(stmts, newArrayExpression.arguments); + let argumentsLength = newArrayExpression.arguments ? newArrayExpression.arguments.length : 0; + let arrayLengthValue: Value; + let arrayLength = -1; + let arrayLengthPosition = FullPosition.DEFAULT; + if (argumentsLength === 1 && (argumentValues[0].getType() instanceof NumberType || argumentValues[0].getType() instanceof UnknownType)) { + arrayLengthValue = argumentValues[0]; + arrayLengthPosition = argPositions[0]; + } else { + arrayLengthValue = ValueUtil.getOrCreateNumberConst(argumentsLength); + arrayLength = argumentsLength; + } + if (baseType instanceof UnknownType) { + if (argumentsLength > 1 && !(argumentValues[0].getType() instanceof UnknownType)) { + baseType = argumentValues[0].getType(); + } else { + baseType = AnyType.getInstance(); + } + } + const newArrayExprPosition = FullPosition.buildFromNode(newArrayExpression, this.sourceFile); + return this.generateArrayExprAndStmts( + baseType, + arrayLengthValue, + arrayLengthPosition, + arrayLength, + argumentValues, + argPositions, + stmts, + newArrayExprPosition, + false + ); + } + + private arrayLiteralExpressionToValueAndStmts(arrayLiteralExpression: ts.ArrayLiteralExpression): ValueAndStmts { + const stmts: Stmt[] = []; + const elementTypes: Set = new Set(); + const elementValues: Value[] = []; + const elementPositions: FullPosition[] = []; + const arrayLength = arrayLiteralExpression.elements.length; + for (const element of arrayLiteralExpression.elements) { + let { value: elementValue, valueOriginalPositions: elementPosition, stmts: elementStmts } = this.tsNodeToValueAndStmts(element); + elementStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(elementValue)) { + ({ + value: elementValue, + valueOriginalPositions: elementPosition, + stmts: elementStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(elementValue, elementPosition)); + elementStmts.forEach(stmt => stmts.push(stmt)); + } + elementValues.push(elementValue); + elementTypes.add(elementValue.getType()); + elementPositions.push(elementPosition[0]); + } + + let baseType: Type = AnyType.getInstance(); + if (elementTypes.size === 1) { + baseType = elementTypes.keys().next().value as Type; + } else if (elementTypes.size > 1) { + baseType = new UnionType(Array.from(elementTypes)); + } + const newArrayExprPosition = FullPosition.buildFromNode(arrayLiteralExpression, this.sourceFile); + return this.generateArrayExprAndStmts( + baseType, + ValueUtil.getOrCreateNumberConst(arrayLength), + FullPosition.DEFAULT, + arrayLength, + elementValues, + elementPositions, + stmts, + newArrayExprPosition, + true + ); + } + + private generateArrayExprAndStmts( + baseType: Type, + arrayLengthValue: Value, + arrayLengthPosition: FullPosition, + arrayLength: number, + initializerValues: Value[], + initializerPositions: FullPosition[], + currStmts: Stmt[], + newArrayExprPosition: FullPosition, + fromLiteral: boolean + ): ValueAndStmts { + const stmts: Stmt[] = [...currStmts]; + const newArrayExpr = new ArkNewArrayExpr(baseType, arrayLengthValue, fromLiteral); + const newArrayExprPositions = [newArrayExprPosition, arrayLengthPosition]; + const { + value: arrayLocal, + valueOriginalPositions: arrayLocalPositions, + stmts: arrayStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(newArrayExpr, newArrayExprPositions); + arrayStmts.forEach(stmt => stmts.push(stmt)); + for (let i = 0; i < arrayLength; i++) { + const indexValue = ValueUtil.getOrCreateNumberConst(i); + const arrayRef = new ArkArrayRef(arrayLocal as Local, indexValue); + const arrayRefPositions = [arrayLocalPositions[0], ...arrayLocalPositions, FullPosition.DEFAULT]; + const assignStmt = new ArkAssignStmt(arrayRef, initializerValues[i]); + assignStmt.setOperandOriginalPositions([...arrayRefPositions, initializerPositions[i]]); + stmts.push(assignStmt); + } + return { + value: arrayLocal, + valueOriginalPositions: arrayLocalPositions, + stmts: stmts, + }; + } + + private prefixUnaryExpressionToValueAndStmts(prefixUnaryExpression: ts.PrefixUnaryExpression): ValueAndStmts { + const stmts: Stmt[] = []; + let { value: operandValue, valueOriginalPositions: operandPositions, stmts: operandStmts } = this.tsNodeToValueAndStmts(prefixUnaryExpression.operand); + operandStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(operandValue)) { + ({ + value: operandValue, + valueOriginalPositions: operandPositions, + stmts: operandStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(operandValue, operandPositions)); + operandStmts.forEach(stmt => stmts.push(stmt)); + } + + const operatorToken = prefixUnaryExpression.operator; + let exprPositions = [FullPosition.buildFromNode(prefixUnaryExpression, this.sourceFile)]; + if (operatorToken === ts.SyntaxKind.PlusPlusToken || operatorToken === ts.SyntaxKind.MinusMinusToken) { + const binaryOperator = operatorToken === ts.SyntaxKind.PlusPlusToken ? NormalBinaryOperator.Addition : NormalBinaryOperator.Subtraction; + const binopExpr = new ArkNormalBinopExpr(operandValue, ValueUtil.getOrCreateNumberConst(1), binaryOperator); + exprPositions.push(...operandPositions, FullPosition.DEFAULT); + const assignStmt = new ArkAssignStmt(operandValue, binopExpr); + assignStmt.setOperandOriginalPositions([...operandPositions, ...exprPositions]); + stmts.push(assignStmt); + return { + value: operandValue, + valueOriginalPositions: operandPositions, + stmts: stmts, + }; + } else if (operatorToken === ts.SyntaxKind.PlusToken) { + return { + value: operandValue, + valueOriginalPositions: operandPositions, + stmts: stmts, + }; + } else { + let unopExpr: Value; + const operator = ArkIRTransformer.tokenToUnaryOperator(operatorToken); + if (operator) { + unopExpr = new ArkUnopExpr(operandValue, operator); + exprPositions.push(...operandPositions); + } else { + unopExpr = ValueUtil.getUndefinedConst(); + exprPositions = [FullPosition.DEFAULT]; + } + return { + value: unopExpr, + valueOriginalPositions: exprPositions, + stmts: stmts, + }; + } + } + + private postfixUnaryExpressionToValueAndStmts(postfixUnaryExpression: ts.PostfixUnaryExpression): ValueAndStmts { + const stmts: Stmt[] = []; + let { value: operandValue, valueOriginalPositions: operandPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(postfixUnaryExpression.operand); + exprStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(operandValue)) { + ({ + value: operandValue, + valueOriginalPositions: operandPositions, + stmts: exprStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(operandValue, operandPositions)); + exprStmts.forEach(stmt => stmts.push(stmt)); + } + + let value: Value; + let exprPositions = [FullPosition.buildFromNode(postfixUnaryExpression, this.sourceFile)]; + const operatorToken = postfixUnaryExpression.operator; + if (operatorToken === ts.SyntaxKind.PlusPlusToken || operatorToken === ts.SyntaxKind.MinusMinusToken) { + const binaryOperator = operatorToken === ts.SyntaxKind.PlusPlusToken ? NormalBinaryOperator.Addition : NormalBinaryOperator.Subtraction; + const binopExpr = new ArkNormalBinopExpr(operandValue, ValueUtil.getOrCreateNumberConst(1), binaryOperator); + exprPositions.push(...operandPositions, FullPosition.DEFAULT); + const assignStmt = new ArkAssignStmt(operandValue, binopExpr); + assignStmt.setOperandOriginalPositions([...operandPositions, ...exprPositions]); + stmts.push(assignStmt); + value = operandValue; + } else { + value = ValueUtil.getUndefinedConst(); + exprPositions = [FullPosition.DEFAULT]; + } + + return { + value: value, + valueOriginalPositions: exprPositions, + stmts: stmts, + }; + } + + private awaitExpressionToValueAndStmts(awaitExpression: ts.AwaitExpression): ValueAndStmts { + const stmts: Stmt[] = []; + let { value: promiseValue, valueOriginalPositions: promisePositions, stmts: promiseStmts } = this.tsNodeToValueAndStmts(awaitExpression.expression); + promiseStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(promiseValue)) { + ({ + value: promiseValue, + valueOriginalPositions: promisePositions, + stmts: promiseStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(promiseValue, promisePositions)); + promiseStmts.forEach(stmt => stmts.push(stmt)); + } + const awaitExpr = new ArkAwaitExpr(promiseValue); + const awaitExprPositions = [FullPosition.buildFromNode(awaitExpression, this.sourceFile), ...promisePositions]; + return { + value: awaitExpr, + valueOriginalPositions: awaitExprPositions, + stmts: stmts, + }; + } + + private yieldExpressionToValueAndStmts(yieldExpression: ts.YieldExpression): ValueAndStmts { + let yieldValue: Value = ValueUtil.getUndefinedConst(); + let yieldPositions = [FullPosition.DEFAULT]; + let stmts: Stmt[] = []; + if (yieldExpression.expression) { + ({ value: yieldValue, valueOriginalPositions: yieldPositions, stmts: stmts } = this.tsNodeToValueAndStmts(yieldExpression.expression)); + } + + const yieldExpr = new ArkYieldExpr(yieldValue); + const yieldExprPositions = [FullPosition.buildFromNode(yieldExpression, this.sourceFile), ...yieldPositions]; + return { + value: yieldExpr, + valueOriginalPositions: yieldExprPositions, + stmts: stmts, + }; + } + + private deleteExpressionToValueAndStmts(deleteExpression: ts.DeleteExpression): ValueAndStmts { + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts(deleteExpression.expression); + const deleteExpr = new ArkDeleteExpr(exprValue as AbstractFieldRef); + const deleteExprPositions = [FullPosition.buildFromNode(deleteExpression, this.sourceFile), ...exprPositions]; + return { + value: deleteExpr, + valueOriginalPositions: deleteExprPositions, + stmts: stmts, + }; + } + + private voidExpressionToValueAndStmts(voidExpression: ts.VoidExpression): ValueAndStmts { + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts(voidExpression.expression); + const { stmts: exprStmts } = this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions); + exprStmts.forEach(stmt => stmts.push(stmt)); + return { + value: ValueUtil.getUndefinedConst(), + valueOriginalPositions: [FullPosition.DEFAULT], + stmts: stmts, + }; + } + + private nonNullExpressionToValueAndStmts(nonNullExpression: ts.NonNullExpression): ValueAndStmts { + return this.tsNodeToValueAndStmts(nonNullExpression.expression); + } + + private parenthesizedExpressionToValueAndStmts(parenthesizedExpression: ts.ParenthesizedExpression): ValueAndStmts { + return this.tsNodeToValueAndStmts(parenthesizedExpression.expression); + } + + private typeOfExpressionToValueAndStmts(typeOfExpression: ts.TypeOfExpression): ValueAndStmts { + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(typeOfExpression.expression); + const typeOfExpr = new ArkTypeOfExpr(exprValue); + const typeOfExprPositions = [FullPosition.buildFromNode(typeOfExpression, this.sourceFile), ...exprPositions]; + return { + value: typeOfExpr, + valueOriginalPositions: typeOfExprPositions, + stmts: exprStmts, + }; + } + + private asExpressionToValueAndStmts(asExpression: ts.AsExpression): ValueAndStmts { + const stmts: Stmt[] = []; + let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(asExpression.expression); + exprStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(exprValue)) { + ({ + value: exprValue, + valueOriginalPositions: exprPositions, + stmts: exprStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions)); + exprStmts.forEach(stmt => stmts.push(stmt)); + } + const castExpr = new ArkCastExpr(exprValue, this.resolveTypeNode(asExpression.type)); + const castExprPositions = [FullPosition.buildFromNode(asExpression, this.sourceFile), ...exprPositions]; + return { + value: castExpr, + valueOriginalPositions: castExprPositions, + stmts: stmts, + }; + } + + private typeAssertionToValueAndStmts(typeAssertion: ts.TypeAssertion): ValueAndStmts { + const { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(typeAssertion.expression); + const castExpr = new ArkCastExpr(exprValue, this.resolveTypeNode(typeAssertion.type)); + const castExprPositions = [FullPosition.buildFromNode(typeAssertion, this.sourceFile), ...exprPositions]; + return { + value: castExpr, + valueOriginalPositions: castExprPositions, + stmts: exprStmts, + }; + } + + public variableDeclarationListToValueAndStmts(variableDeclarationList: ts.VariableDeclarationList): ValueAndStmts { + const stmts: Stmt[] = []; + const isConst = (variableDeclarationList.flags & ts.NodeFlags.Const) !== 0; + for (const declaration of variableDeclarationList.declarations) { + const { stmts: declaredStmts } = this.variableDeclarationToValueAndStmts(declaration, isConst); + declaredStmts.forEach(s => stmts.push(s)); + } + return { + value: ValueUtil.getUndefinedConst(), + valueOriginalPositions: [FullPosition.DEFAULT], + stmts: stmts, + }; + } + + public variableDeclarationToValueAndStmts(variableDeclaration: ts.VariableDeclaration, isConst: boolean, needRightOp: boolean = true): ValueAndStmts { + const leftOpNode = variableDeclaration.name; + const rightOpNode = variableDeclaration.initializer; + const declarationType = variableDeclaration.type ? this.resolveTypeNode(variableDeclaration.type) : UnknownType.getInstance(); + return this.assignmentToValueAndStmts(leftOpNode, rightOpNode, true, isConst, declarationType, needRightOp); + } + + private assignmentToValueAndStmts( + leftOpNode: ts.Node, + rightOpNode: ts.Node | undefined, + variableDefFlag: boolean, + isConst: boolean, + declarationType: Type, + needRightOp: boolean = true + ): ValueAndStmts { + let leftValueAndStmts: ValueAndStmts; + if (ts.isIdentifier(leftOpNode)) { + leftValueAndStmts = this.identifierToValueAndStmts(leftOpNode, variableDefFlag); + } else if (ts.isArrayBindingPattern(leftOpNode) || ts.isArrayLiteralExpression(leftOpNode)) { + leftValueAndStmts = this.arrayDestructuringToValueAndStmts(leftOpNode, isConst); + } else if (ts.isObjectBindingPattern(leftOpNode) || ts.isObjectLiteralExpression(leftOpNode)) { + leftValueAndStmts = this.objectDestructuringToValueAndStmts(leftOpNode, isConst); + } else { + leftValueAndStmts = this.tsNodeToValueAndStmts(leftOpNode); + } + const { value: leftValue, valueOriginalPositions: leftPositions, stmts: leftStmts } = leftValueAndStmts; + + let stmts: Stmt[] = []; + if (needRightOp) { + const { + value: rightValue, + valueOriginalPositions: rightPositions, + stmts: rightStmts, + } = this.assignmentRightOpToValueAndStmts(rightOpNode, leftValue); + if (leftValue instanceof Local) { + if (variableDefFlag) { + leftValue.setConstFlag(isConst); + leftValue.setType(declarationType); + } + if ( + leftValue.getType() instanceof UnknownType && + !(rightValue.getType() instanceof UnknownType) && + !(rightValue.getType() instanceof UndefinedType) + ) { + leftValue.setType(rightValue.getType()); + } + } + const assignStmt = new ArkAssignStmt(leftValue, rightValue); + assignStmt.setOperandOriginalPositions([...leftPositions, ...rightPositions]); + if ( + ts.isArrayBindingPattern(leftOpNode) || + ts.isArrayLiteralExpression(leftOpNode) || + ts.isObjectBindingPattern(leftOpNode) || + ts.isObjectLiteralExpression(leftOpNode) + ) { + rightStmts.forEach(stmt => stmts.push(stmt)); + stmts.push(assignStmt); + leftStmts.forEach(stmt => stmts.push(stmt)); + } else { + rightStmts.forEach(stmt => stmts.push(stmt)); + leftStmts.forEach(stmt => stmts.push(stmt)); + stmts.push(assignStmt); + } + } else { + stmts = leftStmts; + } + return { + value: leftValue, + valueOriginalPositions: leftPositions, + stmts: stmts, + }; + } + + private assignmentRightOpToValueAndStmts(rightOpNode: ts.Node | undefined, leftValue: Value): ValueAndStmts { + let rightValue: Value; + let rightPositions: FullPosition[]; + let tempRightStmts: Stmt[] = []; + const rightStmts: Stmt[] = []; + if (rightOpNode) { + ({ value: rightValue, valueOriginalPositions: rightPositions, stmts: tempRightStmts } = this.tsNodeToValueAndStmts(rightOpNode)); + tempRightStmts.forEach(stmt => rightStmts.push(stmt)); + } else { + rightValue = ValueUtil.getUndefinedConst(); + rightPositions = [FullPosition.DEFAULT]; + } + if (IRUtils.moreThanOneAddress(leftValue) && IRUtils.moreThanOneAddress(rightValue)) { + ({ + value: rightValue, + valueOriginalPositions: rightPositions, + stmts: tempRightStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(rightValue, rightPositions)); + tempRightStmts.forEach(stmt => rightStmts.push(stmt)); + } + return { + value: rightValue, + valueOriginalPositions: rightPositions, + stmts: rightStmts, + }; + } + + // In assignment patterns, the left operand will be an array literal expression + private arrayDestructuringToValueAndStmts(arrayDestructuring: ts.ArrayBindingPattern | ts.ArrayLiteralExpression, isConst: boolean = false): ValueAndStmts { + const stmts: Stmt[] = []; + const arrayTempLocal = this.generateTempLocal(); + const leftOriginalPosition = FullPosition.buildFromNode(arrayDestructuring, this.sourceFile); + const elements = arrayDestructuring.elements; + const isArrayBindingPattern = ts.isArrayBindingPattern(arrayDestructuring); + let index = 0; + for (const element of elements) { + const arrayRef = new ArkArrayRef(arrayTempLocal, ValueUtil.getOrCreateNumberConst(index)); + const arrayRefPositions = [leftOriginalPosition, leftOriginalPosition, FullPosition.DEFAULT]; + const itemName = element.getText(this.sourceFile); + const targetLocal = isArrayBindingPattern ? this.addNewLocal(itemName) : this.getOrCreateLocal(itemName); + const targetLocalPosition = FullPosition.buildFromNode(element, this.sourceFile); + isArrayBindingPattern && targetLocal.setConstFlag(isConst); + const assignStmt = new ArkAssignStmt(targetLocal, arrayRef); + assignStmt.setOperandOriginalPositions([targetLocalPosition, ...arrayRefPositions]); + stmts.push(assignStmt); + index++; + } + return { + value: arrayTempLocal, + valueOriginalPositions: [leftOriginalPosition], + stmts: stmts, + }; + } + + // In assignment patterns, the left operand will be an object literal expression + private objectDestructuringToValueAndStmts( + objectDestructuring: ts.ObjectBindingPattern | ts.ObjectLiteralExpression, + isConst: boolean = false + ): ValueAndStmts { + const stmts: Stmt[] = []; + const objectTempLocal = this.generateTempLocal(); + const leftOriginalPosition = FullPosition.buildFromNode(objectDestructuring, this.sourceFile); + const isObjectBindingPattern = ts.isObjectBindingPattern(objectDestructuring); + const elements = isObjectBindingPattern ? objectDestructuring.elements : objectDestructuring.properties; + for (const element of elements) { + let fieldName = ''; + let targetName = ''; + if (ts.isBindingElement(element)) { + fieldName = element.propertyName ? element.propertyName.getText(this.sourceFile) : element.name.getText(this.sourceFile); + targetName = element.name.getText(this.sourceFile); + } else if (ts.isPropertyAssignment(element)) { + fieldName = element.name.getText(this.sourceFile); + targetName = element.initializer.getText(this.sourceFile); + } else if (ts.isShorthandPropertyAssignment(element)) { + fieldName = element.name.getText(this.sourceFile); + targetName = fieldName; + } else { + continue; + } + + const fieldSignature = ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName); + const fieldRef = new ArkInstanceFieldRef(objectTempLocal, fieldSignature); + const fieldRefPositions = [leftOriginalPosition, leftOriginalPosition]; + const targetLocal = isObjectBindingPattern ? this.addNewLocal(targetName) : this.getOrCreateLocal(targetName); + isObjectBindingPattern && targetLocal.setConstFlag(isConst); + const targetLocalPosition = FullPosition.buildFromNode(element, this.sourceFile); + const assignStmt = new ArkAssignStmt(targetLocal, fieldRef); + assignStmt.setOperandOriginalPositions([targetLocalPosition, ...fieldRefPositions]); + stmts.push(assignStmt); + } + return { + value: objectTempLocal, + valueOriginalPositions: [leftOriginalPosition], + stmts: stmts, + }; + } + + private binaryExpressionToValueAndStmts(binaryExpression: ts.BinaryExpression): ValueAndStmts { + const operatorToken = binaryExpression.operatorToken; + if (operatorToken.kind === ts.SyntaxKind.FirstAssignment) { + const leftOpNode = binaryExpression.left; + const rightOpNode = binaryExpression.right; + const declarationType = UnknownType.getInstance(); + return this.assignmentToValueAndStmts(leftOpNode, rightOpNode, false, false, declarationType, true); + } else if (ArkValueTransformer.isCompoundAssignmentOperator(operatorToken.kind)) { + return this.compoundAssignmentToValueAndStmts(binaryExpression); + } + const stmts: Stmt[] = []; + const binaryExpressionPosition = FullPosition.buildFromNode(binaryExpression, this.sourceFile); + const { value: opValue1, valueOriginalPositions: opPositions1, stmts: opStmts1 } = this.tsNodeToSingleAddressValueAndStmts(binaryExpression.left); + opStmts1.forEach(stmt => stmts.push(stmt)); + + if (operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword) { + const instanceOfExpr = new ArkInstanceOfExpr(opValue1, new UnclearReferenceType(binaryExpression.right.getText(this.sourceFile))); + const instanceOfExprPositions = [binaryExpressionPosition, ...opPositions1]; + const { + value: instanceofRes, + valueOriginalPositions: instanceofPos, + stmts: instanceofStmt, + } = this.arkIRTransformer.generateAssignStmtForValue(instanceOfExpr, instanceOfExprPositions); + instanceofStmt.forEach(stmt => stmts.push(stmt)); + return { + value: instanceofRes, + valueOriginalPositions: instanceofPos, + stmts: stmts, + }; + } + + const { value: opValue2, valueOriginalPositions: opPositions2, stmts: opStmts2 } = this.tsNodeToSingleAddressValueAndStmts(binaryExpression.right); + opStmts2.forEach(stmt => stmts.push(stmt)); + let exprValue: Value; + let exprValuePositions = [binaryExpressionPosition]; + if (operatorToken.kind === ts.SyntaxKind.CommaToken) { + exprValue = opValue2; + } else { + const operator = ArkIRTransformer.tokenToBinaryOperator(operatorToken.kind); + if (operator) { + if (this.isRelationalOperator(operator)) { + exprValue = new ArkConditionExpr(opValue1, opValue2, operator as RelationalBinaryOperator); + } else { + exprValue = new ArkNormalBinopExpr(opValue1, opValue2, operator as NormalBinaryOperator); + } + exprValuePositions.push(...opPositions1, ...opPositions2); + } else { + exprValue = ValueUtil.getUndefinedConst(); + exprValuePositions.push(binaryExpressionPosition); + } + } + return { + value: exprValue, + valueOriginalPositions: exprValuePositions, + stmts: stmts, + }; + } + + private compoundAssignmentToValueAndStmts(binaryExpression: ts.BinaryExpression): ValueAndStmts { + const stmts: Stmt[] = []; + let { value: leftValue, valueOriginalPositions: leftPositions, stmts: leftStmts } = this.tsNodeToValueAndStmts(binaryExpression.left); + leftStmts.forEach(stmt => stmts.push(stmt)); + let { value: rightValue, valueOriginalPositions: rightPositions, stmts: rightStmts } = this.tsNodeToValueAndStmts(binaryExpression.right); + rightStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(leftValue) && IRUtils.moreThanOneAddress(rightValue)) { + const { + value: newRightValue, + valueOriginalPositions: newRightPositions, + stmts: rightStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(rightValue, rightPositions); + rightValue = newRightValue; + rightPositions = newRightPositions; + rightStmts.forEach(stmt => stmts.push(stmt)); + } + + let leftOpValue: Value; + let leftOpPositions: FullPosition[]; + const operator = this.compoundAssignmentTokenToBinaryOperator(binaryExpression.operatorToken.kind); + if (operator) { + const exprValue = new ArkNormalBinopExpr(leftValue, rightValue, operator); + const exprValuePosition = FullPosition.buildFromNode(binaryExpression, this.sourceFile); + const assignStmt = new ArkAssignStmt(leftValue, exprValue); + assignStmt.setOperandOriginalPositions([...leftPositions, exprValuePosition, ...leftPositions, ...rightPositions]); + stmts.push(assignStmt); + leftOpValue = leftValue; + leftOpPositions = leftPositions; + } else { + leftOpValue = ValueUtil.getUndefinedConst(); + leftOpPositions = [leftPositions[0]]; + } + return { + value: leftOpValue, + valueOriginalPositions: leftOpPositions, + stmts: stmts, + }; + } + + private compoundAssignmentTokenToBinaryOperator(token: ts.SyntaxKind): NormalBinaryOperator | null { + switch (token) { + case ts.SyntaxKind.QuestionQuestionEqualsToken: + return NormalBinaryOperator.NullishCoalescing; + case ts.SyntaxKind.AsteriskAsteriskEqualsToken: + return NormalBinaryOperator.Exponentiation; + case ts.SyntaxKind.SlashEqualsToken: + return NormalBinaryOperator.Division; + case ts.SyntaxKind.PlusEqualsToken: + return NormalBinaryOperator.Addition; + case ts.SyntaxKind.MinusEqualsToken: + return NormalBinaryOperator.Subtraction; + case ts.SyntaxKind.AsteriskEqualsToken: + return NormalBinaryOperator.Multiplication; + case ts.SyntaxKind.PercentEqualsToken: + return NormalBinaryOperator.Remainder; + case ts.SyntaxKind.LessThanLessThanEqualsToken: + return NormalBinaryOperator.LeftShift; + case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: + return NormalBinaryOperator.RightShift; + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + return NormalBinaryOperator.UnsignedRightShift; + case ts.SyntaxKind.AmpersandEqualsToken: + return NormalBinaryOperator.BitwiseAnd; + case ts.SyntaxKind.BarEqualsToken: + return NormalBinaryOperator.BitwiseOr; + case ts.SyntaxKind.CaretEqualsToken: + return NormalBinaryOperator.BitwiseXor; + case ts.SyntaxKind.AmpersandAmpersandEqualsToken: + return NormalBinaryOperator.LogicalAnd; + case ts.SyntaxKind.BarBarEqualsToken: + return NormalBinaryOperator.LogicalOr; + default: + } + return null; + } + + public conditionToValueAndStmts(condition: ts.Expression): ValueAndStmts { + const stmts: Stmt[] = []; + let { value: conditionValue, valueOriginalPositions: conditionPositions, stmts: conditionStmts } = this.tsNodeToValueAndStmts(condition); + conditionStmts.forEach(stmt => stmts.push(stmt)); + let conditionExpr: ArkConditionExpr; + if (conditionValue instanceof AbstractBinopExpr && this.isRelationalOperator(conditionValue.getOperator())) { + const operator = conditionValue.getOperator() as RelationalBinaryOperator; + conditionExpr = new ArkConditionExpr(conditionValue.getOp1(), conditionValue.getOp2(), operator); + } else { + if (IRUtils.moreThanOneAddress(conditionValue)) { + ({ + value: conditionValue, + valueOriginalPositions: conditionPositions, + stmts: conditionStmts, + } = this.arkIRTransformer.generateAssignStmtForValue(conditionValue, conditionPositions)); + conditionStmts.forEach(stmt => stmts.push(stmt)); + } + conditionExpr = new ArkConditionExpr(conditionValue, ValueUtil.getOrCreateNumberConst(0), RelationalBinaryOperator.InEquality); + conditionPositions = [conditionPositions[0], ...conditionPositions, FullPosition.DEFAULT]; + } + return { + value: conditionExpr, + valueOriginalPositions: conditionPositions, + stmts: stmts, + }; + } + + private literalNodeToValueAndStmts(literalNode: ts.Node): ValueAndStmts | null { + const syntaxKind = literalNode.kind; + let constant: Constant | null = null; + switch (syntaxKind) { + case ts.SyntaxKind.NumericLiteral: + constant = ValueUtil.getOrCreateNumberConst(parseFloat((literalNode as ts.NumericLiteral).text)); + break; + case ts.SyntaxKind.BigIntLiteral: + constant = ValueUtil.createBigIntConst(BigInt((literalNode as ts.BigIntLiteral).text.slice(0, -1))); + break; + case ts.SyntaxKind.StringLiteral: + constant = ValueUtil.createStringConst((literalNode as ts.StringLiteral).text); + break; + case ts.SyntaxKind.RegularExpressionLiteral: + constant = new Constant((literalNode as ts.RegularExpressionLiteral).text, Builtin.REGEXP_CLASS_TYPE); + break; + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + constant = ValueUtil.createStringConst((literalNode as ts.NoSubstitutionTemplateLiteral).text); + break; + case ts.SyntaxKind.NullKeyword: + constant = ValueUtil.getNullConstant(); + break; + case ts.SyntaxKind.UndefinedKeyword: + constant = ValueUtil.getUndefinedConst(); + break; + case ts.SyntaxKind.TrueKeyword: + constant = ValueUtil.getBooleanConstant(true); + break; + case ts.SyntaxKind.FalseKeyword: + constant = ValueUtil.getBooleanConstant(false); + break; + default: + logger.warn(`ast node's syntaxKind is ${ts.SyntaxKind[literalNode.kind]}, not literalNode`); + } + + if (constant === null) { + return null; + } + return { + value: constant, + valueOriginalPositions: [FullPosition.buildFromNode(literalNode, this.sourceFile)], + stmts: [], + }; + } + + private getOrCreateLocal(localName: string, localType: Type = UnknownType.getInstance()): Local { + let local = this.locals.get(localName); + if (local !== undefined) { + return local; + } + local = this.addNewLocal(localName, localType); + this.addNewGlobal(localName); + return local; + } + + public generateTempLocal(localType: Type = UnknownType.getInstance()): Local { + const tempLocalName = TEMP_LOCAL_PREFIX + this.tempLocalNo; + this.tempLocalNo++; + const tempLocal: Local = new Local(tempLocalName, localType); + this.locals.set(tempLocalName, tempLocal); + return tempLocal; + } + + private isRelationalOperator(operator: BinaryOperator): boolean { + return ( + operator === RelationalBinaryOperator.LessThan || + operator === RelationalBinaryOperator.LessThanOrEqual || + operator === RelationalBinaryOperator.GreaterThan || + operator === RelationalBinaryOperator.GreaterThanOrEqual || + operator === RelationalBinaryOperator.Equality || + operator === RelationalBinaryOperator.InEquality || + operator === RelationalBinaryOperator.StrictEquality || + operator === RelationalBinaryOperator.StrictInequality + ); + } + + private isLiteralNode(node: ts.Node): boolean { + if ( + ts.isStringLiteral(node) || + ts.isNumericLiteral(node) || + ts.isBigIntLiteral(node) || + ts.isRegularExpressionLiteral(node) || + ts.isNoSubstitutionTemplateLiteral(node) || + node.kind === ts.SyntaxKind.NullKeyword || + node.kind === ts.SyntaxKind.TrueKeyword || + node.kind === ts.SyntaxKind.FalseKeyword || + node.kind === ts.SyntaxKind.UndefinedKeyword + ) { + return true; + } + return false; + } + + public resolveTypeNode(type: ts.TypeNode): Type { + const kind = type.kind; + switch (kind) { + case ts.SyntaxKind.BooleanKeyword: + return BooleanType.getInstance(); + case ts.SyntaxKind.NumberKeyword: + return NumberType.getInstance(); + case ts.SyntaxKind.StringKeyword: + return StringType.getInstance(); + case ts.SyntaxKind.UndefinedKeyword: + return UndefinedType.getInstance(); + case ts.SyntaxKind.AnyKeyword: + return AnyType.getInstance(); + case ts.SyntaxKind.VoidKeyword: + return VoidType.getInstance(); + case ts.SyntaxKind.NeverKeyword: + return NeverType.getInstance(); + case ts.SyntaxKind.BigIntKeyword: + return BigIntType.getInstance(); + case ts.SyntaxKind.TypeReference: + return this.resolveTypeReferenceNode(type as ts.TypeReferenceNode); + case ts.SyntaxKind.ArrayType: + return new ArrayType(this.resolveTypeNode((type as ts.ArrayTypeNode).elementType), 1); + case ts.SyntaxKind.UnionType: { + const mayTypes: Type[] = []; + (type as ts.UnionTypeNode).types.forEach(t => mayTypes.push(this.resolveTypeNode(t))); + return new UnionType(mayTypes); + } + case ts.SyntaxKind.IntersectionType: { + const intersectionTypes: Type[] = []; + (type as ts.IntersectionTypeNode).types.forEach(t => intersectionTypes.push(this.resolveTypeNode(t))); + return new IntersectionType(intersectionTypes); + } + case ts.SyntaxKind.TupleType: { + const types: Type[] = []; + (type as ts.TupleTypeNode).elements.forEach(element => { + types.push(this.resolveTypeNode(element)); + }); + return new TupleType(types); + } + case ts.SyntaxKind.NamedTupleMember: + return this.resolveTypeNode((type as ts.NamedTupleMember).type); + case ts.SyntaxKind.LiteralType: + return ArkValueTransformer.resolveLiteralTypeNode(type as ts.LiteralTypeNode, this.sourceFile); + case ts.SyntaxKind.TemplateLiteralType: + return this.resolveTemplateLiteralTypeNode(type as ts.TemplateLiteralTypeNode); + case ts.SyntaxKind.TypeLiteral: + return this.resolveTypeLiteralNode(type as ts.TypeLiteralNode); + case ts.SyntaxKind.FunctionType: + return this.resolveFunctionTypeNode(type as ts.FunctionTypeNode); + case ts.SyntaxKind.ImportType: + return UnknownType.getInstance(); + case ts.SyntaxKind.TypeQuery: + return this.resolveTypeQueryNode(type as ts.TypeQueryNode); + case ts.SyntaxKind.ParenthesizedType: + return this.resolveTypeNode((type as ts.ParenthesizedTypeNode).type); + case ts.SyntaxKind.TypeOperator: + return this.resolveTypeOperatorNode(type as ts.TypeOperatorNode); + default: + return UnknownType.getInstance(); + } + } + + private resolveTypeQueryNode(typeQueryNode: ts.TypeQueryNode): Type { + const genericTypes: Type[] = []; + if (typeQueryNode.typeArguments) { + for (const typeArgument of typeQueryNode.typeArguments) { + genericTypes.push(this.resolveTypeNode(typeArgument)); + } + } + + const exprNameNode = typeQueryNode.exprName; + let opValue: Value; + if (ts.isQualifiedName(exprNameNode)) { + if (exprNameNode.left.getText(this.sourceFile) === THIS_NAME) { + const fieldName = exprNameNode.right.getText(this.sourceFile); + const fieldSignature = + this.declaringMethod.getDeclaringArkClass().getFieldWithName(fieldName)?.getSignature() ?? + ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName); + const baseLocal = + this.locals.get(THIS_NAME) ?? new Local(THIS_NAME, new ClassType(this.declaringMethod.getDeclaringArkClass().getSignature(), genericTypes)); + opValue = new ArkInstanceFieldRef(baseLocal, fieldSignature); + } else { + const exprName = exprNameNode.getText(this.sourceFile); + opValue = new Local(exprName, UnknownType.getInstance()); + } + } else { + const exprName = exprNameNode.escapedText.toString(); + opValue = this.locals.get(exprName) ?? this.globals?.get(exprName) ?? new Local(exprName, UnknownType.getInstance()); + } + + return new TypeQueryExpr(opValue, genericTypes); + } + + private resolveTypeOperatorNode(typeOperatorNode: ts.TypeOperatorNode): Type { + let type = this.resolveTypeNode(typeOperatorNode.type); + + switch (typeOperatorNode.operator) { + case ts.SyntaxKind.ReadonlyKeyword: { + if (type instanceof ArrayType || type instanceof TupleType) { + type.setReadonlyFlag(true); + } + return type; + } + case ts.SyntaxKind.KeyOfKeyword: { + return new KeyofTypeExpr(type); + } + case ts.SyntaxKind.UniqueKeyword: { + return UnknownType.getInstance(); + } + default: + return UnknownType.getInstance(); + } + } + + public static resolveLiteralTypeNode(literalTypeNode: ts.LiteralTypeNode, sourceFile: ts.SourceFile): Type { + const literal = literalTypeNode.literal; + const kind = literal.kind; + switch (kind) { + case ts.SyntaxKind.NullKeyword: + return NullType.getInstance(); + case ts.SyntaxKind.TrueKeyword: + return LiteralType.TRUE; + case ts.SyntaxKind.FalseKeyword: + return LiteralType.FALSE; + case ts.SyntaxKind.NumericLiteral: + return new LiteralType(parseFloat((literal as ts.NumericLiteral).text)); + case ts.SyntaxKind.PrefixUnaryExpression: + return new LiteralType(parseFloat(literal.getText(sourceFile))); + default: + } + return new LiteralType(literal.getText(sourceFile)); + } + + private resolveTemplateLiteralTypeNode(templateLiteralTypeNode: ts.TemplateLiteralTypeNode): Type { + let stringLiterals: string[] = ['']; + const headString = templateLiteralTypeNode.head.rawText || ''; + let newStringLiterals: string[] = []; + for (const stringLiteral of stringLiterals) { + newStringLiterals.push(stringLiteral + headString); + } + stringLiterals = newStringLiterals; + newStringLiterals = []; + + for (const templateSpan of templateLiteralTypeNode.templateSpans) { + const templateType = this.resolveTypeNode(templateSpan.type); + const unfoldTemplateTypes: Type[] = []; + if (templateType instanceof UnionType) { + unfoldTemplateTypes.push(...templateType.getTypes()); + } else { + unfoldTemplateTypes.push(templateType); + } + const unfoldTemplateTypeStrs: string[] = []; + for (const unfoldTemplateType of unfoldTemplateTypes) { + unfoldTemplateTypeStrs.push( + unfoldTemplateType instanceof AliasType ? unfoldTemplateType.getOriginalType().toString() : unfoldTemplateType.toString() + ); + } + + const templateSpanString = templateSpan.literal.rawText || ''; + for (const stringLiteral of stringLiterals) { + for (const unfoldTemplateTypeStr of unfoldTemplateTypeStrs) { + newStringLiterals.push(stringLiteral + unfoldTemplateTypeStr + templateSpanString); + } + } + stringLiterals = newStringLiterals; + newStringLiterals = []; + } + + const templateTypes: Type[] = []; + for (const stringLiteral of stringLiterals) { + templateTypes.push(new LiteralType(stringLiteral)); + } + if (templateTypes.length > 0) { + return new UnionType(templateTypes); + } + return templateTypes[0]; + } + + private resolveTypeReferenceNode(typeReferenceNode: ts.TypeReferenceNode): Type { + const typeReferenceFullName = typeReferenceNode.typeName.getText(this.sourceFile); + if (typeReferenceFullName === Builtin.OBJECT) { + return Builtin.OBJECT_CLASS_TYPE; + } + const aliasTypeAndStmt = this.aliasTypeMap.get(typeReferenceFullName); + + const genericTypes: Type[] = []; + if (typeReferenceNode.typeArguments) { + for (const typeArgument of typeReferenceNode.typeArguments) { + genericTypes.push(this.resolveTypeNode(typeArgument)); + } + } + + if (!aliasTypeAndStmt) { + const typeName = typeReferenceNode.typeName.getText(this.sourceFile); + const local = this.locals.get(typeName); + if (local !== undefined) { + return local.getType(); + } + return new UnclearReferenceType(typeName, genericTypes); + } else { + if (genericTypes.length > 0) { + const oldAlias = aliasTypeAndStmt[0]; + let alias = new AliasType( + oldAlias.getName(), + TypeInference.replaceTypeWithReal(oldAlias.getOriginalType(), genericTypes), + oldAlias.getSignature(), + oldAlias.getGenericTypes() + ); + alias.setRealGenericTypes(genericTypes); + return alias; + } + return aliasTypeAndStmt[0]; + } + } + + private resolveTypeLiteralNode(typeLiteralNode: ts.TypeLiteralNode): Type { + const anonymousClass = new ArkClass(); + const declaringClass = this.declaringMethod.getDeclaringArkClass(); + const declaringNamespace = declaringClass.getDeclaringArkNamespace(); + if (declaringNamespace) { + buildNormalArkClassFromArkNamespace(typeLiteralNode, declaringNamespace, anonymousClass, this.sourceFile); + } else { + buildNormalArkClassFromArkFile(typeLiteralNode, declaringClass.getDeclaringArkFile(), anonymousClass, this.sourceFile); + } + return new ClassType(anonymousClass.getSignature()); + } + + private resolveFunctionTypeNode(functionTypeNode: ts.FunctionTypeNode): Type { + const anonymousMethod = new ArkMethod(); + const declaringClass = this.declaringMethod.getDeclaringArkClass(); + buildArkMethodFromArkClass(functionTypeNode, declaringClass, anonymousMethod, this.sourceFile); + return new FunctionType(anonymousMethod.getSignature()); + } + + public static isCompoundAssignmentOperator(operator: ts.SyntaxKind): boolean { + const compoundAssignmentOperators = [ + ts.SyntaxKind.PlusEqualsToken, + ts.SyntaxKind.MinusEqualsToken, + ts.SyntaxKind.AsteriskAsteriskEqualsToken, + ts.SyntaxKind.AsteriskEqualsToken, + ts.SyntaxKind.SlashEqualsToken, + ts.SyntaxKind.PercentEqualsToken, + ts.SyntaxKind.AmpersandEqualsToken, + ts.SyntaxKind.BarEqualsToken, + ts.SyntaxKind.CaretEqualsToken, + ts.SyntaxKind.LessThanLessThanEqualsToken, + ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, + ts.SyntaxKind.GreaterThanGreaterThanEqualsToken, + ts.SyntaxKind.BarBarEqualsToken, + ts.SyntaxKind.AmpersandAmpersandEqualsToken, + ts.SyntaxKind.QuestionQuestionEqualsToken, + ]; + return compoundAssignmentOperators.includes(operator); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/Builtin.ts b/ets2panda/linter/arkanalyzer/src/core/common/Builtin.ts new file mode 100644 index 0000000000000000000000000000000000000000..5c74ecf4d2d82d15fe7a9166ea515e14d7f18c3b --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/Builtin.ts @@ -0,0 +1,95 @@ +/* + * 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. + */ + +import { ClassSignature, FileSignature, MethodSignature, MethodSubSignature } from '../model/ArkSignature'; +import { ClassType, GenericType, StringType } from '../base/Type'; + +export class Builtin { + // built-in classes + // TODO: Automatically obtain from the standard library + public static OBJECT = 'Object'; + public static ARRAY = 'Array'; + public static SET = 'Set'; + public static MAP = 'Map'; + public static REGEXP = 'RegExp'; + + public static BUILT_IN_CLASSES = this.buildBuiltInClasses(); + + // signature for built-in class + public static DUMMY_PROJECT_NAME = 'ES2015'; + public static DUMMY_FILE_NAME = 'BuiltinClass'; + + public static BUILT_IN_CLASSES_FILE_SIGNATURE = Builtin.buildBuiltInClassesFileSignature(); + public static OBJECT_CLASS_SIGNATURE = this.buildBuiltInClassSignature(this.OBJECT); + public static OBJECT_CLASS_TYPE = new ClassType(this.OBJECT_CLASS_SIGNATURE); + public static ARRAY_CLASS_SIGNATURE = this.buildBuiltInClassSignature(this.ARRAY); + public static SET_CLASS_SIGNATURE = this.buildBuiltInClassSignature(this.SET); + public static MAP_CLASS_SIGNATURE = this.buildBuiltInClassSignature(this.MAP); + public static REGEXP_CLASS_SIGNATURE = this.buildBuiltInClassSignature(this.REGEXP); + public static REGEXP_CLASS_TYPE = new ClassType(this.REGEXP_CLASS_SIGNATURE); + public static BUILT_IN_CLASS_SIGNATURE_MAP = this.buildBuiltInClassSignatureMap(); + + // constants for iterator + public static ITERATOR_FUNCTION = 'iterator'; + public static ITERATOR = 'Iterator'; + public static ITERATOR_NEXT = 'next'; + public static ITERATOR_RESULT = 'IteratorResult'; + public static ITERATOR_RESULT_DONE = 'done'; + public static ITERATOR_RESULT_VALUE = 'value'; + + public static ITERATOR_CLASS_SIGNATURE = this.buildBuiltInClassSignature(this.ITERATOR); + public static ITERATOR_RESULT_CLASS_SIGNATURE = this.buildBuiltInClassSignature(this.ITERATOR_RESULT); + public static ITERATOR_CLASS_TYPE = new ClassType(this.ITERATOR_CLASS_SIGNATURE, [new GenericType('T')]); + public static ITERATOR_RESULT_CLASS_TYPE = new ClassType(this.ITERATOR_RESULT_CLASS_SIGNATURE, [new GenericType('T')]); + + // constants for string + public static TO_STRING = 'toString'; + public static TO_STRING_METHOD_SIGNATURE = new MethodSignature( + ClassSignature.DEFAULT, + new MethodSubSignature(this.TO_STRING, [], StringType.getInstance(), false) + ); + + private static buildBuiltInClasses(): Set { + const builtInClasses = new Set(); + builtInClasses.add(this.OBJECT); + builtInClasses.add(this.ARRAY); + builtInClasses.add(this.SET); + builtInClasses.add(this.MAP); + builtInClasses.add(this.REGEXP); + return builtInClasses; + } + + private static buildBuiltInClassesFileSignature(): FileSignature { + return new FileSignature(this.DUMMY_PROJECT_NAME, this.DUMMY_FILE_NAME); + } + + public static buildBuiltInClassSignature(className: string): ClassSignature { + return new ClassSignature(className, this.BUILT_IN_CLASSES_FILE_SIGNATURE); + } + + private static buildBuiltInClassSignatureMap(): Map { + const builtInClassSignatureMap = new Map(); + builtInClassSignatureMap.set(this.OBJECT, this.OBJECT_CLASS_SIGNATURE); + builtInClassSignatureMap.set(this.ARRAY, this.ARRAY_CLASS_SIGNATURE); + builtInClassSignatureMap.set(this.SET, this.SET_CLASS_SIGNATURE); + builtInClassSignatureMap.set(this.MAP, this.MAP_CLASS_SIGNATURE); + builtInClassSignatureMap.set(this.REGEXP, this.REGEXP_CLASS_SIGNATURE); + return builtInClassSignatureMap; + } + + public static isBuiltinClass(className: string): boolean { + return this.BUILT_IN_CLASSES.has(className); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/Const.ts b/ets2panda/linter/arkanalyzer/src/core/common/Const.ts new file mode 100644 index 0000000000000000000000000000000000000000..1fb1a81e79bd89430b9d063059a8d6b279d0de67 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/Const.ts @@ -0,0 +1,48 @@ +/* + * 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. + */ + +// names +export const NAME_DELIMITER = '$'; +export const NAME_PREFIX = '%'; +export const UNKNOWN_NAME = 'unk'; +export const DEFAULT_NAME = 'dflt'; + +// ArkClass const +export const DEFAULT_ARK_CLASS_NAME = NAME_PREFIX + DEFAULT_NAME; +export const ANONYMOUS_CLASS_PREFIX = NAME_PREFIX + 'AC'; +export const ANONYMOUS_CLASS_DELIMITER = NAME_DELIMITER; + +// ArkMethod const +export const DEFAULT_ARK_METHOD_NAME = NAME_PREFIX + DEFAULT_NAME; +export const INSTANCE_INIT_METHOD_NAME = NAME_PREFIX + 'instInit'; +export const STATIC_INIT_METHOD_NAME = NAME_PREFIX + 'statInit'; +export const STATIC_BLOCK_METHOD_NAME_PREFIX = NAME_PREFIX + 'statBlock'; +export const ANONYMOUS_METHOD_PREFIX = NAME_PREFIX + 'AM'; +export const CALL_SIGNATURE_NAME = 'create'; + +// ArkSignature const +export const UNKNOWN_PROJECT_NAME = NAME_PREFIX + UNKNOWN_NAME; +export const UNKNOWN_FILE_NAME = NAME_PREFIX + UNKNOWN_NAME; +export const UNKNOWN_NAMESPACE_NAME = NAME_PREFIX + UNKNOWN_NAME; +export const UNKNOWN_CLASS_NAME = ''; // temp for being compatible with existing type inference +export const UNKNOWN_FIELD_NAME = ''; // temp for being compatible with existing type inference +export const UNKNOWN_METHOD_NAME = ''; // temp for being compatible with existing type inference + +// IR const +export const TEMP_LOCAL_PREFIX = NAME_PREFIX; +export const LEXICAL_ENV_NAME_PREFIX = TEMP_LOCAL_PREFIX + 'closures'; + +// ArkTS version +export const ARKTS_STATIC_MARK = 'use static'; diff --git a/ets2panda/linter/arkanalyzer/src/core/common/DummyMainCreater.ts b/ets2panda/linter/arkanalyzer/src/core/common/DummyMainCreater.ts new file mode 100644 index 0000000000000000000000000000000000000000..3818ac805174fb65eddb74175543135802ed9d5b --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/DummyMainCreater.ts @@ -0,0 +1,340 @@ +/* + * 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. + */ + +import { Scene } from '../../Scene'; +import { COMPONENT_LIFECYCLE_METHOD_NAME, getCallbackMethodFromStmt, LIFECYCLE_METHOD_NAME } from '../../utils/entryMethodUtils'; +import { Constant } from '../base/Constant'; +import { AbstractInvokeExpr, ArkConditionExpr, ArkInstanceInvokeExpr, ArkNewExpr, ArkStaticInvokeExpr, RelationalBinaryOperator } from '../base/Expr'; +import { Local } from '../base/Local'; +import { ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnVoidStmt } from '../base/Stmt'; +import { ClassType, NumberType, Type } from '../base/Type'; +import { BasicBlock } from '../graph/BasicBlock'; +import { Cfg } from '../graph/Cfg'; +import { ArkBody } from '../model/ArkBody'; +import { ArkClass } from '../model/ArkClass'; +import { ArkFile, Language } from '../model/ArkFile'; +import { ArkMethod } from '../model/ArkMethod'; +import { ClassSignature, FileSignature, MethodSignature } from '../model/ArkSignature'; +import { ArkSignatureBuilder } from '../model/builder/ArkSignatureBuilder'; +import { CONSTRUCTOR_NAME } from './TSConst'; +import { checkAndUpdateMethod } from '../model/builder/ArkMethodBuilder'; +import { ValueUtil } from './ValueUtil'; + +/** +收集所有的onCreate,onStart等函数,构造一个虚拟函数,具体为: +%statInit() +... +count = 0 +while (true) { + if (count === 1) { + temp1 = new ability + temp2 = new want + temp1.onCreate(temp2) + } + if (count === 2) { + onDestroy() + } + ... + if (count === *) { + callbackMethod1() + } + ... +} +return +如果是instanceInvoke还要先实例化对象,如果是其他文件的类或者方法还要添加import信息 + */ + +export class DummyMainCreater { + private entryMethods: ArkMethod[] = []; + private classLocalMap: Map = new Map(); + private dummyMain: ArkMethod = new ArkMethod(); + private scene: Scene; + private tempLocalIndex: number = 0; + + constructor(scene: Scene) { + this.scene = scene; + // Currently get entries from module.json5 can't visit all of abilities + // Todo: handle ablity/component jump, then get entries from module.json5 + this.entryMethods = this.getMethodsFromAllAbilities(); + this.entryMethods.push(...this.getEntryMethodsFromComponents()); + this.entryMethods.push(...this.getCallbackMethods()); + } + + public setEntryMethods(methods: ArkMethod[]): void { + this.entryMethods = methods; + } + + public createDummyMain(): void { + const dummyMainFile = new ArkFile(Language.UNKNOWN); + dummyMainFile.setScene(this.scene); + const dummyMainFileSignature = new FileSignature(this.scene.getProjectName(), '@dummyFile'); + dummyMainFile.setFileSignature(dummyMainFileSignature); + this.scene.setFile(dummyMainFile); + const dummyMainClass = new ArkClass(); + dummyMainClass.setDeclaringArkFile(dummyMainFile); + const dummyMainClassSignature = new ClassSignature( + '@dummyClass', + dummyMainClass.getDeclaringArkFile().getFileSignature(), + dummyMainClass.getDeclaringArkNamespace()?.getSignature() || null + ); + dummyMainClass.setSignature(dummyMainClassSignature); + dummyMainFile.addArkClass(dummyMainClass); + + this.dummyMain = new ArkMethod(); + this.dummyMain.setDeclaringArkClass(dummyMainClass); + const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName('@dummyMain'); + const methodSignature = new MethodSignature(this.dummyMain.getDeclaringArkClass().getSignature(), methodSubSignature); + this.dummyMain.setImplementationSignature(methodSignature); + this.dummyMain.setLineCol(0); + checkAndUpdateMethod(this.dummyMain, dummyMainClass); + dummyMainClass.addMethod(this.dummyMain); + + let defaultMethods: ArkMethod[] = []; + for (const method of this.entryMethods) { + if (method.getDeclaringArkClass().isDefaultArkClass() || method.isStatic()) { + defaultMethods.push(method); + continue; + } + const declaringArkClass = method.getDeclaringArkClass(); + let newLocal: Local | null = null; + for (const local of this.classLocalMap.values()) { + if ((local?.getType() as ClassType).getClassSignature() === declaringArkClass.getSignature()) { + newLocal = local; + break; + } + } + if (!newLocal) { + newLocal = new Local('%' + this.tempLocalIndex, new ClassType(declaringArkClass.getSignature())); + this.tempLocalIndex++; + } + this.classLocalMap.set(method, newLocal); + } + for (const defaultMethod of defaultMethods) { + this.classLocalMap.set(defaultMethod, null); + } + const localSet = new Set(Array.from(this.classLocalMap.values()).filter((value): value is Local => value !== null)); + const dummyBody = new ArkBody(localSet, this.createDummyMainCfg()); + this.dummyMain.setBody(dummyBody); + this.addCfg2Stmt(); + this.scene.addToMethodsMap(this.dummyMain); + } + + private addStaticInit(dummyCfg: Cfg, firstBlock: BasicBlock): void { + let isStartingStmt = true; + for (const method of this.scene.getStaticInitMethods()) { + const staticInvokeExpr = new ArkStaticInvokeExpr(method.getSignature(), []); + const invokeStmt = new ArkInvokeStmt(staticInvokeExpr); + if (isStartingStmt) { + dummyCfg.setStartingStmt(invokeStmt); + isStartingStmt = false; + } + firstBlock.addStmt(invokeStmt); + } + } + + private addClassInit(firstBlock: BasicBlock): void { + const locals = Array.from(new Set(this.classLocalMap.values())); + for (const local of locals) { + if (!local) { + continue; + } + let clsType = local.getType() as ClassType; + let cls = this.scene.getClass(clsType.getClassSignature())!; + const assStmt = new ArkAssignStmt(local!, new ArkNewExpr(clsType)); + firstBlock.addStmt(assStmt); + local.setDeclaringStmt(assStmt); + let consMtd = cls.getMethodWithName(CONSTRUCTOR_NAME); + if (consMtd) { + let ivkExpr = new ArkInstanceInvokeExpr(local, consMtd.getSignature(), []); + let ivkStmt = new ArkInvokeStmt(ivkExpr); + firstBlock.addStmt(ivkStmt); + } + } + } + + private addParamInit(method: ArkMethod, paramLocals: Local[], invokeBlock: BasicBlock): void { + let paramIdx = 0; + for (const param of method.getParameters()) { + let paramType: Type | undefined = param.getType(); + // In ArkIR from abc scenario, param type is undefined in some cases + // Then try to get it from super class(SDK) + // TODO - need handle method overload to get the correct method + if (!paramType) { + let superCls = method.getDeclaringArkClass().getSuperClass(); + let methodInSuperCls = superCls?.getMethodWithName(method.getName()); + if (methodInSuperCls) { + paramType = methodInSuperCls.getParameters().at(paramIdx)?.getType(); + method = methodInSuperCls; + } + } + const paramLocal = new Local('%' + this.tempLocalIndex++, paramType); + paramLocals.push(paramLocal); + if (paramType instanceof ClassType) { + const assStmt = new ArkAssignStmt(paramLocal, new ArkNewExpr(paramType)); + paramLocal.setDeclaringStmt(assStmt); + invokeBlock.addStmt(assStmt); + } + paramIdx++; + } + } + + private addBranches(whileBlock: BasicBlock, countLocal: Local, dummyCfg: Cfg): void { + let lastBlocks: BasicBlock[] = [whileBlock]; + let count = 0; + for (let method of this.entryMethods) { + count++; + const condition = new ArkConditionExpr(countLocal, new Constant(count.toString(), NumberType.getInstance()), RelationalBinaryOperator.Equality); + const ifStmt = new ArkIfStmt(condition); + const ifBlock = new BasicBlock(); + ifBlock.addStmt(ifStmt); + dummyCfg.addBlock(ifBlock); + for (const block of lastBlocks) { + ifBlock.addPredecessorBlock(block); + block.addSuccessorBlock(ifBlock); + } + const invokeBlock = new BasicBlock(); + const paramLocals: Local[] = []; + this.addParamInit(method, paramLocals, invokeBlock); + const local = this.classLocalMap.get(method); + let invokeExpr: AbstractInvokeExpr; + if (local) { + invokeExpr = new ArkInstanceInvokeExpr(local, method.getSignature(), paramLocals); + } else { + invokeExpr = new ArkStaticInvokeExpr(method.getSignature(), paramLocals); + } + const invokeStmt = new ArkInvokeStmt(invokeExpr); + invokeBlock.addStmt(invokeStmt); + dummyCfg.addBlock(invokeBlock); + ifBlock.addSuccessorBlock(invokeBlock); + invokeBlock.addPredecessorBlock(ifBlock); + lastBlocks = [ifBlock, invokeBlock]; + } + for (const block of lastBlocks) { + block.addSuccessorBlock(whileBlock); + whileBlock.addPredecessorBlock(block); + } + } + + private createDummyMainCfg(): Cfg { + const dummyCfg = new Cfg(); + dummyCfg.setDeclaringMethod(this.dummyMain); + const firstBlock = new BasicBlock(); + this.addStaticInit(dummyCfg, firstBlock); + this.addClassInit(firstBlock); + const countLocal = new Local('count', NumberType.getInstance()); + const zero = ValueUtil.getOrCreateNumberConst(0); + const countAssignStmt = new ArkAssignStmt(countLocal, zero); + const truE = ValueUtil.getBooleanConstant(true); + const conditionTrue = new ArkConditionExpr(truE, zero, RelationalBinaryOperator.Equality); + const whileStmt = new ArkIfStmt(conditionTrue); + firstBlock.addStmt(countAssignStmt); + dummyCfg.addBlock(firstBlock); + dummyCfg.setStartingStmt(firstBlock.getStmts()[0]); + const whileBlock = new BasicBlock(); + whileBlock.addStmt(whileStmt); + dummyCfg.addBlock(whileBlock); + firstBlock.addSuccessorBlock(whileBlock); + whileBlock.addPredecessorBlock(firstBlock); + this.addBranches(whileBlock, countLocal, dummyCfg); + const returnStmt = new ArkReturnVoidStmt(); + const returnBlock = new BasicBlock(); + returnBlock.addStmt(returnStmt); + dummyCfg.addBlock(returnBlock); + whileBlock.addSuccessorBlock(returnBlock); + returnBlock.addPredecessorBlock(whileBlock); + return dummyCfg; + } + + private addCfg2Stmt(): void { + const cfg = this.dummyMain.getCfg(); + if (!cfg) { + return; + } + for (const block of cfg.getBlocks()) { + for (const stmt of block.getStmts()) { + stmt.setCfg(cfg); + } + } + } + + public getDummyMain(): ArkMethod { + return this.dummyMain; + } + + private getEntryMethodsFromComponents(): ArkMethod[] { + const COMPONENT_BASE_CLASSES = ['CustomComponent', 'ViewPU']; + let methods: ArkMethod[] = []; + this.scene + .getClasses() + .filter(cls => { + if (COMPONENT_BASE_CLASSES.includes(cls.getSuperClassName())) { + return true; + } + if (cls.hasDecorator('Component')) { + return true; + } + return false; + }) + .forEach(cls => { + methods.push(...cls.getMethods().filter(mtd => COMPONENT_LIFECYCLE_METHOD_NAME.includes(mtd.getName()))); + }); + return methods; + } + + private classInheritsAbility(arkClass: ArkClass): boolean { + const ABILITY_BASE_CLASSES = ['UIExtensionAbility', 'Ability', 'FormExtensionAbility', 'UIAbility', 'BackupExtensionAbility']; + if (ABILITY_BASE_CLASSES.includes(arkClass.getSuperClassName())) { + return true; + } + let superClass = arkClass.getSuperClass(); + while (superClass) { + if (ABILITY_BASE_CLASSES.includes(superClass.getSuperClassName())) { + return true; + } + superClass = superClass.getSuperClass(); + } + return false; + } + + public getMethodsFromAllAbilities(): ArkMethod[] { + let methods: ArkMethod[] = []; + this.scene + .getClasses() + .filter(cls => this.classInheritsAbility(cls)) + .forEach(cls => { + methods.push(...cls.getMethods().filter(mtd => LIFECYCLE_METHOD_NAME.includes(mtd.getName()))); + }); + return methods; + } + + public getCallbackMethods(): ArkMethod[] { + const callbackMethods: ArkMethod[] = []; + this.scene.getMethods().forEach(method => { + if (!method.getCfg()) { + return; + } + method + .getCfg()! + .getStmts() + .forEach(stmt => { + const cbMethod = getCallbackMethodFromStmt(stmt, this.scene); + if (cbMethod && !callbackMethods.includes(cbMethod)) { + callbackMethods.push(cbMethod); + } + }); + }); + return callbackMethods; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/EtsConst.ts b/ets2panda/linter/arkanalyzer/src/core/common/EtsConst.ts new file mode 100644 index 0000000000000000000000000000000000000000..f01f9396e9a7847171d183eee2b6232e64d1e43f --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/EtsConst.ts @@ -0,0 +1,1020 @@ +/* + * 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. + */ + +export const ETS_COMPILER_OPTIONS = { + ets: { + emitDecorators: [ + { + name: 'Entry', + emitParameters: true, + }, + { + name: 'Component', + emitParameters: false, + }, + { + name: 'Reusable', + emitParameters: false, + }, + { + name: 'CustomDialog', + emitParameters: false, + }, + { + name: 'Consume', + emitParameters: true, + }, + { + name: 'Link', + emitParameters: false, + }, + { + name: 'LocalStorageLink', + emitParameters: true, + }, + { + name: 'LocalStorageProp', + emitParameters: true, + }, + { + name: 'ObjectLink', + emitParameters: false, + }, + { + name: 'Prop', + emitParameters: false, + }, + { + name: 'Provide', + emitParameters: true, + }, + { + name: 'State', + emitParameters: false, + }, + { + name: 'StorageLink', + emitParameters: true, + }, + { + name: 'StorageProp', + emitParameters: true, + }, + { + name: 'Builder', + emitParameters: false, + }, + { + name: 'LocalBuilder', + emitParameters: false, + }, + { + name: 'BuilderParam', + emitParameters: false, + }, + { + name: 'Observed', + emitParameters: false, + }, + { + name: 'Require', + emitParameters: false, + }, + { + name: 'Sendable', + emitParameters: false, + }, + { + name: 'Track', + emitParameters: false, + }, + { + name: 'ComponentV2', + emitParameters: true, + }, + { + name: 'ObservedV2', + emitParameters: false, + }, + { + name: 'Trace', + emitParameters: false, + }, + { + name: 'Local', + emitParameters: false, + }, + { + name: 'Param', + emitParameters: false, + }, + { + name: 'Once', + emitParameters: false, + }, + { + name: 'Event', + emitParameters: false, + }, + { + name: 'Monitor', + emitParameters: true, + }, + { + name: 'Provider', + emitParameters: true, + }, + { + name: 'Consumer', + emitParameters: true, + }, + { + name: 'Computed', + emitParameters: false, + }, + { + name: 'Type', + emitParameters: true, + }, + ], + propertyDecorators: [ + { + name: 'Link', + needInitialization: false, + }, + { + name: 'Prop', + needInitialization: false, + }, + { + name: 'ObjectLink', + needInitialization: false, + }, + { + name: 'Consume', + needInitialization: false, + }, + ], + render: { + method: ['build', 'pageTransition'], + decorator: ['LocalBuilder', 'Builder'], + }, + components: [ + 'AbilityComponent', + 'AlphabetIndexer', + 'Animator', + 'Badge', + 'Blank', + 'Button', + 'Calendar', + 'CalendarPicker', + 'Camera', + 'Canvas', + 'Checkbox', + 'CheckboxGroup', + 'Circle', + 'ColorPicker', + 'ColorPickerDialog', + 'Column', + 'ColumnSplit', + 'ContentSlot', + 'Counter', + 'DataPanel', + 'DatePicker', + 'Divider', + 'EffectComponent', + 'Ellipse', + 'EmbeddedComponent', + 'Flex', + 'FolderStack', + 'FormComponent', + 'FormLink', + 'Gauge', + 'GeometryView', + 'Grid', + 'GridItem', + 'GridContainer', + 'Hyperlink', + 'Image', + 'ImageAnimator', + 'Line', + 'List', + 'ListItem', + 'ListItemGroup', + 'LoadingProgress', + 'Marquee', + 'MediaCachedImage', + 'Menu', + 'MenuItem', + 'MenuItemGroup', + 'MovingPhotoView', + 'NavDestination', + 'NavRouter', + 'Navigation', + 'Navigator', + 'NodeContainer', + 'Option', + 'PageTransitionEnter', + 'PageTransitionExit', + 'Panel', + 'Particle', + 'Path', + 'PatternLock', + 'Piece', + 'PluginComponent', + 'Polygon', + 'Polyline', + 'Progress', + 'QRCode', + 'Radio', + 'Rating', + 'Rect', + 'Refresh', + 'RelativeContainer', + 'RemoteWindow', + 'RootScene', + 'Row', + 'RowSplit', + 'RichText', + 'Screen', + 'Scroll', + 'ScrollBar', + 'Search', + 'Section', + 'Select', + 'Shape', + 'Sheet', + 'SideBarContainer', + 'Slider', + 'Span', + 'Stack', + 'Stepper', + 'StepperItem', + 'Swiper', + 'SymbolGlyph', + 'SymbolSpan', + 'TabContent', + 'Tabs', + 'Text', + 'TextPicker', + 'TextClock', + 'TextArea', + 'TextInput', + 'TextTimer', + 'TimePicker', + 'Toggle', + 'Video', + 'Web', + 'WindowScene', + 'WithTheme', + 'XComponent', + 'GridRow', + 'GridCol', + 'WaterFlow', + 'FlowItem', + 'ImageSpan', + 'LocationButton', + 'PasteButton', + 'SaveButton', + 'UIExtensionComponent', + 'IsolatedComponent', + 'RichEditor', + 'Component3D', + 'ContainerSpan', + ], + extend: { + decorator: ['Extend', 'AnimatableExtend'], + components: [ + { + name: 'AbilityComponent', + type: 'AbilityComponentAttribute', + instance: 'AbilityComponentInstance', + }, + { + name: 'AlphabetIndexer', + type: 'AlphabetIndexerAttribute', + instance: 'AlphabetIndexerInstance', + }, + { + name: 'Animator', + type: 'AnimatorAttribute', + instance: 'AnimatorInstance', + }, + { + name: 'Badge', + type: 'BadgeAttribute', + instance: 'BadgeInstance', + }, + { + name: 'Blank', + type: 'BlankAttribute', + instance: 'BlankInstance', + }, + { + name: 'Button', + type: 'ButtonAttribute', + instance: 'ButtonInstance', + }, + { + name: 'Calendar', + type: 'CalendarAttribute', + instance: 'CalendarInstance', + }, + { + name: 'CalendarPicker', + type: 'CalendarPickerAttribute', + instance: 'CalendarPickerInstance', + }, + { + name: 'Camera', + type: 'CameraAttribute', + instance: 'CameraInstance', + }, + { + name: 'Canvas', + type: 'CanvasAttribute', + instance: 'CanvasInstance', + }, + { + name: 'Checkbox', + type: 'CheckboxAttribute', + instance: 'CheckboxInstance', + }, + { + name: 'CheckboxGroup', + type: 'CheckboxGroupAttribute', + instance: 'CheckboxGroupInstance', + }, + { + name: 'Circle', + type: 'CircleAttribute', + instance: 'CircleInstance', + }, + { + name: 'ColorPicker', + type: 'ColorPickerAttribute', + instance: 'ColorPickerInstance', + }, + { + name: 'ColorPickerDialog', + type: 'ColorPickerDialogAttribute', + instance: 'ColorPickerDialogInstance', + }, + { + name: 'Column', + type: 'ColumnAttribute', + instance: 'ColumnInstance', + }, + { + name: 'ColumnSplit', + type: 'ColumnSplitAttribute', + instance: 'ColumnSplitInstance', + }, + { + name: 'Counter', + type: 'CounterAttribute', + instance: 'CounterInstance', + }, + { + name: 'DataPanel', + type: 'DataPanelAttribute', + instance: 'DataPanelInstance', + }, + { + name: 'DatePicker', + type: 'DatePickerAttribute', + instance: 'DatePickerInstance', + }, + { + name: 'Divider', + type: 'DividerAttribute', + instance: 'DividerInstance', + }, + { + name: 'EffectComponent', + type: 'EffectComponentAttribute', + instance: 'EffectComponentInstance', + }, + { + name: 'Ellipse', + type: 'EllipseAttribute', + instance: 'EllipseInstance', + }, + { + name: 'EmbeddedComponent', + type: 'EmbeddedComponentAttribute', + instance: 'EmbeddedComponentInstance', + }, + { + name: 'Flex', + type: 'FlexAttribute', + instance: 'FlexInstance', + }, + { + name: 'FolderStack', + type: 'FolderStackAttribute', + instance: 'FolderStackInstance', + }, + { + name: 'FormComponent', + type: 'FormComponentAttribute', + instance: 'FormComponentInstance', + }, + { + name: 'FormLink', + type: 'FormLinkAttribute', + instance: 'FormLinkInstance', + }, + { + name: 'Gauge', + type: 'GaugeAttribute', + instance: 'GaugeInstance', + }, + { + name: 'GeometryView', + type: 'GeometryViewAttribute', + instance: 'GeometryViewInstance', + }, + { + name: 'Grid', + type: 'GridAttribute', + instance: 'GridInstance', + }, + { + name: 'GridItem', + type: 'GridItemAttribute', + instance: 'GridItemInstance', + }, + { + name: 'GridContainer', + type: 'GridContainerAttribute', + instance: 'GridContainerInstance', + }, + { + name: 'Hyperlink', + type: 'HyperlinkAttribute', + instance: 'HyperlinkInstance', + }, + { + name: 'Image', + type: 'ImageAttribute', + instance: 'ImageInstance', + }, + { + name: 'ImageAnimator', + type: 'ImageAnimatorAttribute', + instance: 'ImageAnimatorInstance', + }, + { + name: 'Line', + type: 'LineAttribute', + instance: 'LineInstance', + }, + { + name: 'List', + type: 'ListAttribute', + instance: 'ListInstance', + }, + { + name: 'ListItem', + type: 'ListItemAttribute', + instance: 'ListItemInstance', + }, + { + name: 'ListItemGroup', + type: 'ListItemGroupAttribute', + instance: 'ListItemGroupInstance', + }, + { + name: 'LoadingProgress', + type: 'LoadingProgressAttribute', + instance: 'LoadingProgressInstance', + }, + { + name: 'Marquee', + type: 'MarqueeAttribute', + instance: 'MarqueeInstance', + }, + { + name: 'MediaCachedImage', + type: 'MediaCachedImageAttribute', + instance: 'MediaCachedImageInstance', + }, + { + name: 'Menu', + type: 'MenuAttribute', + instance: 'MenuInstance', + }, + { + name: 'MenuItem', + type: 'MenuItemAttribute', + instance: 'MenuItemInstance', + }, + { + name: 'MenuItemGroup', + type: 'MenuItemGroupAttribute', + instance: 'MenuItemGroupInstance', + }, + { + name: 'MovingPhotoView', + type: 'MovingPhotoViewAttribute', + instance: 'MovingPhotoViewInstance', + }, + { + name: 'NavDestination', + type: 'NavDestinationAttribute', + instance: 'NavDestinationInstance', + }, + { + name: 'NavRouter', + type: 'NavRouterAttribute', + instance: 'NavRouterInstance', + }, + { + name: 'Navigation', + type: 'NavigationAttribute', + instance: 'NavigationInstance', + }, + { + name: 'Navigator', + type: 'NavigatorAttribute', + instance: 'NavigatorInstance', + }, + { + name: 'NodeContainer', + type: 'NodeContainerAttribute', + instance: 'NodeContainerInstance', + }, + { + name: 'Option', + type: 'OptionAttribute', + instance: 'OptionInstance', + }, + { + name: 'PageTransitionEnter', + type: 'PageTransitionEnterAttribute', + instance: 'PageTransitionEnterInstance', + }, + { + name: 'PageTransitionExit', + type: 'PageTransitionExitAttribute', + instance: 'PageTransitionExitInstance', + }, + { + name: 'Panel', + type: 'PanelAttribute', + instance: 'PanelInstance', + }, + { + name: 'Particle', + type: 'ParticleAttribute', + instance: 'ParticleInstance', + }, + { + name: 'Path', + type: 'PathAttribute', + instance: 'PathInstance', + }, + { + name: 'PatternLock', + type: 'PatternLockAttribute', + instance: 'PatternLockInstance', + }, + { + name: 'Piece', + type: 'PieceAttribute', + instance: 'PieceInstance', + }, + { + name: 'PluginComponent', + type: 'PluginComponentAttribute', + instance: 'PluginComponentInstance', + }, + { + name: 'Polygon', + type: 'PolygonAttribute', + instance: 'PolygonInstance', + }, + { + name: 'Polyline', + type: 'PolylineAttribute', + instance: 'PolylineInstance', + }, + { + name: 'Progress', + type: 'ProgressAttribute', + instance: 'ProgressInstance', + }, + { + name: 'QRCode', + type: 'QRCodeAttribute', + instance: 'QRCodeInstance', + }, + { + name: 'Radio', + type: 'RadioAttribute', + instance: 'RadioInstance', + }, + { + name: 'Rating', + type: 'RatingAttribute', + instance: 'RatingInstance', + }, + { + name: 'Rect', + type: 'RectAttribute', + instance: 'RectInstance', + }, + { + name: 'RelativeContainer', + type: 'RelativeContainerAttribute', + instance: 'RelativeContainerInstance', + }, + { + name: 'Refresh', + type: 'RefreshAttribute', + instance: 'RefreshInstance', + }, + { + name: 'RemoteWindow', + type: 'RemoteWindowAttribute', + instance: 'RemoteWindowInstance', + }, + { + name: 'RootScene', + type: 'RootSceneAttribute', + instance: 'RootSceneInstance', + }, + { + name: 'Row', + type: 'RowAttribute', + instance: 'RowInstance', + }, + { + name: 'RowSplit', + type: 'RowSplitAttribute', + instance: 'RowSplitInstance', + }, + { + name: 'RichText', + type: 'RichTextAttribute', + instance: 'RichTextInstance', + }, + { + name: 'Screen', + type: 'ScreenAttribute', + instance: 'ScreenInstance', + }, + { + name: 'Scroll', + type: 'ScrollAttribute', + instance: 'ScrollInstance', + }, + { + name: 'ScrollBar', + type: 'ScrollBarAttribute', + instance: 'ScrollBarInstance', + }, + { + name: 'Search', + type: 'SearchAttribute', + instance: 'SearchInstance', + }, + { + name: 'Section', + type: 'SectionAttribute', + instance: 'SectionInstance', + }, + { + name: 'Select', + type: 'SelectAttribute', + instance: 'SelectInstance', + }, + { + name: 'Shape', + type: 'ShapeAttribute', + instance: 'ShapeInstance', + }, + { + name: 'Sheet', + type: 'SheetAttribute', + instance: 'SheetInstance', + }, + { + name: 'SideBarContainer', + type: 'SideBarContainerAttribute', + instance: 'SideBarContainerInstance', + }, + { + name: 'Slider', + type: 'SliderAttribute', + instance: 'SliderInstance', + }, + { + name: 'Span', + type: 'SpanAttribute', + instance: 'SpanInstance', + }, + { + name: 'Stack', + type: 'StackAttribute', + instance: 'StackInstance', + }, + { + name: 'Stepper', + type: 'StepperAttribute', + instance: 'StepperInstance', + }, + { + name: 'StepperItem', + type: 'StepperItemAttribute', + instance: 'StepperItemInstance', + }, + { + name: 'Swiper', + type: 'SwiperAttribute', + instance: 'SwiperInstance', + }, + { + name: 'SymbolGlyph', + type: 'SymbolGlyphAttribute', + instance: 'SymbolGlyphInstance', + }, + { + name: 'SymbolSpan', + type: 'SymbolSpanAttribute', + instance: 'SymbolSpanInstance', + }, + { + name: 'TabContent', + type: 'TabContentAttribute', + instance: 'TabContentInstance', + }, + { + name: 'Tabs', + type: 'TabsAttribute', + instance: 'TabsInstance', + }, + { + name: 'Text', + type: 'TextAttribute', + instance: 'TextInstance', + }, + { + name: 'TextPicker', + type: 'TextPickerAttribute', + instance: 'TextPickerInstance', + }, + { + name: 'TextClock', + type: 'TextClockAttribute', + instance: 'TextClockInstance', + }, + { + name: 'TextArea', + type: 'TextAreaAttribute', + instance: 'TextAreaInstance', + }, + { + name: 'TextInput', + type: 'TextInputAttribute', + instance: 'TextInputInstance', + }, + { + name: 'TextTimer', + type: 'TextTimerAttribute', + instance: 'TextTimerInstance', + }, + { + name: 'TimePicker', + type: 'TimePickerAttribute', + instance: 'TimePickerInstance', + }, + { + name: 'Toggle', + type: 'ToggleAttribute', + instance: 'ToggleInstance', + }, + { + name: 'Video', + type: 'VideoAttribute', + instance: 'VideoInstance', + }, + { + name: 'Web', + type: 'WebAttribute', + instance: 'WebInstance', + }, + { + name: 'WindowScene', + type: 'WindowSceneAttribute', + instance: 'WindowSceneInstance', + }, + { + name: 'XComponent', + type: 'XComponentAttribute', + instance: 'XComponentInstance', + }, + { + name: 'GridRow', + type: 'GridRowAttribute', + instance: 'GridRowInstance', + }, + { + name: 'GridCol', + type: 'GridColAttribute', + instance: 'GridColInstance', + }, + { + name: 'WaterFlow', + type: 'WaterFlowAttribute', + instance: 'WaterFlowInstance', + }, + { + name: 'FlowItem', + type: 'FlowItemAttribute', + instance: 'FlowItemInstance', + }, + { + name: 'ImageSpan', + type: 'ImageSpanAttribute', + instance: 'ImageSpanInstance', + }, + { + name: 'LocationButton', + type: 'LocationButtonAttribute', + instance: 'LocationButtonInstance', + }, + { + name: 'PasteButton', + type: 'PasteButtonAttribute', + instance: 'PasteButtonInstance', + }, + { + name: 'SaveButton', + type: 'SaveButtonAttribute', + instance: 'SaveButtonInstance', + }, + { + name: 'UIExtensionComponent', + type: 'UIExtensionComponentAttribute', + instance: 'UIExtensionComponentInstance', + }, + { + name: 'IsolatedComponent', + type: 'IsolatedComponentAttribute', + instance: 'IsolatedComponentInstance', + }, + { + name: 'RichEditor', + type: 'RichEditorAttribute', + instance: 'RichEditorInstance', + }, + { + name: 'Component3D', + type: 'Component3DAttribute', + instance: 'Component3DInstance', + }, + { + name: 'ContainerSpan', + type: 'ContainerSpanAttribute', + instance: 'ContainerSpanInstance', + }, + ], + }, + styles: { + decorator: 'Styles', + component: { + name: 'Common', + type: 'T', + instance: 'CommonInstance', + }, + property: 'stateStyles', + }, + concurrent: { + decorator: 'Concurrent', + }, + customComponent: 'CustomComponent', + syntaxComponents: { + paramsUICallback: ['ForEach', 'LazyForEach'], + attrUICallback: [ + { + name: 'Repeat', + attributes: ['each', 'template'], + }, + ], + }, + libs: [], + }, +}; + +export const COMPONENT_FOR_EACH: string = 'ForEach'; +export const COMPONENT_LAZY_FOR_EACH: string = 'LazyForEach'; + +export const BUILDIN_SYSTEM_COMPONENT: Set = new Set([...ETS_COMPILER_OPTIONS.ets.components, COMPONENT_FOR_EACH, COMPONENT_LAZY_FOR_EACH]); + +export const BUILDIN_ATOMIC_COMPONENT: Set = new Set([ + 'AbilityComponent', + 'AlphabetIndexer', + 'Animator', + 'Blank', + 'CalendarPicker', + 'Camera', + 'Circle', + 'Component3D', + 'ContentSlot', + 'Divider', + 'Ellipse', + 'EmbeddedComponent', + 'FormComponent', + 'FrictionMotion', + 'GeometryView', + 'Image', + 'ImageAnimator', + 'ImageSpan', + 'Line', + 'LoadingProgress', + 'LocationButton', + 'Marquee', + 'MediaCachedImage', + 'NodeContainer', + 'PageTransitionEnter', + 'PageTransitionExit', + 'Particle', + 'PasteButton', + 'Path', + 'PatternLock', + 'Polygon', + 'Polyline', + 'Progress', + 'Radio', + 'Rect', + 'RemoteWindow', + 'RichEditor', + 'RichText', + 'SaveButton', + 'ScrollMotion', + 'Search', + 'Slider', + 'Span', + 'SpringMotion', + 'SpringProp', + 'SymbolSpan', + 'SymbolGlyph', + 'TextArea', + 'TextInput', + 'UIExtensionComponent', + 'Video', + 'Web', +]); + +export const COMPONENT_DECORATOR: Set = new Set(['Reusable', 'Component', 'ComponentV2', 'CustomDialog']); +export const ENTRY_DECORATOR: string = 'Entry'; +export const BUILDER_DECORATOR: string = 'Builder'; +export const BUILDER_PARAM_DECORATOR: string = 'BuilderParam'; + +export function isEtsAtomicComponent(name: string): boolean { + return BUILDIN_ATOMIC_COMPONENT.has(name); +} + +export function isEtsSystemComponent(name: string): boolean { + return BUILDIN_SYSTEM_COMPONENT.has(name); +} + +export function isEtsContainerComponent(name: string): boolean { + return isEtsSystemComponent(name) && !isEtsAtomicComponent(name); +} + +export const COMPONENT_CREATE_FUNCTION: string = 'create'; +export const COMPONENT_POP_FUNCTION: string = 'pop'; +export const COMPONENT_CUSTOMVIEW: string = 'View'; +export const COMPONENT_REPEAT: string = 'Repeat'; + +export const COMPONENT_IF: string = 'If'; +export const COMPONENT_IF_BRANCH: string = 'IfBranch'; +export const COMPONENT_BRANCH_FUNCTION: string = 'branch'; +export const COMPONENT_BUILD_FUNCTION: string = 'build'; + +export const SPECIAL_CONTAINER_COMPONENT: Set = new Set([COMPONENT_IF, COMPONENT_IF_BRANCH, COMPONENT_CUSTOMVIEW, COMPONENT_REPEAT]); + +export const COMPONENT_COMMON: string = 'Common'; +export const COMPONENT_INSTANCE: string = 'Instance'; + +export const COMPONENT_ATTRIBUTE: string = 'Attribute'; +export const CALL_BACK: string = 'Callback'; +export const ON_OFF: Set = new Set(['on', 'off']); + +export const OH_PACKAGE_JSON5 = 'oh-package.json5'; +export const BUILD_PROFILE_JSON5 = 'build-profile.json5'; diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ExprUseReplacer.ts b/ets2panda/linter/arkanalyzer/src/core/common/ExprUseReplacer.ts new file mode 100644 index 0000000000000000000000000000000000000000..9bc96442dfbd372c39a128ee5b60babcc887a126 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/ExprUseReplacer.ts @@ -0,0 +1,142 @@ +/* + * 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. + */ + +import { + AbstractBinopExpr, + AbstractExpr, + AbstractInvokeExpr, + ArkAwaitExpr, + ArkCastExpr, + ArkDeleteExpr, + ArkInstanceInvokeExpr, + ArkInstanceOfExpr, + ArkNewArrayExpr, + ArkPtrInvokeExpr, + ArkTypeOfExpr, + ArkUnopExpr, + ArkYieldExpr, +} from '../base/Expr'; +import { Local } from '../base/Local'; +import { Value } from '../base/Value'; +import { AbstractFieldRef } from '../base/Ref'; + +/** + * Replace old use of a Expr inplace + */ +export class ExprUseReplacer { + private oldUse: Value; + private newUse: Value; + + constructor(oldUse: Value, newUse: Value) { + this.oldUse = oldUse; + this.newUse = newUse; + } + + public caseExpr(expr: AbstractExpr): void { + if (expr instanceof AbstractBinopExpr) { + this.caseBinopExpr(expr); + } else if (expr instanceof AbstractInvokeExpr) { + this.caseInvokeExpr(expr); + } else if (expr instanceof ArkNewArrayExpr) { + this.caseNewArrayExpr(expr); + } else if (expr instanceof ArkTypeOfExpr) { + this.caseTypeOfExpr(expr); + } else if (expr instanceof ArkInstanceOfExpr) { + this.caseInstanceOfExpr(expr); + } else if (expr instanceof ArkCastExpr) { + this.caseCastExpr(expr); + } else if (expr instanceof ArkAwaitExpr) { + this.caseAwaitExpr(expr); + } else if (expr instanceof ArkYieldExpr) { + this.caseYieldExpr(expr); + } else if (expr instanceof ArkDeleteExpr) { + this.caseDeleteExpr(expr); + } else if (expr instanceof ArkUnopExpr) { + this.caseUnopExpr(expr); + } + } + + private caseBinopExpr(expr: AbstractBinopExpr): void { + if (expr.getOp1() === this.oldUse) { + expr.setOp1(this.newUse); + } + if (expr.getOp2() === this.oldUse) { + expr.setOp2(this.newUse); + } + } + + private caseInvokeExpr(expr: AbstractInvokeExpr): void { + let args = expr.getArgs(); + for (let i = 0; i < args.length; i++) { + if (args[i] === this.oldUse) { + args[i] = this.newUse; + } + } + + if (expr instanceof ArkInstanceInvokeExpr && expr.getBase() === this.oldUse) { + expr.setBase( this.newUse); + } else if (expr instanceof ArkPtrInvokeExpr && expr.getFuncPtrLocal() === this.oldUse && this.newUse instanceof Local) { + expr.setFunPtrLocal(this.newUse); + } + } + + private caseNewArrayExpr(expr: ArkNewArrayExpr): void { + if (expr.getSize() === this.oldUse) { + expr.setSize(this.newUse); + } + } + + private caseTypeOfExpr(expr: ArkTypeOfExpr): void { + if (expr.getOp() === this.oldUse) { + expr.setOp(this.newUse); + } + } + + private caseInstanceOfExpr(expr: ArkInstanceOfExpr): void { + if (expr.getOp() === this.oldUse) { + expr.setOp(this.newUse); + } + } + + private caseCastExpr(expr: ArkCastExpr): void { + if (expr.getOp() === this.oldUse) { + expr.setOp(this.newUse); + } + } + + private caseAwaitExpr(expr: ArkAwaitExpr): void { + if (expr.getPromise() === this.oldUse) { + expr.setPromise(this.newUse); + } + } + + private caseDeleteExpr(expr: ArkDeleteExpr): void { + if (expr.getField() === this.oldUse && this.newUse instanceof AbstractFieldRef) { + expr.setField(this.newUse); + } + } + + private caseYieldExpr(expr: ArkYieldExpr): void { + if (expr.getYieldValue() === this.oldUse) { + expr.setYieldValue(this.newUse); + } + } + + private caseUnopExpr(expr: ArkUnopExpr): void { + if (expr.getOp() === this.oldUse) { + expr.setOp(this.newUse); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/IRInference.ts b/ets2panda/linter/arkanalyzer/src/core/common/IRInference.ts new file mode 100644 index 0000000000000000000000000000000000000000..08083474900627f2a07599c37994fc757e87c692 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/IRInference.ts @@ -0,0 +1,836 @@ +/* + * 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. + */ +import { ArkMethod } from '../model/ArkMethod'; +import { + AliasType, + AnnotationNamespaceType, + AnyType, + ArrayType, + ClassType, + FunctionType, + GenericType, + LexicalEnvType, + NullType, + Type, + UnclearReferenceType, + UndefinedType, + UnionType, + UnknownType, +} from '../base/Type'; +import { Local } from '../base/Local'; +import { TypeInference } from './TypeInference'; +import { + AbstractExpr, + AbstractInvokeExpr, + AliasTypeExpr, + ArkInstanceInvokeExpr, + ArkPtrInvokeExpr, + ArkStaticInvokeExpr +} from '../base/Expr'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { Scene } from '../../Scene'; +import { ArkClass } from '../model/ArkClass'; +import { findArkExport, ModelUtils } from './ModelUtils'; +import { ArkField, FieldCategory } from '../model/ArkField'; +import { CALL_BACK } from './EtsConst'; +import { + AliasClassSignature, + BaseSignature, + ClassSignature, + FieldSignature, + MethodSignature, + MethodSubSignature +} from '../model/ArkSignature'; +import { CONSTRUCTOR_NAME, FUNCTION, IMPORT, SUPER_NAME, THIS_NAME } from './TSConst'; +import { Builtin } from './Builtin'; +import { ArkBody } from '../model/ArkBody'; +import { ArkAssignStmt, ArkInvokeStmt } from '../base/Stmt'; +import { + AbstractFieldRef, + AbstractRef, + ArkArrayRef, + ArkInstanceFieldRef, + ArkParameterRef, + ArkStaticFieldRef, + GlobalRef +} from '../base/Ref'; +import { Value } from '../base/Value'; +import { Constant } from '../base/Constant'; +import { + ANONYMOUS_CLASS_PREFIX, + CALL_SIGNATURE_NAME, + DEFAULT_ARK_CLASS_NAME, + NAME_DELIMITER, + NAME_PREFIX, + UNKNOWN_CLASS_NAME +} from './Const'; +import { ValueUtil } from './ValueUtil'; +import { ArkFile } from '../model/ArkFile'; +import { AbstractTypeExpr, KeyofTypeExpr, TypeQueryExpr } from '../base/TypeExpr'; +import { ArkBaseModel } from '../model/ArkBaseModel'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'IRInference'); + +export class IRInference { + private static inferExportInfos(file: ArkFile): void { + file.getExportInfos().forEach(exportInfo => { + if (exportInfo.getArkExport() === undefined) { + let arkExport = findArkExport(exportInfo); + exportInfo.setArkExport(arkExport); + if (arkExport) { + exportInfo.setExportClauseType(arkExport.getExportType()); + } + } + }); + file.getNamespaces().forEach(namespace => { + namespace.getExportInfos().forEach(exportInfo => { + if (exportInfo.getArkExport() === undefined) { + let arkExport = findArkExport(exportInfo); + exportInfo.setArkExport(arkExport); + arkExport !== null ? exportInfo.setExportClauseType(arkExport.getExportType()) : true; + } + }); + }); + } + + private static inferImportInfos(file: ArkFile): void { + file.getImportInfos().forEach(importInfo => { + importInfo.getLazyExportInfo(); + }); + } + + public static inferFile(file: ArkFile): void { + this.inferImportInfos(file); + ModelUtils.getAllClassesInFile(file).forEach(arkClass => { + TypeInference.inferGenericType(arkClass.getGenericsTypes(), arkClass); + const defaultArkMethod = arkClass.getDefaultArkMethod(); + if (defaultArkMethod) { + TypeInference.inferTypeInMethod(defaultArkMethod); + } + arkClass.getFields().forEach(arkField => TypeInference.inferTypeInArkField(arkField)); + const methods = arkClass.getMethods().sort((a, b) => { + const name = a.getName().split(NAME_DELIMITER).reverse().join(); + const anotherName = b.getName().split(NAME_DELIMITER).reverse().join(); + if (name.startsWith(anotherName)) { + return 1; + } else if (anotherName.startsWith(name)) { + return -1; + } + return 0; + }); + methods.forEach(arkMethod => TypeInference.inferTypeInMethod(arkMethod)); + }); + this.inferExportInfos(file); + } + + public static inferStaticInvokeExpr(expr: ArkStaticInvokeExpr, arkMethod: ArkMethod): AbstractInvokeExpr { + const arkClass = arkMethod.getDeclaringArkClass(); + const methodName = expr.getMethodSignature().getMethodSubSignature().getMethodName(); + expr.getArgs().forEach(arg => TypeInference.inferValueType(arg, arkMethod)); + if (methodName === IMPORT) { + const arg = expr.getArg(0); + let type; + if (arg instanceof Constant) { + type = TypeInference.inferDynamicImportType(arg.getValue(), arkClass); + } + if (type) { + expr.getMethodSignature().getMethodSubSignature().setReturnType(type); + } + return expr; + } else if (methodName === SUPER_NAME) { + const superClass = arkClass.getSuperClass(); + if (superClass !== null) { + const newMethodSignature = new MethodSignature(superClass.getSignature(), expr.getMethodSignature().getMethodSubSignature()); + expr.setMethodSignature(newMethodSignature); + } + return expr; + } + const className = expr.getMethodSignature().getDeclaringClassSignature().getClassName(); + if (className && className !== UNKNOWN_CLASS_NAME) { + const baseType = TypeInference.inferBaseType(className, arkClass); + if (baseType) { + let result = this.inferInvokeExpr(expr, baseType, methodName, arkClass.getDeclaringArkFile().getScene()); + if (result) { + this.inferArgs(result, arkMethod); + return result; + } + } + return expr; + } + return this.inferStaticInvokeExprByMethodName(methodName, arkMethod, expr); + } + + private static inferStaticInvokeExprByMethodName(methodName: string, arkMethod: ArkMethod, expr: AbstractInvokeExpr): AbstractInvokeExpr { + const arkClass = arkMethod.getDeclaringArkClass(); + const arkExport = + ModelUtils.getStaticMethodWithName(methodName, arkClass) ?? + arkMethod.getFunctionLocal(methodName) ?? + ModelUtils.findDeclaredLocal(new Local(methodName), arkMethod) ?? + ModelUtils.getArkExportInImportInfoWithName(methodName, arkClass.getDeclaringArkFile()) ?? + arkClass.getDeclaringArkFile().getScene().getSdkGlobal(methodName); + let method; + let signature; + if (arkExport instanceof ArkMethod) { + method = arkExport; + } else if (arkExport instanceof ArkClass) { + method = arkExport.getMethodWithName(CONSTRUCTOR_NAME); + } else if (arkExport instanceof Local) { + const type = TypeInference.replaceAliasType(arkExport.getType()); + if (type instanceof ClassType) { + const cls = arkClass.getDeclaringArkFile().getScene().getClass(type.getClassSignature()); + method = cls?.getMethodWithName(CONSTRUCTOR_NAME) ?? cls?.getMethodWithName(CALL_SIGNATURE_NAME); + } else if (type instanceof FunctionType) { + signature = type.getMethodSignature(); + } + } else if (arkExport instanceof AliasType && arkExport.getOriginalType() instanceof FunctionType) { + signature = (arkExport.getOriginalType() as FunctionType).getMethodSignature(); + } + if (method) { + signature = method.matchMethodSignature(expr.getArgs()); + TypeInference.inferSignatureReturnType(signature, method); + } + if (signature) { + if (arkExport instanceof Local) { + expr = new ArkPtrInvokeExpr(signature, arkExport, expr.getArgs(), expr.getRealGenericTypes()); + } else { + expr.setMethodSignature(signature); + } + this.inferArgs(expr, arkMethod); + } + return expr; + } + + public static inferInstanceInvokeExpr(expr: ArkInstanceInvokeExpr, arkMethod: ArkMethod): AbstractInvokeExpr { + const arkClass = arkMethod.getDeclaringArkClass(); + TypeInference.inferRealGenericTypes(expr.getRealGenericTypes(), arkClass); + this.inferBase(expr, arkMethod); + + const baseType: Type = TypeInference.replaceAliasType(expr.getBase().getType()); + let methodName = expr.getMethodSignature().getMethodSubSignature().getMethodName(); + if (methodName.startsWith(NAME_PREFIX)) { + const declaringStmt = arkMethod.getBody()?.getLocals().get(methodName)?.getDeclaringStmt(); + if (declaringStmt instanceof ArkAssignStmt && declaringStmt.getRightOp() instanceof ArkInstanceFieldRef) { + const rightOp = declaringStmt.getRightOp() as ArkInstanceFieldRef; + methodName = rightOp.getBase().getName() + '.' + rightOp.getFieldName(); + } + } + const scene = arkClass.getDeclaringArkFile().getScene(); + if (methodName === 'forEach' && baseType instanceof ArrayType) { + this.processForEach(expr.getArg(0), baseType, scene); + return expr; + } + expr.getArgs().forEach(arg => TypeInference.inferValueType(arg, arkMethod)); + let result = this.inferInvokeExpr(expr, baseType, methodName, scene) ?? this.processExtendFunc(expr, arkMethod, methodName); + if (result) { + this.inferArgs(result, arkMethod); + return result; + } + logger.warn('invoke ArkInstanceInvokeExpr MethodSignature type fail: ', expr.toString()); + return expr; + } + + /** + * process arkUI function with Annotation @Extend @Styles @AnimatableExtend + * @param expr + * @param arkMethod + * @param methodName + */ + private static processExtendFunc(expr: AbstractInvokeExpr, arkMethod: ArkMethod, methodName: string): AbstractInvokeExpr | null { + const type = TypeInference.inferBaseType(methodName, arkMethod.getDeclaringArkClass()); + if (type instanceof FunctionType) { + const methodSignature = type.getMethodSignature(); + // because of last stmt is ArkReturnVoidStmt, the ArkInvokeStmt at -2 before ArkReturnVoidStmt. + const endIndex = -2; + const endStmt = arkMethod.getDeclaringArkFile().getScene().getMethod(methodSignature)?.getCfg()?.getStmts().at(endIndex); + if (endStmt instanceof ArkInvokeStmt) { + methodSignature.getMethodSubSignature().setReturnType(endStmt.getInvokeExpr().getType()); + } + expr.setMethodSignature(methodSignature); + return expr; + } + return null; + } + + public static inferFieldRef(ref: ArkInstanceFieldRef, arkMethod: ArkMethod): AbstractRef { + this.inferBase(ref, arkMethod); + const baseType: Type = TypeInference.replaceAliasType(ref.getBase().getType()); + if (baseType instanceof ArrayType && ref.getFieldName() !== 'length') { + return new ArkArrayRef(ref.getBase(), ValueUtil.createConst(ref.getFieldName())); + } + + let newFieldSignature = this.generateNewFieldSignature(ref, arkMethod.getDeclaringArkClass(), baseType); + if (newFieldSignature) { + if (newFieldSignature.isStatic()) { + return new ArkStaticFieldRef(newFieldSignature); + } + ref.setFieldSignature(newFieldSignature); + } + return ref; + } + + private static inferBase(instance: ArkInstanceFieldRef | ArkInstanceInvokeExpr, arkMethod: ArkMethod): void { + const base = instance.getBase(); + if (base.getName() === THIS_NAME) { + const declaringArkClass = arkMethod.getDeclaringArkClass(); + if (declaringArkClass.isAnonymousClass()) { + let newBase = this.inferThisLocal(arkMethod); + if (newBase) { + instance.setBase(newBase); + } + } else if (base.getType() instanceof UnknownType) { + base.setType(new ClassType(declaringArkClass.getSignature(), declaringArkClass.getRealTypes())); + } + } else { + const value = arkMethod.getBody()?.getUsedGlobals()?.get(base.getName()); + if (value instanceof GlobalRef && !value.getRef()) { + const arkExport = ModelUtils.findGlobalRef(base.getName(), arkMethod); + if (arkExport instanceof Local) { + arkExport.getUsedStmts().push(...base.getUsedStmts()); + value.setRef(arkExport); + } + } + this.inferLocal(instance.getBase(), arkMethod); + } + } + + public static inferThisLocal(arkMethod: ArkMethod): Local | null { + const arkClass = arkMethod.getDeclaringArkClass(); + if (!arkClass.isAnonymousClass()) { + return null; + } + + const value = arkMethod.getBody()?.getUsedGlobals()?.get(THIS_NAME); + if (value instanceof Local) { + return value; + } else { + const thisType = TypeInference.inferBaseType(arkClass.getSignature().getDeclaringClassName(), arkClass); + if (thisType instanceof ClassType) { + const newBase = new Local(THIS_NAME, thisType); + let usedGlobals = arkMethod.getBody()?.getUsedGlobals(); + if (!usedGlobals) { + usedGlobals = new Map(); + arkMethod.getBody()?.setUsedGlobals(usedGlobals); + } + usedGlobals.set(THIS_NAME, newBase); + return newBase; + } + } + return null; + } + + private static inferArgs(expr: AbstractInvokeExpr, arkMethod: ArkMethod): void { + const scene = arkMethod.getDeclaringArkFile().getScene(); + const parameters = expr.getMethodSignature().getMethodSubSignature().getParameters(); + let realTypes: Type[] = []; + const len = expr.getArgs().length; + for (let index = 0; index < len; index++) { + const arg = expr.getArg(index); + if (index >= parameters.length) { + break; + } + const argType = arg.getType(); + const paramType = parameters[index].getType(); + this.inferArg(expr, argType, paramType, scene, realTypes); + } + if (realTypes.length > 0 && !expr.getRealGenericTypes()) { + expr.setRealGenericTypes(realTypes); + } + } + + private static inferArg(expr: AbstractInvokeExpr, argType: Type, paramType: Type, scene: Scene, realTypes: Type[]): void { + if (paramType instanceof UnionType) { + paramType.getTypes().forEach(t => this.inferArg(expr, argType, t, scene, realTypes)); + } else if (paramType instanceof AliasType) { + this.inferArg(expr, argType, paramType.getOriginalType(), scene, realTypes); + } else if (paramType instanceof ArrayType && argType instanceof ArrayType) { + this.inferArg(expr, argType.getBaseType(), paramType.getBaseType(), scene, realTypes); + } else if (expr instanceof ArkInstanceInvokeExpr && expr.getBase().getType() instanceof ArrayType) { + if (paramType instanceof ArrayType && paramType.getBaseType() instanceof GenericType) { + this.inferArg(expr, argType, (expr.getBase().getType() as ArrayType).getBaseType(), scene, realTypes); + } + } + + if (paramType instanceof ClassType && scene.getProjectSdkMap().has(paramType.getClassSignature().getDeclaringFileSignature().getProjectName())) { + this.inferArgTypeWithSdk(paramType, scene, argType); + } else if (paramType instanceof GenericType || paramType instanceof AnyType) { + realTypes.push(argType); + } else if (paramType instanceof FunctionType && argType instanceof FunctionType) { + if (paramType.getMethodSignature().getParamLength() > 0 && paramType.getMethodSignature().getType() instanceof GenericType) { + const paramMethod = scene.getMethod(expr.getMethodSignature()); + const argMethod = scene.getMethod(argType.getMethodSignature()); + if (paramMethod && paramMethod.getGenericTypes() && argMethod) { + TypeInference.inferTypeInMethod(argMethod); + } + } + const realTypes = expr.getRealGenericTypes(); + TypeInference.inferFunctionType(argType, paramType.getMethodSignature().getMethodSubSignature(), realTypes); + } + } + + public static inferRightWithSdkType(leftType: Type, rightType: Type, ackClass: ArkClass): void { + if (leftType instanceof AliasType) { + this.inferRightWithSdkType(TypeInference.replaceAliasType(leftType), rightType, ackClass); + } else if (leftType instanceof UnionType) { + leftType.getTypes().forEach(t => this.inferRightWithSdkType(t, rightType, ackClass)); + } else if (leftType instanceof ClassType) { + IRInference.inferArgTypeWithSdk(leftType, ackClass.getDeclaringArkFile().getScene(), rightType); + } else if (rightType instanceof ArrayType && leftType instanceof ArrayType) { + const baseType = TypeInference.replaceAliasType(leftType.getBaseType()); + if (baseType instanceof ClassType) { + IRInference.inferArgTypeWithSdk(baseType, ackClass.getDeclaringArkFile().getScene(), rightType.getBaseType()); + } + } + } + + public static inferArgTypeWithSdk(sdkType: ClassType, scene: Scene, argType: Type): void { + if (!scene.getProjectSdkMap().has(sdkType.getClassSignature().getDeclaringFileSignature().getProjectName())) { + return; + } + if (argType instanceof UnionType) { + argType.getTypes().forEach(t => this.inferArgTypeWithSdk(sdkType, scene, t)); + } else if (argType instanceof ClassType && argType.getClassSignature().getClassName().startsWith(ANONYMOUS_CLASS_PREFIX)) { + this.inferAnonymousClass(scene.getClass(argType.getClassSignature()), sdkType.getClassSignature()); + } else if (argType instanceof FunctionType) { + const param = scene.getClass(sdkType.getClassSignature())?.getMethodWithName(CALL_SIGNATURE_NAME)?.getSignature().getMethodSubSignature(); + const realTypes = sdkType.getRealGenericTypes(); + TypeInference.inferFunctionType(argType, param, realTypes); + } + } + + private static inferInvokeExpr(expr: AbstractInvokeExpr, baseType: Type, methodName: string, scene: Scene): AbstractInvokeExpr | null { + if (baseType instanceof AliasType) { + return this.inferInvokeExpr(expr, baseType.getOriginalType(), methodName, scene); + } else if (baseType instanceof UnionType) { + for (let type of baseType.flatType()) { + if (type instanceof UndefinedType || type instanceof NullType) { + continue; + } + let result = this.inferInvokeExpr(expr, type, methodName, scene); + if (result) { + return result; + } + } + } + if (baseType instanceof ClassType) { + return this.inferInvokeExprWithDeclaredClass(expr, baseType, methodName, scene); + } else if (baseType instanceof AnnotationNamespaceType) { + const namespace = scene.getNamespace(baseType.getNamespaceSignature()); + if (namespace) { + const foundMethod = ModelUtils.findPropertyInNamespace(methodName, namespace); + if (foundMethod instanceof ArkMethod) { + let signature = foundMethod.matchMethodSignature(expr.getArgs()); + TypeInference.inferSignatureReturnType(signature, foundMethod); + expr.setMethodSignature(signature); + return expr instanceof ArkInstanceInvokeExpr ? new ArkStaticInvokeExpr(signature, expr.getArgs(), expr.getRealGenericTypes()) : expr; + } + } + } else if (baseType instanceof FunctionType) { + return IRInference.inferInvokeExprWithFunction(methodName, expr, baseType, scene); + } else if (baseType instanceof ArrayType) { + return IRInference.inferInvokeExprWithArray(methodName, expr, baseType, scene); + } + return null; + } + + private static inferInvokeExprWithArray(methodName: string, expr: AbstractInvokeExpr, baseType: ArrayType, scene: Scene): AbstractInvokeExpr | null { + if (methodName === Builtin.ITERATOR_FUNCTION) { + const returnType = expr.getMethodSignature().getMethodSubSignature().getReturnType(); + if (returnType instanceof ClassType && returnType.getClassSignature().getDeclaringFileSignature().getProjectName() === Builtin.DUMMY_PROJECT_NAME) { + expr.setRealGenericTypes([baseType.getBaseType()]); + return expr; + } + } else { + const arrayInterface = scene.getSdkGlobal(Builtin.ARRAY); + if (arrayInterface instanceof ArkClass) { + return this.inferInvokeExpr(expr, new ClassType(arrayInterface.getSignature(), [baseType.getBaseType()]), methodName, scene); + } + } + return null; + } + + private static inferInvokeExprWithFunction(methodName: string, expr: AbstractInvokeExpr, baseType: FunctionType, scene: Scene): AbstractInvokeExpr | null { + if (methodName === CALL_SIGNATURE_NAME) { + expr.setMethodSignature(baseType.getMethodSignature()); + return expr; + } + const funcInterface = scene.getSdkGlobal(FUNCTION); + if (funcInterface instanceof ArkClass) { + const method = ModelUtils.findPropertyInClass(methodName, funcInterface); + if (method instanceof ArkMethod) { + expr.setRealGenericTypes([baseType]); + expr.setMethodSignature(method.getSignature()); + return expr; + } + } + return null; + } + + private static inferInvokeExprWithDeclaredClass( + expr: AbstractInvokeExpr, + baseType: ClassType, + methodName: string, + scene: Scene + ): AbstractInvokeExpr | null { + if (Builtin.isBuiltinClass(baseType.getClassSignature().getClassName())) { + expr.setMethodSignature(new MethodSignature(baseType.getClassSignature(), expr.getMethodSignature().getMethodSubSignature())); + } + let declaredClass = scene.getClass(baseType.getClassSignature()); + if (!declaredClass) { + const globalClass = scene.getSdkGlobal(baseType.getClassSignature().getClassName()); + if (globalClass instanceof ArkClass) { + declaredClass = globalClass; + } + } + const method = declaredClass ? ModelUtils.findPropertyInClass(methodName, declaredClass) : null; + if (method instanceof ArkMethod) { + const methodSignature = method.matchMethodSignature(expr.getArgs()); + TypeInference.inferSignatureReturnType(methodSignature, method); + expr.setMethodSignature(this.replaceMethodSignature(expr.getMethodSignature(), methodSignature)); + expr.setRealGenericTypes(IRInference.getRealTypes(method, declaredClass, baseType)); + if (method.isStatic() && expr instanceof ArkInstanceInvokeExpr) { + return new ArkStaticInvokeExpr(methodSignature, expr.getArgs(), expr.getRealGenericTypes()); + } + return expr; + } else if (method instanceof ArkField) { + const type = method.getType(); + let methodSignature; + if (type instanceof FunctionType) { + methodSignature = type.getMethodSignature(); + } else if (type instanceof ClassType && type.getClassSignature().getClassName().endsWith(CALL_BACK)) { + const callback = scene.getClass(type.getClassSignature())?.getMethodWithName(CALL_SIGNATURE_NAME); + if (callback) { + methodSignature = callback.getSignature(); + } + } + if (methodSignature) { + const ptr = + expr instanceof ArkInstanceInvokeExpr + ? new ArkInstanceFieldRef(expr.getBase(), method.getSignature()) + : new ArkStaticFieldRef(method.getSignature()); + expr = new ArkPtrInvokeExpr(methodSignature, ptr, expr.getArgs(), expr.getRealGenericTypes()); + } + return expr; + } else if (methodName === CONSTRUCTOR_NAME) { + //sdk隐式构造 + const subSignature = new MethodSubSignature(methodName, [], new ClassType(baseType.getClassSignature())); + expr.setMethodSignature(new MethodSignature(baseType.getClassSignature(), subSignature)); + return expr; + } else if (methodName === Builtin.ITERATOR_NEXT) { + //sdk隐式构造 + const returnType = expr.getMethodSignature().getMethodSubSignature().getReturnType(); + if (returnType instanceof ClassType && returnType.getClassSignature().getDeclaringFileSignature().getProjectName() === Builtin.DUMMY_PROJECT_NAME) { + returnType.setRealGenericTypes(baseType.getRealGenericTypes()); + return expr; + } + } + return null; + } + + private static getRealTypes(method: ArkMethod, declaredClass: ArkClass | null, baseType: ClassType): Type[] | undefined { + let realTypes; + if (method.getDeclaringArkClass() === declaredClass) { + realTypes = baseType.getRealGenericTypes(); + } else if (declaredClass?.getRealTypes()) { + realTypes = declaredClass?.getRealTypes(); + } else if (declaredClass?.hasComponentDecorator()) { + realTypes = [new ClassType(declaredClass?.getSignature())]; + } + return realTypes; + } + + public static replaceMethodSignature(init: MethodSignature, declared: MethodSignature): MethodSignature { + const className = init.getDeclaringClassSignature().getClassName(); + let classSignature; + if (declared.getDeclaringClassSignature().getClassName().endsWith('Interface')) { + classSignature = new AliasClassSignature(className, declared.getDeclaringClassSignature()); + } + let newSubSignature; + if (classSignature || newSubSignature) { + return new MethodSignature(classSignature ?? declared.getDeclaringClassSignature(), newSubSignature ?? declared.getMethodSubSignature()); + } + return declared; + } + + private static processForEach(arg: Value, baseType: ArrayType, scene: Scene): void { + const argType = arg.getType(); + if (argType instanceof FunctionType) { + const argMethodSignature = argType.getMethodSignature(); + const argMethod = scene.getMethod(argMethodSignature); + if (argMethod != null && argMethod.getBody()) { + const body = argMethod.getBody() as ArkBody; + const firstStmt = body.getCfg().getStartingStmt(); + if (firstStmt instanceof ArkAssignStmt && firstStmt.getRightOp() instanceof ArkParameterRef) { + const parameterRef = firstStmt.getRightOp() as ArkParameterRef; + parameterRef.setType(baseType.getBaseType()); + const argMethodParams = argMethod.getSignature().getMethodSubSignature().getParameters(); + const actualParam = argMethodParams[argMethodParams.length - 1]; + actualParam.setType(baseType.getBaseType()); + } + TypeInference.inferTypeInMethod(argMethod); + } + } else { + logger.warn(`arg of forEach must be callable`); + } + } + + public static inferLocal(base: Local, arkMethod: ArkMethod): void { + const arkClass = arkMethod.getDeclaringArkClass(); + let baseType: Type | null | undefined = base.getType(); + if (baseType instanceof UnclearReferenceType) { + baseType = TypeInference.inferUnclearRefName(baseType.getName(), arkClass); + } else if (TypeInference.isUnclearType(baseType)) { + const declaringStmt = base.getDeclaringStmt(); + if (!declaringStmt || !declaringStmt.getOriginalText() || declaringStmt.getOriginalText()?.startsWith(base.getName())) { + baseType = ModelUtils.findDeclaredLocal(base, arkMethod)?.getType() ?? TypeInference.inferBaseType(base.getName(), arkClass); + } + } + if (baseType instanceof UnionType || (baseType && !TypeInference.isUnclearType(baseType))) { + base.setType(baseType); + } + } + + private static generateNewFieldSignature(ref: AbstractFieldRef, arkClass: ArkClass, baseType: Type): FieldSignature | null { + if (baseType instanceof UnionType) { + for (let type of baseType.flatType()) { + if (type instanceof UndefinedType || type instanceof NullType) { + continue; + } + let newFieldSignature = this.generateNewFieldSignature(ref, arkClass, type); + if (!TypeInference.isUnclearType(newFieldSignature?.getType())) { + return newFieldSignature; + } + } + return null; + } else if (baseType instanceof AliasType) { + return this.generateNewFieldSignature(ref, arkClass, baseType.getOriginalType()); + } + const fieldName = ref.getFieldName().replace(/[\"|\']/g, ''); + const propertyAndType = TypeInference.inferFieldType(baseType, fieldName, arkClass); + let propertyType = propertyAndType?.[1]; + if (!propertyType || propertyType instanceof UnknownType) { + const newType = TypeInference.inferBaseType(fieldName, arkClass); + if (newType) { + propertyType = newType; + } + } else if (TypeInference.isUnclearType(propertyType)) { + const newType = TypeInference.inferUnclearedType(propertyType, arkClass); + if (newType) { + propertyType = newType; + } + } + let staticFlag: boolean; + let signature: BaseSignature; + if (baseType instanceof ClassType) { + const property = propertyAndType?.[0]; + if (property instanceof ArkField && property.getCategory() !== FieldCategory.ENUM_MEMBER) { + return property.getSignature(); + } + staticFlag = + baseType.getClassSignature().getClassName() === DEFAULT_ARK_CLASS_NAME || + ((property instanceof ArkField || property instanceof ArkMethod) && property.isStatic()); + signature = property instanceof ArkMethod ? property.getSignature().getDeclaringClassSignature() : baseType.getClassSignature(); + } else if (baseType instanceof AnnotationNamespaceType) { + staticFlag = true; + signature = baseType.getNamespaceSignature(); + } else { + return null; + } + return new FieldSignature(fieldName, signature, propertyType ?? ref.getType(), staticFlag); + } + + public static inferAnonymousClass(anon: ArkClass | null, declaredSignature: ClassSignature, set: Set = new Set()): void { + if (!anon) { + return; + } + const key = anon.getSignature().toString(); + if (set.has(key)) { + return; + } else { + set.add(key); + } + const scene = anon.getDeclaringArkFile().getScene(); + const declaredClass = scene.getClass(declaredSignature); + if (!declaredClass) { + return; + } + for (const anonField of anon.getFields()) { + const property = ModelUtils.findPropertyInClass(anonField.getName(), declaredClass); + if (property instanceof ArkField) { + this.assignAnonField(property, anonField, scene, set); + } else if (property instanceof ArkMethod) { + const type = anonField.getType(); + if (type instanceof FunctionType) { + this.assignAnonMethod(scene.getMethod(type.getMethodSignature()), property); + } + anonField.setSignature( + new FieldSignature(anonField.getName(), property.getDeclaringArkClass().getSignature(), new FunctionType(property.getSignature())) + ); + } + } + for (const anonMethod of anon.getMethods()) { + this.assignAnonMethod(anonMethod, declaredClass.getMethodWithName(anonMethod.getName())); + } + } + + private static assignAnonMethod(anonMethod: ArkMethod | null, declaredMethod: ArkMethod | null): void { + if (declaredMethod && anonMethod) { + anonMethod.setImplementationSignature(declaredMethod.matchMethodSignature(anonMethod.getSubSignature().getParameters())); + } + } + + private static assignAnonField(property: ArkField, anonField: ArkField, scene: Scene, set: Set): void { + function deepInfer(anonType: Type, declaredSignature: ClassSignature): void { + if (anonType instanceof ClassType && anonType.getClassSignature().getClassName().startsWith(ANONYMOUS_CLASS_PREFIX)) { + IRInference.inferAnonymousClass(scene.getClass(anonType.getClassSignature()), declaredSignature, set); + } + } + + const type = property.getSignature().getType(); + const lastStmt = anonField.getInitializer().at(-1); + if (lastStmt instanceof ArkAssignStmt) { + const rightType = lastStmt.getRightOp().getType(); + if (type instanceof ClassType) { + deepInfer(rightType, type.getClassSignature()); + } else if (type instanceof ArrayType && type.getBaseType() instanceof ClassType && rightType instanceof ArrayType) { + const baseType = rightType.getBaseType(); + const classSignature = (type.getBaseType() as ClassType).getClassSignature(); + if (baseType instanceof UnionType) { + baseType.getTypes().forEach(t => deepInfer(t, classSignature)); + } else { + deepInfer(rightType.getBaseType(), classSignature); + } + } else if (type instanceof FunctionType && rightType instanceof FunctionType) { + TypeInference.inferFunctionType(rightType, type.getMethodSignature().getMethodSubSignature(), type.getRealGenericTypes()); + } + const leftOp = lastStmt.getLeftOp(); + if (leftOp instanceof AbstractFieldRef) { + leftOp.setFieldSignature(property.getSignature()); + } + } + anonField.setSignature(property.getSignature()); + } + + public static inferAliasTypeExpr(expr: AliasTypeExpr, arkMethod: ArkMethod): AbstractExpr { + const originalObject = expr.getOriginalObject(); + let model; + if (originalObject instanceof Local) { + model = ModelUtils.findArkModelByRefName(originalObject.getName(), arkMethod.getDeclaringArkClass()); + } else if (originalObject instanceof AbstractTypeExpr) { + originalObject.inferType(arkMethod); + model = originalObject; + } else if (originalObject instanceof Type) { + const type = TypeInference.inferUnclearedType(originalObject, arkMethod.getDeclaringArkClass()); + + // If original Object is ClassType, AliasType or UnclearReferenceType with real generic types, + // the type after infer should be revert back to the object itself. + if (type instanceof ClassType) { + const scene = arkMethod.getDeclaringArkFile().getScene(); + model = ModelUtils.findArkModelBySignature(type.getClassSignature(), scene); + } else if (type instanceof AliasType) { + const scene = arkMethod.getDeclaringArkFile().getScene(); + model = ModelUtils.findArkModelBySignature(type.getSignature(), scene); + } else if (type) { + model = type; + } + if (expr.getRealGenericTypes() !== undefined && originalObject instanceof UnclearReferenceType) { + expr.setRealGenericTypes(originalObject.getGenericTypes()); + } + } + + if (AliasTypeExpr.isAliasTypeOriginalModel(model)) { + expr.setOriginalObject(model); + } + return expr; + } + + public static inferTypeQueryExpr(expr: TypeQueryExpr, arkMethod: ArkMethod): void { + let gTypes = expr.getGenerateTypes(); + if (gTypes) { + for (let i = 0; i < gTypes.length; i++) { + const newType = TypeInference.inferUnclearedType(gTypes[i], arkMethod.getDeclaringArkClass()); + if (newType) { + gTypes[i] = newType; + } + } + } + + const opValue = expr.getOpValue(); + let opValueType; + if (opValue instanceof ArkBaseModel) { + opValueType = ModelUtils.parseArkBaseModel2Type(opValue) ?? UnknownType.getInstance(); + } else { + opValueType = opValue.getType(); + } + + if (!TypeInference.isUnclearType(opValueType)) { + return; + } + if (opValue instanceof Local) { + const newOpValueType = TypeInference.inferBaseType(opValue.getName(), arkMethod.getDeclaringArkClass()); + const scene = arkMethod.getDeclaringArkFile().getScene(); + if (newOpValueType instanceof ClassType) { + const newOpValue = ModelUtils.findArkModelBySignature(newOpValueType.getClassSignature(), scene); + if (newOpValue instanceof ArkBaseModel) { + expr.setOpValue(newOpValue); + } + } else if (newOpValueType instanceof FunctionType) { + const newOpValue = ModelUtils.findArkModelBySignature(newOpValueType.getMethodSignature(), scene); + if (newOpValue instanceof ArkBaseModel) { + expr.setOpValue(newOpValue); + } + } else { + this.inferLocal(opValue, arkMethod); + } + } else if (opValue instanceof AbstractRef || opValue instanceof AbstractExpr) { + expr.setOpValue(opValue.inferType(arkMethod)); + } + } + + public static inferKeyofTypeExpr(expr: KeyofTypeExpr, arkMethod: ArkMethod): void { + const opType = expr.getOpType(); + if (TypeInference.isUnclearType(opType)) { + if (opType instanceof TypeQueryExpr) { + this.inferTypeQueryExpr(opType, arkMethod); + } else { + const type = TypeInference.inferUnclearedType(opType, arkMethod.getDeclaringArkClass()); + if (type) { + expr.setOpType(type); + } + } + } + } + + public static inferParameterRef(ref: ArkParameterRef, arkMethod: ArkMethod): AbstractRef { + const paramType = ref.getType(); + if (paramType instanceof UnknownType || paramType instanceof UnclearReferenceType) { + const type1 = arkMethod.getSignature().getMethodSubSignature().getParameters()[ref.getIndex()]?.getType(); + if (!TypeInference.isUnclearType(type1)) { + ref.setType(type1); + return ref; + } + } else if (paramType instanceof LexicalEnvType) { + paramType + .getClosures() + .filter(c => TypeInference.isUnclearType(c.getType())) + .forEach(e => this.inferLocal(e, arkMethod)); + return ref; + } + let type = TypeInference.inferUnclearedType(paramType, arkMethod.getDeclaringArkClass()); + if (type) { + ref.setType(type); + } + return ref; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/IRUtils.ts b/ets2panda/linter/arkanalyzer/src/core/common/IRUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6b5ea378ea243bbf73f9dc2ebde3bb9f45e4a32 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/IRUtils.ts @@ -0,0 +1,154 @@ +/* + * 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. + */ + +import { AbstractBinopExpr, AbstractInvokeExpr, ArkCastExpr, ArkUnopExpr } from '../base/Expr'; +import { AbstractFieldRef, AbstractRef, ArkArrayRef, ArkInstanceFieldRef, ArkStaticFieldRef } from '../base/Ref'; +import { Value } from '../base/Value'; +import { Scene } from '../../Scene'; +import ts from 'ohos-typescript'; +import { SceneOptions } from '../../Config'; +import { ArkMetadataKind, CommentItem, CommentsMetadata } from '../model/ArkMetadata'; +import { Stmt } from '../base/Stmt'; +import { ArkBaseModel } from '../model/ArkBaseModel'; +import { FullPosition } from '../base/Position'; +import { Local } from '../base/Local'; +import { NAME_PREFIX } from './Const'; + +export class IRUtils { + public static moreThanOneAddress(value: Value): boolean { + if ( + value instanceof AbstractBinopExpr || + value instanceof AbstractInvokeExpr || + value instanceof AbstractFieldRef || + value instanceof ArkArrayRef || + value instanceof ArkCastExpr || + value instanceof ArkUnopExpr + ) { + return true; + } + return false; + } + + public static generateTextForStmt(scene: Scene): void { + for (const method of scene.getMethods()) { + const cfg = method.getCfg(); + if (cfg) { + for (const stmt of cfg.getStmts()) { + stmt.setText(stmt.toString()); + } + } + } + } + + public static setComments(metadata: Stmt | ArkBaseModel, node: ts.Node, sourceFile: ts.SourceFile, options: SceneOptions): void { + const leadingCommentsMetadata = this.getCommentsMetadata(node, sourceFile, options, true); + if (leadingCommentsMetadata.getComments().length > 0) { + metadata.setMetadata(ArkMetadataKind.LEADING_COMMENTS, leadingCommentsMetadata); + } + + const trailingCommentsMetadata = this.getCommentsMetadata(node, sourceFile, options, false); + if (trailingCommentsMetadata.getComments().length > 0) { + metadata.setMetadata(ArkMetadataKind.TRAILING_COMMENTS, trailingCommentsMetadata); + } + } + + public static getCommentsMetadata(node: ts.Node, sourceFile: ts.SourceFile, options: SceneOptions, isLeading: boolean): CommentsMetadata { + const comments: CommentItem[] = []; + if ((isLeading && !options.enableLeadingComments) || (!isLeading && !options.enableTrailingComments)) { + return new CommentsMetadata(comments); + } + + // node.pos is the start position of + const commentRanges = + (isLeading ? ts.getLeadingCommentRanges(sourceFile.text, node.pos) : ts.getTrailingCommentRanges(sourceFile.text, node.end)) || []; + // leading comment, while node.end is the + // end position of the statement + const getPosition = (pos: number, end: number): FullPosition => { + const start = ts.getLineAndCharacterOfPosition(sourceFile, pos); + const endPos = ts.getLineAndCharacterOfPosition(sourceFile, end); + return new FullPosition(start.line + 1, start.character + 1, endPos.line + 1, endPos.character + 1); + }; + + for (const range of commentRanges) { + comments.push({ + content: sourceFile.text.substring(range.pos, range.end).replace(/\r\n/g, '\n'), + position: getPosition(range.pos, range.end), + }); + } + + return new CommentsMetadata(comments); + } + + public static isTempLocal(value: Value): boolean { + return value instanceof Local && value.getName().startsWith(NAME_PREFIX); + } + + public static findOperandIdx(stmt: Stmt, operand: Value): number { + let index: number = -1; + const operands = stmt.getDefAndUses(); + for (let i = 0; i < operands.length; i++) { + if (operands[i] === operand) { + index = i; + break; + } + } + return index; + } + + public static adjustOperandOriginalPositions(stmt: Stmt, oldValue: Value, newValue: Value): void { + const operandOriginalPositions = stmt.getOperandOriginalPositions(); + if (!operandOriginalPositions) { + return; + } + const operandOriginalPositionSize = operandOriginalPositions.length; + const defUseSize = stmt.getDefAndUses().length; + const oldValueUseSize = oldValue.getUses().length; + const newValueUseSize = newValue.getUses().length; + const oldValueIdx = IRUtils.findOperandIdx(stmt, oldValue); + const baseValueOffset = 1; + const fieldValueOffset = 2; + + if (oldValue instanceof AbstractRef && newValue instanceof AbstractRef) { + if (newValue instanceof ArkStaticFieldRef) { + operandOriginalPositions.splice(oldValueIdx + baseValueOffset, oldValueUseSize - newValueUseSize); + } else if (oldValue instanceof ArkStaticFieldRef) { + operandOriginalPositions.splice(oldValueIdx + baseValueOffset, 0, ...IRUtils.generateDefaultPositions(newValueUseSize - oldValueUseSize)); + } + + if (oldValue instanceof ArkInstanceFieldRef && newValue instanceof ArkArrayRef) { + if (operandOriginalPositionSize === defUseSize) { + // may not reserve positions for field name + operandOriginalPositions.splice(oldValueIdx + fieldValueOffset, 0, ...IRUtils.generateDefaultPositions(newValueUseSize - oldValueUseSize)); + } + } else if (oldValue instanceof ArkArrayRef && newValue instanceof ArkInstanceFieldRef) { + operandOriginalPositions.splice(oldValueIdx + fieldValueOffset, oldValueUseSize - newValueUseSize); + } + } else if (oldValue instanceof AbstractInvokeExpr && newValue instanceof AbstractInvokeExpr) { + if (oldValueUseSize === newValueUseSize + 1) { + operandOriginalPositions.splice(oldValueIdx + baseValueOffset, 1); + } else if (oldValueUseSize === newValueUseSize - 1) { + operandOriginalPositions.splice(oldValueIdx + baseValueOffset, 0, FullPosition.DEFAULT); + } + } + } + + public static generateDefaultPositions(count: number): FullPosition[] { + const defaultPositions: FullPosition[] = []; + for (let i = 0; i < count; i++) { + defaultPositions.push(FullPosition.DEFAULT); + } + return defaultPositions; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ModelUtils.ts b/ets2panda/linter/arkanalyzer/src/core/common/ModelUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..7b90129608f4f99a927f46f22ad6f4491e4f6572 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/ModelUtils.ts @@ -0,0 +1,772 @@ +/* + * 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. + */ + +import { Local } from '../base/Local'; +import { ArkClass } from '../model/ArkClass'; +import { ArkFile } from '../model/ArkFile'; +import { ArkMethod } from '../model/ArkMethod'; +import { ArkNamespace } from '../model/ArkNamespace'; +import { + AliasTypeSignature, + ClassSignature, + FieldSignature, + FileSignature, + fileSignatureCompare, + LocalSignature, + MethodSignature, + NamespaceSignature, + Signature, +} from '../model/ArkSignature'; +import { ArkExport, ExportInfo, ExportType, FromInfo } from '../model/ArkExport'; +import { ArkField } from '../model/ArkField'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { FileUtils, ModulePath } from '../../utils/FileUtils'; +import path from 'path'; +import { Sdk } from '../../Config'; +import { ALL, DEFAULT, THIS_NAME } from './TSConst'; +import { buildDefaultExportInfo } from '../model/builder/ArkExportBuilder'; +import { + AnnotationNamespaceType, + ClassType, + FunctionType, + Type, + UnclearReferenceType, + UnknownType +} from '../base/Type'; +import { Scene } from '../../Scene'; +import { DEFAULT_ARK_CLASS_NAME, DEFAULT_ARK_METHOD_NAME, NAME_DELIMITER, TEMP_LOCAL_PREFIX } from './Const'; +import { EMPTY_STRING } from './ValueUtil'; +import { ArkBaseModel } from '../model/ArkBaseModel'; +import { ArkAssignStmt } from '../base/Stmt'; +import { ClosureFieldRef } from '../base/Ref'; +import { SdkUtils } from './SdkUtils'; + +export class ModelUtils { + public static implicitArkUIBuilderMethods: Set = new Set(); + + public static getMethodSignatureFromArkClass(arkClass: ArkClass, methodName: string): MethodSignature | null { + for (const arkMethod of arkClass.getMethods()) { + if (arkMethod.getName() === methodName) { + return arkMethod.getSignature(); + } + } + return null; + } + + public static getClassWithNameInNamespaceRecursively(className: string, ns: ArkNamespace): ArkClass | null { + if (className === '') { + return null; + } + let res: ArkClass | null = null; + res = ns.getClassWithName(className); + if (res == null) { + let declaringNs = ns.getDeclaringArkNamespace(); + if (declaringNs != null) { + res = this.getClassWithNameInNamespaceRecursively(className, declaringNs); + } else { + res = this.getClassInFileWithName(className, ns.getDeclaringArkFile()); + } + } + return res; + } + + public static getClassWithNameFromClass(className: string, startFrom: ArkClass): ArkClass | null { + if (!className.includes('.')) { + let res: ArkClass | null = null; + const arkNamespace = startFrom.getDeclaringArkNamespace(); + if (arkNamespace) { + res = this.getClassWithNameInNamespaceRecursively(className, arkNamespace); + } else { + res = this.getClassInFileWithName(className, startFrom.getDeclaringArkFile()); + } + return res; + } else { + const names = className.split('.'); + let nameSpace = this.getNamespaceWithNameFromClass(names[0], startFrom); + for (let i = 1; i < names.length - 1; i++) { + if (nameSpace) { + nameSpace = nameSpace.getNamespaceWithName(names[i]); + } + } + if (nameSpace) { + return nameSpace.getClassWithName(names[names.length - 1]); + } + } + return null; + } + + /** + * search class within the file that contain the given method + */ + public static getClassWithName(className: string, thisClass: ArkClass): ArkClass | null { + if (thisClass.getName() === className) { + return thisClass; + } + let classSearched = thisClass.getDeclaringArkNamespace()?.getClassWithName(className); + if (!classSearched) { + classSearched = thisClass.getDeclaringArkFile().getClassWithName(className); + } + return classSearched; + } + + /** search class within the given file */ + public static getClassInFileWithName(className: string, arkFile: ArkFile): ArkClass | null { + let classSearched = arkFile.getClassWithName(className); + if (classSearched != null) { + return classSearched; + } + return null; + } + + public static getClassInImportInfoWithName(className: string, arkFile: ArkFile): ArkClass | null { + let arkExport = this.getArkExportInImportInfoWithName(className, arkFile); + if (arkExport instanceof ArkClass) { + return arkExport; + } + return null; + } + + /** search type within the given file import infos */ + public static getArkExportInImportInfoWithName(name: string, arkFile: ArkFile): ArkExport | null { + return arkFile.getImportInfoBy(name)?.getLazyExportInfo()?.getArkExport() ?? null; + } + + /** search method within the file that contain the given method */ + public static getMethodWithName(methodName: string, startFrom: ArkMethod): ArkMethod | null { + if (!methodName.includes('.')) { + if (startFrom.getName() === methodName) { + return startFrom; + } + + const thisClass = startFrom.getDeclaringArkClass(); + let methodSearched: ArkMethod | null = thisClass.getMethodWithName(methodName); + if (!methodSearched) { + methodSearched = thisClass.getStaticMethodWithName(methodName); + } + return methodSearched; + } else { + const names = methodName.split('.'); + let nameSpace = this.getNamespaceWithName(names[0], startFrom.getDeclaringArkClass()); + for (let i = 1; i < names.length - 1; i++) { + if (nameSpace) { + nameSpace = nameSpace.getNamespaceWithName(names[i]); + } + } + if (nameSpace) { + return nameSpace.getDefaultClass().getMethodWithName(names[names.length - 1]); + } + } + return null; + } + + public static getNamespaceWithNameFromClass(namespaceName: string, startFrom: ArkClass): ArkNamespace | null { + const thisNamespace = startFrom.getDeclaringArkNamespace(); + let namespaceSearched: ArkNamespace | null = null; + if (thisNamespace) { + namespaceSearched = thisNamespace.getNamespaceWithName(namespaceName); + if (namespaceSearched) { + return namespaceSearched; + } + } + const thisFile = startFrom.getDeclaringArkFile(); + namespaceSearched = this.getNamespaceInFileWithName(namespaceName, thisFile); + return namespaceSearched; + } + + public static getNamespaceWithName(namespaceName: string, thisClass: ArkClass): ArkNamespace | null { + let thisNamespace: ArkNamespace | null | undefined = thisClass.getDeclaringArkNamespace(); + let namespaceSearched: ArkNamespace | null = null; + while (!namespaceSearched && thisNamespace) { + namespaceSearched = thisNamespace.getNamespaceWithName(namespaceName); + thisNamespace = thisNamespace.getDeclaringArkNamespace(); + } + if (!namespaceSearched) { + namespaceSearched = thisClass.getDeclaringArkFile().getNamespaceWithName(namespaceName); + } + return namespaceSearched; + } + + public static getNamespaceInFileWithName(namespaceName: string, arkFile: ArkFile): ArkNamespace | null { + let namespaceSearched = arkFile.getNamespaceWithName(namespaceName); + if (namespaceSearched) { + return namespaceSearched; + } + + return null; + } + + public static getNamespaceInImportInfoWithName(namespaceName: string, arkFile: ArkFile): ArkNamespace | null { + let arkExport = this.getArkExportInImportInfoWithName(namespaceName, arkFile); + if (arkExport instanceof ArkNamespace) { + return arkExport; + } + return null; + } + + public static getStaticMethodWithName(methodName: string, thisClass: ArkClass): ArkMethod | null { + const thisNamespace = thisClass.getDeclaringArkNamespace(); + if (thisNamespace) { + const defaultClass = thisNamespace.getClassWithName(DEFAULT_ARK_CLASS_NAME); + if (defaultClass) { + const method = defaultClass.getMethodWithName(methodName); + if (method) { + return method; + } + } + } + return this.getStaticMethodInFileWithName(methodName, thisClass.getDeclaringArkFile()); + } + + public static getStaticMethodInFileWithName(methodName: string, arkFile: ArkFile): ArkMethod | null { + const defaultClass = arkFile.getClasses().find(cls => cls.getName() === DEFAULT_ARK_CLASS_NAME) || null; + if (defaultClass) { + let method = defaultClass.getMethodWithName(methodName); + if (method) { + return method; + } + } + return null; + } + + public static getStaticMethodInImportInfoWithName(methodName: string, arkFile: ArkFile): ArkMethod | null { + let arkExport = this.getArkExportInImportInfoWithName(methodName, arkFile); + if (arkExport instanceof ArkMethod) { + return arkExport; + } + return null; + } + + public static getLocalInImportInfoWithName(localName: string, arkFile: ArkFile): Local | null { + let arkExport = this.getArkExportInImportInfoWithName(localName, arkFile); + if (arkExport instanceof Local) { + return arkExport; + } + return null; + } + + /* get nested namespaces in a file */ + public static getAllNamespacesInFile(arkFile: ArkFile): ArkNamespace[] { + const arkNamespaces: ArkNamespace[] = arkFile.getNamespaces(); + for (const arkNamespace of arkFile.getNamespaces()) { + this.getAllNamespacesInNamespace(arkNamespace, arkNamespaces); + } + return arkNamespaces; + } + + /* get nested namespaces in a namespace */ + public static getAllNamespacesInNamespace(arkNamespace: ArkNamespace, allNamespaces: ArkNamespace[]): void { + allNamespaces.push(...arkNamespace.getNamespaces()); + for (const nestedNamespace of arkNamespace.getNamespaces()) { + this.getAllNamespacesInNamespace(nestedNamespace, allNamespaces); + } + } + + public static getAllClassesInFile(arkFile: ArkFile): ArkClass[] { + const allClasses = arkFile.getClasses(); + this.getAllNamespacesInFile(arkFile).forEach(namespace => { + allClasses.push(...namespace.getClasses()); + }); + return allClasses; + } + + public static getAllMethodsInFile(arkFile: ArkFile): ArkMethod[] { + const allMethods: ArkMethod[] = []; + this.getAllClassesInFile(arkFile).forEach(cls => { + allMethods.push(...cls.getMethods()); + }); + return allMethods; + } + + public static isArkUIBuilderMethod(arkMethod: ArkMethod): boolean { + let isArkUIBuilderMethod = arkMethod.hasBuilderDecorator() || this.implicitArkUIBuilderMethods.has(arkMethod); + + if (!isArkUIBuilderMethod && arkMethod.getName() === 'build' && arkMethod.getDeclaringArkClass().hasComponentDecorator() && !arkMethod.isStatic()) { + const fileName = arkMethod.getDeclaringArkClass().getDeclaringArkFile().getName(); + if (fileName.endsWith('.ets')) { + isArkUIBuilderMethod = true; + } + } + return isArkUIBuilderMethod; + } + + public static getArkClassInBuild(scene: Scene, classType: ClassType): ArkClass | null { + const classSignature = classType.getClassSignature(); + const file = scene.getFile(classSignature.getDeclaringFileSignature()); + const namespaceSignature = classSignature.getDeclaringNamespaceSignature(); + if (namespaceSignature) { + return file?.getNamespace(namespaceSignature)?.getClass(classSignature) || null; + } + return file?.getClassWithName(classSignature.getClassName()) || null; + } + + public static getDefaultClass(arkClass: ArkClass): ArkClass | null { + return arkClass.getDeclaringArkNamespace()?.getDefaultClass() ?? arkClass.getDeclaringArkFile().getDefaultClass(); + } + + public static getClass(method: ArkMethod, signature: ClassSignature): ArkClass | null { + let cls: ArkClass | undefined | null = method.getDeclaringArkFile().getScene().getClass(signature); + if (cls) { + return cls; + } + let importInfo = method.getDeclaringArkFile().getImportInfoBy(signature.getClassName()); + let exportInfo = importInfo ? findExportInfo(importInfo) : null; + let arkExport = exportInfo?.getArkExport(); + if (arkExport instanceof ArkClass) { + return arkExport; + } + + cls = method.getDeclaringArkClass().getDeclaringArkNamespace()?.getClassWithName(signature.getClassName()); + if (cls) { + return cls; + } + + for (const ns of method.getDeclaringArkFile().getAllNamespacesUnderThisFile()) { + cls = ns.getClassWithName(signature.getClassName()); + if (cls) { + return cls; + } + } + + return method.getDeclaringArkFile().getClassWithName(signature.getClassName()); + } + + public static findPropertyInNamespace(name: string, namespace: ArkNamespace): ArkExport | undefined { + return ( + namespace.getDefaultClass()?.getMethodWithName(name) ?? + findArkExport(namespace.getExportInfoBy(name)) ?? + namespace.getClassWithName(name) ?? + namespace.getNamespaceWithName(name) ?? + namespace.getDefaultClass()?.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(name) ?? + namespace.getDefaultClass()?.getDefaultArkMethod()?.getBody()?.getLocals()?.get(name) + ); + } + + public static findPropertyInClass(name: string, arkClass: ArkClass): ArkExport | ArkField | null { + let property: ArkExport | ArkField | null = + arkClass.getMethodWithName(name) ?? + arkClass.getStaticMethodWithName(name) ?? + arkClass.getFieldWithName(name) ?? + arkClass.getStaticFieldWithName(name); + if (property) { + return property; + } + if (arkClass.isDefaultArkClass()) { + return findArkExport(arkClass.getDeclaringArkFile().getExportInfoBy(name)); + } + for (const heritage of arkClass.getAllHeritageClasses()) { + property = this.findPropertyInClass(name, heritage); + if (property) { + return property; + } + } + return null; + } + + public static findDeclaredLocal(local: Local, arkMethod: ArkMethod, times: number = 0): Local | null { + if (arkMethod.getDeclaringArkFile().getScene().getOptions().isScanAbc) { + return null; + } + const name: string = local.getName(); + if (name === THIS_NAME || name.startsWith(TEMP_LOCAL_PREFIX)) { + return null; + } + const parameter = arkMethod.getParameters().find(p => p.getName() === name); + if (parameter) { + return new Local(parameter.getName(), parameter.getType()); + } + if (times > 0) { + const declaredLocal = arkMethod.getBody()?.getLocals().get(name); + if ( + declaredLocal && + declaredLocal.getDeclaringStmt() instanceof ArkAssignStmt && + !((declaredLocal.getDeclaringStmt() as ArkAssignStmt).getRightOp() instanceof ClosureFieldRef) + ) { + return declaredLocal; + } + } + let parentName = arkMethod.getName(); + if (parentName === DEFAULT_ARK_METHOD_NAME) { + return null; + } + let invokeMethod: ArkMethod | null | undefined = arkMethod.getOuterMethod(); + if (!invokeMethod) { + const className = arkMethod.getDeclaringArkClass().getName(); + const outerStart = className.indexOf(NAME_DELIMITER); + const outerEnd = className.lastIndexOf('.'); + if (outerStart > -1 && outerEnd > -1) { + invokeMethod = arkMethod + .getDeclaringArkFile() + .getClassWithName(className.substring(outerStart + 1, outerEnd)) + ?.getMethodWithName(className.substring(outerEnd + 1)); + } else { + const cls = arkMethod.getDeclaringArkClass(); + invokeMethod = cls.getDefaultArkMethod() ?? cls.getDeclaringArkFile().getDefaultClass()?.getDefaultArkMethod(); + } + } + if (invokeMethod) { + return this.findDeclaredLocal(local, invokeMethod, ++times); + } + return null; + } + + public static findArkModel(baseName: string, arkClass: ArkClass): ArkExport | ArkField | null { + let arkModel: ArkExport | ArkField | null = + arkClass.getMethodWithName(baseName) ?? + arkClass.getStaticMethodWithName(baseName) ?? + arkClass.getFieldWithName(baseName) ?? + arkClass.getStaticFieldWithName(baseName); + if (arkModel) { + return arkModel; + } + arkModel = + ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getLocals()?.get(baseName) ?? + ModelUtils.getClassWithName(baseName, arkClass) ?? + ModelUtils.getNamespaceWithName(baseName, arkClass) ?? + ModelUtils.getDefaultClass(arkClass)?.getMethodWithName(baseName) ?? + ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(baseName) ?? + ModelUtils.getArkExportInImportInfoWithName(baseName, arkClass.getDeclaringArkFile()); + if (!arkModel && !arkClass.getDeclaringArkFile().getImportInfoBy(baseName)) { + arkModel = arkClass.getDeclaringArkFile().getScene().getSdkGlobal(baseName); + } + return arkModel; + } + + public static findGlobalRef(refName: string, method: ArkMethod): ArkExport | null { + return ( + this.findDeclaredLocal(new Local(refName), method, 1) ?? + this.getArkExportInImportInfoWithName(refName, method.getDeclaringArkFile()) ?? + method.getDeclaringArkFile().getScene().getSdkGlobal(refName) + ); + } + + public static findArkModelByRefName(refName: string, arkClass: ArkClass): ArkExport | ArkField | null { + const singleNames = refName.split('.'); + let model = null; + for (let i = 0; i < singleNames.length; i++) { + if (model instanceof Local || model instanceof ArkField) { + const type = model.getType(); + if (type instanceof ClassType) { + model = arkClass.getDeclaringArkFile().getScene().getClass(type.getClassSignature()); + } else if (type instanceof AnnotationNamespaceType) { + model = arkClass.getDeclaringArkFile().getScene().getNamespace(type.getNamespaceSignature()); + } + } + const name = singleNames[i].replace(/<(\w+)>/, EMPTY_STRING); + if (i === 0) { + model = this.findArkModel(name, arkClass); + } else if (model instanceof ArkClass) { + model = this.findPropertyInClass(name, model); + } else if (model instanceof ArkNamespace) { + model = this.findPropertyInNamespace(name, model); + } + if (!model) { + return null; + } + } + return model; + } + + public static findArkModelBySignature(signature: Signature, scene: Scene): ArkExport | ArkField | null { + if (signature instanceof ClassSignature) { + return scene.getClass(signature); + } else if (signature instanceof NamespaceSignature) { + return scene.getNamespace(signature); + } else if (signature instanceof MethodSignature) { + return scene.getMethod(signature); + } else if (signature instanceof FieldSignature) { + const declare = this.findArkModelBySignature(signature.getDeclaringSignature(), scene); + if (declare instanceof ArkClass) { + return this.findPropertyInClass(signature.getFieldName(), declare); + } else if (declare instanceof ArkNamespace) { + return this.findPropertyInNamespace(signature.getFieldName(), declare) || null; + } + return null; + } else if (signature instanceof LocalSignature) { + const declare = scene.getMethod(signature.getDeclaringMethodSignature()); + return declare?.getBody()?.getLocals().get(signature.getName()) ?? declare?.getBody()?.getAliasTypeByName(signature.getName()) ?? null; + } else if (signature instanceof AliasTypeSignature) { + const declare = scene.getMethod(signature.getDeclaringMethodSignature()); + return declare?.getBody()?.getAliasTypeByName(signature.getName()) ?? null; + } + return null; + } + + public static parseArkBaseModel2Type(arkBaseModel: ArkBaseModel): Type | null { + if (arkBaseModel instanceof ArkClass) { + return new ClassType(arkBaseModel.getSignature(), arkBaseModel.getGenericsTypes()); + } else if (arkBaseModel instanceof ArkNamespace) { + return AnnotationNamespaceType.getInstance(arkBaseModel.getSignature()); + } else if (arkBaseModel instanceof ArkMethod) { + return new FunctionType(arkBaseModel.getSignature()); + } else if (arkBaseModel instanceof ArkField) { + if (arkBaseModel.getType() instanceof UnknownType || arkBaseModel.getType() instanceof UnclearReferenceType) { + return null; + } + return arkBaseModel.getType(); + } + return null; + } +} + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ModelUtils'); +let moduleMap: Map | undefined; + +/** + * find arkFile by from info + * export xx from '../xx' + * import xx from '@ohos/xx' + * import xx from '@ohos.xx' + * @param im importInfo or exportInfo + */ +export function getArkFile(im: FromInfo): ArkFile | null | undefined { + const from = im.getFrom(); + if (!from) { + return null; + } + if (/^([^@]*\/)([^\/]*)$/.test(from)) { + //relative path + const parentPath = /^\.{1,2}\//.test(from) ? path.dirname(im.getDeclaringArkFile().getFilePath()) : im.getDeclaringArkFile().getProjectDir(); + const originPath = path.resolve(parentPath, from); + return getArkFileFromScene(im, originPath); + } else if (/^@[a-z|\-]+?\//.test(from)) { + //module path + const arkFile = getArkFileFromOtherModule(im); + if (arkFile) { + return arkFile; + } + } + + //sdk path + const file = SdkUtils.getImportSdkFile(from); + if (file) { + return file; + } + const scene = im.getDeclaringArkFile().getScene(); + for (const sdk of scene.getProjectSdkMap().values()) { + const arkFile = getArkFileFormMap(sdk.name, processSdkPath(sdk, from), scene); + if (arkFile) { + return arkFile; + } + } + return null; +} + +/** + * find from info's export + * @param fromInfo importInfo or exportInfo + */ +export function findExportInfo(fromInfo: FromInfo): ExportInfo | null { + let file = getArkFile(fromInfo); + if (!file) { + logger.warn(`${fromInfo.getOriginName()} ${fromInfo.getFrom()} file not found: + ${fromInfo.getDeclaringArkFile()?.getFileSignature()?.toString()}`); + return null; + } + if (fileSignatureCompare(file.getFileSignature(), fromInfo.getDeclaringArkFile().getFileSignature())) { + for (let exportInfo of file.getExportInfos()) { + if (exportInfo.getOriginName() === fromInfo.getOriginName()) { + exportInfo.setArkExport(file.getDefaultClass()); + return exportInfo; + } + } + return null; + } + let exportInfo = findExportInfoInfile(fromInfo, file) || null; + if (exportInfo === null) { + logger.warn('export info not found, ' + fromInfo.getFrom() + ' in file: ' + fromInfo.getDeclaringArkFile().getFileSignature().toString()); + return null; + } + const arkExport = findArkExport(exportInfo); + exportInfo.setArkExport(arkExport); + if (arkExport) { + exportInfo.setExportClauseType(arkExport.getExportType()); + } + return exportInfo; +} + +export function findArkExport(exportInfo: ExportInfo | undefined): ArkExport | null { + if (!exportInfo) { + return null; + } + let arkExport = exportInfo.getArkExport(); + if (arkExport || arkExport === null) { + return arkExport; + } + if (!exportInfo.getFrom()) { + const name = exportInfo.getOriginName(); + const defaultClass = exportInfo.getDeclaringArkNamespace()?.getDefaultClass() ?? exportInfo.getDeclaringArkFile().getDefaultClass(); + if (exportInfo.getExportClauseType() === ExportType.LOCAL) { + arkExport = defaultClass.getDefaultArkMethod()?.getBody()?.getExportLocalByName(name); + } else if (exportInfo.getExportClauseType() === ExportType.TYPE) { + arkExport = defaultClass.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(name); + } else { + arkExport = findArkExportInFile(name, exportInfo.getDeclaringArkFile()); + } + } else if (exportInfo.getExportClauseType() === ExportType.UNKNOWN) { + const result = findExportInfo(exportInfo); + if (result) { + arkExport = result.getArkExport() || null; + } + } + if (arkExport) { + exportInfo.setArkExport(arkExport); + } else { + logger.warn(`${exportInfo.getExportClauseName()} get arkExport fail from ${exportInfo.getFrom()} at + ${exportInfo.getDeclaringArkFile().getFileSignature().toString()}`); + } + return arkExport || null; +} + +export function findArkExportInFile(name: string, declaringArkFile: ArkFile): ArkExport | null { + let arkExport: ArkExport | undefined | null = + declaringArkFile.getNamespaceWithName(name) ?? + declaringArkFile.getDefaultClass().getDefaultArkMethod()?.getBody()?.getAliasTypeByName(name) ?? + declaringArkFile.getClassWithName(name) ?? + declaringArkFile.getDefaultClass().getMethodWithName(name) ?? + declaringArkFile.getDefaultClass().getDefaultArkMethod()?.getBody()?.getExportLocalByName(name); + + if (!arkExport) { + const importInfo = declaringArkFile.getImportInfoBy(name); + if (importInfo) { + const result = findExportInfo(importInfo); + if (result) { + arkExport = result.getArkExport(); + } + } + } + return arkExport || null; +} + +function processSdkPath(sdk: Sdk, formPath: string): string { + let originPath = path.join(sdk.path, formPath); + if (FileUtils.isDirectory(originPath)) { + formPath = path.join(formPath, FileUtils.getIndexFileName(originPath)); + } + return `${formPath}`; +} + +function getArkFileFromScene(im: FromInfo, originPath: string): ArkFile | null { + if (FileUtils.isDirectory(originPath)) { + originPath = path.join(originPath, FileUtils.getIndexFileName(originPath)); + } + const fileName = path.relative(im.getDeclaringArkFile().getProjectDir(), originPath); + const scene = im.getDeclaringArkFile().getScene(); + if (/\.e?ts$/.test(originPath)) { + const fromSignature = new FileSignature(im.getDeclaringArkFile().getProjectName(), fileName); + return scene.getFile(fromSignature); + } + const projectName = im.getDeclaringArkFile().getProjectName(); + return getArkFileFormMap(projectName, fileName, scene); +} + +function getArkFileFormMap(projectName: string, filePath: string, scene: Scene): ArkFile | null { + if (/\.e?ts$/.test(filePath)) { + return scene.getFile(new FileSignature(projectName, filePath)); + } + const fileSuffixArray = scene.getOptions().supportFileExts; + if (!fileSuffixArray) { + return null; + } + for (const suffix of fileSuffixArray) { + const arkFile = scene.getFile(new FileSignature(projectName, filePath + suffix)); + if (arkFile) { + return arkFile; + } + } + return null; +} + +function findExportInfoInfile(fromInfo: FromInfo, file: ArkFile): ExportInfo | undefined { + const exportName = fromInfo.isDefault() ? DEFAULT : fromInfo.getOriginName(); + let exportInfo = file.getExportInfoBy(exportName); + if (exportInfo) { + return exportInfo; + } + + if (exportName === DEFAULT) { + exportInfo = file.getExportInfos().find(p => p.isDefault()); + if (exportInfo) { + file.addExportInfo(exportInfo, DEFAULT); + return exportInfo; + } + } + + if (fromInfo.getOriginName() === ALL) { + exportInfo = buildDefaultExportInfo(fromInfo, file); + file.addExportInfo(exportInfo, ALL); + } else if (/\.d\.e?ts$/.test(file.getName())) { + let declare = exportName === DEFAULT ? undefined : findArkExportInFile(fromInfo.getOriginName(), file) || undefined; + exportInfo = buildDefaultExportInfo(fromInfo, file, declare); + } + + return exportInfo; +} + +export function initModulePathMap(ohPkgContentMap: Map): void { + if (moduleMap) { + moduleMap.clear(); + } + moduleMap = FileUtils.generateModuleMap(ohPkgContentMap); +} + +function getArkFileFromOtherModule(fromInfo: FromInfo): ArkFile | undefined { + if (!moduleMap || moduleMap.size === 0) { + return undefined; + } + const from = fromInfo.getFrom()!; + let index: number; + let file; + let modulePath; + //find file by given from like '@ohos/module/src/xxx' '@ohos/module/index' + if ((index = from.indexOf('src')) > 0 || (index = from.indexOf('Index')) > 0 || (index = from.indexOf('index')) > 0) { + modulePath = moduleMap.get(from.substring(0, index).replace(/\/*$/, '')); + file = findFileInModule(fromInfo, modulePath, from.substring(index)); + } + if (file) { + return file; + } + modulePath = modulePath ?? moduleMap.get(from); + if (!modulePath) { + return file; + } + //find file in module json main path + if (modulePath.main) { + file = getArkFileFromScene(fromInfo, modulePath.main); + } + //find file in module path Index.ts + if (!file && FileUtils.isDirectory(modulePath.path)) { + file = findFileInModule(fromInfo, modulePath, FileUtils.getIndexFileName(modulePath.path)); + } + //find file in module path/src/main/ets/TsIndex.ts + if (!file) { + file = findFileInModule(fromInfo, modulePath, '/src/main/ets/TsIndex.ts'); + } + return file; +} + +function findFileInModule(fromInfo: FromInfo, modulePath: ModulePath | undefined, contentPath: string): ArkFile | undefined { + if (!modulePath) { + return undefined; + } + const originPath = path.join(modulePath.path, contentPath); + let file; + if (originPath !== modulePath.main) { + file = getArkFileFromScene(fromInfo, originPath); + } + if (file && findExportInfoInfile(fromInfo, file)) { + return file; + } + return undefined; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/RefUseReplacer.ts b/ets2panda/linter/arkanalyzer/src/core/common/RefUseReplacer.ts new file mode 100644 index 0000000000000000000000000000000000000000..765fb7384134dbce6bd583d59e1fce2bc4de07d9 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/RefUseReplacer.ts @@ -0,0 +1,55 @@ +/* + * 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. + */ + +import { Local } from '../base/Local'; +import { AbstractRef, ArkArrayRef, ArkInstanceFieldRef } from '../base/Ref'; +import { Value } from '../base/Value'; + +/** + * Replace old use of a Ref inplace + */ +export class RefUseReplacer { + private oldUse: Value; + private newUse: Value; + + constructor(oldUse: Value, newUse: Value) { + this.oldUse = oldUse; + this.newUse = newUse; + } + + public caseRef(ref: AbstractRef): void { + if (ref instanceof ArkInstanceFieldRef) { + this.caseFieldRef(ref); + } else if (ref instanceof ArkArrayRef) { + this.caseArrayRef(ref); + } + } + + private caseFieldRef(ref: ArkInstanceFieldRef): void { + if (ref.getBase() === this.oldUse && this.newUse instanceof Local) { + ref.setBase(this.newUse); + } + } + + private caseArrayRef(ref: ArkArrayRef): void { + if (ref.getBase() === this.oldUse) { + if (this.newUse instanceof Local) { + ref.setBase(this.newUse); + } + } else if (ref.getIndex() === this.oldUse) { + ref.setIndex(this.newUse); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/SdkUtils.ts b/ets2panda/linter/arkanalyzer/src/core/common/SdkUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..84f185987813e6866c2bf4fc398e9e2c9a0d20d1 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/SdkUtils.ts @@ -0,0 +1,152 @@ +/* + * 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. + */ + +import { ArkFile } from '../model/ArkFile'; +import { ArkExport, ExportInfo } from '../model/ArkExport'; +import { COMPONENT_ATTRIBUTE } from './EtsConst'; +import { GLOBAL_THIS_NAME, THIS_NAME } from './TSConst'; +import { TEMP_LOCAL_PREFIX } from './Const'; +import { ArkClass, ClassCategory } from '../model/ArkClass'; +import { LocalSignature } from '../model/ArkSignature'; +import { ModelUtils } from './ModelUtils'; +import { Local } from '../base/Local'; +import { ArkMethod } from '../model/ArkMethod'; +import path from 'path'; +import { ClassType } from '../base/Type'; +import { AbstractFieldRef } from '../base/Ref'; +import { ArkNamespace } from '../model/ArkNamespace'; +import { TypeInference } from './TypeInference'; + +export class SdkUtils { + + private static sdkImportMap: Map = new Map(); + + public static buildSdkImportMap(file: ArkFile): void { + const fileName = path.basename(file.getName()); + if (fileName.startsWith('@')) { + this.sdkImportMap.set(fileName.replace(/\.d\.e?ts$/, ''), file); + } + } + + public static getImportSdkFile(from: string): ArkFile | undefined { + return this.sdkImportMap.get(from); + } + + public static buildGlobalMap(file: ArkFile, globalMap: Map): void { + const isGlobalPath = file + .getScene() + .getOptions() + .sdkGlobalFolders?.find(x => file.getFilePath().includes(path.sep + x + path.sep)); + if (!isGlobalPath) { + return; + } + ModelUtils.getAllClassesInFile(file).forEach(cls => { + if (!cls.isAnonymousClass() && !cls.isDefaultArkClass()) { + SdkUtils.loadClass(globalMap, cls); + } + if (cls.isDefaultArkClass()) { + cls.getMethods() + .filter(mtd => !mtd.isDefaultArkMethod() && !mtd.isAnonymousMethod()) + .forEach(mtd => globalMap.set(mtd.getName(), mtd)); + } + }); + const defaultArkMethod = file.getDefaultClass().getDefaultArkMethod(); + if (defaultArkMethod) { + TypeInference.inferTypeInMethod(defaultArkMethod); + } + defaultArkMethod + ?.getBody() + ?.getLocals() + .forEach(local => { + const name = local.getName(); + if (name !== THIS_NAME && !name.startsWith(TEMP_LOCAL_PREFIX)) { + this.loadGlobalLocal(local, defaultArkMethod, globalMap); + } + }); + defaultArkMethod + ?.getBody() + ?.getAliasTypeMap() + ?.forEach(a => globalMap.set(a[0].getName(), a[0])); + ModelUtils.getAllNamespacesInFile(file).forEach(ns => globalMap.set(ns.getName(), ns)); + } + + private static loadClass(globalMap: Map, cls: ArkClass): void { + const old = globalMap.get(cls.getName()); + if (old instanceof ArkClass) { + if (old.getCategory() === ClassCategory.CLASS) { + this.copyMethod(cls, old); + } else { + this.copyMethod(old, cls); + globalMap.delete(cls.getName()); + globalMap.set(cls.getName(), cls); + } + } else if (!old) { + globalMap.set(cls.getName(), cls); + } + } + + private static loadGlobalLocal(local: Local, defaultArkMethod: ArkMethod, globalMap: Map): void { + const name = local.getName(); + local.setSignature(new LocalSignature(name, defaultArkMethod.getSignature())); + const scene = defaultArkMethod.getDeclaringArkFile().getScene(); + if (scene.getOptions().isScanAbc) { + const instance = globalMap.get(name + 'Interface'); + const attr = globalMap.get(name + COMPONENT_ATTRIBUTE); + if (attr instanceof ArkClass && instance instanceof ArkClass) { + instance + .getMethods() + .filter(m => !attr.getMethodWithName(m.getName())) + .forEach(m => attr.addMethod(m)); + globalMap.set(name, attr); + return; + } + } + const old = globalMap.get(name); + if (!old) { + globalMap.set(name, local); + } else if (old instanceof ArkClass && local.getType() instanceof ClassType) { + const localConstructor = scene.getClass((local.getType() as ClassType).getClassSignature()); + if (localConstructor) { + localConstructor + .getMethods() + .filter(m => !old.getMethodWithName(m.getName())) + .forEach(m => old.addMethod(m)); + } + } + } + + private static copyMethod(from: ArkClass, to: ArkClass): void { + from.getMethods().forEach(method => { + const dist = method.isStatic() ? to.getStaticMethodWithName(method.getName()) : to.getMethodWithName(method.getName()); + const distSignatures = dist?.getDeclareSignatures(); + if (distSignatures) { + method.getDeclareSignatures()?.forEach(x => distSignatures.push(x)); + } else { + to.addMethod(method); + } + }); + } + + public static computeGlobalThis(leftOp: AbstractFieldRef, arkMethod: ArkMethod): void { + const globalThis = arkMethod.getDeclaringArkFile().getScene().getSdkGlobal(GLOBAL_THIS_NAME); + if (globalThis instanceof ArkNamespace) { + const exportInfo = new ExportInfo.Builder() + .exportClauseName(leftOp.getFieldName()) + .arkExport(new Local(leftOp.getFieldName(), leftOp.getType())) + .build(); + globalThis.addExportInfo(exportInfo); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/StmtDefReplacer.ts b/ets2panda/linter/arkanalyzer/src/core/common/StmtDefReplacer.ts new file mode 100644 index 0000000000000000000000000000000000000000..134cebf5fa48bd9d773693e52bf7894c9d116fbb --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/StmtDefReplacer.ts @@ -0,0 +1,45 @@ +/* + * 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. + */ + +import { Value } from '../base/Value'; +import { ArkAssignStmt, Stmt } from '../base/Stmt'; +import { IRUtils } from './IRUtils'; + +/** + * Replace old def(Value) of a Stmt inplace + */ +export class StmtDefReplacer { + private oldDef: Value; + private newDef: Value; + + constructor(oldDef: Value, newDef: Value) { + this.oldDef = oldDef; + this.newDef = newDef; + } + + public caseStmt(stmt: Stmt): void { + if (stmt instanceof ArkAssignStmt) { + this.caseAssignStmt(stmt); + } + } + + private caseAssignStmt(stmt: ArkAssignStmt): void { + const lValue = stmt.getLeftOp(); + if (lValue === this.oldDef) { + IRUtils.adjustOperandOriginalPositions(stmt, this.oldDef, this.newDef); + stmt.setLeftOp(this.newDef); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/StmtUseReplacer.ts b/ets2panda/linter/arkanalyzer/src/core/common/StmtUseReplacer.ts new file mode 100644 index 0000000000000000000000000000000000000000..82e743935c43dcc8e5a5179f5cff85d5dc708e01 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/StmtUseReplacer.ts @@ -0,0 +1,109 @@ +/* + * 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. + */ + +import { AbstractExpr, AbstractInvokeExpr, ArkConditionExpr } from '../base/Expr'; +import { AbstractRef } from '../base/Ref'; +import { ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkThrowStmt, Stmt } from '../base/Stmt'; +import { Value } from '../base/Value'; +import { ExprUseReplacer } from './ExprUseReplacer'; +import { RefUseReplacer } from './RefUseReplacer'; +import { IRUtils } from './IRUtils'; + +/** + * Replace old use(Value) of a Stmt inplace + */ +export class StmtUseReplacer { + private oldUse: Value; + private newUse: Value; + + constructor(oldUse: Value, newUse: Value) { + this.oldUse = oldUse; + this.newUse = newUse; + } + + public caseStmt(stmt: Stmt): void { + if (stmt instanceof ArkAssignStmt) { + this.caseAssignStmt(stmt); + } else if (stmt instanceof ArkInvokeStmt) { + this.caseInvokeStmt(stmt); + } else if (stmt instanceof ArkReturnStmt) { + this.caseReturnStmt(stmt); + } else if (stmt instanceof ArkIfStmt) { + this.caseIfStmt(stmt); + } else if (stmt instanceof ArkThrowStmt) { + this.caseThrowStmt(stmt); + } + } + + private caseAssignStmt(stmt: ArkAssignStmt): void { + const lValue = stmt.getLeftOp(); + if (lValue instanceof AbstractRef) { + const refUseReplacer = new RefUseReplacer(this.oldUse, this.newUse); + refUseReplacer.caseRef(lValue); + } + + const rValue = stmt.getRightOp(); + if (rValue === this.oldUse) { + IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse); + stmt.setRightOp(this.newUse); + } else if (rValue instanceof AbstractRef) { + const refUseReplacer = new RefUseReplacer(this.oldUse, this.newUse); + refUseReplacer.caseRef(rValue); + } else if (rValue instanceof AbstractExpr) { + const exprUseReplacer = new ExprUseReplacer(this.oldUse, this.newUse); + exprUseReplacer.caseExpr(rValue); + } + } + + private caseInvokeStmt(stmt: ArkInvokeStmt): void { + const invokeExpr = stmt.getInvokeExpr(); + if (invokeExpr === this.oldUse) { + if (this.newUse instanceof AbstractInvokeExpr) { + IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse); + stmt.replaceInvokeExpr(this.newUse); + } + } else { + let exprUseReplacer = new ExprUseReplacer(this.oldUse, this.newUse); + exprUseReplacer.caseExpr(stmt.getInvokeExpr()); + } + } + + private caseReturnStmt(stmt: ArkReturnStmt): void { + if (stmt.getOp() === this.oldUse) { + IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse); + stmt.setReturnValue(this.newUse); + } + } + + private caseIfStmt(stmt: ArkIfStmt): void { + const conditionExpr = stmt.getConditionExpr(); + if (conditionExpr === this.oldUse) { + if (this.newUse instanceof ArkConditionExpr) { + IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse); + stmt.setConditionExpr(this.newUse); + } + } else { + let exprUseReplacer = new ExprUseReplacer(this.oldUse, this.newUse); + exprUseReplacer.caseExpr(stmt.getConditionExpr()); + } + } + + private caseThrowStmt(stmt: ArkThrowStmt): void { + if (stmt.getOp() === this.oldUse) { + IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse); + stmt.setOp(this.newUse); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/TSConst.ts b/ets2panda/linter/arkanalyzer/src/core/common/TSConst.ts new file mode 100644 index 0000000000000000000000000000000000000000..929711063de8c852b0ab5bd754a8f89b509cc51a --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/TSConst.ts @@ -0,0 +1,41 @@ +/* + * 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. + */ + +export const CONSTRUCTOR_NAME = 'constructor'; +export const SUPER_NAME = 'super'; +export const THIS_NAME = 'this'; +export const GLOBAL_THIS_NAME: string = 'globalThis'; + +export const DEFAULT = 'default'; + +export const ALL = '*'; + +export const IMPORT = 'import'; +export const PROMISE = 'Promise'; +export const FUNCTION = 'Function'; + +// ast const +export const DECLARE_KEYWORD = 'DeclareKeyword'; +export const NULL_KEYWORD = 'null'; +export const UNDEFINED_KEYWORD = 'undefined'; +export const ANY_KEYWORD = 'any'; +export const UNKNOWN_KEYWORD = 'unknown'; +export const BOOLEAN_KEYWORD = 'boolean'; +export const NUMBER_KEYWORD = 'number'; +export const STRING_KEYWORD = 'string'; +export const VOID_KEYWORD = 'void'; +export const NEVER_KEYWORD = 'never'; +export const BIGINT_KEYWORD = 'bigint'; +export const TSCONFIG_JSON = 'tsconfig.json'; diff --git a/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts b/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts new file mode 100644 index 0000000000000000000000000000000000000000..e754272cbfd07f2cd1290ef386b91ac55e12fa2a --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/TypeInference.ts @@ -0,0 +1,885 @@ +/* + * 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. + */ + +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { AbstractExpr, ArkInstanceInvokeExpr, ArkPtrInvokeExpr, ArkStaticInvokeExpr } from '../base/Expr'; +import { Local } from '../base/Local'; +import { AbstractFieldRef, AbstractRef, ArkArrayRef, ArkInstanceFieldRef, ArkParameterRef, ArkStaticFieldRef } from '../base/Ref'; +import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkReturnStmt, Stmt } from '../base/Stmt'; +import { + AliasType, + AnnotationNamespaceType, + AnyType, + ArrayType, + BigIntType, + BooleanType, + ClassType, + EnumValueType, + FunctionType, + GenericType, + IntersectionType, + NeverType, + NullType, + NumberType, + StringType, + TupleType, + Type, + UnclearReferenceType, + UndefinedType, + UnionType, + UnknownType, + VoidType, +} from '../base/Type'; +import { ArkMethod } from '../model/ArkMethod'; +import { ArkExport } from '../model/ArkExport'; +import { ArkClass, ClassCategory } from '../model/ArkClass'; +import { ArkField } from '../model/ArkField'; +import { Value } from '../base/Value'; +import { Constant } from '../base/Constant'; +import { ArkNamespace } from '../model/ArkNamespace'; +import { + ALL, + ANY_KEYWORD, + BIGINT_KEYWORD, + BOOLEAN_KEYWORD, + CONSTRUCTOR_NAME, + GLOBAL_THIS_NAME, + NEVER_KEYWORD, + NULL_KEYWORD, + NUMBER_KEYWORD, + PROMISE, + STRING_KEYWORD, + SUPER_NAME, + THIS_NAME, + UNDEFINED_KEYWORD, + VOID_KEYWORD, +} from './TSConst'; +import { ModelUtils } from './ModelUtils'; +import { Builtin } from './Builtin'; +import { MethodSignature, MethodSubSignature, NamespaceSignature } from '../model/ArkSignature'; +import { INSTANCE_INIT_METHOD_NAME, LEXICAL_ENV_NAME_PREFIX, UNKNOWN_FILE_NAME } from './Const'; +import { EMPTY_STRING } from './ValueUtil'; +import { ImportInfo } from '../model/ArkImport'; +import { MethodParameter } from '../model/builder/ArkMethodBuilder'; +import { IRInference } from './IRInference'; +import { AbstractTypeExpr, KeyofTypeExpr, TypeQueryExpr } from '../base/TypeExpr'; +import { SdkUtils } from './SdkUtils'; +import { ModifierType } from '../model/ArkBaseModel'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'TypeInference'); + +export class TypeInference { + public static inferTypeInArkField(arkField: ArkField): void { + const arkClass = arkField.getDeclaringArkClass(); + const stmts = arkField.getInitializer(); + const method = arkClass.getMethodWithName(INSTANCE_INIT_METHOD_NAME) ?? arkClass.getMethodWithName(CONSTRUCTOR_NAME); + for (const stmt of stmts) { + if (method) { + this.resolveStmt(stmt, method); + } + } + const beforeType = arkField.getType(); + if (!this.isUnclearType(beforeType)) { + return; + } + let rightType: Type | undefined; + let fieldRef: ArkInstanceFieldRef | undefined; + const lastStmt = stmts[stmts.length - 1]; + if (lastStmt instanceof ArkAssignStmt) { + rightType = lastStmt.getRightOp().getType(); + if (lastStmt.getLeftOp() instanceof ArkInstanceFieldRef) { + fieldRef = lastStmt.getLeftOp() as ArkInstanceFieldRef; + } + } + let fieldType; + if (beforeType) { + fieldType = this.inferUnclearedType(beforeType, arkClass); + } + if (fieldType) { + arkField.getSignature().setType(fieldType); + fieldRef?.setFieldSignature(arkField.getSignature()); + } else if (rightType && this.isUnclearType(beforeType) && !this.isUnclearType(rightType)) { + arkField.getSignature().setType(rightType); + fieldRef?.setFieldSignature(arkField.getSignature()); + } + } + + /** + * Infer type for a given unclear type. + * It returns an array with 2 items, original object and original type. + * The original object is null if there is no object, or it failed to find the object. + * The original type is null if failed to infer the type. + * @param leftOpType + * @param declaringArkClass + * @param visited + * @returns + */ + public static inferUnclearedType(leftOpType: Type, declaringArkClass: ArkClass, visited: Set = new Set()): Type | null | undefined { + if (visited.has(leftOpType)) { + return leftOpType; + } else { + visited.add(leftOpType); + } + let type; + if (leftOpType instanceof ClassType && leftOpType.getClassSignature().getDeclaringFileSignature().getFileName() === UNKNOWN_FILE_NAME) { + type = TypeInference.inferUnclearRefName(leftOpType.getClassSignature().getClassName(), declaringArkClass); + } else if (leftOpType instanceof UnionType || leftOpType instanceof IntersectionType || leftOpType instanceof TupleType) { + let types = leftOpType.getTypes(); + for (let i = 0; i < types.length; i++) { + let newType = this.inferUnclearedType(types[i], declaringArkClass, visited); + if (newType) { + types[i] = newType; + } + } + type = leftOpType; + } else if (leftOpType instanceof ArrayType) { + let baseType = this.inferUnclearedType(leftOpType.getBaseType(), declaringArkClass, visited); + if (baseType) { + leftOpType.setBaseType(baseType); + type = leftOpType; + } + } else if (leftOpType instanceof AliasType) { + let baseType = this.inferUnclearedType(leftOpType.getOriginalType(), declaringArkClass, visited); + if (baseType) { + leftOpType.setOriginalType(baseType); + type = leftOpType; + } + } else if (leftOpType instanceof AnnotationNamespaceType) { + type = this.inferUnclearRefName(leftOpType.getOriginType(), declaringArkClass); + } else if (leftOpType instanceof UnclearReferenceType) { + type = this.inferUnclearRefType(leftOpType, declaringArkClass); + } + return type; + } + + public static inferTypeInMethod(arkMethod: ArkMethod): void { + const arkClass = arkMethod.getDeclaringArkClass(); + this.inferGenericType(arkMethod.getGenericTypes(), arkClass); + const signatures: MethodSignature[] = []; + arkMethod.getDeclareSignatures()?.forEach(m => signatures.push(m)); + const impl = arkMethod.getImplementationSignature(); + if (impl) { + signatures.push(impl); + } + signatures.forEach(s => { + s.getMethodSubSignature() + .getParameters() + .forEach(p => { + this.inferParameterType(p, arkMethod); + }); + }); + const body = arkMethod.getBody(); + if (!body) { + signatures.forEach(s => this.inferSignatureReturnType(s, arkMethod)); + return; + } + const cfg = body.getCfg(); + for (const block of cfg.getBlocks()) { + for (const stmt of block.getStmts()) { + this.resolveStmt(stmt, arkMethod); + } + } + signatures.forEach(s => this.inferSignatureReturnType(s, arkMethod)); + } + + private static resolveStmt(stmt: Stmt, arkMethod: ArkMethod): void { + try { + this.resolveTypeExprsInStmt(stmt, arkMethod); + this.resolveExprsInStmt(stmt, arkMethod); + this.resolveFieldRefsInStmt(stmt, arkMethod); + this.resolveArkAssignStmt(stmt, arkMethod); + this.resolveArkReturnStmt(stmt, arkMethod); + } catch (e) { + logger.warn('stmt is not correct: ' + stmt.toString()); + } + } + + /** + * @Deprecated + * @param arkMethod + */ + public static inferSimpleTypeInMethod(arkMethod: ArkMethod): void { + const body = arkMethod.getBody(); + if (!body) { + logger.warn('empty body'); + return; + } + const cfg = body.getCfg(); + for (const block of cfg.getBlocks()) { + for (const stmt of block.getStmts()) { + TypeInference.inferSimpleTypeInStmt(stmt); + } + } + } + + /** + * infer type for Exprs in stmt which invoke method. + * such as ArkInstanceInvokeExpr ArkStaticInvokeExpr ArkNewExpr + */ + private static resolveExprsInStmt(stmt: Stmt, arkMethod: ArkMethod): void { + for (const expr of stmt.getExprs()) { + const newExpr = expr.inferType(arkMethod); + if ( + stmt.containsInvokeExpr() && + ((expr instanceof ArkInstanceInvokeExpr && newExpr instanceof ArkStaticInvokeExpr) || newExpr instanceof ArkPtrInvokeExpr) + ) { + stmt.replaceUse(expr, newExpr); + } + } + if (stmt instanceof ArkAliasTypeDefineStmt && this.isUnclearType(stmt.getAliasType().getOriginalType())) { + stmt.getAliasType().setOriginalType(stmt.getAliasTypeExpr().getType()); + } + } + + /** + * infer value type for TypeExprs in stmt which specify the type such as TypeQueryExpr + */ + private static resolveTypeExprsInStmt(stmt: Stmt, arkMethod: ArkMethod): void { + for (let typeExpr of stmt.getTypeExprs()) { + typeExpr.inferType(arkMethod); + } + } + + /** + * infer type for fieldRefs in stmt. + */ + private static resolveFieldRefsInStmt(stmt: Stmt, arkMethod: ArkMethod): void { + for (const use of stmt.getUses()) { + if (use instanceof AbstractRef) { + this.processRef(use, stmt, arkMethod); + } + } + const stmtDef = stmt.getDef(); + if (stmtDef && stmtDef instanceof AbstractRef) { + if ( + arkMethod.getName() === INSTANCE_INIT_METHOD_NAME && + stmtDef instanceof ArkInstanceFieldRef && + stmtDef.getBase().getName() === THIS_NAME && + arkMethod.getDeclaringArkClass().isAnonymousClass() && + stmtDef.getFieldName().indexOf('.') === -1 + ) { + return; + } + const fieldRef = stmtDef.inferType(arkMethod); + stmt.replaceDef(stmtDef, fieldRef); + } + } + + private static processRef(use: AbstractRef | ArkInstanceFieldRef, stmt: Stmt, arkMethod: ArkMethod): void { + const fieldRef = use.inferType(arkMethod); + if (fieldRef instanceof ArkStaticFieldRef && stmt instanceof ArkAssignStmt) { + stmt.replaceUse(use, fieldRef); + } else if (use instanceof ArkInstanceFieldRef && fieldRef instanceof ArkArrayRef && stmt instanceof ArkAssignStmt) { + const index = fieldRef.getIndex(); + if (index instanceof Constant && index.getType() instanceof StringType) { + const local = arkMethod?.getBody()?.getLocals().get(index.getValue()); + if (local) { + fieldRef.setIndex(local); + } + } + stmt.replaceUse(use, fieldRef); + } + } + + public static parseArkExport2Type(arkExport: ArkExport | undefined | null): Type | null { + if (!arkExport) { + return null; + } + if (arkExport instanceof ArkClass) { + return new ClassType(arkExport.getSignature(), arkExport.getGenericsTypes()); + } else if (arkExport instanceof ArkNamespace) { + return AnnotationNamespaceType.getInstance(arkExport.getSignature()); + } else if (arkExport instanceof ArkMethod) { + return new FunctionType(arkExport.getSignature()); + } else if (arkExport instanceof Local) { + if (arkExport.getType() instanceof UnknownType || arkExport.getType() instanceof UnclearReferenceType) { + return null; + } + return arkExport.getType(); + } else if (arkExport instanceof AliasType) { + return arkExport; + } else { + return null; + } + } + + /** + * infer and pass type for ArkAssignStmt right and left + * @param stmt + * @param arkMethod + */ + public static resolveArkAssignStmt(stmt: Stmt, arkMethod: ArkMethod): void { + if (!(stmt instanceof ArkAssignStmt)) { + return; + } + const arkClass = arkMethod.getDeclaringArkClass(); + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local && rightOp.getType() instanceof UnknownType) { + IRInference.inferLocal(rightOp, arkMethod); + } + let rightType: Type | null | undefined = rightOp.getType(); + if (this.isUnclearType(rightType)) { + rightType = this.inferUnclearedType(rightType, arkClass); + if (rightType) { + this.setValueType(rightOp, rightType); + } + } + TypeInference.resolveLeftOp(stmt, arkClass, rightType, arkMethod); + } + + private static resolveLeftOp(stmt: ArkAssignStmt, arkClass: ArkClass, rightType: Type | null | undefined, arkMethod: ArkMethod): void { + const leftOp = stmt.getLeftOp(); + let leftType: Type | null | undefined = leftOp.getType(); + if (this.isUnclearType(leftType)) { + const newLeftType = this.inferUnclearedType(leftType, arkClass); + if (!newLeftType && !this.isUnclearType(rightType)) { + leftType = rightType; + } else if (newLeftType) { + leftType = newLeftType; + } + } else if (leftOp instanceof Local && leftOp.getName() === THIS_NAME) { + const thisLocal = IRInference.inferThisLocal(arkMethod); + if (thisLocal) { + stmt.setLeftOp(thisLocal); + } else { + leftType = rightType; + } + } + if (leftType && !this.isUnclearType(leftType)) { + this.setValueType(leftOp, leftType); + if (leftOp instanceof Local && stmt.getOriginalText()?.startsWith(leftOp.getName())) { + let localDef = ModelUtils.findDeclaredLocal(leftOp, arkMethod); + if (localDef && this.isUnclearType(localDef.getType())) { + localDef.setType(leftType); + } + } + if (rightType) { + IRInference.inferRightWithSdkType(leftType, rightType, arkClass); + } + if (leftOp instanceof AbstractFieldRef) { + const declaringSignature = leftOp.getFieldSignature().getDeclaringSignature(); + if (declaringSignature instanceof NamespaceSignature && declaringSignature.getNamespaceName() === GLOBAL_THIS_NAME) { + SdkUtils.computeGlobalThis(leftOp, arkMethod); + } + } + } + } + + private static setValueType(value: Value, type: Type): void { + if (value instanceof Local || value instanceof ArkParameterRef) { + value.setType(type); + } else if (value instanceof AbstractFieldRef) { + value.getFieldSignature().setType(type); + } + } + + public static isUnclearType(type: Type | null | undefined): boolean { + // TODO: For UnionType, IntersectionType and TupleType, it should recurse check every item of them. + if (!type || type instanceof UnknownType || type instanceof UnclearReferenceType || type instanceof NullType || type instanceof UndefinedType) { + return true; + } else if ( + type instanceof ClassType && + (type.getClassSignature().getDeclaringFileSignature().getFileName() === UNKNOWN_FILE_NAME || + (type.getClassSignature().getClassName() === PROMISE && !type.getRealGenericTypes()) || + (type.getClassSignature().getDeclaringFileSignature().getFileName() === Builtin.DUMMY_FILE_NAME && + type.getRealGenericTypes()?.find(t => t instanceof GenericType))) + ) { + return true; + } else if (type instanceof UnionType || type instanceof IntersectionType || type instanceof TupleType) { + return !!type.getTypes().find(t => this.hasUnclearReferenceType(t)); + } else if (type instanceof ArrayType) { + const baseType = type.getBaseType(); + return this.hasUnclearReferenceType(baseType) || baseType instanceof GenericType; + } else if (type instanceof AliasType) { + return this.isUnclearType(type.getOriginalType()); + } else if (type instanceof KeyofTypeExpr) { + return this.isUnclearType(type.getOpType()); + } else if (type instanceof TypeQueryExpr) { + return this.isUnclearType(type.getType()); + } + return false; + } + + // This is the temporal function to check unclearReferenceType recursively and can be removed after typeInfer supports multiple candidate types. + private static hasUnclearReferenceType(type: Type, visited: Set = new Set()): boolean { + if (visited.has(type)) { + return false; + } else { + visited.add(type); + } + if (type instanceof UnclearReferenceType) { + return true; + } else if (type instanceof UnionType || type instanceof IntersectionType || type instanceof TupleType) { + return !!type.getTypes().find(t => this.hasUnclearReferenceType(t, visited)); + } else if (type instanceof ArrayType) { + return this.hasUnclearReferenceType(type.getBaseType(), visited); + } else if (type instanceof AliasType) { + return this.hasUnclearReferenceType(type.getOriginalType(), visited); + } else if (type instanceof KeyofTypeExpr) { + return this.hasUnclearReferenceType(type.getOpType(), visited); + } else if (type instanceof TypeQueryExpr) { + return this.hasUnclearReferenceType(type.getType(), visited); + } + return false; + } + + public static inferSimpleTypeInStmt(stmt: Stmt): void { + if (stmt instanceof ArkAssignStmt) { + const leftOp = stmt.getLeftOp(); + if (leftOp instanceof Local) { + const leftOpType = leftOp.getType(); + if (leftOpType instanceof UnknownType) { + const rightOp = stmt.getRightOp(); + leftOp.setType(rightOp.getType()); + } + } + } + } + + // Deal only with simple situations + public static buildTypeFromStr(typeStr: string): Type { + switch (typeStr) { + case BOOLEAN_KEYWORD: + return BooleanType.getInstance(); + case NUMBER_KEYWORD: + return NumberType.getInstance(); + case STRING_KEYWORD: + return StringType.getInstance(); + case UNDEFINED_KEYWORD: + return UndefinedType.getInstance(); + case NULL_KEYWORD: + return NullType.getInstance(); + case ANY_KEYWORD: + return AnyType.getInstance(); + case VOID_KEYWORD: + return VoidType.getInstance(); + case NEVER_KEYWORD: + return NeverType.getInstance(); + case BIGINT_KEYWORD: + return BigIntType.getInstance(); + case 'RegularExpression': { + const classSignature = Builtin.REGEXP_CLASS_SIGNATURE; + return new ClassType(classSignature); + } + default: + return new UnclearReferenceType(typeStr); + } + } + + public static inferValueType(value: Value, arkMethod: ArkMethod): Type | null { + if (value instanceof ArkInstanceFieldRef || value instanceof ArkInstanceInvokeExpr) { + this.inferValueType(value.getBase(), arkMethod); + } + if (value instanceof AbstractRef || value instanceof AbstractExpr || value instanceof Local) { + value.inferType(arkMethod); + } + return value.getType(); + } + + private static inferParameterType(param: MethodParameter, arkMethod: ArkMethod): void { + let pType = param.getType(); + const arkClass = arkMethod.getDeclaringArkClass(); + let type; + if (pType instanceof AbstractTypeExpr) { + pType.inferType(arkMethod); + } else if (param.getName() === 'value' && arkClass.hasComponentDecorator() && arkMethod.getName() === CONSTRUCTOR_NAME) { + type = this.parseArkExport2Type(arkClass); + } else { + type = TypeInference.inferUnclearedType(pType, arkClass); + } + if (type) { + param.setType(type); + } + } + + public static inferSignatureReturnType(oldSignature: MethodSignature, arkMethod: ArkMethod): void { + if (oldSignature.getMethodSubSignature().getMethodName() === CONSTRUCTOR_NAME) { + const newReturnType = new ClassType(oldSignature.getDeclaringClassSignature()); + oldSignature.getMethodSubSignature().setReturnType(newReturnType); + return; + } + const currReturnType = oldSignature.getType(); + if (!this.isUnclearType(currReturnType)) { + return; + } + + if (currReturnType instanceof AbstractTypeExpr) { + currReturnType.inferType(arkMethod); + return; + } + + if (currReturnType instanceof ArrayType && currReturnType.getBaseType() instanceof AbstractTypeExpr) { + (currReturnType.getBaseType() as AbstractTypeExpr).inferType(arkMethod); + return; + } + + const newReturnType = this.inferUnclearedType(currReturnType, arkMethod.getDeclaringArkClass()); + if (newReturnType) { + oldSignature.getMethodSubSignature().setReturnType(newReturnType); + } else if (arkMethod.getBody()) { + const returnType = TypeInference.inferReturnType(arkMethod); + if (returnType) { + oldSignature.getMethodSubSignature().setReturnType(returnType); + } + } + } + + private static inferReturnType(arkMethod: ArkMethod): Type | null { + const typeMap: Map = new Map(); + for (let returnValue of arkMethod.getReturnValues()) { + const type = returnValue.getType(); + if (type instanceof UnionType) { + type.flatType() + .filter(t => !TypeInference.isUnclearType(t)) + .forEach(t => typeMap.set(t.toString(), t)); + } else if (!TypeInference.isUnclearType(type)) { + typeMap.set(type.toString(), type); + } + } + if (typeMap.size > 0) { + const types: Type[] = Array.from(typeMap.values()); + let returnType = types.length === 1 ? types[0] : new UnionType(types); + if (arkMethod.containsModifier(ModifierType.ASYNC)) { + const promise = arkMethod.getDeclaringArkFile().getScene().getSdkGlobal(PROMISE); + if (promise instanceof ArkClass) { + returnType = new ClassType(promise.getSignature(), [returnType]); + } + } + return returnType; + } + return null; + } + + public static inferGenericType(types: GenericType[] | undefined, arkClass: ArkClass): void { + types?.forEach(type => { + const defaultType = type.getDefaultType(); + if (defaultType instanceof UnclearReferenceType) { + const newDefaultType = TypeInference.inferUnclearRefName(defaultType.getName(), arkClass); + if (newDefaultType) { + type.setDefaultType(this.replaceTypeWithReal(newDefaultType)); + } + } + const constraint = type.getConstraint(); + if (constraint instanceof UnclearReferenceType) { + const newConstraint = TypeInference.inferUnclearRefName(constraint.getName(), arkClass); + if (newConstraint) { + type.setConstraint(this.replaceTypeWithReal(newConstraint)); + } + } + }); + } + + /** + * Infer type for a given {@link UnclearReferenceType} type. + * It returns original type. + * The original type is null if it failed to infer the type. + * @param urType + * @param arkClass + * @returns + */ + public static inferUnclearRefType(urType: UnclearReferenceType, arkClass: ArkClass): Type | null { + const realTypes = urType.getGenericTypes(); + this.inferRealGenericTypes(realTypes, arkClass); + if (urType.getName() === Builtin.ARRAY) { + return new ArrayType(realTypes[0] ?? AnyType.getInstance(), 1); + } + const type = this.inferUnclearRefName(urType.getName(), arkClass); + return type ? this.replaceTypeWithReal(type, realTypes) : null; + } + + /** + * Find out the original object and type for a given unclear reference type name. + * It returns original type. + * The original type is null if it failed to infer the type. + * @param refName + * @param arkClass + * @returns + */ + public static inferUnclearRefName(refName: string, arkClass: ArkClass): Type | null { + if (!refName) { + return null; + } + //split and iterate to infer each type + const singleNames = refName.split('.'); + let type = null; + for (let i = 0; i < singleNames.length; i++) { + let genericName: string = EMPTY_STRING; + const name = singleNames[i].replace(/<(\w+)>/, (match, group1) => { + genericName = group1; + return EMPTY_STRING; + }); + if (i === 0) { + type = singleNames.length > 1 ? this.inferBaseType(name, arkClass) : this.inferTypeByName(name, arkClass); + } else if (type) { + type = this.inferFieldType(type, name, arkClass)?.[1]; + } + if (!type) { + return null; + } + if (genericName) { + const realTypes = genericName.split(',').map(generic => { + const realType = this.inferUnclearRefName(generic, arkClass); + return realType ?? new UnclearReferenceType(generic); + }); + if (type instanceof ClassType) { + type = new ClassType(type.getClassSignature(), realTypes); + } else if (type instanceof FunctionType) { + type = new FunctionType(type.getMethodSignature(), realTypes); + } + } + } + return type; + } + + /** + * Find out the original object and type for a given base type and the field name. + * It returns an array with 2 items, original object and original type. + * The original object is null if there is no object, or it failed to find the object. + * The original type is null if it failed to infer the type. + * @param baseType + * @param fieldName + * @param declareClass + * @returns + */ + public static inferFieldType(baseType: Type, fieldName: string, declareClass: ArkClass): [any, Type] | null { + if (baseType instanceof AliasType) { + baseType = baseType.getOriginalType(); + } else if (baseType instanceof UnionType && baseType.getCurrType()) { + baseType = baseType.getCurrType(); + } + let propertyAndType: [any, Type] | null = null; + if (baseType instanceof ClassType) { + if ( + fieldName === Builtin.ITERATOR_RESULT_VALUE && + baseType.getClassSignature().getDeclaringFileSignature().getProjectName() === Builtin.DUMMY_PROJECT_NAME + ) { + const types = baseType.getRealGenericTypes(); + if (types && types.length > 0) { + return [null, types[0]]; + } + return null; + } + propertyAndType = this.inferClassFieldType(declareClass, baseType, fieldName); + } else if (baseType instanceof AnnotationNamespaceType) { + const namespace = declareClass.getDeclaringArkFile().getScene().getNamespace(baseType.getNamespaceSignature()); + if (namespace) { + const property = ModelUtils.findPropertyInNamespace(fieldName, namespace); + const propertyType = this.parseArkExport2Type(property); + if (propertyType) { + propertyAndType = [property, propertyType]; + } + } + } else { + logger.warn('infer unclear reference type fail: ' + fieldName); + } + return propertyAndType; + } + + private static inferClassFieldType(declareClass: ArkClass, baseType: ClassType, fieldName: string): [any, Type] | null { + const arkClass = declareClass.getDeclaringArkFile().getScene().getClass(baseType.getClassSignature()); + if (!arkClass) { + return null; + } + const property = ModelUtils.findPropertyInClass(fieldName, arkClass); + let propertyType: Type | null = null; + if (property instanceof ArkField) { + if (arkClass.getCategory() === ClassCategory.ENUM) { + let constant; + const lastStmt = property.getInitializer().at(-1); + if (lastStmt instanceof ArkAssignStmt && lastStmt.getRightOp() instanceof Constant) { + constant = lastStmt.getRightOp() as Constant; + } + propertyType = new EnumValueType(property.getSignature(), constant); + } else { + propertyType = property.getType(); + } + } else if (property) { + propertyType = this.parseArkExport2Type(property); + } + if (propertyType) { + return [property, propertyType]; + } else if (arkClass.isAnonymousClass()) { + const fieldType = this.inferUnclearRefName(fieldName, arkClass); + return fieldType ? [null, fieldType] : null; + } + return null; + } + + /** + * Find out the original object and type for a given base name. + * It returns original type. + * The original type is null if failed to infer the type. + * @param baseName + * @param arkClass + * @returns + */ + public static inferBaseType(baseName: string, arkClass: ArkClass): Type | null { + if (SUPER_NAME === baseName) { + return this.parseArkExport2Type(arkClass.getSuperClass()); + } + const field = ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getLocals()?.get(baseName); + if (field && !this.isUnclearType(field.getType())) { + return field.getType(); + } + let arkExport: ArkExport | null = + ModelUtils.getClassWithName(baseName, arkClass) ?? + ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(baseName) ?? + ModelUtils.getNamespaceWithName(baseName, arkClass) ?? + ModelUtils.getDefaultClass(arkClass)?.getMethodWithName(baseName) ?? + ModelUtils.getArkExportInImportInfoWithName(baseName, arkClass.getDeclaringArkFile()); + if (!arkExport && !arkClass.getDeclaringArkFile().getImportInfoBy(baseName)) { + arkExport = arkClass.getDeclaringArkFile().getScene().getSdkGlobal(baseName); + } + return this.parseArkExport2Type(arkExport); + } + + public static inferTypeByName(typeName: string, arkClass: ArkClass): Type | null { + let arkExport: ArkExport | null = + ModelUtils.getClassWithName(typeName, arkClass) ?? + ModelUtils.getDefaultClass(arkClass)?.getDefaultArkMethod()?.getBody()?.getAliasTypeByName(typeName) ?? + ModelUtils.getArkExportInImportInfoWithName(typeName, arkClass.getDeclaringArkFile()); + if (arkExport instanceof ArkClass || arkExport instanceof AliasType) { + return this.parseArkExport2Type(arkExport); + } + if (!arkClass.getDeclaringArkFile().getImportInfoBy(typeName)) { + arkExport = arkClass.getDeclaringArkFile().getScene().getSdkGlobal(typeName); + } + if (arkExport instanceof ArkClass || arkExport instanceof AliasType) { + return this.parseArkExport2Type(arkExport); + } + return null; + } + + public static inferRealGenericTypes(realTypes: Type[] | undefined, arkClass: ArkClass): void { + if (!realTypes) { + return; + } + for (let i = 0; i < realTypes.length; i++) { + const mayType = realTypes[i]; + if (this.isUnclearType(mayType)) { + const newType = this.inferUnclearedType(mayType, arkClass); + if (newType) { + realTypes[i] = newType; + } + } + } + } + + public static inferDynamicImportType(from: string, arkClass: ArkClass): Type | null { + const importInfo = new ImportInfo(); + importInfo.setNameBeforeAs(ALL); + importInfo.setImportClauseName(ALL); + importInfo.setImportFrom(from); + importInfo.setDeclaringArkFile(arkClass.getDeclaringArkFile()); + return TypeInference.parseArkExport2Type(importInfo.getLazyExportInfo()?.getArkExport()); + } + + public static replaceTypeWithReal(type: Type, realTypes?: Type[], visited: Set = new Set()): Type { + if (visited.has(type)) { + return type; + } else { + visited.add(type); + } + if (type instanceof GenericType) { + const realType = realTypes?.[type.getIndex()] ?? type.getDefaultType() ?? type.getConstraint(); + return realType ?? type; + } else if (type instanceof AnyType) { + const realType = realTypes?.[0]; + return realType ?? type; + } + return this.replaceRecursiveType(type, visited, realTypes); + } + + public static replaceRecursiveType(type: Type, visited: Set, realTypes?: Type[]): Type { + if (type instanceof ClassType) { + const replacedTypes = type.getRealGenericTypes()?.map(g => this.replaceTypeWithReal(g, realTypes, visited)) ?? realTypes; + return replacedTypes && replacedTypes.length > 0 ? new ClassType(type.getClassSignature(), replacedTypes) : type; + } else if (type instanceof FunctionType) { + const replacedTypes = type.getRealGenericTypes()?.map(g => this.replaceTypeWithReal(g, realTypes, visited)) ?? realTypes; + return replacedTypes && replacedTypes.length > 0 ? new FunctionType(type.getMethodSignature(), replacedTypes) : type; + } else if (type instanceof AliasType && realTypes) { + const newObjectType = this.replaceTypeWithReal(type.getOriginalType(), realTypes, visited); + const replacedTypes = type.getRealGenericTypes()?.map(g => this.replaceTypeWithReal(g, realTypes, visited)) ?? realTypes; + if (replacedTypes.length > 0) { + const newAliasType = new AliasType(type.getName(), newObjectType, type.getSignature(), type.getGenericTypes()); + newAliasType.setRealGenericTypes(replacedTypes); + return newAliasType; + } + } else if (type instanceof UnionType && realTypes) { + const types: Type[] = []; + type.flatType().forEach(t => types.push(this.replaceTypeWithReal(t, realTypes, visited))); + return new UnionType(types, this.replaceTypeWithReal(type.getCurrType(), realTypes, visited)); + } else if (type instanceof IntersectionType && realTypes) { + const types: Type[] = []; + type.getTypes().forEach(t => types.push(this.replaceTypeWithReal(t, realTypes, visited))); + return new IntersectionType(types); + } else if (type instanceof ArrayType && realTypes) { + const replacedBaseType = this.replaceTypeWithReal(type.getBaseType(), realTypes, visited); + return new ArrayType(replacedBaseType, type.getDimension()); + } else if (type instanceof TupleType && realTypes) { + let replacedTypes: Type[] = []; + type.getTypes().forEach(t => replacedTypes.push(this.replaceTypeWithReal(t, realTypes, visited))); + return new TupleType(replacedTypes); + } + return type; + } + + public static replaceAliasType(type: Type): Type { + let aliasType = type; + while (aliasType instanceof AliasType) { + aliasType = aliasType.getOriginalType(); + } + return aliasType; + } + + public static inferFunctionType(argType: FunctionType, paramSubSignature: MethodSubSignature | undefined, realTypes: Type[] | undefined): void { + const returnType = argType.getMethodSignature().getMethodSubSignature().getReturnType(); + const declareType = paramSubSignature?.getReturnType(); + if (declareType instanceof GenericType && realTypes && !this.isUnclearType(returnType) && !(returnType instanceof VoidType)) { + realTypes[declareType.getIndex()] = returnType; + } + const params = paramSubSignature?.getParameters(); + if (!params) { + return; + } + argType + .getMethodSignature() + .getMethodSubSignature() + .getParameters() + .filter(p => !p.getName().startsWith(LEXICAL_ENV_NAME_PREFIX)) + .forEach((p, i) => { + let type = params?.[i]?.getType(); + if (type instanceof GenericType && realTypes) { + type = realTypes?.[type.getIndex()]; + } + if (type) { + p.setType(type); + } + }); + } + + private static resolveArkReturnStmt(stmt: Stmt, arkMethod: ArkMethod): void { + if (!(stmt instanceof ArkReturnStmt)) { + return; + } + let returnType: Type | undefined = arkMethod.getSignature().getType(); + if (returnType instanceof ClassType && returnType.getClassSignature().getClassName() === PROMISE) { + returnType = returnType.getRealGenericTypes()?.at(0); + } + if (returnType) { + IRInference.inferRightWithSdkType(returnType, stmt.getOp().getType(), arkMethod.getDeclaringArkClass()); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/ValueUtil.ts b/ets2panda/linter/arkanalyzer/src/core/common/ValueUtil.ts new file mode 100644 index 0000000000000000000000000000000000000000..1731b701b04d71d60c4e12b93931b2c9ec0547aa --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/ValueUtil.ts @@ -0,0 +1,63 @@ +/* + * 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. + */ + +import { BigIntConstant, BooleanConstant, Constant, NullConstant, NumberConstant, StringConstant, UndefinedConstant } from '../base/Constant'; + +export const EMPTY_STRING = ''; + +export class ValueUtil { + private static readonly NumberConstantCache: Map = new Map(); + public static readonly EMPTY_STRING_CONSTANT = new StringConstant(EMPTY_STRING); + + public static getOrCreateNumberConst(n: number): Constant { + let constant = this.NumberConstantCache.get(n); + if (constant === undefined) { + constant = new NumberConstant(n); + this.NumberConstantCache.set(n, constant); + } + return constant; + } + + public static createBigIntConst(bigInt: bigint): BigIntConstant { + return new BigIntConstant(bigInt); + } + + public static createStringConst(str: string): Constant { + if (str === EMPTY_STRING) { + return this.EMPTY_STRING_CONSTANT; + } + return new StringConstant(str); + } + + public static createConst(str: string): Constant { + const n = Number(str); + if (!isNaN(n)) { + return this.getOrCreateNumberConst(n); + } + return new StringConstant(str); + } + + public static getUndefinedConst(): Constant { + return UndefinedConstant.getInstance(); + } + + public static getNullConstant(): Constant { + return NullConstant.getInstance(); + } + + public static getBooleanConstant(value: boolean): Constant { + return BooleanConstant.getInstance(value); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/common/VisibleValue.ts b/ets2panda/linter/arkanalyzer/src/core/common/VisibleValue.ts new file mode 100644 index 0000000000000000000000000000000000000000..762f02592e50211b74c82e9b72a6f9af3230735f --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/common/VisibleValue.ts @@ -0,0 +1,204 @@ +/* + * 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. + */ + +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { Local } from '../base/Local'; +import { ArkInstanceFieldRef, ArkStaticFieldRef } from '../base/Ref'; +import { ArkAssignStmt } from '../base/Stmt'; +import { ClassType } from '../base/Type'; +import { Value } from '../base/Value'; +import { BasicBlock } from '../graph/BasicBlock'; +import { ArkClass } from '../model/ArkClass'; +import { ArkFile } from '../model/ArkFile'; +import { ArkMethod } from '../model/ArkMethod'; +import { ArkNamespace } from '../model/ArkNamespace'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'VisibleValue'); + +export class VisibleValue { + private scopeChain: Scope[]; // 不包含currScope + private currScope: Scope; + private currVisibleValues: Value[]; + + constructor() { + // TODO:填充全局变量 + this.currScope = new Scope([], 0); + this.scopeChain = [this.currScope]; + this.currVisibleValues = [...this.currScope.values]; + } + + /** get values that is visible in curr scope */ + public getCurrVisibleValues(): Value[] { + return this.currVisibleValues; + } + + public getScopeChain(): Scope[] { + return this.scopeChain; + } + + /** udpate visible values after entered a scope, only support step by step */ + public updateIntoScope(model: ArkModel): void { + let name = ''; + if (model instanceof BasicBlock) { + name = 'block: ' + model.toString(); + } else { + name = model.getName(); + } + logger.info('---- into scope:{', name, '}'); + + // get values in this scope + let values: Value[] = []; + if (model instanceof ArkFile || model instanceof ArkNamespace) { + values = this.getVisibleValuesIntoFileOrNameSpace(model); + } else if (model instanceof ArkClass) { + values = this.getVisibleValuesIntoClass(model); + } else if (model instanceof ArkMethod) { + values = this.getVisibleValuesIntoMethod(model); + } else if (model instanceof BasicBlock) { + values = this.getVisibleValuesIntoBasicBlock(model); + } + + // handle scope chain + const targetDepth = this.getTargetDepth(model); + this.addScope(values, targetDepth, model); + } + + /** udpate visible values after left a scope, only support step by step */ + public updateOutScope(): void { + const currModel = this.currScope.arkModel as ArkModel; + + let name = ''; + if (currModel instanceof BasicBlock) { + name = 'block: ' + currModel.toString(); + } else { + name = currModel.getName(); + } + logger.info('---- out scope:{', name, '}'); + + let targetDepth = this.currScope.depth; + if (currModel instanceof BasicBlock) { + const successorsCnt = currModel.getSuccessors().length; + // if successorsCnt <= 0, unchange + if (successorsCnt > 1) { + targetDepth += 1; // goto inner scope + } + } + this.deleteScope(targetDepth); + } + + /** clear up previous scope */ + private deleteScope(targetDepth: number): void { + const prevDepth = this.currScope.depth; + if (targetDepth > prevDepth) { + return; + } + + let popScopeValuesCnt = 0; + let popScopeCnt = 0; + for (let i = this.scopeChain.length - 1; i >= 0; i--) { + if (this.scopeChain[i].depth < targetDepth) { + break; + } + popScopeCnt += 1; + popScopeValuesCnt += this.scopeChain[i].values.length; + } + + this.scopeChain.splice(this.scopeChain.length - popScopeCnt, popScopeCnt)[0]; // popScopeCnt >= 1 + this.currScope = this.scopeChain[this.scopeChain.length - 1]; + const totalValuesCnt = this.currVisibleValues.length; + this.currVisibleValues.splice(totalValuesCnt - popScopeValuesCnt, popScopeValuesCnt); + } + + /** add this scope to scope chain and update visible values */ + private addScope(values: Value[], targetDepth: number, model: ArkModel): void { + const newScope = new Scope(values, targetDepth, model); + this.currScope = newScope; + this.scopeChain.push(this.currScope); + this.currVisibleValues.push(...this.currScope.values); + } + + // TODO:构造嵌套关系树 + private getTargetDepth(model: ArkModel): number { + const prevDepth = this.currScope.depth; + const prevModel = this.currScope.arkModel; + let targetDepth = prevDepth + 1; + if (model instanceof BasicBlock) { + const predecessorsCnt = model.getPredecessors().length; + if (predecessorsCnt <= 1) { + targetDepth = prevDepth + 1; + } else { + targetDepth = prevDepth; + } + } else if (model instanceof ArkFile && prevModel instanceof ArkFile) { + targetDepth = prevDepth; + } else if (model instanceof ArkNamespace && prevModel instanceof ArkNamespace) { + targetDepth = prevDepth; + } else if (model instanceof ArkClass && prevModel instanceof ArkClass) { + targetDepth = prevDepth; + } else if (model instanceof ArkMethod && prevModel instanceof ArkMethod) { + targetDepth = prevDepth; + } + return targetDepth; + } + + private getVisibleValuesIntoFileOrNameSpace(fileOrNameSpace: ArkFile | ArkNamespace): Value[] { + let values: Value[] = []; + return values; + } + + private getVisibleValuesIntoClass(cls: ArkClass): Value[] { + const values: Value[] = []; + const fields = cls.getFields(); + const classSignature = cls.getSignature(); + for (const field of fields) { + if (field.isStatic()) { + const staticFieldRef = new ArkStaticFieldRef(field.getSignature()); + values.push(staticFieldRef); + } else { + const instanceFieldRef = new ArkInstanceFieldRef(new Local('this', new ClassType(classSignature)), field.getSignature()); + values.push(instanceFieldRef); + } + } + return values; + } + + private getVisibleValuesIntoMethod(method: ArkMethod): Value[] { + let visibleValues: Value[] = []; + return visibleValues; + } + + private getVisibleValuesIntoBasicBlock(basiceBlock: BasicBlock): Value[] { + const visibleValues: Value[] = []; + for (const stmt of basiceBlock.getStmts()) { + if (stmt instanceof ArkAssignStmt) { + visibleValues.push(stmt.getLeftOp()); + } + } + return visibleValues; + } +} + +type ArkModel = ArkFile | ArkNamespace | ArkClass | ArkMethod | BasicBlock; + +export class Scope { + public values: Value[]; + public depth: number; + public arkModel: ArkModel | null; + constructor(values: Value[], depth: number = -1, arkModel: ArkModel | null = null) { + this.values = values; + this.depth = depth; + this.arkModel = arkModel; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowProblem.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowProblem.ts new file mode 100644 index 0000000000000000000000000000000000000000..f877a1be0eb5a041a60931f74aa391db77c3474e --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowProblem.ts @@ -0,0 +1,54 @@ +/* + * 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. + */ + +import { Stmt } from '../base/Stmt'; +import { ArkMethod } from '../model/ArkMethod'; + +export abstract class DataflowProblem { + /** + * Transfer the outFact of srcStmt to the inFact of tgtStmt + * + * Return true if keeping progagation (i.e., tgtStmt will be added to the WorkList for further analysis) + */ + /* + abstract transferNormalEdge(srcStmt: Stmt, tgtStmt: Stmt, result: DataflowResult): boolean; + + abstract transferCallToReturnEdge(srcStmt: Stmt, tgtStmt: Stmt, result: DataflowResult): boolean; + + abstract transferCallEdge(srcStmt: Stmt, tgtStmt: Stmt, result: DataflowResult): boolean; + + abstract transferReturnEdge(srcStmt: Stmt, tgtStmt: Stmt, result: DataflowResult): boolean; + */ + + abstract getNormalFlowFunction(srcStmt: Stmt, tgtStmt: Stmt): FlowFunction; + + abstract getCallFlowFunction(srcStmt: Stmt, method: ArkMethod): FlowFunction; + + abstract getExitToReturnFlowFunction(srcStmt: Stmt, tgtStmt: Stmt, callStmt: Stmt): FlowFunction; + + abstract getCallToReturnFlowFunction(srcStmt: Stmt, tgtStmt: Stmt): FlowFunction; + + abstract createZeroValue(): D; + + abstract getEntryPoint(): Stmt; + + abstract getEntryMethod(): ArkMethod; + + abstract factEqual(d1: D, d2: D): boolean; +} + +export interface FlowFunction { + getDataFacts(d: D): Set; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowResult.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowResult.ts new file mode 100644 index 0000000000000000000000000000000000000000..d01d56d46aa907ce971a28496066daf0d6f02204 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowResult.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +import { Stmt } from '../base/Stmt'; +import { Fact } from './Fact'; + +export class DataflowResult { + stmt2InFacts: Map = new Map(); + stmt2OutFacts: Map = new Map(); + + //should we specifically keep global facts or just embedding them into the two maps above + globalFacts: Set = new Set(); +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowSolver.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowSolver.ts new file mode 100644 index 0000000000000000000000000000000000000000..523dd9a41b17104bc1b850c060e8a50fd796ba03 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/DataflowSolver.ts @@ -0,0 +1,357 @@ +/* + * 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. + */ + +import { Scene } from '../../Scene'; +import { AbstractInvokeExpr } from '../base/Expr'; +import { ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, Stmt } from '../base/Stmt'; +import { ArkMethod } from '../model/ArkMethod'; +import { DataflowProblem, FlowFunction } from './DataflowProblem'; +import { PathEdge, PathEdgePoint } from './Edge'; +import { BasicBlock } from '../graph/BasicBlock'; +import { CallGraph } from '../../callgraph/model/CallGraph'; +import { ClassHierarchyAnalysis } from '../../callgraph/algorithm/ClassHierarchyAnalysis'; +import { addCfg2Stmt } from '../../utils/entryMethodUtils'; +import { getRecallMethodInParam } from './Util'; + +/* +this program is roughly an implementation of the paper: Practical Extensions to the IFDS Algorithm. +compare to the original ifds paper : Precise Interprocedural Dataflow Analysis via Graph Reachability, +it have several improvments: +1. construct supergraph on demand(implement in this program); +2. use endSummary and incoming tables to speed up the program(implement in this program) +3. handle ssa form(not implement) +4. handle data facts which subsume another(not implement) +*/ +type CallToReturnCacheEdge = PathEdge; + +export abstract class DataflowSolver { + protected problem: DataflowProblem; + protected workList: Array>; + protected pathEdgeSet: Set>; + protected zeroFact: D; + protected inComing: Map, Set>>; + protected endSummary: Map, Set>>; + protected summaryEdge: Set>; // summaryEdge不是加速一个函数内多次调用同一个函数,而是加速多次调用同一个函数f时,f内的函数调用 + protected scene: Scene; + protected CHA!: ClassHierarchyAnalysis; + protected stmtNexts: Map>; + protected laterEdges: Set> = new Set(); + + constructor(problem: DataflowProblem, scene: Scene) { + this.problem = problem; + this.scene = scene; + scene.inferTypes(); + this.zeroFact = problem.createZeroValue(); + this.workList = new Array>(); + this.pathEdgeSet = new Set>(); + this.inComing = new Map, Set>>(); + this.endSummary = new Map, Set>>(); + this.summaryEdge = new Set>(); + this.stmtNexts = new Map(); + } + + public solve(): void { + this.init(); + this.doSolve(); + } + + protected computeResult(stmt: Stmt, d: D): boolean { + for (let pathEdge of this.pathEdgeSet) { + if (pathEdge.edgeEnd.node === stmt && pathEdge.edgeEnd.fact === d) { + return true; + } + } + return false; + } + + protected getChildren(stmt: Stmt): Stmt[] { + return Array.from(this.stmtNexts.get(stmt) || []); + } + + protected init(): void { + let edgePoint: PathEdgePoint = new PathEdgePoint(this.problem.getEntryPoint(), this.zeroFact); + let edge: PathEdge = new PathEdge(edgePoint, edgePoint); + this.workList.push(edge); + this.pathEdgeSet.add(edge); + + // build CHA + let cg = new CallGraph(this.scene); + this.CHA = new ClassHierarchyAnalysis(this.scene, cg); + this.buildStmtMapInClass(); + this.setCfg4AllStmt(); + return; + } + + protected buildStmtMapInClass(): void { + const methods = this.scene.getMethods(); + methods.push(this.problem.getEntryMethod()); + for (const method of methods) { + const cfg = method.getCfg(); + const blocks: BasicBlock[] = []; + if (cfg) { + blocks.push(...cfg.getBlocks()); + } + for (const block of blocks) { + this.buildStmtMapInBlock(block); + } + } + } + + protected buildStmtMapInBlock(block: BasicBlock): void { + const stmts = block.getStmts(); + for (let stmtIndex = 0; stmtIndex < stmts.length; stmtIndex++) { + const stmt = stmts[stmtIndex]; + if (stmtIndex !== stmts.length - 1) { + this.stmtNexts.set(stmt, new Set([stmts[stmtIndex + 1]])); + } else { + const set: Set = new Set(); + for (const successor of block.getSuccessors()) { + set.add(successor.getStmts()[0]); + } + this.stmtNexts.set(stmt, set); + } + } + } + + protected setCfg4AllStmt(): void { + for (const cls of this.scene.getClasses()) { + for (const mtd of cls.getMethods(true)) { + addCfg2Stmt(mtd); + } + } + } + + protected getAllCalleeMethods(callNode: ArkInvokeStmt): Set { + const callSites = this.CHA.resolveCall( + this.CHA.getCallGraph().getCallGraphNodeByMethod(this.problem.getEntryMethod().getSignature()).getID(), + callNode + ); + const methods: Set = new Set(); + for (const callSite of callSites) { + const method = this.scene.getMethod(this.CHA.getCallGraph().getMethodByFuncID(callSite.calleeFuncID)!); + if (method) { + methods.add(method); + } + } + return methods; + } + + protected getReturnSiteOfCall(call: Stmt): Stmt { + return [...this.stmtNexts.get(call)!][0]; + } + + protected getStartOfCallerMethod(call: Stmt): Stmt { + const cfg = call.getCfg()!; + const paraNum = cfg.getDeclaringMethod().getParameters().length; + return [...cfg.getBlocks()][0].getStmts()[paraNum]; + } + + protected pathEdgeSetHasEdge(edge: PathEdge): boolean { + for (const path of this.pathEdgeSet) { + this.problem.factEqual(path.edgeEnd.fact, edge.edgeEnd.fact); + if ( + path.edgeEnd.node === edge.edgeEnd.node && + this.problem.factEqual(path.edgeEnd.fact, edge.edgeEnd.fact) && + path.edgeStart.node === edge.edgeStart.node && + this.problem.factEqual(path.edgeStart.fact, edge.edgeStart.fact) + ) { + return true; + } + } + return false; + } + + protected propagate(edge: PathEdge): void { + if (!this.pathEdgeSetHasEdge(edge)) { + let index = this.workList.length; + for (let i = 0; i < this.workList.length; i++) { + if (this.laterEdges.has(this.workList[i])) { + index = i; + break; + } + } + this.workList.splice(index, 0, edge); + this.pathEdgeSet.add(edge); + } + } + + protected processExitNode(edge: PathEdge): void { + let startEdgePoint: PathEdgePoint = edge.edgeStart; + let exitEdgePoint: PathEdgePoint = edge.edgeEnd; + const summary = this.endSummary.get(startEdgePoint); + if (summary === undefined) { + this.endSummary.set(startEdgePoint, new Set([exitEdgePoint])); + } else { + summary.add(exitEdgePoint); + } + const callEdgePoints = this.inComing.get(startEdgePoint); + if (callEdgePoints === undefined) { + if (startEdgePoint.node.getCfg()!.getDeclaringMethod() === this.problem.getEntryMethod()) { + return; + } + throw new Error('incoming does not have ' + startEdgePoint.node.getCfg()?.getDeclaringMethod().toString()); + } + for (let callEdgePoint of callEdgePoints) { + let returnSite: Stmt = this.getReturnSiteOfCall(callEdgePoint.node); + let returnFlowFunc: FlowFunction = this.problem.getExitToReturnFlowFunction(exitEdgePoint.node, returnSite, callEdgePoint.node); + this.handleFacts(returnFlowFunc, returnSite, exitEdgePoint, callEdgePoint); + } + } + + private handleFacts(returnFlowFunc: FlowFunction, returnSite: Stmt, exitEdgePoint: PathEdgePoint, callEdgePoint: PathEdgePoint): void { + for (let fact of returnFlowFunc.getDataFacts(exitEdgePoint.fact)) { + let returnSitePoint: PathEdgePoint = new PathEdgePoint(returnSite, fact); + let cacheEdge: CallToReturnCacheEdge = new PathEdge(callEdgePoint, returnSitePoint); + let summaryEdgeHasCacheEdge = false; + for (const sEdge of this.summaryEdge) { + if (sEdge.edgeStart === callEdgePoint && sEdge.edgeEnd.node === returnSite && sEdge.edgeEnd.fact === fact) { + summaryEdgeHasCacheEdge = true; + break; + } + } + if (summaryEdgeHasCacheEdge) { + continue; + } + this.summaryEdge.add(cacheEdge); + let startOfCaller: Stmt = this.getStartOfCallerMethod(callEdgePoint.node); + for (let pathEdge of this.pathEdgeSet) { + if (pathEdge.edgeStart.node === startOfCaller && pathEdge.edgeEnd === callEdgePoint) { + this.propagate(new PathEdge(pathEdge.edgeStart, returnSitePoint)); + } + } + } + } + + protected processNormalNode(edge: PathEdge): void { + let start: PathEdgePoint = edge.edgeStart; + let end: PathEdgePoint = edge.edgeEnd; + let stmts: Stmt[] = [...this.getChildren(end.node)].reverse(); + for (let stmt of stmts) { + let flowFunction: FlowFunction = this.problem.getNormalFlowFunction(end.node, stmt); + let set: Set = flowFunction.getDataFacts(end.fact); + for (let fact of set) { + let edgePoint: PathEdgePoint = new PathEdgePoint(stmt, fact); + const edge = new PathEdge(start, edgePoint); + this.propagate(edge); + this.laterEdges.add(edge); + } + } + } + + protected processCallNode(edge: PathEdge): void { + let start: PathEdgePoint = edge.edgeStart; + let callEdgePoint: PathEdgePoint = edge.edgeEnd; + const invokeStmt = callEdgePoint.node as ArkInvokeStmt; + let callees: Set; + if (this.scene.getFile(invokeStmt.getInvokeExpr().getMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature())) { + callees = this.getAllCalleeMethods(callEdgePoint.node as ArkInvokeStmt); + } else { + callees = new Set([getRecallMethodInParam(invokeStmt)!]); + } + let returnSite: Stmt = this.getReturnSiteOfCall(callEdgePoint.node); + for (let callee of callees) { + let callFlowFunc: FlowFunction = this.problem.getCallFlowFunction(invokeStmt, callee); + if (!callee.getCfg()) { + continue; + } + let firstStmt: Stmt = [...callee.getCfg()!.getBlocks()][0].getStmts()[callee.getParameters().length]; + let facts: Set = callFlowFunc.getDataFacts(callEdgePoint.fact); + for (let fact of facts) { + this.callNodeFactPropagate(edge, firstStmt, fact, returnSite); + } + } + let callToReturnflowFunc: FlowFunction = this.problem.getCallToReturnFlowFunction(edge.edgeEnd.node, returnSite); + let set: Set = callToReturnflowFunc.getDataFacts(callEdgePoint.fact); + for (let fact of set) { + this.propagate(new PathEdge(start, new PathEdgePoint(returnSite, fact))); + } + for (let cacheEdge of this.summaryEdge) { + if (cacheEdge.edgeStart === edge.edgeEnd && cacheEdge.edgeEnd.node === returnSite) { + this.propagate(new PathEdge(start, cacheEdge.edgeEnd)); + } + } + } + + protected callNodeFactPropagate(edge: PathEdge, firstStmt: Stmt, fact: D, returnSite: Stmt): void { + let callEdgePoint: PathEdgePoint = edge.edgeEnd; + // method start loop path edge + let startEdgePoint: PathEdgePoint = new PathEdgePoint(firstStmt, fact); + this.propagate(new PathEdge(startEdgePoint, startEdgePoint)); + //add callEdgePoint in inComing.get(startEdgePoint) + let coming: Set> | undefined; + for (const incoming of this.inComing.keys()) { + if (incoming.fact === startEdgePoint.fact && incoming.node === startEdgePoint.node) { + coming = this.inComing.get(incoming); + break; + } + } + if (coming === undefined) { + this.inComing.set(startEdgePoint, new Set([callEdgePoint])); + } else { + coming.add(callEdgePoint); + } + let exitEdgePoints: Set> = new Set(); + for (const end of Array.from(this.endSummary.keys())) { + if (end.fact === fact && end.node === firstStmt) { + exitEdgePoints = this.endSummary.get(end)!; + } + } + for (let exitEdgePoint of exitEdgePoints) { + let returnFlowFunc = this.problem.getExitToReturnFlowFunction(exitEdgePoint.node, returnSite, callEdgePoint.node); + for (let returnFact of returnFlowFunc.getDataFacts(exitEdgePoint.fact)) { + this.summaryEdge.add(new PathEdge(edge.edgeEnd, new PathEdgePoint(returnSite, returnFact))); + } + } + } + + protected doSolve(): void { + while (this.workList.length !== 0) { + let pathEdge: PathEdge = this.workList.shift()!; + if (this.laterEdges.has(pathEdge)) { + this.laterEdges.delete(pathEdge); + } + let targetStmt: Stmt = pathEdge.edgeEnd.node; + if (this.isCallStatement(targetStmt)) { + this.processCallNode(pathEdge); + } else if (this.isExitStatement(targetStmt)) { + this.processExitNode(pathEdge); + } else { + this.processNormalNode(pathEdge); + } + } + } + + protected isCallStatement(stmt: Stmt): boolean { + for (const expr of stmt.getExprs()) { + if (expr instanceof AbstractInvokeExpr) { + if (this.scene.getFile(expr.getMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature())) { + return true; + } + if (stmt instanceof ArkInvokeStmt && getRecallMethodInParam(stmt)) { + return true; + } + } + } + return false; + } + + protected isExitStatement(stmt: Stmt): boolean { + return stmt instanceof ArkReturnStmt || stmt instanceof ArkReturnVoidStmt; + } + + public getPathEdgeSet(): Set> { + return this.pathEdgeSet; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/Edge.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/Edge.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f37f08ab0751ef36ea007e74f977c259f5b979a --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/Edge.ts @@ -0,0 +1,36 @@ +/* + * 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. + */ + +import { Stmt } from '../base/Stmt'; + +export class PathEdgePoint { + public node: Stmt; + public fact: D; + + constructor(node: Stmt, fact: D) { + this.node = node; + this.fact = fact; + } +} + +export class PathEdge { + public edgeStart: PathEdgePoint; + public edgeEnd: PathEdgePoint; + + constructor(start: PathEdgePoint, end: PathEdgePoint) { + this.edgeStart = start; + this.edgeEnd = end; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/Fact.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/Fact.ts new file mode 100644 index 0000000000000000000000000000000000000000..accc0b13e0bcb0259c63042a7e60f6505d6c6674 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/Fact.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +import { Value } from '../base/Value'; +import { Stmt } from '../base/Stmt'; + +export class Fact { + values: Set = new Set(); + valueMap: Map = new Map(); // 用最近的def代表value的值 +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/GenericDataFlow.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/GenericDataFlow.ts new file mode 100644 index 0000000000000000000000000000000000000000..a6b4e50d733e67e0a845ab61ea3cfeaf8c5490c8 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/GenericDataFlow.ts @@ -0,0 +1,232 @@ +/* + * 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. + */ + +/** + * Generic Data Flow Analysis Framework + * + * This module provides a generic framework for implementing data flow analyses, + * such as Reaching Definitions, Live Variables, and Available Expressions. + * The framework is designed to be flexible and extensible, allowing users to + * define custom flow graphs, transfer functions, and meet operations. + * + * Design Notes: + * - The framework is designed to be generic and reusable, allowing users to + * implement custom data flow analyses by defining appropriate transfer functions + * and meet operations. + * - The solver uses a worklist algorithm to efficiently compute the MFP solution. + * - The analysis can be configured as either forward or backward, depending on + * the problem requirements. + * + */ + +/** + * Represents a flow graph for data flow analysis. + * Provides access to nodes in post-order and reverse post-order, as well as + * methods to retrieve successors and predecessors of a given node. + * + * @template T - The type of nodes in the graph (e.g., node IDs or node objects). + */ +export interface FlowGraph { + // Nodes in reverse post-order, which is useful for backward data flow analysis. + nodesInReversePostOrder?: T[]; + // Nodes in post-order, which is useful for forward data flow analysis. + nodesInPostOrder: T[]; + // Get precessors of Node t. + pred(t: T): T[]; + // Get successors of Node t. + succ(t: T): T[]; +} + +/** + * DS (Data Set) is an interface that defines the basic operations for a data set. + * It requires the data set to be iterable, comparable, and countable. + */ +interface DS { + /** + * Returns an iterator that allows iterating over the elements of the data set. + * @returns An iterable iterator over the elements of the data set. + */ + [Symbol.iterator](): IterableIterator; + + /** + * Checks whether the current data set is equal to another data set. + */ + equals(d: DS): boolean; + + /** + * Counts the number of elements in the data set. + */ + count(): number; +} + +/** + * Represents the transfer function used in data flow analysis. + * The transfer function computes the output value (out set) of a node + * based on its input value (in set) and the node's properties. + * + * @template Node - The type of nodes in the graph. + * @template V - The type of data flow values (e.g., sets, bit vectors). + */ +export interface TransferFunction { + /** + * Computes the output value for a node based on its input value. + * + * @param n - The node for which the output value is computed. + * @param x - The input value (in set) for the node. + * @returns The output value (out set) for the node. + */ + apply(n: Node, x: V): V; +} + +/** + * Represents a data flow problem, encapsulating all the necessary components + * for performing data flow analysis, such as the flow graph, transfer function, + * meet operation, and initialization configuration. + * + * @template Node - The type of nodes in the graph. + * @template V - The type of data flow values. + */ +export interface DataFlowProblem { + /** + * The flow graph for the data flow analysis. + */ + flowGraph: FlowGraph; + /** + * The transfer function used to compute out sets from in sets. + */ + transferFunction: TransferFunction; + /** + * The meet operation used to combine values from multiple paths (e.g., union or intersection). + */ + meet: (a: V, b: V) => V; + /** + * The initialization configuration for in and out sets. + */ + initIn: Map; + initOut: Map; + /** + * Indicates whether the analysis is forward (true) or backward (false). + */ + forward: boolean; + /** + * The empty value used to initialize in and out sets (e.g., an empty set). + */ + empty: V; +} + +/** + * Represents the result of a data flow analysis. + * Contains the in and out sets for each node, as well as the corresponding data flow problem. + * + * @template Node - The type of nodes in the graph. + * @template V - The type of data flow values. + */ +export class Solution { + in: Map; + out: Map; + problem: DataFlowProblem; + + constructor(i: Map, out: Map, problem: DataFlowProblem) { + this.in = i; + this.out = out; + this.problem = problem; + } +} + +/** + * A solver for data flow analysis problems. + * Implements forward and backward data flow analysis using a worklist algorithm. + * The solver computes the Maximum Fixed Point (MFP) solution, which is a safe + * over-approximation of the ideal Meet-Over-All-Paths (MOP) solution. + */ +export class MFPDataFlowSolver { + /** + * Computes the MFP solution for a forward data flow analysis problem. + * + * @template Node - The type of nodes in the graph. + * @template V - The type of data flow values. + * @param problem - The data flow problem to solve. + * @returns The solution containing the in and out sets for all nodes. + */ + calculateMopSolutionForwards(problem: DataFlowProblem): Solution { + let _out: Map = problem.initOut; + let _in: Map = problem.initIn; + let workList: Node[] = problem.flowGraph.nodesInPostOrder; + let newEntries: Set = new Set(); + + while (workList.length > 0) { + newEntries.clear(); + workList.forEach(n => { + let inSet: V | undefined; + const predecessors = problem.flowGraph.pred(n); + if (predecessors && predecessors.length > 0) { + const predecessorOuts = predecessors.map(pred => _out.get(pred)); + inSet = predecessorOuts.reduce((acc, cur) => problem.meet(acc!, cur!), problem.empty); + } else { + inSet = problem.empty; + } + + _in.set(n, inSet!); + let old: V | undefined = _out.get(n); + let newSet: V = problem.transferFunction.apply(n, inSet!); + + if (!old || old.count() === 0 || !old.equals(newSet)) { + _out.set(n, newSet); + problem.flowGraph.succ(n).forEach(succ => newEntries.add(succ)); + } + }); + + workList = [...newEntries]; + } + + return new Solution(_in, _out, problem); + } + + /** + * Computes the MFP solution for a backward data flow analysis problem. + * + * @template Node - The type of nodes in the graph. + * @template V - The type of data flow values. + * @param problem - The data flow problem to solve. + * @returns The solution containing the in and out sets for all nodes. + */ + calculateMopSolutionBackwards(problem: DataFlowProblem): Solution { + let _out: Map = problem.initOut; + let _in: Map = problem.initIn; + let workList: Node[] = problem.flowGraph.nodesInPostOrder; + let newEntries: Set = new Set(); + + while (workList.length > 0) { + newEntries.clear(); + workList.forEach(n => { + let outSet: T = problem.flowGraph.succ(n).reduce((acc, curr) => { + return problem.meet(acc, _in.get(curr)!); + }, problem.empty); + + _out.set(n, outSet); + let old: T | undefined = _in.get(n); + let newSet: T = problem.transferFunction.apply(n, outSet); + if (!old || !old.equals(newSet)) { + _in.set(n, newSet); + problem.flowGraph.pred(n).forEach(pred => newEntries.add(pred)); + } + }); + + workList = [...newEntries]; + } + + return new Solution(_in, _out, problem); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/ReachingDef.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/ReachingDef.ts new file mode 100644 index 0000000000000000000000000000000000000000..b9b491e6972b08f45a2f051686b6ecd61cf424cd --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/ReachingDef.ts @@ -0,0 +1,211 @@ +/* + * 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. + */ + +/** + * Reaching Definitions Data Flow Analysis + * + * This module implements the Reaching Definitions data flow analysis algorithm. + * Reaching Definitions is a forward data flow analysis that determines, for each + * program point, the set of variable definitions (assignments) that may reach + * that point without being overwritten. + * + * Key Components: + * 1. **Transfer Function**: + * - Computes the out set for each node based on its in set. + * - Uses gen and kill sets to model the effects of assignments: + * - **gen**: The set of definitions generated by the current node. + * - **kill**: The set of definitions killed (overwritten) by the current node. + * + * 2. **Meet Operation**: + * - Combines data flow values from multiple paths (e.g., union for reaching definitions). + * - Ensures that the analysis is conservative (safe) by over-approximating the result. + * + * The analysis is forward, meaning it propagates information from predecessors to successors. + * + */ + +import { ArkAssignStmt, Stmt } from '../base/Stmt'; +import { Value } from '../base/Value'; +import { BaseImplicitGraph, NodeID } from '../graph/BaseImplicitGraph'; +import { ArkMethod } from '../model/ArkMethod'; +import { DataFlowProblem, TransferFunction, FlowGraph } from './GenericDataFlow'; +import { SparseBitVector } from '../../utils/SparseBitVector'; +import { Cfg } from '../graph/Cfg'; + +type RDNode = Stmt; +type DFNodeCollection = SparseBitVector; +let coCtor: new (s: number) => SparseBitVector = SparseBitVector; +const BV_SIZE = 32; + +export class ReachingDefProblem implements DataFlowProblem { + flowGraph: ReachingDefFlowGraph; + transferFunction: ReachingDefTransferFunction; + meet: (a: DFNodeCollection, b: DFNodeCollection) => DFNodeCollection; + initIn: Map; + initOut: Map; + forward: boolean; + empty: DFNodeCollection = new coCtor(BV_SIZE); + + constructor(method: ArkMethod, forward: boolean = true) { + this.flowGraph = new ReachingDefFlowGraph(method); + this.transferFunction = new ReachingDefTransferFunction(this.flowGraph); + this.meet = (x: DFNodeCollection, y: DFNodeCollection): DFNodeCollection => { + let r = x.clone(); + r.unionWith(y); + return r; + }; + this.initIn = new Map(this.flowGraph.nodesInPostOrder.map(i => [i, new coCtor(BV_SIZE)])); + this.initOut = new Map(this.flowGraph.nodesInPostOrder.map(i => [i, new coCtor(BV_SIZE)])); + this.forward = forward; + } +} + +/** + * Represents the control flow graph (CFG) for reaching definitions analysis. + * This class implements the FlowGraph interface and provides methods to retrieve + * successors and predecessors of nodes, as well as topological orderings of nodes. + */ +class ReachingDefFlowGraph extends BaseImplicitGraph implements FlowGraph { + nodesInPostOrder: NodeID[]; + + constructor(method: ArkMethod) { + super(); + const cfg = method.getCfg(); + if (!cfg) { + throw new Error('CFG not found'); + } + + const nodes = cfg.getStmts(); + this.nodeToIdMap = new Map(nodes.map((x, i) => [x, i])); + this.idToNodeMap = new Map(nodes.map((x, i) => [i, x])); + this.nodesInPostOrder = nodes.map((_, i) => i); + + this.initSuccPred(nodes, cfg); + } + + getGraphName(): string { + return 'Reaching Definition Flow Graph'; + } + + dumpNodes(): void { + this.nodeToIdMap?.forEach((id, node) => console.log(id + ': ' + node.toString())); + } + + private initSuccPred(nodes: RDNode[], cfg: Cfg): void { + this.succMap = new Map(); + this.predMap = new Map(); + + cfg.getBlocks().forEach(bb => { + let stmts = bb.getStmts(); + if (stmts.length === 0) { + return; + } + + for (let i = 0; i < stmts.length - 1; i++) { + let c = this.nodeToIdMap!.get(stmts[i])!; + let n = this.nodeToIdMap!.get(stmts[i + 1])!; + if (c === undefined || n === undefined) { + continue; + } + this.succMap.set(c, [n]); + this.predMap.set(n, [c]); + } + + let terminate = bb.getTail(); + if (!terminate) { + throw new Error('cfg has no terminal'); + } + + let successors = bb.getSuccessors(); + // try...catch语句,catch所在的block在CFG表示里是没有前驱block的,需要在这里额外查找并将exceptionalSuccessorBlocks作为try块的后继块之一 + const exceptionalSuccessorBlocks = bb.getExceptionalSuccessorBlocks(); + if (exceptionalSuccessorBlocks !== undefined) { + successors.push(...exceptionalSuccessorBlocks); + } + successors.forEach(succBB => { + let head = succBB.getHead(); + if (!head) { + return; + } + let t = this.nodeToIdMap?.get(terminate!)!; + let h = this.nodeToIdMap?.get(head)!; + if (t === undefined || h === undefined) { + return; + } + // Terminate's succ + let succ = this.succMap.get(t) ?? []; + succ.push(h); + this.succMap.set(t, succ); + + // Head's pred + let pred = this.predMap.get(h) ?? []; + pred.push(t); + this.predMap.set(h, pred); + }); + }); + } +} + +/** + * Represents the transfer function for reaching definitions analysis. + */ +export class ReachingDefTransferFunction implements TransferFunction { + gen: DFNodeCollection; + kill: Map; + + constructor(flowGraph: ReachingDefFlowGraph) { + this.gen = new coCtor(BV_SIZE); + this.kill = new Map(); + this.initGenKill(flowGraph); + } + + apply(n: NodeID, x: DFNodeCollection): DFNodeCollection { + const result = x.clone(); + if (this.gen.test(n)) { + result.set(n); + } + + const killSet = this.kill.get(n); + if (killSet) { + for (const item of killSet) { + result.reset(item); + } + } + return result; + } + + private initGenKill(g: ReachingDefFlowGraph): void { + let genValue2Nodes: Map = new Map(); + // Init Gen + g.getNodeToIdMap().forEach((id, node) => { + if (node instanceof ArkAssignStmt) { + let lop = node.getLeftOp(); + let genNodes = genValue2Nodes.get(lop) ?? new coCtor(BV_SIZE); + genNodes.set(id); + genValue2Nodes.set(lop, genNodes); + this.gen.set(id); + } + }); + + // Init Kill + genValue2Nodes.forEach((defNodes, v) => { + for (const i of defNodes) { + const killSet = defNodes.clone(); + killSet.reset(i); + this.kill.set(i, killSet); + } + }); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/UndefinedVariable.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/UndefinedVariable.ts new file mode 100644 index 0000000000000000000000000000000000000000..2cd026b53bbfa666fb5f63161e71a4e69bd22847 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/UndefinedVariable.ts @@ -0,0 +1,271 @@ +/* + * 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. + */ + +import { Scene } from '../../Scene'; +import { DataflowProblem, FlowFunction } from './DataflowProblem'; +import { Local } from '../base/Local'; +import { Value } from '../base/Value'; +import { ClassType, UndefinedType } from '../base/Type'; +import { ArkAssignStmt, ArkInvokeStmt, Stmt } from '../base/Stmt'; +import { ArkMethod } from '../model/ArkMethod'; +import { Constant } from '../base/Constant'; +import { AbstractRef, ArkInstanceFieldRef, ArkStaticFieldRef } from '../base/Ref'; +import { DataflowSolver } from './DataflowSolver'; +import { ArkInstanceInvokeExpr, ArkStaticInvokeExpr } from '../base/Expr'; +import { FileSignature, NamespaceSignature } from '../model/ArkSignature'; +import { ArkClass } from '../model/ArkClass'; +import { LocalEqual, RefEqual } from './Util'; +import { INSTANCE_INIT_METHOD_NAME, STATIC_INIT_METHOD_NAME } from '../common/Const'; +import { ArkField } from '../model/ArkField'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'Scene'); + +export class UndefinedVariableChecker extends DataflowProblem { + zeroValue: Constant = new Constant('undefined', UndefinedType.getInstance()); + entryPoint: Stmt; + entryMethod: ArkMethod; + scene: Scene; + classMap: Map; + globalVariableMap: Map; + outcomes: Outcome[] = []; + constructor(stmt: Stmt, method: ArkMethod) { + super(); + this.entryPoint = stmt; + this.entryMethod = method; + this.scene = method.getDeclaringArkFile().getScene(); + this.classMap = this.scene.getClassMap(); + this.globalVariableMap = this.scene.getGlobalVariableMap(); + } + + getEntryPoint(): Stmt { + return this.entryPoint; + } + + getEntryMethod(): ArkMethod { + return this.entryMethod; + } + + private isUndefined(val: Value): boolean { + if (val instanceof Constant) { + let constant: Constant = val as Constant; + if (constant.getType() instanceof UndefinedType) { + return true; + } + } + return false; + } + + getNormalFlowFunction(srcStmt: Stmt, tgtStmt: Stmt): FlowFunction { + let checkerInstance: UndefinedVariableChecker = this; + return new (class implements FlowFunction { + getDataFacts(dataFact: Value): Set { + let ret: Set = new Set(); + if (checkerInstance.getEntryPoint() === srcStmt && checkerInstance.getZeroValue() === dataFact) { + ret.add(checkerInstance.getZeroValue()); + return ret; + } + if (srcStmt instanceof ArkAssignStmt) { + checkerInstance.insideNormalFlowFunction(ret, srcStmt, dataFact); + } + return ret; + } + })(); + } + + insideNormalFlowFunction(ret: Set, srcStmt: ArkAssignStmt, dataFact: Value): void { + if (!this.factEqual(srcStmt.getDef()!, dataFact)) { + if (!(dataFact instanceof Local && dataFact.getName() === srcStmt.getDef()!.toString())) { + ret.add(dataFact); + } + } + let ass: ArkAssignStmt = srcStmt as ArkAssignStmt; + let assigned: Value = ass.getLeftOp(); + let rightOp: Value = ass.getRightOp(); + if (this.getZeroValue() === dataFact) { + if (this.isUndefined(rightOp)) { + ret.add(assigned); + } + } else if (this.factEqual(rightOp, dataFact) || rightOp.getType() instanceof UndefinedType) { + ret.add(assigned); + } else if (rightOp instanceof ArkInstanceFieldRef) { + const base = rightOp.getBase(); + if (base === dataFact || (!base.getDeclaringStmt() && base.getName() === dataFact.toString())) { + this.outcomes.push(new Outcome(rightOp, ass)); + logger.info('undefined base'); + logger.info(srcStmt.toString()); + logger.info(srcStmt.getOriginPositionInfo().toString()); + } + } else if (dataFact instanceof ArkInstanceFieldRef && rightOp === dataFact.getBase()) { + const field = new ArkInstanceFieldRef(srcStmt.getLeftOp() as Local, dataFact.getFieldSignature()); + ret.add(field); + } + } + + getCallFlowFunction(srcStmt: Stmt, method: ArkMethod): FlowFunction { + let checkerInstance: UndefinedVariableChecker = this; + return new (class implements FlowFunction { + getDataFacts(dataFact: Value): Set { + const ret: Set = new Set(); + if (checkerInstance.getZeroValue() === dataFact) { + checkerInstance.insideCallFlowFunction(ret, method); + } else { + const callExpr = srcStmt.getExprs()[0]; + if ( + callExpr instanceof ArkInstanceInvokeExpr && + dataFact instanceof ArkInstanceFieldRef && + callExpr.getBase().getName() === dataFact.getBase().getName() + ) { + // todo:base转this + const thisRef = new ArkInstanceFieldRef( + new Local('this', new ClassType(method.getDeclaringArkClass().getSignature())), + dataFact.getFieldSignature() + ); + ret.add(thisRef); + } else if ( + callExpr instanceof ArkStaticInvokeExpr && + dataFact instanceof ArkStaticFieldRef && + callExpr.getMethodSignature().getDeclaringClassSignature() === dataFact.getFieldSignature().getDeclaringSignature() + ) { + ret.add(dataFact); + } + } + checkerInstance.addParameters(srcStmt, dataFact, method, ret); + return ret; + } + })(); + } + + insideCallFlowFunction(ret: Set, method: ArkMethod): void { + ret.add(this.getZeroValue()); + // 加上调用函数能访问到的所有静态变量,如果不考虑多线程,加上所有变量,考虑则要统计之前已经处理过的变量并排除 + for (const field of method.getDeclaringArkClass().getStaticFields(this.classMap)) { + if (field.getInitializer() === undefined) { + ret.add(new ArkStaticFieldRef(field.getSignature())); + } + } + for (const local of method.getDeclaringArkClass().getGlobalVariable(this.globalVariableMap)) { + ret.add(local); + } + // 加上所有未定义初始值的属性 + if (method.getName() === INSTANCE_INIT_METHOD_NAME || method.getName() === STATIC_INIT_METHOD_NAME) { + for (const field of method.getDeclaringArkClass().getFields()) { + this.addUndefinedField(field, method, ret); + } + } + } + + addUndefinedField(field: ArkField, method: ArkMethod, ret: Set): void { + let defined = false; + for (const stmt of method.getCfg()!.getStmts()) { + const def = stmt.getDef(); + if (def instanceof ArkInstanceFieldRef && def.getFieldSignature() === field.getSignature()) { + defined = true; + break; + } + } + if (!defined) { + const fieldRef = new ArkInstanceFieldRef(new Local('this', new ClassType(method.getDeclaringArkClass().getSignature())), field.getSignature()); + ret.add(fieldRef); + } + } + + addParameters(srcStmt: Stmt, dataFact: Value, method: ArkMethod, ret: Set): void { + const callStmt = srcStmt as ArkInvokeStmt; + const args = callStmt.getInvokeExpr().getArgs(); + for (let i = 0; i < args.length; i++) { + if (args[i] === dataFact || (this.isUndefined(args[i]) && this.getZeroValue() === dataFact)) { + const realParameter = [...method.getCfg()!.getBlocks()][0].getStmts()[i].getDef(); + if (realParameter) { + ret.add(realParameter); + } + } else if (dataFact instanceof ArkInstanceFieldRef && dataFact.getBase().getName() === args[i].toString()) { + const realParameter = [...method.getCfg()!.getBlocks()][0].getStmts()[i].getDef(); + if (realParameter) { + const retRef = new ArkInstanceFieldRef(realParameter as Local, dataFact.getFieldSignature()); + ret.add(retRef); + } + } + } + } + + getExitToReturnFlowFunction(srcStmt: Stmt, tgtStmt: Stmt, callStmt: Stmt): FlowFunction { + let checkerInstance: UndefinedVariableChecker = this; + return new (class implements FlowFunction { + getDataFacts(dataFact: Value): Set { + let ret: Set = new Set(); + if (dataFact === checkerInstance.getZeroValue()) { + ret.add(checkerInstance.getZeroValue()); + } + return ret; + } + })(); + } + + getCallToReturnFlowFunction(srcStmt: Stmt, tgtStmt: Stmt): FlowFunction { + let checkerInstance: UndefinedVariableChecker = this; + return new (class implements FlowFunction { + getDataFacts(dataFact: Value): Set { + const ret: Set = new Set(); + if (checkerInstance.getZeroValue() === dataFact) { + ret.add(checkerInstance.getZeroValue()); + } + const defValue = srcStmt.getDef(); + if (!(defValue && defValue === dataFact)) { + ret.add(dataFact); + } + return ret; + } + })(); + } + + createZeroValue(): Value { + return this.zeroValue; + } + + getZeroValue(): Value { + return this.zeroValue; + } + + factEqual(d1: Value, d2: Value): boolean { + if (d1 instanceof Constant && d2 instanceof Constant) { + return d1 === d2; + } else if (d1 instanceof Local && d2 instanceof Local) { + return LocalEqual(d1, d2); + } else if (d1 instanceof AbstractRef && d2 instanceof AbstractRef) { + return RefEqual(d1, d2); + } + return false; + } + + public getOutcomes(): Outcome[] { + return this.outcomes; + } +} + +export class UndefinedVariableSolver extends DataflowSolver { + constructor(problem: UndefinedVariableChecker, scene: Scene) { + super(problem, scene); + } +} + +class Outcome { + value: Value; + stmt: Stmt; + constructor(v: Value, s: Stmt) { + this.value = v; + this.stmt = s; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/dataflow/Util.ts b/ets2panda/linter/arkanalyzer/src/core/dataflow/Util.ts new file mode 100644 index 0000000000000000000000000000000000000000..34ca4323dfd4d7ee46796de6fdc1a8fdb21c760d --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/dataflow/Util.ts @@ -0,0 +1,62 @@ +/* + * 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. + */ + +import { ArkInvokeStmt } from '../base/Stmt'; +import { FunctionType } from '../base/Type'; +import { ArkMethod } from '../model/ArkMethod'; +import { Local } from '../base/Local'; +import { AbstractRef, ArkStaticFieldRef, ArkInstanceFieldRef } from '../base/Ref'; + +export const INTERNAL_PARAMETER_SOURCE: string[] = ['@ohos.app.ability.Want.d.ts: Want']; + +export const INTERNAL_SINK_METHOD: string[] = [ + 'console.<@%unk/%unk: .log()>', + 'console.<@%unk/%unk: .error()>', + 'console.<@%unk/%unk: .info()>', + 'console.<@%unk/%unk: .warn()>', + 'console.<@%unk/%unk: .assert()>', +]; + +export function getRecallMethodInParam(stmt: ArkInvokeStmt): ArkMethod | null { + for (const param of stmt.getInvokeExpr().getArgs()) { + if (param.getType() instanceof FunctionType) { + const methodSignature = (param.getType() as FunctionType).getMethodSignature(); + const method = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkClass().getMethod(methodSignature); + if (method) { + return method; + } + } + } + return null; +} + +export function LocalEqual(local1: Local, local2: Local): boolean { + if (local1.getName() === 'this' && local2.getName() === 'this') { + return true; + } + const method1 = local1.getDeclaringStmt()?.getCfg()?.getDeclaringMethod(); + const method2 = local2.getDeclaringStmt()?.getCfg()?.getDeclaringMethod(); + const nameEqual = local1.getName() === local2.getName(); + return method1 === method2 && nameEqual; +} + +export function RefEqual(ref1: AbstractRef, ref2: AbstractRef): boolean { + if (ref1 instanceof ArkStaticFieldRef && ref2 instanceof ArkStaticFieldRef) { + return ref1.getFieldSignature().toString() === ref2.getFieldSignature().toString(); + } else if (ref1 instanceof ArkInstanceFieldRef && ref2 instanceof ArkInstanceFieldRef) { + return LocalEqual(ref1.getBase(), ref2.getBase()) && ref1.getFieldSignature().toString() === ref2.getFieldSignature().toString(); + } + return false; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/BaseExplicitGraph.ts b/ets2panda/linter/arkanalyzer/src/core/graph/BaseExplicitGraph.ts new file mode 100644 index 0000000000000000000000000000000000000000..fc55eb7e989930622539e9feb4db434354a10db5 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/BaseExplicitGraph.ts @@ -0,0 +1,205 @@ +/* + * 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. + */ + +import { Kind, NodeID, GraphTraits } from './GraphTraits'; + +export { Kind, NodeID }; +export abstract class BaseEdge { + private src: BaseNode; + private dst: BaseNode; + protected kind: Kind; + + constructor(s: BaseNode, d: BaseNode, k: Kind) { + this.src = s; + this.dst = d; + this.kind = k; + } + + public getSrcID(): NodeID { + return this.src.getID(); + } + + public getDstID(): NodeID { + return this.dst.getID(); + } + + public getSrcNode(): BaseNode { + return this.src; + } + + public getDstNode(): BaseNode { + return this.dst; + } + + public getKind(): Kind { + return this.kind; + } + + public setKind(kind: Kind): void { + this.kind = kind; + } + + public getEndPoints(): { src: NodeID; dst: NodeID } { + return { + src: this.src.getID(), + dst: this.dst.getID(), + }; + } + + public getDotAttr(): string { + return 'color=black'; + } +} + +export abstract class BaseNode { + private id: NodeID; + protected kind: Kind; + private inEdges: Set = new Set(); + private outEdges: Set = new Set(); + + constructor(id: NodeID, k: Kind) { + this.id = id; + this.kind = k; + } + + public getID(): NodeID { + return this.id; + } + + public getKind(): Kind { + return this.kind; + } + + public setKind(kind: Kind): void { + this.kind = kind; + } + + public hasIncomingEdges(): boolean { + return this.inEdges.size !== 0; + } + + public hasOutgoingEdges(): boolean { + return this.outEdges.size === 0; + } + + public hasIncomingEdge(e: BaseEdge): boolean { + return this.inEdges.has(e); + } + + public hasOutgoingEdge(e: BaseEdge): boolean { + return this.outEdges.has(e); + } + + public addIncomingEdge(e: BaseEdge): void { + this.inEdges.add(e); + } + + public addOutgoingEdge(e: BaseEdge): void { + this.outEdges.add(e); + } + + public removeIncomingEdge(e: BaseEdge): boolean { + return this.inEdges.delete(e); + } + + public removeOutgoingEdge(e: BaseEdge): boolean { + return this.outEdges.delete(e); + } + + public getIncomingEdge(): Set { + return this.inEdges; + } + + public getOutgoingEdges(): Set { + return this.outEdges; + } + + public getDotAttr(): string { + return 'shape=box'; + } + + public abstract getDotLabel(): string; +} + +export abstract class BaseExplicitGraph implements GraphTraits { + protected edgeNum: number = 0; + protected nodeNum: number = 0; + protected idToNodeMap: Map; + protected edgeMarkSet: Set; + + constructor() { + this.idToNodeMap = new Map(); + this.edgeMarkSet = new Set(); + } + + public getNodeNum(): number { + return this.nodeNum; + } + + public nodesItor(): IterableIterator { + return this.idToNodeMap.values(); + } + + public addNode(n: BaseNode): void { + this.idToNodeMap.set(n.getID(), n); + this.nodeNum++; + } + + public getNode(id: NodeID): BaseNode | undefined { + if (!this.idToNodeMap.has(id)) { + throw new Error(`Can find Node # ${id}`); + } + + return this.idToNodeMap.get(id); + } + + public hasNode(id: NodeID): boolean { + return this.idToNodeMap.has(id); + } + + public removeNode(id: NodeID): boolean { + if (this.idToNodeMap.delete(id)) { + this.nodeNum--; + return true; + } + return false; + } + + public hasEdge(src: BaseNode, dst: BaseNode): boolean { + for (let e of src.getOutgoingEdges()) { + if (e.getDstNode() === dst) { + return true; + } + } + + return false; + } + + public ifEdgeExisting(edge: BaseEdge): boolean { + let edgeMark: string = `${edge.getSrcID()}-${edge.getDstID()}:${edge.getKind()}`; + if (this.edgeMarkSet.has(edgeMark)) { + return true; + } + + this.edgeMarkSet.add(edgeMark); + return false; + } + + public getNodesIter(): IterableIterator { + return this.idToNodeMap.values(); + } + + public abstract getGraphName(): string; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/BaseImplicitGraph.ts b/ets2panda/linter/arkanalyzer/src/core/graph/BaseImplicitGraph.ts new file mode 100644 index 0000000000000000000000000000000000000000..8eb3556425baf36bee2bfb76cc2e209fe5db1316 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/BaseImplicitGraph.ts @@ -0,0 +1,139 @@ +/* + * 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 { NodeID, GraphTraits } from './GraphTraits'; + +export { NodeID }; + +/** + * BaseImplicitGraph is an abstract class that represents an implicit graph. + * An implicit graph is a graph representation where node and edge information is implicitly stored using maps. + * This class implements the GraphTraits interface and provides basic graph operations. + */ +export abstract class BaseImplicitGraph implements GraphTraits { + /** + * idToNodeMap is an optional map that maps node IDs (NodeID) to node objects (Node). + * If not initialized, calling related methods will throw an error. + */ + protected idToNodeMap?: Map; + + /** + * nodeToIdMap is a map that maps node objects (Node) to node IDs (NodeID). + * This map must be initialized in the subclass. + */ + protected nodeToIdMap!: Map; + + /** + * succMap is a map that stores the successors of each node. + * The key is a node ID (NodeID), and the value is an array of successor node IDs. + */ + succMap!: Map; + + /** + * predMap is a map that stores the predecessors of each node. + * The key is a node ID (NodeID), and the value is an array of predecessor node IDs. + */ + predMap!: Map; + + constructor() {} + + /** + * Gets the number of nodes in the graph. + * @returns The number of nodes in the graph. + */ + public getNodeNum(): number { + return this.nodeToIdMap.size; + } + + /** + * Returns an iterator for all nodes in the graph. + * @returns An iterator for traversing all nodes in the graph. + */ + public nodesItor(): IterableIterator { + return this.nodeToIdMap.keys(); + } + + /** + * Gets the node object corresponding to a given node ID. + * @param id The node ID. + * @returns The corresponding node object. + * @throws Throws an error if idToNodeMap is not initialized or if the node is not found. + */ + public getNode(id: NodeID): Node { + if (!this.idToNodeMap) { + throw new Error(`initialize this.idToNodeMap first`); + } + + if (!this.idToNodeMap.has(id)) { + throw new Error(`Can find Node # ${id}`); + } + + return this.idToNodeMap.get(id)!; + } + + public getNodeID(s: Node): NodeID { + if (!this.nodeToIdMap.has(s)) { + throw new Error(`Can find Node # ${s}`); + } + + return this.nodeToIdMap.get(s)!; + } + + /** + * Checks whether the graph contains a specific node ID. + * @param id The node ID. + * @returns Returns true if the node ID exists in the graph; otherwise, returns false. + * @throws Throws an error if idToNodeMap is not initialized. + */ + public hasNode(id: NodeID): boolean { + if (!this.idToNodeMap) { + throw new Error(`initialize this.idToNodeMap first`); + } + + return this.idToNodeMap.has(id); + } + + /** + * Gets the list of successor node IDs for a given node. + * @param id The node ID. + * @returns An array of successor node IDs. Returns an empty array if no successors are found. + */ + public succ(id: NodeID): NodeID[] { + return this.succMap.get(id) ?? []; + } + + /** + * Gets the list of predecessor node IDs for a given node. + * @param id The node ID. + * @returns An array of predecessor node IDs. Returns an empty array if no predecessors are found. + */ + public pred(id: NodeID): NodeID[] { + return this.predMap.get(id) ?? []; + } + + /** + * Gets the nodeToIdMap, which maps node objects to node IDs. + * @returns The nodeToIdMap. + */ + public getNodeToIdMap(): Map { + return this.nodeToIdMap; + } + + /** + * Abstract method to get the name of the graph. + * Subclasses must implement this method. + * @returns The name of the graph. + */ + public abstract getGraphName(): string; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/BasicBlock.ts b/ets2panda/linter/arkanalyzer/src/core/graph/BasicBlock.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8487e4e1221dd312bd115ee0e33ba464ec80412 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/BasicBlock.ts @@ -0,0 +1,288 @@ +/* + * 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. + */ + +import { ArkIfStmt, ArkReturnStmt, ArkReturnVoidStmt, Stmt } from '../base/Stmt'; +import { ArkError, ArkErrorCode } from '../common/ArkError'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'BasicBlock'); + +/** + * @category core/graph + * A `BasicBlock` is composed of: + * - ID: a **number** that uniquely identify the basic block, initialized as -1. + * - Statements: an **array** of statements in the basic block. + * - Predecessors: an **array** of basic blocks in front of the current basic block. More accurately, these basic + * blocks can reach the current block through edges. + * - Successors: an **array** of basic blocks after the current basic block. More accurately, the current block can + * reach these basic blocks through edges. + */ +export class BasicBlock { + private id: number = -1; + private stmts: Stmt[] = []; + private predecessorBlocks: BasicBlock[] = []; + private successorBlocks: BasicBlock[] = []; + private exceptionalSuccessorBlocks?: BasicBlock[]; + + constructor() {} + + public getId(): number { + return this.id; + } + + public setId(id: number): void { + this.id = id; + } + + /** + * Returns an array of the statements in a basic block. + * @returns An array of statements in a basic block. + */ + public getStmts(): Stmt[] { + return this.stmts; + } + + public addStmt(stmt: Stmt): void { + this.stmts.push(stmt); + } + + /** + * Adds the given stmt at the beginning of the basic block. + * @param stmt + */ + public addHead(stmt: Stmt | Stmt[]): void { + if (stmt instanceof Stmt) { + this.stmts.unshift(stmt); + } else { + this.stmts.unshift(...stmt); + } + } + + /** + * Adds the given stmt at the end of the basic block. + * @param stmt + */ + public addTail(stmt: Stmt | Stmt[]): void { + if (stmt instanceof Stmt) { + this.stmts.push(stmt); + } else { + stmt.forEach(stmt => this.stmts.push(stmt)); + } + } + + /** + * Inserts toInsert in the basic block after point. + * @param toInsert + * @param point + * @returns The number of successfully inserted statements + */ + public insertAfter(toInsert: Stmt | Stmt[], point: Stmt): number { + let index = this.stmts.indexOf(point); + if (index < 0) { + return 0; + } + return this.insertPos(index + 1, toInsert); + } + + /** + * Inserts toInsert in the basic block befor point. + * @param toInsert + * @param point + * @returns The number of successfully inserted statements + */ + public insertBefore(toInsert: Stmt | Stmt[], point: Stmt): number { + let index = this.stmts.indexOf(point); + if (index < 0) { + return 0; + } + return this.insertPos(index, toInsert); + } + + /** + * Removes the given stmt from this basic block. + * @param stmt + * @returns + */ + public remove(stmt: Stmt): void { + let index = this.stmts.indexOf(stmt); + if (index < 0) { + return; + } + this.stmts.splice(index, 1); + } + + /** + * Removes the first stmt from this basic block. + */ + public removeHead(): void { + this.stmts.splice(0, 1); + } + + /** + * Removes the last stmt from this basic block. + */ + public removeTail(): void { + this.stmts.splice(this.stmts.length - 1, 1); + } + + public getHead(): Stmt | null { + if (this.stmts.length === 0) { + return null; + } + return this.stmts[0]; + } + + public getTail(): Stmt | null { + let size = this.stmts.length; + if (size === 0) { + return null; + } + return this.stmts[size - 1]; + } + + /** + * Returns successors of the current basic block, whose types are also basic blocks (i.e.{@link BasicBlock}). + * @returns Successors of the current basic block. + * @example + * 1. get block successors. + + ```typescript + const body = arkMethod.getBody(); + const blocks = [...body.getCfg().getBlocks()] + for (let i = 0; i < blocks.length; i++) { + const block = blocks[i] + ... + for (const next of block.getSuccessors()) { + ... + } + } + ``` + */ + public getSuccessors(): BasicBlock[] { + return this.successorBlocks; + } + + /** + * Returns predecessors of the current basic block, whose types are also basic blocks. + * @returns An array of basic blocks. + */ + public getPredecessors(): BasicBlock[] { + return this.predecessorBlocks; + } + + public addPredecessorBlock(block: BasicBlock): void { + this.predecessorBlocks.push(block); + } + + public setPredecessorBlock(idx: number, block: BasicBlock): boolean { + if (idx < this.predecessorBlocks.length) { + this.predecessorBlocks[idx] = block; + return true; + } + return false; + } + + public setSuccessorBlock(idx: number, block: BasicBlock): boolean { + if (idx < this.successorBlocks.length) { + this.successorBlocks[idx] = block; + return true; + } + return false; + } + + // Temp just for SSA + public addStmtToFirst(stmt: Stmt): void { + this.addHead(stmt); + } + + // Temp just for SSA + public addSuccessorBlock(block: BasicBlock): void { + this.successorBlocks.push(block); + } + + public removePredecessorBlock(block: BasicBlock): boolean { + let index = this.predecessorBlocks.indexOf(block); + if (index < 0) { + return false; + } + this.predecessorBlocks.splice(index, 1); + return true; + } + + public removeSuccessorBlock(block: BasicBlock): boolean { + let index = this.successorBlocks.indexOf(block); + if (index < 0) { + return false; + } + this.successorBlocks.splice(index, 1); + return true; + } + + public toString(): string { + let strs: string[] = []; + for (const stmt of this.stmts) { + strs.push(stmt.toString() + '\n'); + } + return strs.join(''); + } + + public validate(): ArkError { + let branchStmts: Stmt[] = []; + for (const stmt of this.stmts) { + if (stmt instanceof ArkIfStmt || stmt instanceof ArkReturnStmt || stmt instanceof ArkReturnVoidStmt) { + branchStmts.push(stmt); + } + } + + if (branchStmts.length > 1) { + let errMsg = `More than one branch or return stmts in the block: ${branchStmts.map(value => value.toString()).join('\n')}`; + logger.error(errMsg); + return { + errCode: ArkErrorCode.BB_MORE_THAN_ONE_BRANCH_RET_STMT, + errMsg: errMsg, + }; + } + + if (branchStmts.length === 1 && branchStmts[0] !== this.stmts[this.stmts.length - 1]) { + let errMsg = `${branchStmts[0].toString()} not at the end of block.`; + logger.error(errMsg); + return { + errCode: ArkErrorCode.BB_BRANCH_RET_STMT_NOT_AT_END, + errMsg: errMsg, + }; + } + + return { errCode: ArkErrorCode.OK }; + } + + private insertPos(index: number, toInsert: Stmt | Stmt[]): number { + if (toInsert instanceof Stmt) { + this.stmts.splice(index, 0, toInsert); + return 1; + } + this.stmts.splice(index, 0, ...toInsert); + return toInsert.length; + } + + public getExceptionalSuccessorBlocks(): BasicBlock[] | undefined { + return this.exceptionalSuccessorBlocks; + } + + public addExceptionalSuccessorBlock(block: BasicBlock): void { + if (!this.exceptionalSuccessorBlocks) { + this.exceptionalSuccessorBlocks = []; + } + this.exceptionalSuccessorBlocks.push(block); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts b/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts new file mode 100644 index 0000000000000000000000000000000000000000..4ef2fadcaf347b848862c8e586dc20911828d8fb --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/Cfg.ts @@ -0,0 +1,293 @@ +/* + * 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. + */ + +import { DefUseChain } from '../base/DefUseChain'; +import { Local } from '../base/Local'; +import { Stmt } from '../base/Stmt'; +import { ArkError, ArkErrorCode } from '../common/ArkError'; +import { ArkMethod } from '../model/ArkMethod'; +import { BasicBlock } from './BasicBlock'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { ArkStaticInvokeExpr } from '../base/Expr'; +import { Value } from '../base/Value'; +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'BasicBlock'); + +/** + * @category core/graph + */ +export class Cfg { + private blocks: Set = new Set(); + private stmtToBlock: Map = new Map(); + private startingStmt!: Stmt; + + private defUseChains: DefUseChain[] = []; + private declaringMethod: ArkMethod = new ArkMethod(); + + constructor() {} + + public getStmts(): Stmt[] { + let stmts = new Array(); + for (const block of this.blocks) { + block.getStmts().forEach(s => stmts.push(s)); + } + return stmts; + } + + /** + * Inserts toInsert in the basic block in CFG after point. + * @param toInsert + * @param point + * @returns The number of successfully inserted statements + */ + public insertAfter(toInsert: Stmt | Stmt[], point: Stmt): number { + const block = this.stmtToBlock.get(point); + if (!block) { + return 0; + } + + this.updateStmt2BlockMap(block, toInsert); + return block.insertAfter(toInsert, point); + } + + /** + * Inserts toInsert in the basic block in CFG befor point. + * @param toInsert + * @param point + * @returns The number of successfully inserted statements + */ + public insertBefore(toInsert: Stmt | Stmt[], point: Stmt): number { + const block = this.stmtToBlock.get(point); + if (!block) { + return 0; + } + + this.updateStmt2BlockMap(block, toInsert); + return block.insertBefore(toInsert, point); + } + + /** + * Removes the given stmt from the basic block in CFG. + * @param stmt + * @returns + */ + public remove(stmt: Stmt): void { + const block = this.stmtToBlock.get(stmt); + if (!block) { + return; + } + this.stmtToBlock.delete(stmt); + block.remove(stmt); + } + + /** + * Update stmtToBlock Map + * @param block + * @param changed + */ + public updateStmt2BlockMap(block: BasicBlock, changed?: Stmt | Stmt[]): void { + if (!changed) { + for (const stmt of block.getStmts()) { + this.stmtToBlock.set(stmt, block); + } + } else if (changed instanceof Stmt) { + this.stmtToBlock.set(changed, block); + } else { + for (const insert of changed) { + this.stmtToBlock.set(insert, block); + } + } + } + + // TODO: 添加block之间的边 + public addBlock(block: BasicBlock): void { + this.blocks.add(block); + + for (const stmt of block.getStmts()) { + this.stmtToBlock.set(stmt, block); + } + } + + public getBlocks(): Set { + return this.blocks; + } + + public getStartingBlock(): BasicBlock | undefined { + return this.stmtToBlock.get(this.startingStmt); + } + + public getStartingStmt(): Stmt { + return this.startingStmt; + } + + public setStartingStmt(newStartingStmt: Stmt): void { + this.startingStmt = newStartingStmt; + } + + public getDeclaringMethod(): ArkMethod { + return this.declaringMethod; + } + + public setDeclaringMethod(method: ArkMethod): void { + this.declaringMethod = method; + } + + public getDefUseChains(): DefUseChain[] { + return this.defUseChains; + } + + // TODO: 整理成类似jimple的输出 + public toString(): string { + return 'cfg'; + } + + public buildDefUseStmt(locals: Set): void { + for (const block of this.blocks) { + for (const stmt of block.getStmts()) { + const defValue = stmt.getDef(); + if (defValue && defValue instanceof Local && defValue.getDeclaringStmt() === null) { + defValue.setDeclaringStmt(stmt); + } + for (const value of stmt.getUses()) { + this.buildUseStmt(value, locals, stmt); + } + } + } + } + + private buildUseStmt(value: Value, locals: Set, stmt: Stmt): void { + if (value instanceof Local) { + value.addUsedStmt(stmt); + } else if (value instanceof ArkStaticInvokeExpr) { + for (let local of locals) { + if (local.getName() === value.getMethodSignature().getMethodSubSignature().getMethodName()) { + local.addUsedStmt(stmt); + return; + } + } + } + } + + private handleDefUseForValue(value: Value, block: BasicBlock, stmt: Stmt, stmtIndex: number): void { + const name = value.toString(); + const defStmts: Stmt[] = []; + // 判断本block之前有无对应def + for (let i = stmtIndex - 1; i >= 0; i--) { + const beforeStmt = block.getStmts()[i]; + if (beforeStmt.getDef() && beforeStmt.getDef()?.toString() === name) { + defStmts.push(beforeStmt); + break; + } + } + // 本block有对应def直接结束,否则找所有的前序block + if (defStmts.length !== 0) { + this.defUseChains.push(new DefUseChain(value, defStmts[0], stmt)); + return; + } + const needWalkBlocks: BasicBlock[] = [...block.getPredecessors()]; + const walkedBlocks = new Set(); + while (needWalkBlocks.length > 0) { + const predecessor = needWalkBlocks.pop(); + if (!predecessor) { + return; + } + const predecessorStmts = predecessor.getStmts(); + let predecessorHasDef = false; + for (let i = predecessorStmts.length - 1; i >= 0; i--) { + const beforeStmt = predecessorStmts[i]; + if (beforeStmt.getDef() && beforeStmt.getDef()?.toString() === name) { + defStmts.push(beforeStmt); + predecessorHasDef = true; + break; + } + } + walkedBlocks.add(predecessor); + if (predecessorHasDef) { + continue; + } + for (const morePredecessor of predecessor.getPredecessors()) { + if (!walkedBlocks.has(morePredecessor) && !needWalkBlocks.includes(morePredecessor)) { + needWalkBlocks.unshift(morePredecessor); + } + } + } + for (const def of defStmts) { + this.defUseChains.push(new DefUseChain(value, def, stmt)); + } + } + + public buildDefUseChain(): void { + for (const block of this.blocks) { + for (let stmtIndex = 0; stmtIndex < block.getStmts().length; stmtIndex++) { + const stmt = block.getStmts()[stmtIndex]; + for (const value of stmt.getUses()) { + this.handleDefUseForValue(value, block, stmt, stmtIndex); + } + } + } + } + + public getUnreachableBlocks(): Set { + let unreachable = new Set(); + let startBB = this.getStartingBlock(); + if (!startBB) { + return unreachable; + } + let postOrder = this.dfsPostOrder(startBB); + for (const bb of this.blocks) { + if (!postOrder.has(bb)) { + unreachable.add(bb); + } + } + return unreachable; + } + + public validate(): ArkError { + let startBB = this.getStartingBlock(); + if (!startBB) { + let errMsg = `Not found starting block}`; + logger.error(errMsg); + return { + errCode: ArkErrorCode.CFG_NOT_FOUND_START_BLOCK, + errMsg: errMsg, + }; + } + + let unreachable = this.getUnreachableBlocks(); + if (unreachable.size !== 0) { + let errMsg = `Unreachable blocks: ${Array.from(unreachable) + .map(value => value.toString()) + .join('\n')}`; + logger.error(errMsg); + return { + errCode: ArkErrorCode.CFG_HAS_UNREACHABLE_BLOCK, + errMsg: errMsg, + }; + } + + return { errCode: ArkErrorCode.OK }; + } + + private dfsPostOrder(node: BasicBlock, visitor: Set = new Set(), postOrder: Set = new Set()): Set { + visitor.add(node); + for (const succ of node.getSuccessors()) { + if (visitor.has(succ)) { + continue; + } + this.dfsPostOrder(succ, visitor, postOrder); + } + postOrder.add(node); + return postOrder; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/DependsGraph.ts b/ets2panda/linter/arkanalyzer/src/core/graph/DependsGraph.ts new file mode 100644 index 0000000000000000000000000000000000000000..dc3f40e69d0aa9c011acab21e5790ddb738bfb02 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/DependsGraph.ts @@ -0,0 +1,115 @@ +/* + * 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. + */ + +import { BaseEdge, BaseExplicitGraph, BaseNode, Kind, NodeID } from './BaseExplicitGraph'; +interface Attributes { + [name: string]: any; +} + +interface NodeAttributes extends Attributes { + name: string; + kind: Kind; +} + +interface EdgeAttributes extends Attributes { + kind: Kind; +} + +export class DependsNode extends BaseNode { + private attr: NodeAttr; + + public constructor(id: NodeID, attr: NodeAttr) { + super(id, attr.kind); + this.attr = attr; + } + + public getNodeAttr(): NodeAttr { + return this.attr; + } + + public setNodeAttr(attr: NodeAttr): void { + this.attr = attr; + } + + public getDotLabel(): string { + return this.attr.name; + } +} + +export class DependsEdge extends BaseEdge { + private attr: EdgeAttr; + + public constructor(s: DependsNode, d: DependsNode, attr: EdgeAttr) { + super(s, d, attr.kind); + this.attr = attr; + } + + public getEdgeAttr(): EdgeAttr { + return this.attr; + } + + public setEdgeAttr(attr: EdgeAttr): void { + this.attr = attr; + } + + public getKey(): string { + return `${this.getSrcID()}-${this.getDstID()}-${this.getKind()}`; + } +} + +export class DependsGraph extends BaseExplicitGraph { + protected depsMap: Map; + protected edgesMap: Map>; + + constructor() { + super(); + this.depsMap = new Map(); + this.edgesMap = new Map(); + } + + public hasDepsNode(key: string): boolean { + return this.depsMap.has(key); + } + + public addDepsNode(key: string, attr: NodeAttr): DependsNode { + if (this.depsMap.has(key)) { + // update attr + let node = this.getNode(this.depsMap.get(key)!) as DependsNode; + node.setNodeAttr(attr); + return node; + } + + let node = new DependsNode(this.getNodeNum(), attr); + this.depsMap.set(key, node.getID()); + this.addNode(node); + return node; + } + + public addEdge(src: DependsNode, dst: DependsNode, attr: EdgeAttr): DependsEdge { + let edge = new DependsEdge(src, dst, attr); + let key = edge.getKey(); + if (this.edgesMap.has(key)) { + return this.edgesMap.get(key)!; + } + this.edgesMap.set(key, edge); + src.addOutgoingEdge(edge); + dst.addIncomingEdge(edge); + return edge; + } + + public getGraphName(): string { + return 'DependsGraph'; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/DominanceFinder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/DominanceFinder.ts new file mode 100644 index 0000000000000000000000000000000000000000..08afcef3be19921d3b6f6883a312a16bf37479d7 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/DominanceFinder.ts @@ -0,0 +1,129 @@ +/* + * 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. + */ + +import { BasicBlock } from './BasicBlock'; +import { Cfg } from './Cfg'; + +export class DominanceFinder { + private blocks: BasicBlock[] = []; + private blockToIdx = new Map(); + private idoms: number[] = []; + private domFrontiers: number[][] = []; + + constructor(cfg: Cfg) { + this.blocks = Array.from(cfg.getBlocks()); + for (let i = 0; i < this.blocks.length; i++) { + let block = this.blocks[i]; + this.blockToIdx.set(block, i); + } + const startingBlock = cfg.getStartingBlock(); + + // calculate immediate dominator for each block + this.idoms = new Array(this.blocks.length); + this.idoms[0] = 0; + for (let i = 1; i < this.idoms.length; i++) { + this.idoms[i] = -1; + } + let isChanged = true; + while (isChanged) { + isChanged = false; + for (const block of this.blocks) { + if (block === startingBlock) { + continue; + } + let blockIdx = this.blockToIdx.get(block) as number; + let preds = Array.from(block.getPredecessors()); + let newIdom = this.getFirstDefinedBlockPredIdx(preds); + if (preds.length <= 0 || newIdom === -1) { + continue; + } + for (const pred of preds) { + let predIdx = this.blockToIdx.get(pred) as number; + this.idoms[predIdx] !== -1 ? (newIdom = this.intersect(newIdom, predIdx)) : null; + } + if (this.idoms[blockIdx] !== newIdom) { + this.idoms[blockIdx] = newIdom; + isChanged = true; + } + } + } + + // calculate dominance frontiers for each block + this.domFrontiers = new Array(this.blocks.length); + for (let i = 0; i < this.domFrontiers.length; i++) { + this.domFrontiers[i] = new Array(); + } + for (const block of this.blocks) { + let preds = Array.from(block.getPredecessors()); + if (preds.length <= 1) { + continue; + } + let blockIdx = this.blockToIdx.get(block) as number; + for (const pred of preds) { + let predIdx = this.blockToIdx.get(pred) as number; + while (predIdx !== this.idoms[blockIdx]) { + this.domFrontiers[predIdx].push(blockIdx); + predIdx = this.idoms[predIdx]; + } + } + } + } + + public getDominanceFrontiers(block: BasicBlock): Set { + if (!this.blockToIdx.has(block)) { + throw new Error('The given block: ' + block + ' is not in Cfg!'); + } + let idx = this.blockToIdx.get(block) as number; + let dfs = new Set(); + let dfsIdx = this.domFrontiers[idx]; + for (const dfIdx of dfsIdx) { + dfs.add(this.blocks[dfIdx]); + } + return dfs; + } + + public getBlocks(): BasicBlock[] { + return this.blocks; + } + + public getBlockToIdx(): Map { + return this.blockToIdx; + } + + public getImmediateDominators(): number[] { + return this.idoms; + } + + private getFirstDefinedBlockPredIdx(preds: BasicBlock[]): number { + for (const block of preds) { + let idx = this.blockToIdx.get(block) as number; + if (this.idoms[idx] !== -1) { + return idx; + } + } + return -1; + } + + private intersect(a: number, b: number): number { + while (a !== b) { + if (a > b) { + a = this.idoms[a]; + } else { + b = this.idoms[b]; + } + } + return a; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/DominanceTree.ts b/ets2panda/linter/arkanalyzer/src/core/graph/DominanceTree.ts new file mode 100644 index 0000000000000000000000000000000000000000..5b595c8418b9fea5fb41b7825b1446438c3eab7e --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/DominanceTree.ts @@ -0,0 +1,75 @@ +/* + * 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. + */ + +import { BasicBlock } from './BasicBlock'; +import { DominanceFinder } from './DominanceFinder'; + +export class DominanceTree { + private blocks: BasicBlock[] = []; + private blockToIdx = new Map(); + private children: number[][] = []; + private parents: number[] = []; + + constructor(dominanceFinder: DominanceFinder) { + this.blocks = dominanceFinder.getBlocks(); + this.blockToIdx = dominanceFinder.getBlockToIdx(); + let idoms = dominanceFinder.getImmediateDominators(); + + // build the tree + let treeSize = this.blocks.length; + this.children = new Array(treeSize); + this.parents = new Array(treeSize); + for (let i = 0; i < treeSize; i++) { + this.children[i] = []; + this.parents[i] = -1; + } + for (let i = 0; i < treeSize; i++) { + if (idoms[i] !== i) { + this.parents[i] = idoms[i]; + this.children[idoms[i]].push(i); + } + } + } + + public getAllNodesDFS(): BasicBlock[] { + let dfsBlocks = new Array(); + let queue = new Array(); + queue.push(this.getRoot()); + while (queue.length !== 0) { + let curr = queue.splice(0, 1)[0]; + dfsBlocks.push(curr); + let childList = this.getChildren(curr); + if (childList.length !== 0) { + for (let i = childList.length - 1; i >= 0; i--) { + queue.splice(0, 0, childList[i]); + } + } + } + return dfsBlocks; + } + + public getChildren(block: BasicBlock): BasicBlock[] { + let childList = new Array(); + let idx = this.blockToIdx.get(block) as number; + for (const i of this.children[idx]) { + childList.push(this.blocks[i]); + } + return childList; + } + + public getRoot(): BasicBlock { + return this.blocks[0]; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/GraphTraits.ts b/ets2panda/linter/arkanalyzer/src/core/graph/GraphTraits.ts new file mode 100644 index 0000000000000000000000000000000000000000..b9a8a1f71fb2d2f61961d9107088a1e0a7078efe --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/GraphTraits.ts @@ -0,0 +1,23 @@ +/* + * 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. + */ + +export type NodeID = number; +export type Kind = number; + +export interface GraphTraits { + nodesItor(): IterableIterator; + getGraphName(): string; + getNode(id: NodeID): Node | undefined; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/Scc.ts b/ets2panda/linter/arkanalyzer/src/core/graph/Scc.ts new file mode 100644 index 0000000000000000000000000000000000000000..aeb568012db582c7a1cd860edb59b2f22820a163 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/Scc.ts @@ -0,0 +1,278 @@ +/* + * 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. + */ + +import { BaseNode } from './BaseExplicitGraph'; +import { NodeID, GraphTraits } from './GraphTraits'; + +type NodeSet = Set; +type NodeStack = NodeID[]; +type Node2RepSCCInfoMap = Map; +type Node2NodeMap = Map; + +/** + * Basic SCC info for a single node + */ +class NodeSCCInfo { + private _rep: NodeID; + private _subNodes: NodeSet; + + constructor() { + this._rep = Number.MAX_SAFE_INTEGER; + this._subNodes = new Set(); + } + + get rep(): NodeID { + return this._rep; + } + + set rep(n: NodeID) { + this._rep = n; + } + + addSubNodes(n: NodeID): void { + this._subNodes.add(n); + } + + get subNodes(): NodeSet { + return this._subNodes; + } +} + +/** + * Detect strongly connected components in a directed graph + * A topological graph is an extra product from this algorithm + * Advanced Nuutila’s algorithm which come from the following paper: + * Wave Propagation and Deep Propagation for pointer Analysis + * CGO 2009 + */ +export class SCCDetection> { + // graph G = (V, E) + private _G: Graph; + // counter + private _I: number; + // map of V to {1, . . . , |V |} ∪ ⊥, associates the + // nodes in V to the order in which they are visited by + // Nuutila’s algorithm. Initially, D(v) = ⊥. + private _D: Node2NodeMap; + // map of V to V , associates each node in a cycle to + // the representative of that cycle. Initially R(v) = v. + private _R: Node2RepSCCInfoMap; + // stack of V, holds the nodes that are in a cycle, but + // have not yet been inserted into C. Initially empty + private _S: NodeStack; + // stack of V , holds the nodes of V that are represenatives + // of strongly connected components. T keeps the + // nodes in topological order, that is, the top node has no + // predecessors. Initially empty + private _T: NodeStack; + private repNodes: NodeSet; + private visitedNodes: Set; + private inSCCNodes: Set; + + constructor(GT: Graph) { + this._G = GT; + this._I = 0; + this._D = new Map(); + this._S = new Array(); + this._T = new Array(); + this.repNodes = new Set(); + this._R = new Map(); + this.visitedNodes = new Set(); + this.inSCCNodes = new Set(); + } + + private isVisited(n: NodeID): boolean { + return this.visitedNodes.has(n); + } + + private inSCC(n: NodeID): boolean { + return this.inSCCNodes.has(n); + } + + private setVisited(n: NodeID): void { + this.visitedNodes.add(n); + } + + private setInSCC(n: NodeID): void { + this.inSCCNodes.add(n); + } + + private setRep(n: NodeID, r: NodeID): void { + let sccIn = this._R.get(n); + if (!sccIn) { + sccIn = new NodeSCCInfo(); + this._R.set(n, sccIn); + } + sccIn.rep = r; + + let rInfo = this._R.get(r); + if (!rInfo) { + rInfo = new NodeSCCInfo(); + this._R.set(r, rInfo); + } + rInfo.addSubNodes(n); + if (n !== r) { + sccIn.subNodes.clear(); + this.repNodes.add(r); + } + } + + private getRep(n: NodeID): NodeID { + let info = this._R.get(n); + if (!info) { + info = new NodeSCCInfo(); + this._R.set(n, info); + } + return info.rep; + } + + private getNode(id: NodeID): BaseNode { + let n = this._G.getNode(id); + if (!n) { + throw new Error('Node is not found'); + } + return n; + } + + private visit(v: NodeID): void { + this._I += 1; + this._D.set(v, this._I); + this.setRep(v, v); + this.setVisited(v); + + let node = this.getNode(v); + node.getOutgoingEdges().forEach(e => { + let w: NodeID = e.getDstID(); + if (!this.isVisited(w)) { + this.visit(w); + } + + if (!this.inSCC(w)) { + let repV = this.getRep(v); + let repW = this.getRep(w); + if (!this._D.has(repV) || !this._D.has(repW)) { + throw new Error('Error happening in SCC detection'); + } + let rep = this._D.get(repV)! < this._D.get(repW)! ? repV : repW; + this.setRep(v, rep); + } + }); + + if (this.getRep(v) === v) { + this.setInSCC(v); + while (this._S.length > 0) { + let w = this._S.at(this._S.length - 1)!; + if (this._D.get(w)! <= this._D.get(v)!) { + break; + } else { + this._S.pop(); + this.setInSCC(w); + this.setRep(w, v); + } + } + this._T.push(v); + } else { + this._S.push(v); + } + } + + private clear(): void { + this._R.clear(); + this._I = 0; + this._D.clear(); + this.repNodes.clear(); + this._S.length = 0; + this._T.length = 0; + this.inSCCNodes.clear(); + this.visitedNodes.clear(); + } + + /** + * Get the rep node + * If not found return itself + */ + public getRepNode(n: NodeID): NodeID { + const it = this._R.get(n); + if (!it) { + throw new Error('scc rep not found'); + } + const rep = it.rep; + return rep !== Number.MAX_SAFE_INTEGER ? rep : n; + } + + /** + * Start to detect and collapse SCC + */ + public find(): void { + this.clear(); + let nodeIt = this._G.nodesItor(); + for (let node of nodeIt) { + const nodeId: NodeID = node.getID(); + if (!this.isVisited(nodeId) && !this._D.has(nodeId)) { + this.visit(nodeId); + } + } + } + + public getTopoAndCollapsedNodeStack(): NodeStack { + return this._T; + } + + public getNode2SCCInfoMap(): Node2RepSCCInfoMap { + return this._R; + } + + // whether the node is in a cycle + public nodeIsInCycle(n: NodeID): boolean { + const rep = this.getRepNode(n); + const subNodesCount = this.getSubNodes(rep).size; + // multi-node cycle + if (subNodesCount > 1) { + return true; + } + // self-cycle: a call a + let repNode = this._G.getNode(rep)!; + for (const e of repNode?.getOutgoingEdges()) { + if (e.getDstID() === rep) { + return true; + } + } + return false; + } + + public getMySCCNodes(n: NodeID): NodeSet { + const rep = this.getRepNode(n); + return this.getSubNodes(rep); + } + + // get all subnodes in one scc + public getSubNodes(n: NodeID): NodeSet { + const it = this._R.get(n); + if (!it) { + throw new Error('sccInfo not found for a node'); + } + let sub = it.subNodes; + if (sub.size === 0) { + sub.add(n); + } + + return sub; + } + + // get all representative nodes + public getRepNodes(): NodeSet { + return this.repNodes; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/ViewTree.ts b/ets2panda/linter/arkanalyzer/src/core/graph/ViewTree.ts new file mode 100644 index 0000000000000000000000000000000000000000..b37c77074882c8cac5e34cc7a4b91c9acf846f58 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/ViewTree.ts @@ -0,0 +1,140 @@ +/* + * 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. + */ + +import { Constant } from '../base/Constant'; +import { Decorator } from '../base/Decorator'; +import { ArkInstanceFieldRef } from '../base/Ref'; +import { Stmt } from '../base/Stmt'; +import { Type } from '../base/Type'; +import { ArkField } from '../model/ArkField'; +import { ArkMethod } from '../model/ArkMethod'; +import { ClassSignature, MethodSignature } from '../model/ArkSignature'; + +/** + * @category core/graph + */ +export interface ViewTreeNode { + /** Component node name */ + name: string; + /** @deprecated Use {@link attributes} instead. */ + stmts: Map; + /** Component attribute stmts, key is attribute name, value is [Stmt, [Uses Values]]. */ + attributes: Map; + /** Used state values. */ + stateValues: Set; + /** Node's parent, CustomComponent and root node no parent. */ + parent: ViewTreeNode | null; + /** Node's children. */ + children: ViewTreeNode[]; + /** @deprecated Use {@link signature} instead. */ + classSignature?: ClassSignature | MethodSignature; + /** CustomComponent class signature or Builder method signature. */ + signature?: ClassSignature | MethodSignature; + + /** + * Custom component value transfer + * - key: ArkField, child custom component class stateValue field. + * - value: ArkField | ArkMethod, parent component transfer value. + * key is BuilderParam, the value is Builder ArkMethod. + * Others, the value is parent class stateValue field. + */ + stateValuesTransfer?: Map; + + /** BuilderParam placeholders ArkField. */ + builderParam?: ArkField; + + /** builderParam bind builder method signature. */ + builder?: MethodSignature; + + /** + * walk node and node's children + * @param selector Node selector function, return true skipping the follow-up nodes. + * @returns + * - true: There are nodes that meet the selector. + * - false: does not exist. + */ + walk(selector: (item: ViewTreeNode) => boolean): boolean; + + /** + * Whether the node type is Builder. + * @returns true: node is Builder, false others. + */ + isBuilder(): boolean; + + /** + * Whether the node type is custom component. + * @returns true: node is custom component, false others. + */ + isCustomComponent(): boolean; +} + +/** + * ArkUI Component Tree + * @example + * // Component Class get ViewTree + * let arkClas: ArkClass = ...; + * let viewtree = arkClas.getViewTree(); + * + * // get viewtree root node + * let root: ViewTreeNode = viewtree.getRoot(); + * + * // get viewtree stateValues Map + * let stateValues: Map> = viewtree.getStateValues(); + * + * // walk all nodes + * root.walk((node) => { + * // check node is builder + * if (node.isBuilder()) { + * xx + * } + * + * // check node is sub CustomComponent + * if (node.isCustomComponent()) { + * xx + * } + * + * if (xxx) { + * // Skip the remaining nodes and end the traversal + * return true; + * } + * + * return false; + * }) + * + * @category core/graph + */ +export interface ViewTree { + /** + * @deprecated Use {@link getStateValues} instead. + */ + isClassField(name: string): boolean; + + /** + * @deprecated Use {@link getStateValues} instead. + */ + getClassFieldType(name: string): Decorator | Type | undefined; + + /** + * Map of the component controlled by the state variable + * @returns + */ + getStateValues(): Map>; + + /** + * ViewTree root node. + * @returns root node + */ + getRoot(): ViewTreeNode | null; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/CfgBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/CfgBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..5cd44402ec52488fb5bef3750f8b7af54b0c2f3e --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/CfgBuilder.ts @@ -0,0 +1,1269 @@ +/* + * 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. + */ + +import * as ts from 'ohos-typescript'; +import { Local } from '../../base/Local'; +import { ArkAliasTypeDefineStmt, ArkReturnStmt, ArkReturnVoidStmt, Stmt } from '../../base/Stmt'; +import { BasicBlock } from '../BasicBlock'; +import { Cfg } from '../Cfg'; +import { ArkClass } from '../../model/ArkClass'; +import { ArkMethod } from '../../model/ArkMethod'; +import { ArkIRTransformer, ValueAndStmts } from '../../common/ArkIRTransformer'; +import { ModelUtils } from '../../common/ModelUtils'; +import { IRUtils } from '../../common/IRUtils'; +import { AliasType, ClassType, UnclearReferenceType, UnknownType, VoidType } from '../../base/Type'; +import { Trap } from '../../base/Trap'; +import { GlobalRef } from '../../base/Ref'; +import { LoopBuilder } from './LoopBuilder'; +import { SwitchBuilder } from './SwitchBuilder'; +import { ConditionBuilder } from './ConditionBuilder'; +import { TrapBuilder } from './TrapBuilder'; +import { CONSTRUCTOR_NAME, PROMISE } from '../../common/TSConst'; +import { ModifierType } from '../../model/ArkBaseModel'; + +class StatementBuilder { + type: string; + //节点对应源代码 + code: string; + next: StatementBuilder | null; + lasts: Set; + walked: boolean; + index: number; + // TODO:以下两个属性需要获取 + line: number; //行号//ast节点存了一个start值为这段代码的起始地址,可以从start开始往回查原文有几个换行符确定行号 + column: number; // 列 + astNode: ts.Node | null; //ast节点对象 + scopeID: number; + addressCode3: string[] = []; + block: BlockBuilder | null; + ifExitPass: boolean; + passTmies: number = 0; + numOfIdentifier: number = 0; + isDoWhile: boolean = false; + + constructor(type: string, code: string, astNode: ts.Node | null, scopeID: number) { + this.type = type; + this.code = code; + this.next = null; + this.lasts = new Set(); + this.walked = false; + this.index = 0; + this.line = -1; + this.column = -1; + this.astNode = astNode; + this.scopeID = scopeID; + this.block = null; + this.ifExitPass = false; + } +} + +class ConditionStatementBuilder extends StatementBuilder { + nextT: StatementBuilder | null; + nextF: StatementBuilder | null; + loopBlock: BlockBuilder | null; + condition: string; + doStatement: StatementBuilder | null = null; + + constructor(type: string, code: string, astNode: ts.Node, scopeID: number) { + super(type, code, astNode, scopeID); + this.nextT = null; + this.nextF = null; + this.loopBlock = null; + this.condition = ''; + } +} + +export class SwitchStatementBuilder extends StatementBuilder { + nexts: StatementBuilder[]; + cases: Case[] = []; + default: StatementBuilder | null = null; + afterSwitch: StatementBuilder | null = null; + + constructor(type: string, code: string, astNode: ts.Node, scopeID: number) { + super(type, code, astNode, scopeID); + this.nexts = []; + } +} + +export class TryStatementBuilder extends StatementBuilder { + tryFirst: StatementBuilder | null = null; + tryExit: StatementBuilder | null = null; + catchStatement: StatementBuilder | null = null; + catchError: string = ''; + finallyStatement: StatementBuilder | null = null; + afterFinal: StatementBuilder | null = null; + + constructor(type: string, code: string, astNode: ts.Node, scopeID: number) { + super(type, code, astNode, scopeID); + } +} + +class Case { + value: string; + stmt: StatementBuilder; + valueNode!: ts.Node; + + constructor(value: string, stmt: StatementBuilder) { + this.value = value; + this.stmt = stmt; + } +} + +class DefUseChain { + def: StatementBuilder; + use: StatementBuilder; + + constructor(def: StatementBuilder, use: StatementBuilder) { + this.def = def; + this.use = use; + } +} + +class Variable { + name: string; + lastDef: StatementBuilder; + defUse: DefUseChain[]; + properties: Variable[] = []; + propOf: Variable | null = null; + + constructor(name: string, lastDef: StatementBuilder) { + this.name = name; + this.lastDef = lastDef; + this.defUse = []; + } +} + +class Scope { + id: number; + + constructor(id: number) { + this.id = id; + } +} + +export class BlockBuilder { + id: number; + stmts: StatementBuilder[]; + nexts: BlockBuilder[] = []; + lasts: BlockBuilder[] = []; + walked: boolean = false; + + constructor(id: number, stmts: StatementBuilder[]) { + this.id = id; + this.stmts = stmts; + } +} + +class Catch { + errorName: string; + from: number; + to: number; + withLabel: number; + + constructor(errorName: string, from: number, to: number, withLabel: number) { + this.errorName = errorName; + this.from = from; + this.to = to; + this.withLabel = withLabel; + } +} + +class TextError extends Error { + constructor(message: string) { + // 调用父类的构造函数,并传入错误消息 + super(message); + + // 设置错误类型的名称 + this.name = 'TextError'; + } +} + +export class CfgBuilder { + name: string; + astRoot: ts.Node; + entry: StatementBuilder; + exit: StatementBuilder; + loopStack: ConditionStatementBuilder[]; + switchExitStack: StatementBuilder[]; + functions: CfgBuilder[]; + breakin: string; + statementArray: StatementBuilder[]; + dotEdges: number[][]; + scopes: Scope[]; + tempVariableNum: number; + current3ACstm: StatementBuilder; + blocks: BlockBuilder[]; + currentDeclarationKeyword: string; + variables: Variable[]; + declaringClass: ArkClass; + importFromPath: string[]; + catches: Catch[]; + exits: StatementBuilder[] = []; + emptyBody: boolean = false; + arrowFunctionWithoutBlock: boolean = false; + + private sourceFile: ts.SourceFile; + private declaringMethod: ArkMethod; + + constructor(ast: ts.Node, name: string, declaringMethod: ArkMethod, sourceFile: ts.SourceFile) { + this.name = name; + this.astRoot = ast; + this.declaringMethod = declaringMethod; + this.declaringClass = declaringMethod.getDeclaringArkClass(); + this.entry = new StatementBuilder('entry', '', ast, 0); + this.loopStack = []; + this.switchExitStack = []; + this.functions = []; + this.breakin = ''; + this.statementArray = []; + this.dotEdges = []; + this.exit = new StatementBuilder('exit', 'return;', null, 0); + this.scopes = []; + this.tempVariableNum = 0; + this.current3ACstm = this.entry; + this.blocks = []; + this.currentDeclarationKeyword = ''; + this.variables = []; + this.importFromPath = []; + this.catches = []; + this.sourceFile = sourceFile; + this.arrowFunctionWithoutBlock = true; + } + + public getDeclaringMethod(): ArkMethod { + return this.declaringMethod; + } + + judgeLastType(s: StatementBuilder, lastStatement: StatementBuilder): void { + if (lastStatement.type === 'ifStatement') { + let lastIf = lastStatement as ConditionStatementBuilder; + if (lastIf.nextT == null) { + lastIf.nextT = s; + s.lasts.add(lastIf); + } else { + lastIf.nextF = s; + s.lasts.add(lastIf); + } + } else if (lastStatement.type === 'loopStatement') { + let lastLoop = lastStatement as ConditionStatementBuilder; + lastLoop.nextT = s; + s.lasts.add(lastLoop); + } else if (lastStatement.type === 'catchOrNot') { + let lastLoop = lastStatement as ConditionStatementBuilder; + lastLoop.nextT = s; + s.lasts.add(lastLoop); + } else { + lastStatement.next = s; + s.lasts.add(lastStatement); + } + } + + ASTNodeBreakStatement(c: ts.Node, lastStatement: StatementBuilder): void { + let p: ts.Node | null = c; + while (p && p !== this.astRoot) { + if (ts.isWhileStatement(p) || ts.isDoStatement(p) || ts.isForStatement(p) || ts.isForInStatement(p) || ts.isForOfStatement(p)) { + const lastLoopNextF = this.loopStack[this.loopStack.length - 1].nextF!; + this.judgeLastType(lastLoopNextF, lastStatement); + lastLoopNextF.lasts.add(lastStatement); + return; + } + if (ts.isCaseClause(p) || ts.isDefaultClause(p)) { + const lastSwitchExit = this.switchExitStack[this.switchExitStack.length - 1]; + this.judgeLastType(lastSwitchExit, lastStatement); + lastSwitchExit.lasts.add(lastStatement); + return; + } + p = p.parent; + } + } + + ASTNodeIfStatement(c: ts.IfStatement, lastStatement: StatementBuilder, scopeID: number): StatementBuilder { + let ifstm: ConditionStatementBuilder = new ConditionStatementBuilder('ifStatement', '', c, scopeID); + this.judgeLastType(ifstm, lastStatement); + let ifexit: StatementBuilder = new StatementBuilder('ifExit', '', c, scopeID); + this.exits.push(ifexit); + ifstm.condition = c.expression.getText(this.sourceFile); + ifstm.code = 'if (' + ifstm.condition + ')'; + if (ts.isBlock(c.thenStatement)) { + this.walkAST(ifstm, ifexit, [...c.thenStatement.statements]); + } else { + this.walkAST(ifstm, ifexit, [c.thenStatement]); + } + if (c.elseStatement) { + if (ts.isBlock(c.elseStatement)) { + this.walkAST(ifstm, ifexit, [...c.elseStatement.statements]); + } else { + this.walkAST(ifstm, ifexit, [c.elseStatement]); + } + } + if (!ifstm.nextT) { + ifstm.nextT = ifexit; + ifexit.lasts.add(ifstm); + } + if (!ifstm.nextF) { + ifstm.nextF = ifexit; + ifexit.lasts.add(ifstm); + } + return ifexit; + } + + ASTNodeWhileStatement(c: ts.WhileStatement, lastStatement: StatementBuilder, scopeID: number): StatementBuilder { + this.breakin = 'loop'; + let loopstm = new ConditionStatementBuilder('loopStatement', '', c, scopeID); + this.loopStack.push(loopstm); + this.judgeLastType(loopstm, lastStatement); + let loopExit = new StatementBuilder('loopExit', '', c, scopeID); + this.exits.push(loopExit); + loopstm.nextF = loopExit; + loopExit.lasts.add(loopstm); + loopstm.condition = c.expression.getText(this.sourceFile); + loopstm.code = 'while (' + loopstm.condition + ')'; + if (ts.isBlock(c.statement)) { + this.walkAST(loopstm, loopstm, [...c.statement.statements]); + } else { + this.walkAST(loopstm, loopstm, [c.statement]); + } + if (!loopstm.nextF) { + loopstm.nextF = loopExit; + loopExit.lasts.add(loopstm); + } + if (!loopstm.nextT) { + loopstm.nextT = loopExit; + loopExit.lasts.add(loopstm); + } + this.loopStack.pop(); + return loopExit; + } + + ASTNodeForStatement(c: ts.ForInOrOfStatement | ts.ForStatement, lastStatement: StatementBuilder, scopeID: number): StatementBuilder { + this.breakin = 'loop'; + let loopstm = new ConditionStatementBuilder('loopStatement', '', c, scopeID); + this.loopStack.push(loopstm); + this.judgeLastType(loopstm, lastStatement); + let loopExit = new StatementBuilder('loopExit', '', c, scopeID); + this.exits.push(loopExit); + loopstm.nextF = loopExit; + loopExit.lasts.add(loopstm); + loopstm.code = 'for ('; + if (ts.isForStatement(c)) { + loopstm.code += + c.initializer?.getText(this.sourceFile) + '; ' + c.condition?.getText(this.sourceFile) + '; ' + c.incrementor?.getText(this.sourceFile); + } else if (ts.isForOfStatement(c)) { + loopstm.code += c.initializer?.getText(this.sourceFile) + ' of ' + c.expression.getText(this.sourceFile); + } else { + loopstm.code += c.initializer?.getText(this.sourceFile) + ' in ' + c.expression.getText(this.sourceFile); + } + loopstm.code += ')'; + if (ts.isBlock(c.statement)) { + this.walkAST(loopstm, loopstm, [...c.statement.statements]); + } else { + this.walkAST(loopstm, loopstm, [c.statement]); + } + if (!loopstm.nextF) { + loopstm.nextF = loopExit; + loopExit.lasts.add(loopstm); + } + if (!loopstm.nextT) { + loopstm.nextT = loopExit; + loopExit.lasts.add(loopstm); + } + this.loopStack.pop(); + return loopExit; + } + + ASTNodeDoStatement(c: ts.DoStatement, lastStatement: StatementBuilder, scopeID: number): StatementBuilder { + this.breakin = 'loop'; + let loopstm = new ConditionStatementBuilder('loopStatement', '', c, scopeID); + this.loopStack.push(loopstm); + let loopExit = new StatementBuilder('loopExit', '', c, scopeID); + this.exits.push(loopExit); + loopstm.nextF = loopExit; + loopExit.lasts.add(loopstm); + loopstm.condition = c.expression.getText(this.sourceFile); + loopstm.code = 'while (' + loopstm.condition + ')'; + loopstm.isDoWhile = true; + if (ts.isBlock(c.statement)) { + this.walkAST(lastStatement, loopstm, [...c.statement.statements]); + } else { + this.walkAST(lastStatement, loopstm, [c.statement]); + } + let lastType = lastStatement.type; + if (lastType === 'ifStatement' || lastType === 'loopStatement') { + let lastCondition = lastStatement as ConditionStatementBuilder; + loopstm.nextT = lastCondition.nextT; + lastCondition.nextT?.lasts.add(loopstm); + } else { + loopstm.nextT = lastStatement.next; + lastStatement.next?.lasts.add(loopstm); + } + if (loopstm.nextT && loopstm.nextT !== loopstm) { + loopstm.nextT.isDoWhile = true; + loopstm.doStatement = loopstm.nextT; + } + this.loopStack.pop(); + return loopExit; + } + + ASTNodeSwitchStatement(c: ts.SwitchStatement, lastStatement: StatementBuilder, scopeID: number): StatementBuilder { + this.breakin = 'switch'; + let switchstm = new SwitchStatementBuilder('switchStatement', '', c, scopeID); + this.judgeLastType(switchstm, lastStatement); + let switchExit = new StatementBuilder('switchExit', '', null, scopeID); + this.exits.push(switchExit); + this.switchExitStack.push(switchExit); + switchExit.lasts.add(switchstm); + switchstm.code = 'switch (' + c.expression + ')'; + let lastCaseExit: StatementBuilder | null = null; + for (let i = 0; i < c.caseBlock.clauses.length; i++) { + const clause = c.caseBlock.clauses[i]; + let casestm: StatementBuilder; + if (ts.isCaseClause(clause)) { + casestm = new StatementBuilder('statement', 'case ' + clause.expression.getText(this.sourceFile) + ':', clause, scopeID); + } else { + casestm = new StatementBuilder('statement', 'default:', clause, scopeID); + } + switchstm.nexts.push(casestm); + casestm.lasts.add(switchstm); + let caseExit = new StatementBuilder('caseExit', '', null, scopeID); + this.exits.push(caseExit); + this.walkAST(casestm, caseExit, [...clause.statements]); + if (ts.isCaseClause(clause)) { + const cas = new Case(casestm.code, casestm.next!); + switchstm.cases.push(cas); + } else { + switchstm.default = casestm.next; + } + switchstm.nexts[switchstm.nexts.length - 1] = casestm.next!; + for (const stmt of [...casestm.lasts]) { + casestm.next!.lasts.add(stmt); + } + casestm.next!.lasts.delete(casestm); + + if (lastCaseExit) { + lastCaseExit.next = casestm.next; + casestm.next?.lasts.add(lastCaseExit); + } + lastCaseExit = caseExit; + if (i === c.caseBlock.clauses.length - 1) { + caseExit.next = switchExit; + switchExit.lasts.add(caseExit); + } + } + this.switchExitStack.pop(); + return switchExit; + } + + ASTNodeTryStatement(c: ts.TryStatement, lastStatement: StatementBuilder, scopeID: number): StatementBuilder { + let trystm = new TryStatementBuilder('tryStatement', 'try', c, scopeID); + this.judgeLastType(trystm, lastStatement); + let tryExit = new StatementBuilder('tryExit', '', c, scopeID); + this.exits.push(tryExit); + trystm.tryExit = tryExit; + this.walkAST(trystm, tryExit, [...c.tryBlock.statements]); + trystm.tryFirst = trystm.next; + trystm.next?.lasts.add(trystm); + if (c.catchClause) { + let text = 'catch'; + if (c.catchClause.variableDeclaration) { + text += '(' + c.catchClause.variableDeclaration.getText(this.sourceFile) + ')'; + } + let catchOrNot = new ConditionStatementBuilder('catchOrNot', text, c, scopeID); + let catchExit = new StatementBuilder('catch exit', '', c, scopeID); + catchOrNot.nextF = catchExit; + catchExit.lasts.add(catchOrNot); + this.walkAST(catchOrNot, catchExit, [...c.catchClause.block.statements]); + if (!catchOrNot.nextT) { + catchOrNot.nextT = catchExit; + catchExit.lasts.add(catchOrNot); + } + const catchStatement = new StatementBuilder('statement', catchOrNot.code, c.catchClause, catchOrNot.nextT.scopeID); + catchStatement.next = catchOrNot.nextT; + trystm.catchStatement = catchStatement; + catchStatement.lasts.add(trystm); + if (c.catchClause.variableDeclaration) { + trystm.catchError = c.catchClause.variableDeclaration.getText(this.sourceFile); + } else { + trystm.catchError = 'Error'; + } + } + let final = new StatementBuilder('statement', 'finally', c, scopeID); + let finalExit = new StatementBuilder('finallyExit', '', c, scopeID); + this.exits.push(finalExit); + if (c.finallyBlock && c.finallyBlock.statements.length > 0) { + this.walkAST(final, finalExit, [...c.finallyBlock.statements]); + } else { + let dummyFinally = new StatementBuilder('statement', 'dummyFinally', c, new Scope(this.scopes.length).id); + final.next = dummyFinally; + dummyFinally.lasts.add(final); + dummyFinally.next = finalExit; + finalExit.lasts.add(dummyFinally); + } + trystm.finallyStatement = final.next; + tryExit.next = final.next; + final.next?.lasts.add(tryExit); + + trystm.next = finalExit; + finalExit.lasts.add(trystm); + return finalExit; + } + + walkAST(lastStatement: StatementBuilder, nextStatement: StatementBuilder, nodes: ts.Node[]): void { + let scope = new Scope(this.scopes.length); + this.scopes.push(scope); + for (let i = 0; i < nodes.length; i++) { + let c = nodes[i]; + if (ts.isVariableStatement(c) || ts.isExpressionStatement(c) || ts.isThrowStatement(c) || ts.isTypeAliasDeclaration(c)) { + let s = new StatementBuilder('statement', c.getText(this.sourceFile), c, scope.id); + this.judgeLastType(s, lastStatement); + lastStatement = s; + } else if (!this.declaringMethod.isDefaultArkMethod() && ts.isFunctionDeclaration(c)) { + let s = new StatementBuilder('functionDeclarationStatement', c.getText(this.sourceFile), c, scope.id); + this.judgeLastType(s, lastStatement); + lastStatement = s; + } else if (!this.declaringMethod.isDefaultArkMethod() && ts.isClassDeclaration(c)) { + let s = new StatementBuilder('classDeclarationStatement', c.getText(this.sourceFile), c, scope.id); + this.judgeLastType(s, lastStatement); + lastStatement = s; + } else if (ts.isReturnStatement(c)) { + let s = new StatementBuilder('returnStatement', c.getText(this.sourceFile), c, scope.id); + this.judgeLastType(s, lastStatement); + lastStatement = s; + break; + } else if (ts.isBreakStatement(c)) { + this.ASTNodeBreakStatement(c, lastStatement); + return; + } else if (ts.isContinueStatement(c)) { + const lastLoop = this.loopStack[this.loopStack.length - 1]; + this.judgeLastType(lastLoop, lastStatement); + lastLoop.lasts.add(lastStatement); + return; + } else if (ts.isIfStatement(c)) { + lastStatement = this.ASTNodeIfStatement(c, lastStatement, scope.id); + } else if (ts.isWhileStatement(c)) { + lastStatement = this.ASTNodeWhileStatement(c, lastStatement, scope.id); + } + if (ts.isForStatement(c) || ts.isForInStatement(c) || ts.isForOfStatement(c)) { + lastStatement = this.ASTNodeForStatement(c, lastStatement, scope.id); + } else if (ts.isDoStatement(c)) { + lastStatement = this.ASTNodeDoStatement(c, lastStatement, scope.id); + } else if (ts.isSwitchStatement(c)) { + lastStatement = this.ASTNodeSwitchStatement(c, lastStatement, scope.id); + } else if (ts.isBlock(c)) { + let blockExit = new StatementBuilder('blockExit', '', c, scope.id); + this.exits.push(blockExit); + this.walkAST(lastStatement, blockExit, c.getChildren(this.sourceFile)[1].getChildren(this.sourceFile)); + lastStatement = blockExit; + } else if (ts.isTryStatement(c)) { + lastStatement = this.ASTNodeTryStatement(c, lastStatement, scope.id); + } else if (ts.isExportAssignment(c)) { + if (ts.isNewExpression(c.expression) || ts.isObjectLiteralExpression(c.expression)) { + let s = new StatementBuilder('statement', c.getText(this.sourceFile), c, scope.id); + this.judgeLastType(s, lastStatement); + lastStatement = s; + } + } + } + if (lastStatement.type !== 'breakStatement' && lastStatement.type !== 'continueStatement' && lastStatement.type !== 'returnStatement') { + lastStatement.next = nextStatement; + nextStatement.lasts.add(lastStatement); + } + } + + addReturnInEmptyMethod(): void { + if (this.entry.next === this.exit) { + const ret = new StatementBuilder('returnStatement', 'return;', null, this.entry.scopeID); + this.entry.next = ret; + ret.lasts.add(this.entry); + ret.next = this.exit; + this.exit.lasts = new Set([ret]); + } + } + + deleteExitAfterCondition(last: ConditionStatementBuilder, exit: StatementBuilder): void { + if (last.nextT === exit) { + last.nextT = exit.next; + const lasts = exit.next!.lasts; + lasts.delete(exit); + lasts.add(last); + } else if (last.nextF === exit) { + last.nextF = exit.next; + const lasts = exit.next!.lasts; + lasts.delete(exit); + lasts.add(last); + } + } + + deleteExitAfterSwitch(last: SwitchStatementBuilder, exit: StatementBuilder): void { + if (exit.type === 'switchExit') { + last.afterSwitch = exit.next; + } + exit.next!.lasts.delete(exit); + last.nexts = last.nexts.filter(item => item !== exit); + if (last.nexts.length === 0) { + last.next = exit.next; + exit.next?.lasts.add(last); + } + } + + deleteExit(): void { + for (const exit of this.exits) { + const lasts = [...exit.lasts]; + for (const last of lasts) { + if (last instanceof ConditionStatementBuilder) { + this.deleteExitAfterCondition(last, exit); + } else if (last instanceof SwitchStatementBuilder) { + this.deleteExitAfterSwitch(last, exit); + } else if (last instanceof TryStatementBuilder && exit.type === 'finallyExit') { + last.afterFinal = exit.next; + last.next = last.tryFirst; + exit.lasts.delete(last); + } else { + last.next = exit.next; + const lasts = exit.next!.lasts; + lasts.delete(exit); + lasts.add(last); + } + } + } + // 部分语句例如return后面的exit语句的next无法在上面清除 + for (const exit of this.exits) { + if (exit.next && exit.next.lasts.has(exit)) { + exit.next.lasts.delete(exit); + } + } + } + + addStmt2BlockStmtQueueInSpecialCase(stmt: StatementBuilder, stmtQueue: StatementBuilder[]): StatementBuilder | null { + if (stmt.next) { + if (((stmt.type === 'continueStatement' || stmt.next.type === 'loopStatement') && stmt.next.block) || stmt.next.type.includes('exit')) { + return null; + } + stmt.next.passTmies++; + if (stmt.next.passTmies === stmt.next.lasts.size || stmt.next.type === 'loopStatement' || stmt.next.isDoWhile) { + if ( + stmt.next.scopeID !== stmt.scopeID && + !(stmt.next instanceof ConditionStatementBuilder && stmt.next.doStatement) && + !(ts.isCaseClause(stmt.astNode!) || ts.isDefaultClause(stmt.astNode!)) + ) { + stmtQueue.push(stmt.next); + return null; + } + return stmt.next; + } + } + return null; + } + + addStmt2BlockStmtQueue(stmt: StatementBuilder, stmtQueue: StatementBuilder[]): StatementBuilder | null { + if (stmt instanceof ConditionStatementBuilder) { + stmtQueue.push(stmt.nextF!); + stmtQueue.push(stmt.nextT!); + } else if (stmt instanceof SwitchStatementBuilder) { + if (stmt.nexts.length === 0) { + stmtQueue.push(stmt.afterSwitch!); + } + for (let i = stmt.nexts.length - 1; i >= 0; i--) { + stmtQueue.push(stmt.nexts[i]); + } + } else if (stmt instanceof TryStatementBuilder) { + if (stmt.finallyStatement) { + stmtQueue.push(stmt.finallyStatement); + } + if (stmt.catchStatement) { + stmtQueue.push(stmt.catchStatement); + } + if (stmt.tryFirst) { + stmtQueue.push(stmt.tryFirst); + } + } else if (stmt.next) { + return this.addStmt2BlockStmtQueueInSpecialCase(stmt, stmtQueue); + } + return null; + } + + buildBlocks(): void { + const stmtQueue = [this.entry]; + const handledStmts: Set = new Set(); + while (stmtQueue.length > 0) { + let stmt = stmtQueue.pop()!; + if (stmt.type.includes('exit')) { + continue; + } + if (handledStmts.has(stmt)) { + continue; + } + const block = new BlockBuilder(this.blocks.length, []); + this.blocks.push(block); + while (stmt && !handledStmts.has(stmt)) { + if (stmt.type === 'loopStatement' && block.stmts.length > 0 && !stmt.isDoWhile) { + stmtQueue.push(stmt); + break; + } + if (stmt.type.includes('Exit')) { + break; + } + block.stmts.push(stmt); + stmt.block = block; + handledStmts.add(stmt); + const addRet = this.addStmt2BlockStmtQueue(stmt, stmtQueue); + if (addRet instanceof StatementBuilder) { + stmt = addRet; + } else { + break; + } + } + } + } + + buildConditionNextBlocks(originStatement: ConditionStatementBuilder, block: BlockBuilder, isLastStatement: boolean): void { + let nextT = originStatement.nextT?.block; + if (nextT && (isLastStatement || nextT !== block) && !originStatement.nextT?.type.includes(' exit')) { + block.nexts.push(nextT); + nextT.lasts.push(block); + } + let nextF = originStatement.nextF?.block; + if (nextF && (isLastStatement || nextF !== block) && !originStatement.nextF?.type.includes(' exit')) { + block.nexts.push(nextF); + nextF.lasts.push(block); + } + } + + buildSwitchNextBlocks(originStatement: SwitchStatementBuilder, block: BlockBuilder, isLastStatement: boolean): void { + if (originStatement.nexts.length === 0) { + const nextBlock = originStatement.afterSwitch!.block; + if (nextBlock && (isLastStatement || nextBlock !== block)) { + block.nexts.push(nextBlock); + nextBlock.lasts.push(block); + } + } + for (const next of originStatement.nexts) { + const nextBlock = next.block; + if (nextBlock && (isLastStatement || nextBlock !== block)) { + block.nexts.push(nextBlock); + nextBlock.lasts.push(block); + } + } + } + + buildNormalNextBlocks(originStatement: StatementBuilder, block: BlockBuilder, isLastStatement: boolean): void { + let next = originStatement.next?.block; + if (next && (isLastStatement || next !== block) && !originStatement.next?.type.includes(' exit')) { + block.nexts.push(next); + next.lasts.push(block); + } + } + + buildBlocksNextLast(): void { + for (let block of this.blocks) { + for (let originStatement of block.stmts) { + let isLastStatement = block.stmts.indexOf(originStatement) === block.stmts.length - 1; + if (originStatement instanceof ConditionStatementBuilder) { + this.buildConditionNextBlocks(originStatement, block, isLastStatement); + } else if (originStatement instanceof SwitchStatementBuilder) { + this.buildSwitchNextBlocks(originStatement, block, isLastStatement); + } else { + this.buildNormalNextBlocks(originStatement, block, isLastStatement); + } + } + } + } + + addReturnBlock(returnStatement: StatementBuilder, notReturnStmts: StatementBuilder[]): void { + let returnBlock = new BlockBuilder(this.blocks.length, [returnStatement]); + returnStatement.block = returnBlock; + this.blocks.push(returnBlock); + for (const notReturnStmt of notReturnStmts) { + if (notReturnStmt instanceof ConditionStatementBuilder) { + if (this.exit === notReturnStmt.nextT) { + notReturnStmt.nextT = returnStatement; + notReturnStmt.block?.nexts.splice(0, 0, returnBlock); + } else if (this.exit === notReturnStmt.nextF) { + notReturnStmt.nextF = returnStatement; + notReturnStmt.block?.nexts.push(returnBlock); + } + } else { + notReturnStmt.next = returnStatement; + notReturnStmt.block?.nexts.push(returnBlock); + } + returnStatement.lasts.add(notReturnStmt); + returnStatement.next = this.exit; + const lasts = [...this.exit.lasts]; + lasts[lasts.indexOf(notReturnStmt)] = returnStatement; + this.exit.lasts = new Set(lasts); + returnBlock.lasts.push(notReturnStmt.block!); + } + this.exit.block = returnBlock; + } + + addReturnStmt(): void { + let notReturnStmts: StatementBuilder[] = []; + for (let stmt of [...this.exit.lasts]) { + if (stmt.type !== 'returnStatement') { + notReturnStmts.push(stmt); + } + } + if (notReturnStmts.length < 1) { + return; + } + const returnStatement = new StatementBuilder('returnStatement', 'return;', null, this.exit.scopeID); + let TryOrSwitchExit = false; + if (notReturnStmts.length === 1 && notReturnStmts[0].block) { + let p: ts.Node | null = notReturnStmts[0].astNode; + while (p && p !== this.astRoot) { + if (ts.isTryStatement(p) || ts.isSwitchStatement(p)) { + TryOrSwitchExit = true; + break; + } + p = p.parent; + } + } + if (notReturnStmts.length === 1 && !(notReturnStmts[0] instanceof ConditionStatementBuilder) && !TryOrSwitchExit) { + const notReturnStmt = notReturnStmts[0]; + notReturnStmt.next = returnStatement; + returnStatement.lasts = new Set([notReturnStmt]); + returnStatement.next = this.exit; + const lasts = [...this.exit.lasts]; + lasts[lasts.indexOf(notReturnStmt)] = returnStatement; + this.exit.lasts = new Set(lasts); + notReturnStmt.block?.stmts.push(returnStatement); + returnStatement.block = notReturnStmt.block; + } else { + this.addReturnBlock(returnStatement, notReturnStmts); + } + } + + resetWalked(): void { + for (let stmt of this.statementArray) { + stmt.walked = false; + } + } + + addStmtBuilderPosition(): void { + for (const stmt of this.statementArray) { + if (stmt.astNode) { + const { line, character } = ts.getLineAndCharacterOfPosition(this.sourceFile, stmt.astNode.getStart(this.sourceFile)); + stmt.line = line + 1; + stmt.column = character + 1; + } + } + } + + CfgBuilder2Array(stmt: StatementBuilder): void { + if (stmt.walked) { + return; + } + stmt.walked = true; + stmt.index = this.statementArray.length; + if (!stmt.type.includes(' exit')) { + this.statementArray.push(stmt); + } + if (stmt.type === 'ifStatement' || stmt.type === 'loopStatement' || stmt.type === 'catchOrNot') { + let cstm = stmt as ConditionStatementBuilder; + if (cstm.nextT == null || cstm.nextF == null) { + this.errorTest(cstm); + return; + } + this.CfgBuilder2Array(cstm.nextF); + this.CfgBuilder2Array(cstm.nextT); + } else if (stmt.type === 'switchStatement') { + let sstm = stmt as SwitchStatementBuilder; + for (let ss of sstm.nexts) { + this.CfgBuilder2Array(ss); + } + } else if (stmt.type === 'tryStatement') { + let trystm = stmt as TryStatementBuilder; + if (trystm.tryFirst) { + this.CfgBuilder2Array(trystm.tryFirst); + } + if (trystm.catchStatement) { + this.CfgBuilder2Array(trystm.catchStatement); + } + if (trystm.finallyStatement) { + this.CfgBuilder2Array(trystm.finallyStatement); + } + if (trystm.next) { + this.CfgBuilder2Array(trystm.next); + } + } else { + if (stmt.next != null) { + this.CfgBuilder2Array(stmt.next); + } + } + } + + getDotEdges(stmt: StatementBuilder): void { + if (this.statementArray.length === 0) { + this.CfgBuilder2Array(this.entry); + } + if (stmt.walked) { + return; + } + stmt.walked = true; + if (stmt.type === 'ifStatement' || stmt.type === 'loopStatement' || stmt.type === 'catchOrNot') { + let cstm = stmt as ConditionStatementBuilder; + if (cstm.nextT == null || cstm.nextF == null) { + this.errorTest(cstm); + return; + } + let edge = [cstm.index, cstm.nextF.index]; + this.dotEdges.push(edge); + edge = [cstm.index, cstm.nextT.index]; + this.dotEdges.push(edge); + this.getDotEdges(cstm.nextF); + this.getDotEdges(cstm.nextT); + } else if (stmt.type === 'switchStatement') { + let sstm = stmt as SwitchStatementBuilder; + for (let ss of sstm.nexts) { + let edge = [sstm.index, ss.index]; + this.dotEdges.push(edge); + this.getDotEdges(ss); + } + } else { + if (stmt.next != null) { + let edge = [stmt.index, stmt.next.index]; + this.dotEdges.push(edge); + this.getDotEdges(stmt.next); + } + } + } + + errorTest(stmt: StatementBuilder): void { + let mes = 'ifnext error '; + if (this.declaringClass?.getDeclaringArkFile()) { + mes += this.declaringClass?.getDeclaringArkFile().getName() + '.' + this.declaringClass.getName() + '.' + this.name; + } + mes += '\n' + stmt.code; + throw new TextError(mes); + } + + buildStatementBuilder4ArrowFunction(stmt: ts.Node): void { + let s = new StatementBuilder('statement', stmt.getText(this.sourceFile), stmt, 0); + this.entry.next = s; + s.lasts = new Set([this.entry]); + s.next = this.exit; + this.exit.lasts = new Set([s]); + } + + buildCfgBuilder(): void { + let stmts: ts.Node[] = []; + if (ts.isSourceFile(this.astRoot)) { + stmts = [...this.astRoot.statements]; + } else if ( + ts.isFunctionDeclaration(this.astRoot) || + ts.isMethodDeclaration(this.astRoot) || + ts.isConstructorDeclaration(this.astRoot) || + ts.isGetAccessorDeclaration(this.astRoot) || + ts.isSetAccessorDeclaration(this.astRoot) || + ts.isFunctionExpression(this.astRoot) || + ts.isClassStaticBlockDeclaration(this.astRoot) + ) { + if (this.astRoot.body) { + stmts = [...this.astRoot.body.statements]; + } else { + this.emptyBody = true; + } + } else if (ts.isArrowFunction(this.astRoot)) { + if (ts.isBlock(this.astRoot.body)) { + stmts = [...this.astRoot.body.statements]; + } + } else if ( + ts.isMethodSignature(this.astRoot) || + ts.isConstructSignatureDeclaration(this.astRoot) || + ts.isCallSignatureDeclaration(this.astRoot) || + ts.isFunctionTypeNode(this.astRoot) + ) { + this.emptyBody = true; + } else if (ts.isModuleDeclaration(this.astRoot) && ts.isModuleBlock(this.astRoot.body!)) { + stmts = [...this.astRoot.body.statements]; + } + if (!ModelUtils.isArkUIBuilderMethod(this.declaringMethod)) { + this.walkAST(this.entry, this.exit, stmts); + } else { + this.handleBuilder(stmts); + } + if (ts.isArrowFunction(this.astRoot) && !ts.isBlock(this.astRoot.body)) { + this.buildStatementBuilder4ArrowFunction(this.astRoot.body); + } + this.addReturnInEmptyMethod(); + this.deleteExit(); + this.CfgBuilder2Array(this.entry); + this.addStmtBuilderPosition(); + this.buildBlocks(); + this.blocks = this.blocks.filter(b => b.stmts.length !== 0); + this.buildBlocksNextLast(); + this.addReturnStmt(); + } + + private handleBuilder(stmts: ts.Node[]): void { + let lastStmt = this.entry; + for (const stmt of stmts) { + const stmtBuilder = new StatementBuilder('statement', stmt.getText(this.sourceFile), stmt, 0); + lastStmt.next = stmtBuilder; + stmtBuilder.lasts.add(lastStmt); + lastStmt = stmtBuilder; + } + lastStmt.next = this.exit; + this.exit.lasts.add(lastStmt); + } + + public isBodyEmpty(): boolean { + return this.emptyBody; + } + + public buildCfg(): { + cfg: Cfg; + locals: Set; + globals: Map | null; + aliasTypeMap: Map; + traps: Trap[]; + } { + if (ts.isArrowFunction(this.astRoot) && !ts.isBlock(this.astRoot.body)) { + return this.buildCfgForSimpleArrowFunction(); + } + + return this.buildNormalCfg(); + } + + public buildCfgForSimpleArrowFunction(): { + cfg: Cfg; + locals: Set; + globals: Map | null; + aliasTypeMap: Map; + traps: Trap[]; + } { + const stmts: Stmt[] = []; + const arkIRTransformer = new ArkIRTransformer(this.sourceFile, this.declaringMethod); + arkIRTransformer.prebuildStmts().forEach(stmt => stmts.push(stmt)); + const expressionBodyNode = (this.astRoot as ts.ArrowFunction).body as ts.Expression; + const expressionBodyStmts: Stmt[] = []; + let { + value: expressionBodyValue, + valueOriginalPositions: expressionBodyPositions, + stmts: tempStmts, + } = arkIRTransformer.tsNodeToValueAndStmts(expressionBodyNode); + tempStmts.forEach(stmt => expressionBodyStmts.push(stmt)); + if (IRUtils.moreThanOneAddress(expressionBodyValue)) { + ({ + value: expressionBodyValue, + valueOriginalPositions: expressionBodyPositions, + stmts: tempStmts, + } = arkIRTransformer.generateAssignStmtForValue(expressionBodyValue, expressionBodyPositions)); + tempStmts.forEach(stmt => expressionBodyStmts.push(stmt)); + } + const returnStmt = new ArkReturnStmt(expressionBodyValue); + returnStmt.setOperandOriginalPositions([expressionBodyPositions[0], ...expressionBodyPositions]); + expressionBodyStmts.push(returnStmt); + arkIRTransformer.mapStmtsToTsStmt(expressionBodyStmts, expressionBodyNode); + expressionBodyStmts.forEach(stmt => stmts.push(stmt)); + const cfg = new Cfg(); + const blockInCfg = new BasicBlock(); + blockInCfg.setId(0); + stmts.forEach(stmt => { + blockInCfg.addStmt(stmt); + stmt.setCfg(cfg); + }); + cfg.addBlock(blockInCfg); + cfg.setStartingStmt(stmts[0]); + return { + cfg: cfg, + locals: arkIRTransformer.getLocals(), + globals: arkIRTransformer.getGlobals(), + aliasTypeMap: arkIRTransformer.getAliasTypeMap(), + traps: [], + }; + } + + public buildNormalCfg(): { + cfg: Cfg; + locals: Set; + globals: Map | null; + aliasTypeMap: Map; + traps: Trap[]; + } { + const { blockBuilderToCfgBlock, basicBlockSet, arkIRTransformer } = this.initializeBuild(); + const { blocksContainLoopCondition, blockBuildersBeforeTry, blockBuildersContainSwitch, valueAndStmtsOfSwitchAndCasesAll } = this.processBlocks( + blockBuilderToCfgBlock, + basicBlockSet, + arkIRTransformer + ); + + const currBlockId = this.blocks.length; + this.linkBasicBlocks(blockBuilderToCfgBlock); + this.adjustBlocks( + blockBuilderToCfgBlock, + blocksContainLoopCondition, + basicBlockSet, + blockBuildersContainSwitch, + valueAndStmtsOfSwitchAndCasesAll, + arkIRTransformer + ); + + const trapBuilder = new TrapBuilder(); + const traps = trapBuilder.buildTraps(blockBuilderToCfgBlock, blockBuildersBeforeTry, arkIRTransformer, basicBlockSet); + + const cfg = this.createCfg(blockBuilderToCfgBlock, basicBlockSet, currBlockId); + return { + cfg, + locals: arkIRTransformer.getLocals(), + globals: arkIRTransformer.getGlobals(), + aliasTypeMap: arkIRTransformer.getAliasTypeMap(), + traps, + }; + } + + private initializeBuild(): { + blockBuilderToCfgBlock: Map; + basicBlockSet: Set; + arkIRTransformer: ArkIRTransformer; + } { + const blockBuilderToCfgBlock = new Map(); + const basicBlockSet = new Set(); + const arkIRTransformer = new ArkIRTransformer(this.sourceFile, this.declaringMethod); + return { blockBuilderToCfgBlock, basicBlockSet, arkIRTransformer }; + } + + private processBlocks( + blockBuilderToCfgBlock: Map, + basicBlockSet: Set, + arkIRTransformer: ArkIRTransformer + ): { + blocksContainLoopCondition: Set; + blockBuildersBeforeTry: Set; + blockBuildersContainSwitch: BlockBuilder[]; + valueAndStmtsOfSwitchAndCasesAll: ValueAndStmts[][]; + } { + const blocksContainLoopCondition = new Set(); + const blockBuildersBeforeTry = new Set(); + const blockBuildersContainSwitch: BlockBuilder[] = []; + const valueAndStmtsOfSwitchAndCasesAll: ValueAndStmts[][] = []; + for (let i = 0; i < this.blocks.length; i++) { + const stmtsInBlock: Stmt[] = []; + if (i === 0) { + arkIRTransformer.prebuildStmts().forEach(stmt => stmtsInBlock.push(stmt)); + } + const stmtsCnt = this.blocks[i].stmts.length; + if (this.blocks[i].stmts[stmtsCnt - 1].type === 'tryStatement') { + blockBuildersBeforeTry.add(this.blocks[i]); + } + for (const statementBuilder of this.blocks[i].stmts) { + if (statementBuilder.type === 'loopStatement') { + blocksContainLoopCondition.add(this.blocks[i]); + } else if (statementBuilder instanceof SwitchStatementBuilder) { + blockBuildersContainSwitch.push(this.blocks[i]); + const valueAndStmtsOfSwitchAndCases = arkIRTransformer.switchStatementToValueAndStmts(statementBuilder.astNode as ts.SwitchStatement); + valueAndStmtsOfSwitchAndCasesAll.push(valueAndStmtsOfSwitchAndCases); + continue; + } + if (statementBuilder.astNode && statementBuilder.code !== '') { + arkIRTransformer.tsNodeToStmts(statementBuilder.astNode).forEach(s => stmtsInBlock.push(s)); + } else if (statementBuilder.code.startsWith('return')) { + stmtsInBlock.push(this.generateReturnStmt(arkIRTransformer)); + } + } + const blockInCfg = new BasicBlock(); + blockInCfg.setId(this.blocks[i].id); + for (const stmt of stmtsInBlock) { + blockInCfg.addStmt(stmt); + } + basicBlockSet.add(blockInCfg); + blockBuilderToCfgBlock.set(this.blocks[i], blockInCfg); + } + return { + blocksContainLoopCondition, + blockBuildersBeforeTry, + blockBuildersContainSwitch, + valueAndStmtsOfSwitchAndCasesAll, + }; + } + + private generateReturnStmt(arkIRTransformer: ArkIRTransformer): Stmt { + if (this.name === CONSTRUCTOR_NAME) { + this.declaringMethod.getSubSignature().setReturnType(arkIRTransformer.getThisLocal().getType()); + return new ArkReturnStmt(arkIRTransformer.getThisLocal()); + } + if (this.declaringMethod.getSubSignature().getReturnType() instanceof UnknownType && !this.declaringMethod.getAsteriskToken()) { + if (this.declaringMethod.containsModifier(ModifierType.ASYNC)) { + const promise = this.declaringMethod.getDeclaringArkFile().getScene().getSdkGlobal(PROMISE); + if (promise instanceof ArkClass) { + this.declaringMethod.getSubSignature().setReturnType(new ClassType(promise.getSignature())); + } else { + this.declaringMethod.getSubSignature().setReturnType(new UnclearReferenceType(PROMISE, [VoidType.getInstance()])); + } + } else { + this.declaringMethod.getSubSignature().setReturnType(VoidType.getInstance()); + } + } + return new ArkReturnVoidStmt(); + } + + private adjustBlocks( + blockBuilderToCfgBlock: Map, + blocksContainLoopCondition: Set, + basicBlockSet: Set, + blockBuildersContainSwitch: BlockBuilder[], + valueAndStmtsOfSwitchAndCasesAll: ValueAndStmts[][], + arkIRTransformer: ArkIRTransformer + ): void { + const loopBuilder = new LoopBuilder(); + loopBuilder.rebuildBlocksInLoop(blockBuilderToCfgBlock, blocksContainLoopCondition, basicBlockSet, this.blocks); + const switchBuilder = new SwitchBuilder(); + switchBuilder.buildSwitch(blockBuilderToCfgBlock, blockBuildersContainSwitch, valueAndStmtsOfSwitchAndCasesAll, arkIRTransformer, basicBlockSet); + const conditionalBuilder = new ConditionBuilder(); + conditionalBuilder.rebuildBlocksContainConditionalOperator(basicBlockSet, ModelUtils.isArkUIBuilderMethod(this.declaringMethod)); + } + + private createCfg(blockBuilderToCfgBlock: Map, basicBlockSet: Set, prevBlockId: number): Cfg { + let currBlockId = prevBlockId; + for (const blockBuilder of this.blocks) { + if (blockBuilder.id === -1) { + blockBuilder.id = currBlockId++; + const block = blockBuilderToCfgBlock.get(blockBuilder) as BasicBlock; + block.setId(blockBuilder.id); + } + } + + const cfg = new Cfg(); + const startingBasicBlock = blockBuilderToCfgBlock.get(this.blocks[0])!; + cfg.setStartingStmt(startingBasicBlock.getStmts()[0]); + currBlockId = 0; + for (const basicBlock of basicBlockSet) { + basicBlock.setId(currBlockId++); + cfg.addBlock(basicBlock); + } + for (const stmt of cfg.getStmts()) { + stmt.setCfg(cfg); + } + return cfg; + } + + private linkBasicBlocks(blockBuilderToCfgBlock: Map): void { + for (const [blockBuilder, cfgBlock] of blockBuilderToCfgBlock) { + for (const successorBlockBuilder of blockBuilder.nexts) { + if (!blockBuilderToCfgBlock.get(successorBlockBuilder)) { + continue; + } + const successorBlock = blockBuilderToCfgBlock.get(successorBlockBuilder) as BasicBlock; + cfgBlock.addSuccessorBlock(successorBlock); + } + for (const predecessorBlockBuilder of blockBuilder.lasts) { + if (!blockBuilderToCfgBlock.get(predecessorBlockBuilder)) { + continue; + } + const predecessorBlock = blockBuilderToCfgBlock.get(predecessorBlockBuilder) as BasicBlock; + cfgBlock.addPredecessorBlock(predecessorBlock); + } + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/ConditionBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/ConditionBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..2cb3c912011f5f3fb682b8702db617876616fd0f --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/ConditionBuilder.ts @@ -0,0 +1,301 @@ +/* + * 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 { BasicBlock } from '../BasicBlock'; +import { ArkIRTransformer, DummyStmt } from '../../common/ArkIRTransformer'; +import { ArkAssignStmt, Stmt } from '../../base/Stmt'; +import { Local } from '../../base/Local'; +import { IRUtils } from '../../common/IRUtils'; + +/** + * Builder for condition in CFG + */ +export class ConditionBuilder { + public rebuildBlocksContainConditionalOperator(basicBlockSet: Set, isArkUIBuilder: boolean): void { + if (isArkUIBuilder) { + this.deleteDummyConditionalOperatorStmt(basicBlockSet); + return; + } + + const currBasicBlocks = Array.from(basicBlockSet); + for (const currBasicBlock of currBasicBlocks) { + const stmtsInCurrBasicBlock = Array.from(currBasicBlock.getStmts()); + const stmtsCnt = stmtsInCurrBasicBlock.length; + let conditionalOperatorEndPos = -1; + for (let i = stmtsCnt - 1; i >= 0; i--) { + const stmt = stmtsInCurrBasicBlock[i]; + if (stmt instanceof DummyStmt && stmt.toString()?.startsWith(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT)) { + conditionalOperatorEndPos = i; + break; + } + } + if (conditionalOperatorEndPos === -1) { + continue; + } + + let { generatedTopBlock: generatedTopBlock, generatedBottomBlocks: generatedBottomBlocks } = this.generateBlocksContainConditionalOperatorGroup( + stmtsInCurrBasicBlock.slice(0, conditionalOperatorEndPos + 1), + basicBlockSet + ); + + if (conditionalOperatorEndPos !== stmtsCnt - 1) { + // need create a new basic block for rest statements + const { generatedTopBlock: extraBlock } = this.generateBlockWithoutConditionalOperator( + stmtsInCurrBasicBlock.slice(conditionalOperatorEndPos + 1) + ); + generatedBottomBlocks.forEach(generatedBottomBlock => { + generatedBottomBlock.addSuccessorBlock(extraBlock); + extraBlock.addPredecessorBlock(generatedBottomBlock); + }); + basicBlockSet.add(extraBlock); + generatedBottomBlocks = this.removeUnnecessaryBlocksInConditionalOperator(extraBlock, basicBlockSet); + } + this.relinkPrevAndSuccOfBlockContainConditionalOperator(currBasicBlock, generatedTopBlock, generatedBottomBlocks); + basicBlockSet.delete(currBasicBlock); + } + } + + private relinkPrevAndSuccOfBlockContainConditionalOperator( + currBasicBlock: BasicBlock, + generatedTopBlock: BasicBlock, + generatedBottomBlocks: BasicBlock[] + ): void { + const predecessorsOfCurrBasicBlock = Array.from(currBasicBlock.getPredecessors()); + predecessorsOfCurrBasicBlock.forEach(predecessor => { + predecessor.removeSuccessorBlock(currBasicBlock); + currBasicBlock.removePredecessorBlock(predecessor); + generatedTopBlock.addPredecessorBlock(predecessor); + predecessor.addSuccessorBlock(generatedTopBlock); + }); + const successorsOfCurrBasicBlock = Array.from(currBasicBlock.getSuccessors()); + successorsOfCurrBasicBlock.forEach(successor => { + successor.removePredecessorBlock(currBasicBlock); + currBasicBlock.removeSuccessorBlock(successor); + generatedBottomBlocks.forEach(generatedBottomBlock => { + generatedBottomBlock.addSuccessorBlock(successor); + successor.addPredecessorBlock(generatedBottomBlock); + }); + }); + } + + private generateBlocksContainConditionalOperatorGroup( + sourceStmts: Stmt[], + basicBlockSet: Set + ): { + generatedTopBlock: BasicBlock; + generatedBottomBlocks: BasicBlock[]; + } { + const { firstEndPos: firstEndPos } = this.findFirstConditionalOperator(sourceStmts); + if (firstEndPos === -1) { + return this.generateBlockWithoutConditionalOperator(sourceStmts); + } + const { + generatedTopBlock: firstGeneratedTopBlock, + generatedBottomBlocks: firstGeneratedBottomBlocks, + generatedAllBlocks: firstGeneratedAllBlocks, + } = this.generateBlocksContainSingleConditionalOperator(sourceStmts.slice(0, firstEndPos + 1)); + const generatedTopBlock = firstGeneratedTopBlock; + let generatedBottomBlocks = firstGeneratedBottomBlocks; + firstGeneratedAllBlocks.forEach(block => basicBlockSet.add(block)); + const stmtsCnt = sourceStmts.length; + if (firstEndPos !== stmtsCnt - 1) { + // need handle other conditional operators + const { generatedTopBlock: restGeneratedTopBlock, generatedBottomBlocks: restGeneratedBottomBlocks } = + this.generateBlocksContainConditionalOperatorGroup(sourceStmts.slice(firstEndPos + 1, stmtsCnt), basicBlockSet); + firstGeneratedBottomBlocks.forEach(firstGeneratedBottomBlock => { + firstGeneratedBottomBlock.addSuccessorBlock(restGeneratedTopBlock); + restGeneratedTopBlock.addPredecessorBlock(firstGeneratedBottomBlock); + }); + restGeneratedBottomBlocks.forEach(block => basicBlockSet.add(block)); + this.removeUnnecessaryBlocksInConditionalOperator(restGeneratedTopBlock, basicBlockSet); + generatedBottomBlocks = restGeneratedBottomBlocks; + } + return { generatedTopBlock, generatedBottomBlocks }; + } + + private generateBlocksContainSingleConditionalOperator(sourceStmts: Stmt[]): { + generatedTopBlock: BasicBlock; + generatedBottomBlocks: BasicBlock[]; + generatedAllBlocks: BasicBlock[]; + } { + const { firstIfTruePos: ifTruePos, firstIfFalsePos: ifFalsePos, firstEndPos: endPos } = this.findFirstConditionalOperator(sourceStmts); + if (endPos === -1) { + return this.generateBlockWithoutConditionalOperator(sourceStmts); + } + const { generatedTopBlock: generatedTopBlock, generatedAllBlocks: generatedAllBlocks } = this.generateBlockWithoutConditionalOperator( + sourceStmts.slice(0, ifTruePos) + ); + let generatedBottomBlocks: BasicBlock[] = []; + const { + generatedTopBlock: generatedTopBlockOfTrueBranch, + generatedBottomBlocks: generatedBottomBlocksOfTrueBranch, + generatedAllBlocks: generatedAllBlocksOfTrueBranch, + } = this.generateBlocksContainSingleConditionalOperator(sourceStmts.slice(ifTruePos + 1, ifFalsePos)); + generatedBottomBlocks.push(...generatedBottomBlocksOfTrueBranch); + generatedAllBlocks.push(...generatedAllBlocksOfTrueBranch); + const { + generatedTopBlock: generatedTopBlockOfFalseBranch, + generatedBottomBlocks: generatedBottomBlocksOfFalseBranch, + generatedAllBlocks: generatedAllBlocksOfFalseBranch, + } = this.generateBlocksContainSingleConditionalOperator(sourceStmts.slice(ifFalsePos + 1, endPos)); + generatedBottomBlocks.push(...generatedBottomBlocksOfFalseBranch); + generatedAllBlocks.push(...generatedAllBlocksOfFalseBranch); + + generatedTopBlock.addSuccessorBlock(generatedTopBlockOfTrueBranch); + generatedTopBlockOfTrueBranch.addPredecessorBlock(generatedTopBlock); + generatedTopBlock.addSuccessorBlock(generatedTopBlockOfFalseBranch); + generatedTopBlockOfFalseBranch.addPredecessorBlock(generatedTopBlock); + const stmtsCnt = sourceStmts.length; + if (endPos !== stmtsCnt - 1) { + // need create a new basic block for rest statements + const { generatedTopBlock: extraBlock } = this.generateBlockWithoutConditionalOperator(sourceStmts.slice(endPos + 1)); + generatedBottomBlocks.forEach(generatedBottomBlock => { + generatedBottomBlock.addSuccessorBlock(extraBlock); + extraBlock.addPredecessorBlock(generatedBottomBlock); + }); + generatedBottomBlocks = [extraBlock]; + generatedAllBlocks.push(extraBlock); + } + return { generatedTopBlock, generatedBottomBlocks, generatedAllBlocks }; + } + + private generateBlockWithoutConditionalOperator(sourceStmts: Stmt[]): { + generatedTopBlock: BasicBlock; + generatedBottomBlocks: BasicBlock[]; + generatedAllBlocks: BasicBlock[]; + } { + const generatedBlock = new BasicBlock(); + sourceStmts.forEach(stmt => generatedBlock.addStmt(stmt)); + return { + generatedTopBlock: generatedBlock, + generatedBottomBlocks: [generatedBlock], + generatedAllBlocks: [generatedBlock], + }; + } + + private deleteDummyConditionalOperatorStmt(basicBlockSet: Set): void { + for (const basicBlock of basicBlockSet) { + const stmts = Array.from(basicBlock.getStmts()); + for (const stmt of stmts) { + if (stmt instanceof DummyStmt && stmt.toString()?.startsWith(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR)) { + basicBlock.remove(stmt); + } + } + } + } + + private findFirstConditionalOperator(stmts: Stmt[]): { + firstIfTruePos: number; + firstIfFalsePos: number; + firstEndPos: number; + } { + let firstIfTruePos = -1; + let firstIfFalsePos = -1; + let firstEndPos = -1; + let firstConditionalOperatorNo = ''; + for (let i = 0; i < stmts.length; i++) { + const stmt = stmts[i]; + if (stmt instanceof DummyStmt) { + if (stmt.toString().startsWith(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT) && firstIfTruePos === -1) { + firstIfTruePos = i; + firstConditionalOperatorNo = stmt.toString().replace(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT, ''); + } else if (stmt.toString() === ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT + firstConditionalOperatorNo) { + firstIfFalsePos = i; + } else if (stmt.toString() === ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT + firstConditionalOperatorNo) { + firstEndPos = i; + } + } + } + return { firstIfTruePos, firstIfFalsePos, firstEndPos }; + } + + private removeUnnecessaryBlocksInConditionalOperator(bottomBlock: BasicBlock, allBlocks: Set): BasicBlock[] { + const firstStmtInBottom = bottomBlock.getStmts()[0]; + if (!(firstStmtInBottom instanceof ArkAssignStmt)) { + return [bottomBlock]; + } + + const targetValue = firstStmtInBottom.getLeftOp(); + const tempResultValue = firstStmtInBottom.getRightOp(); + if (!(targetValue instanceof Local && IRUtils.isTempLocal(tempResultValue))) { + return [bottomBlock]; + } + const oldPredecessors = Array.from(bottomBlock.getPredecessors()); + const newPredecessors: BasicBlock[] = []; + for (const predecessor of oldPredecessors) { + predecessor.removeSuccessorBlock(bottomBlock); + newPredecessors.push(...this.replaceTempRecursively(predecessor, targetValue as Local, tempResultValue as Local, allBlocks)); + } + + bottomBlock.remove(firstStmtInBottom); + if (bottomBlock.getStmts().length === 0) { + // must be a new block without successors + allBlocks.delete(bottomBlock); + return newPredecessors; + } + + oldPredecessors.forEach(oldPredecessor => { + bottomBlock.removePredecessorBlock(oldPredecessor); + }); + newPredecessors.forEach(newPredecessor => { + bottomBlock.addPredecessorBlock(newPredecessor); + newPredecessor.addSuccessorBlock(bottomBlock); + }); + return [bottomBlock]; + } + + private replaceTempRecursively(currBottomBlock: BasicBlock, targetLocal: Local, tempResultLocal: Local, allBlocks: Set): BasicBlock[] { + const stmts = currBottomBlock.getStmts(); + const stmtsCnt = stmts.length; + let tempResultReassignStmt: Stmt | null = null; + for (let i = stmtsCnt - 1; i >= 0; i--) { + const stmt = stmts[i]; + if (stmt instanceof ArkAssignStmt && stmt.getLeftOp() === tempResultLocal) { + if (IRUtils.isTempLocal(stmt.getRightOp())) { + tempResultReassignStmt = stmt; + } else { + stmt.setLeftOp(targetLocal); + } + } + } + + let newBottomBlocks: BasicBlock[] = []; + if (tempResultReassignStmt) { + const oldPredecessors = currBottomBlock.getPredecessors(); + const newPredecessors: BasicBlock[] = []; + const prevTempResultLocal = (tempResultReassignStmt as ArkAssignStmt).getRightOp() as Local; + for (const predecessor of oldPredecessors) { + predecessor.removeSuccessorBlock(currBottomBlock); + newPredecessors.push(...this.replaceTempRecursively(predecessor, targetLocal, prevTempResultLocal, allBlocks)); + } + + currBottomBlock.remove(tempResultReassignStmt); + if (currBottomBlock.getStmts().length === 0) { + // remove this block + newBottomBlocks = newPredecessors; + allBlocks.delete(currBottomBlock); + } else { + currBottomBlock.getPredecessors().splice(0, oldPredecessors.length, ...newPredecessors); + newPredecessors.forEach(newPredecessor => { + newPredecessor.addSuccessorBlock(currBottomBlock); + }); + newBottomBlocks = [currBottomBlock]; + } + } else { + newBottomBlocks = [currBottomBlock]; + } + return newBottomBlocks; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/LoopBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/LoopBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..f082fe773aabcb56931dc677b0390b2093d9ba3b --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/LoopBuilder.ts @@ -0,0 +1,392 @@ +/* + * 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 { BasicBlock } from '../BasicBlock'; +import { ArkAssignStmt, ArkIfStmt, Stmt } from '../../base/Stmt'; +import { AbstractInvokeExpr } from '../../base/Expr'; +import { Builtin } from '../../common/Builtin'; +import { ArkIRTransformer } from '../../common/ArkIRTransformer'; +import { BlockBuilder } from './CfgBuilder'; + +/** + * Builder for loop in CFG + */ +export class LoopBuilder { + public rebuildBlocksInLoop( + blockBuilderToCfgBlock: Map, + blocksContainLoopCondition: Set, + basicBlockSet: Set, + blockBuilders: BlockBuilder[] + ): void { + for (const blockBuilder of blocksContainLoopCondition) { + if (!blockBuilderToCfgBlock.get(blockBuilder)) { + continue; + } + const block = blockBuilderToCfgBlock.get(blockBuilder) as BasicBlock; + + const blockId = block.getId(); + const stmts = block.getStmts(); + const stmtsCnt = stmts.length; + const { ifStmtIdx, iteratorNextStmtIdx, dummyInitializerStmtIdx } = this.findIteratorIdx(stmts); + if (iteratorNextStmtIdx !== -1 || dummyInitializerStmtIdx !== -1) { + const lastStmtIdxBeforeCondition = iteratorNextStmtIdx !== -1 ? iteratorNextStmtIdx : dummyInitializerStmtIdx; + const stmtsInsertBeforeCondition = stmts.slice(0, lastStmtIdxBeforeCondition); + + // If the loop body is empty, the loop conditional block should contain its own + const emptyLoopBody = blockBuilder.nexts.length === 1; + if (emptyLoopBody) { + blockBuilder.nexts.splice(0, 0, blockBuilder); + blockBuilder.lasts.push(blockBuilder); + block.getSuccessors().splice(0, 0, block); + block.addPredecessorBlock(block); + } + + let prevBlockBuilderContainsLoop = this.doesPrevBlockBuilderContainLoop(blockBuilder, blockId, blocksContainLoopCondition); + if (prevBlockBuilderContainsLoop) { + // should create an extra block when previous block contains loop condition + this.insertBeforeConditionBlockBuilder( + blockBuilderToCfgBlock, + blockBuilder, + stmtsInsertBeforeCondition, + false, + basicBlockSet, + blockBuilders + ); + } else { + const blockBuilderBeforeCondition = blockBuilder.lasts[0]; + const blockBeforeCondition = blockBuilderToCfgBlock.get(blockBuilderBeforeCondition) as BasicBlock; + stmtsInsertBeforeCondition.forEach(stmt => blockBeforeCondition?.getStmts().push(stmt)); + } + if (dummyInitializerStmtIdx !== -1 && ifStmtIdx !== stmtsCnt - 1) { + // put incrementor statements into block which reenters condition + this.adjustIncrementorStmts( + stmts, + ifStmtIdx, + blockBuilder, + blockId, + blockBuilderToCfgBlock, + blocksContainLoopCondition, + basicBlockSet, + emptyLoopBody, + blockBuilders + ); + } else if (iteratorNextStmtIdx !== -1) { + // put statements which get value of iterator into block after condition + const blockBuilderAfterCondition = blockBuilder.nexts[0]; + const blockAfterCondition = blockBuilderToCfgBlock.get(blockBuilderAfterCondition) as BasicBlock; + const stmtsAfterCondition = stmts.slice(ifStmtIdx + 1); + blockAfterCondition?.getStmts().splice(0, 0, ...stmtsAfterCondition); + } + // remove statements which should not in condition + const firstStmtIdxInCondition = iteratorNextStmtIdx !== -1 ? iteratorNextStmtIdx : dummyInitializerStmtIdx + 1; + stmts.splice(0, firstStmtIdxInCondition); + stmts.splice(ifStmtIdx - firstStmtIdxInCondition + 1); + } + } + } + + private doesPrevBlockBuilderContainLoop(currBlockBuilder: BlockBuilder, currBlockId: number, blocksContainLoopCondition: Set): boolean { + let prevBlockBuilderContainsLoop = false; + for (const prevBlockBuilder of currBlockBuilder.lasts) { + if (prevBlockBuilder.id < currBlockId && blocksContainLoopCondition.has(prevBlockBuilder)) { + prevBlockBuilderContainsLoop = true; + break; + } + } + return prevBlockBuilderContainsLoop; + } + + private insertBeforeConditionBlockBuilder( + blockBuilderToCfgBlock: Map, + conditionBlockBuilder: BlockBuilder, + stmtsInsertBeforeCondition: Stmt[], + collectReenter: Boolean, + basicBlockSet: Set, + blockBuilders: BlockBuilder[] + ): void { + if (stmtsInsertBeforeCondition.length === 0) { + return; + } + const blockId = conditionBlockBuilder.id; + const block = this.getBlockFromMap(blockBuilderToCfgBlock, conditionBlockBuilder); + const { blockBuildersBeforeCondition, blocksBeforeCondition, blockBuildersReenterCondition, blocksReenterCondition } = + this.collectBlocksBeforeAndReenter(blockBuilderToCfgBlock, conditionBlockBuilder, blockId); + + const { collectedBlockBuilders, collectedBlocks } = this.getCollectedBlocks( + collectReenter, + blockBuildersBeforeCondition, + blocksBeforeCondition, + blockBuildersReenterCondition, + blocksReenterCondition + ); + + const { blockBuilderInsertBeforeCondition, blockInsertBeforeCondition } = this.createAndLinkBlocks( + collectedBlockBuilders, + collectedBlocks, + conditionBlockBuilder, + stmtsInsertBeforeCondition, + block + ); + + this.updatePredecessors( + collectedBlockBuilders, + blockBuilderToCfgBlock, + conditionBlockBuilder, + blockBuilderInsertBeforeCondition, + blockInsertBeforeCondition + ); + + const { newPrevBlockBuildersBeforeCondition, newPrevBlocksBeforeCondition } = this.getNewPrevBlocks( + collectReenter, + blockBuildersBeforeCondition, + blocksBeforeCondition, + blockBuilderInsertBeforeCondition, + blockInsertBeforeCondition, + blockBuildersReenterCondition, + blocksReenterCondition + ); + + this.updateConditionBlockBuilder(conditionBlockBuilder, newPrevBlockBuildersBeforeCondition, block, newPrevBlocksBeforeCondition); + + this.finalizeInsertion(blockBuilderInsertBeforeCondition, blockInsertBeforeCondition, basicBlockSet, blockBuilderToCfgBlock, blockBuilders); + } + + private getBlockFromMap(blockBuilderToCfgBlock: Map, conditionBlockBuilder: BlockBuilder): BasicBlock { + return blockBuilderToCfgBlock.get(conditionBlockBuilder) as BasicBlock; + } + + private collectBlocksBeforeAndReenter( + blockBuilderToCfgBlock: Map, + conditionBlockBuilder: BlockBuilder, + blockId: number + ): { + blockBuildersBeforeCondition: BlockBuilder[]; + blocksBeforeCondition: BasicBlock[]; + blockBuildersReenterCondition: BlockBuilder[]; + blocksReenterCondition: BasicBlock[]; + } { + const blockBuildersBeforeCondition: BlockBuilder[] = []; + const blocksBeforeCondition: BasicBlock[] = []; + const blockBuildersReenterCondition: BlockBuilder[] = []; + const blocksReenterCondition: BasicBlock[] = []; + for (const prevBlockBuilder of conditionBlockBuilder.lasts) { + const prevBlock = blockBuilderToCfgBlock.get(prevBlockBuilder) as BasicBlock; + if (prevBlock.getId() < blockId) { + blockBuildersBeforeCondition.push(prevBlockBuilder); + blocksBeforeCondition.push(prevBlock); + } else { + blockBuildersReenterCondition.push(prevBlockBuilder); + blocksReenterCondition.push(prevBlock); + } + } + return { + blockBuildersBeforeCondition, + blocksBeforeCondition, + blockBuildersReenterCondition, + blocksReenterCondition, + }; + } + + private getCollectedBlocks( + collectReenter: Boolean, + blockBuildersBeforeCondition: BlockBuilder[], + blocksBeforeCondition: BasicBlock[], + blockBuildersReenterCondition: BlockBuilder[], + blocksReenterCondition: BasicBlock[] + ): { collectedBlockBuilders: BlockBuilder[]; collectedBlocks: BasicBlock[] } { + let collectedBlockBuilders: BlockBuilder[] = []; + let collectedBlocks: BasicBlock[] = []; + if (collectReenter) { + collectedBlockBuilders = blockBuildersReenterCondition; + collectedBlocks = blocksReenterCondition; + } else { + collectedBlockBuilders = blockBuildersBeforeCondition; + collectedBlocks = blocksBeforeCondition; + } + return { collectedBlockBuilders, collectedBlocks }; + } + + private createAndLinkBlocks( + collectedBlockBuilders: BlockBuilder[], + collectedBlocks: BasicBlock[], + conditionBlockBuilder: BlockBuilder, + stmtsInsertBeforeCondition: Stmt[], + block: BasicBlock + ): { + blockBuilderInsertBeforeCondition: BlockBuilder; + blockInsertBeforeCondition: BasicBlock; + } { + const blockBuilderInsertBeforeCondition = new BlockBuilder(-1, []); + blockBuilderInsertBeforeCondition.lasts.push(...collectedBlockBuilders); + blockBuilderInsertBeforeCondition.nexts.push(conditionBlockBuilder); + const blockInsertBeforeCondition = new BasicBlock(); + stmtsInsertBeforeCondition.forEach(stmt => blockInsertBeforeCondition.getStmts().push(stmt)); + blockInsertBeforeCondition.getPredecessors().push(...collectedBlocks); + blockInsertBeforeCondition.addSuccessorBlock(block); + return { blockBuilderInsertBeforeCondition, blockInsertBeforeCondition }; + } + + private updatePredecessors( + collectedBlockBuilders: BlockBuilder[], + blockBuilderToCfgBlock: Map, + conditionBlockBuilder: BlockBuilder, + blockBuilderInsertBeforeCondition: BlockBuilder, + blockInsertBeforeCondition: BasicBlock + ): void { + for (const prevBlockBuilder of collectedBlockBuilders) { + const prevBlock = blockBuilderToCfgBlock.get(prevBlockBuilder) as BasicBlock; + for (let j = 0; j < prevBlockBuilder.nexts.length; j++) { + if (prevBlockBuilder.nexts[j] === conditionBlockBuilder) { + prevBlockBuilder.nexts[j] = blockBuilderInsertBeforeCondition; + prevBlock.setSuccessorBlock(j, blockInsertBeforeCondition); + break; + } + } + } + } + + private getNewPrevBlocks( + collectReenter: Boolean, + blockBuildersBeforeCondition: BlockBuilder[], + blocksBeforeCondition: BasicBlock[], + blockBuilderInsertBeforeCondition: BlockBuilder, + blockInsertBeforeCondition: BasicBlock, + blockBuildersReenterCondition: BlockBuilder[], + blocksReenterCondition: BasicBlock[] + ): { + newPrevBlockBuildersBeforeCondition: BlockBuilder[]; + newPrevBlocksBeforeCondition: BasicBlock[]; + } { + let newPrevBlockBuildersBeforeCondition: BlockBuilder[] = []; + let newPrevBlocksBeforeCondition: BasicBlock[] = []; + if (collectReenter) { + newPrevBlockBuildersBeforeCondition = [...blockBuildersBeforeCondition, blockBuilderInsertBeforeCondition]; + newPrevBlocksBeforeCondition = [...blocksBeforeCondition, blockInsertBeforeCondition]; + } else { + newPrevBlockBuildersBeforeCondition = [blockBuilderInsertBeforeCondition, ...blockBuildersReenterCondition]; + newPrevBlocksBeforeCondition = [blockInsertBeforeCondition, ...blocksReenterCondition]; + } + return { + newPrevBlockBuildersBeforeCondition, + newPrevBlocksBeforeCondition, + }; + } + + private updateConditionBlockBuilder( + conditionBlockBuilder: BlockBuilder, + newPrevBlockBuildersBeforeCondition: BlockBuilder[], + block: BasicBlock, + newPrevBlocksBeforeCondition: BasicBlock[] + ): void { + conditionBlockBuilder.lasts = newPrevBlockBuildersBeforeCondition; + const predecessorsCnt = block.getPredecessors().length; + block.getPredecessors().splice(0, predecessorsCnt, ...newPrevBlocksBeforeCondition); + } + + private finalizeInsertion( + blockBuilderInsertBeforeCondition: BlockBuilder, + blockInsertBeforeCondition: BasicBlock, + basicBlockSet: Set, + blockBuilderToCfgBlock: Map, + blockBuilders: BlockBuilder[] + ): void { + blockBuilders.push(blockBuilderInsertBeforeCondition); + basicBlockSet.add(blockInsertBeforeCondition); + blockBuilderToCfgBlock.set(blockBuilderInsertBeforeCondition, blockInsertBeforeCondition); + } + + private findIteratorIdx(stmts: Stmt[]): { + ifStmtIdx: number; + iteratorNextStmtIdx: number; + dummyInitializerStmtIdx: number; + } { + let ifStmtIdx = -1; + let iteratorNextStmtIdx = -1; + let dummyInitializerStmtIdx = -1; + const stmtsCnt = stmts.length; + for (let i = 0; i < stmtsCnt; i++) { + const stmt = stmts[i]; + if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof AbstractInvokeExpr) { + const invokeExpr = stmt.getRightOp() as AbstractInvokeExpr; + if (invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName() === Builtin.ITERATOR_NEXT) { + iteratorNextStmtIdx = i; + continue; + } + } + if (stmt.toString() === ArkIRTransformer.DUMMY_LOOP_INITIALIZER_STMT) { + dummyInitializerStmtIdx = i; + continue; + } + if (stmt instanceof ArkIfStmt) { + ifStmtIdx = i; + break; + } + } + return { + ifStmtIdx: ifStmtIdx, + iteratorNextStmtIdx: iteratorNextStmtIdx, + dummyInitializerStmtIdx: dummyInitializerStmtIdx, + }; + } + + private adjustIncrementorStmts( + stmts: Stmt[], + ifStmtIdx: number, + currBlockBuilder: BlockBuilder, + currBlockId: number, + blockBuilderToCfgBlock: Map, + blocksContainLoopCondition: Set, + basicBlockSet: Set, + emptyLoopBody: boolean, + blockBuilders: BlockBuilder[] + ): void { + const stmtsReenterCondition = stmts.slice(ifStmtIdx + 1); + if (emptyLoopBody) { + const incrementorBlockBuilder = new BlockBuilder(-1, []); + incrementorBlockBuilder.lasts.push(currBlockBuilder); + currBlockBuilder.nexts[0] = incrementorBlockBuilder; + incrementorBlockBuilder.nexts.push(currBlockBuilder); + currBlockBuilder.lasts[1] = incrementorBlockBuilder; + const incrementorBlock = new BasicBlock(); + blockBuilderToCfgBlock.set(incrementorBlockBuilder, incrementorBlock); + stmtsReenterCondition.forEach(stmt => incrementorBlock.getStmts().push(stmt)); + const currBlock = blockBuilderToCfgBlock.get(currBlockBuilder) as BasicBlock; + incrementorBlock.getPredecessors().push(currBlock); + currBlock.setPredecessorBlock(1, incrementorBlock); + incrementorBlock.addSuccessorBlock(currBlock); + currBlock.setSuccessorBlock(0, incrementorBlock); + basicBlockSet.add(incrementorBlock); + return; + } + + const blockBuildersReenterCondition: BlockBuilder[] = []; + for (const prevBlockBuilder of currBlockBuilder.lasts) { + const prevBlock = blockBuilderToCfgBlock.get(prevBlockBuilder) as BasicBlock; + + if (prevBlock.getId() > currBlockId) { + blockBuildersReenterCondition.push(prevBlockBuilder); + } + } + + if (blockBuildersReenterCondition.length > 1 || blocksContainLoopCondition.has(blockBuildersReenterCondition[0])) { + // put incrementor statements into an extra block + this.insertBeforeConditionBlockBuilder(blockBuilderToCfgBlock, currBlockBuilder, stmtsReenterCondition, true, basicBlockSet, blockBuilders); + } else { + // put incrementor statements into prev reenter block + const blockReenterCondition = blockBuilderToCfgBlock.get(blockBuildersReenterCondition[0]) as BasicBlock; + stmtsReenterCondition.forEach(stmt => blockReenterCondition?.getStmts().push(stmt)); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/SwitchBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/SwitchBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..3fa74eacf9467ab50c7900424be90e8274b8c3a2 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/SwitchBuilder.ts @@ -0,0 +1,167 @@ +/* + * 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 { BasicBlock } from '../BasicBlock'; +import { ArkIRTransformer, ValueAndStmts } from '../../common/ArkIRTransformer'; +import { Stmt } from '../../base/Stmt'; +import { BlockBuilder, SwitchStatementBuilder } from './CfgBuilder'; +import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'SwitchBuilder'); + +/** + * Builder for switch statement in CFG + */ +export class SwitchBuilder { + public buildSwitch( + blockBuilderToCfgBlock: Map, + blockBuildersContainSwitch: BlockBuilder[], + valueAndStmtsOfSwitchAndCasesAll: ValueAndStmts[][], + arkIRTransformer: ArkIRTransformer, + basicBlockSet: Set + ): void { + for (let i = 0; i < blockBuildersContainSwitch.length; i++) { + const blockBuilderContainSwitch = blockBuildersContainSwitch[i]; + + if (!blockBuilderToCfgBlock.has(blockBuilderContainSwitch)) { + logger.error(`can't find basicBlock corresponding to the blockBuilder.`); + continue; + } + + const blockContainSwitch = blockBuilderToCfgBlock.get(blockBuilderContainSwitch)!; + const valueAndStmtsOfSwitch = valueAndStmtsOfSwitchAndCasesAll[i][0]; + const stmtsOfSwitch = valueAndStmtsOfSwitch.stmts; + stmtsOfSwitch.forEach((stmt: Stmt) => { + blockContainSwitch.addStmt(stmt); + }); + + const stmtsCnt = blockBuilderContainSwitch.stmts.length; + const switchStmtBuilder = blockBuilderContainSwitch.stmts[stmtsCnt - 1] as SwitchStatementBuilder; + const cases = switchStmtBuilder.cases; + let nonEmptyCaseCnt = 0; + for (const currCase of cases) { + if (currCase.stmt.block) { + // there are stmts after this case + nonEmptyCaseCnt++; + } + } + if (nonEmptyCaseCnt === 0) { + continue; + } + + const caseCnt = cases.length; + const caseIfBlocks = this.generateIfBlocksForCases( + valueAndStmtsOfSwitchAndCasesAll[i], + caseCnt, + blockContainSwitch, + basicBlockSet, + arkIRTransformer + ); + this.linkIfBlockAndCaseBlock(blockContainSwitch, caseIfBlocks, switchStmtBuilder, blockBuilderToCfgBlock); + } + } + + private generateIfBlocksForCases( + valueAndStmtsOfSwitchAndCases: ValueAndStmts[], + caseCnt: number, + blockContainSwitch: BasicBlock, + basicBlockSet: Set, + arkIRTransformer: ArkIRTransformer + ): BasicBlock[] { + const valueAndStmtsOfSwitch = valueAndStmtsOfSwitchAndCases[0]; + const valueOfSwitch = valueAndStmtsOfSwitch.value; + const caseIfBlocks: BasicBlock[] = []; + + for (let j = 0; j < caseCnt; j++) { + let caseIfBlock: BasicBlock; + if (j === 0) { + caseIfBlock = blockContainSwitch; + } else { + caseIfBlock = new BasicBlock(); + basicBlockSet.add(caseIfBlock); + } + caseIfBlocks.push(caseIfBlock); + + const caseValueAndStmts = valueAndStmtsOfSwitchAndCases[j + 1]; + const caseValue = caseValueAndStmts.value; + const caseStmts = caseValueAndStmts.stmts; + caseStmts.forEach((stmt: Stmt) => { + caseIfBlock.addStmt(stmt); + }); + const caseIfStmts = arkIRTransformer.generateIfStmtForValues( + valueOfSwitch, + valueAndStmtsOfSwitch.valueOriginalPositions, + caseValue, + caseValueAndStmts.valueOriginalPositions + ); + caseIfStmts.forEach((stmt: Stmt) => { + caseIfBlock.addStmt(stmt); + }); + } + return caseIfBlocks; + } + + private linkIfBlockAndCaseBlock( + blockContainSwitch: BasicBlock, + caseIfBlocks: BasicBlock[], + switchStmtBuilder: SwitchStatementBuilder, + blockBuilderToCfgBlock: Map + ): boolean { + const successorsOfBlockContainSwitch = Array.from(blockContainSwitch.getSuccessors()); + const expectedSuccessorsOfCaseIfBlock: BasicBlock[] = []; + const defaultStmtBuilder = switchStmtBuilder.default; + if (defaultStmtBuilder && defaultStmtBuilder.block) { + expectedSuccessorsOfCaseIfBlock.push(...successorsOfBlockContainSwitch.splice(-1, 1)); + } else { + const afterSwitchStmtBuilder = switchStmtBuilder.afterSwitch; + const afterSwitchBlockBuilder = afterSwitchStmtBuilder?.block; + if (!afterSwitchBlockBuilder || !blockBuilderToCfgBlock.has(afterSwitchBlockBuilder)) { + logger.error(`can't find basicBlock corresponding to the blockBuilder.`); + return false; + } + expectedSuccessorsOfCaseIfBlock.push(blockBuilderToCfgBlock.get(afterSwitchBlockBuilder)!); + } + const caseCnt = switchStmtBuilder.cases.length; + for (let i = caseCnt - 1; i >= 0; i--) { + const currCase = switchStmtBuilder.cases[i]; + if (currCase.stmt.block) { + expectedSuccessorsOfCaseIfBlock.push(...successorsOfBlockContainSwitch.splice(-1, 1)); + } else { + // if there are no stmts after this case, reuse the successor of the next case + expectedSuccessorsOfCaseIfBlock.push(...expectedSuccessorsOfCaseIfBlock.slice(-1)); + } + } + expectedSuccessorsOfCaseIfBlock.reverse(); + + blockContainSwitch.getSuccessors().forEach(successor => { + successor.getPredecessors().splice(0, 1); + }); + blockContainSwitch.getSuccessors().splice(0); + for (let j = 0; j < caseCnt; j++) { + const caseIfBlock = caseIfBlocks[j]; + caseIfBlock.addSuccessorBlock(expectedSuccessorsOfCaseIfBlock[j]); + expectedSuccessorsOfCaseIfBlock[j].addPredecessorBlock(caseIfBlock); + if (j === caseCnt - 1) { + // the false branch of last case should be default or block after switch statement + caseIfBlock.addSuccessorBlock(expectedSuccessorsOfCaseIfBlock[j + 1]); + expectedSuccessorsOfCaseIfBlock[j + 1].addPredecessorBlock(caseIfBlock); + } else { + caseIfBlock.addSuccessorBlock(caseIfBlocks[j + 1]); + caseIfBlocks[j + 1].addPredecessorBlock(caseIfBlock); + } + } + return true; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/TrapBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/TrapBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..160df9fdc0420bd843f79edbbe7f43552c9e3699 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/TrapBuilder.ts @@ -0,0 +1,311 @@ +/* + * 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 { BasicBlock } from '../BasicBlock'; +import { ArkIRTransformer } from '../../common/ArkIRTransformer'; +import { Trap } from '../../base/Trap'; +import { ArkCaughtExceptionRef } from '../../base/Ref'; +import { UnknownType } from '../../base/Type'; +import { FullPosition } from '../../base/Position'; +import { ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, ArkThrowStmt, Stmt } from '../../base/Stmt'; +import { BlockBuilder, TryStatementBuilder } from './CfgBuilder'; +import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'TrapBuilder'); + +/** + * Builder for traps from try...catch + */ +export class TrapBuilder { + public buildTraps( + blockBuilderToCfgBlock: Map, + blockBuildersBeforeTry: Set, + arkIRTransformer: ArkIRTransformer, + basicBlockSet: Set + ): Trap[] { + const traps: Trap[] = []; + for (const blockBuilderBeforeTry of blockBuildersBeforeTry) { + if (blockBuilderBeforeTry.nexts.length === 0) { + logger.error(`can't find try block.`); + continue; + } + const blockBuilderContainTry = blockBuilderBeforeTry.nexts[0]; + const stmtsCnt = blockBuilderBeforeTry.stmts.length; + const tryStmtBuilder = blockBuilderBeforeTry.stmts[stmtsCnt - 1] as TryStatementBuilder; + const finallyBlockBuilder = tryStmtBuilder.finallyStatement?.block; + if (!finallyBlockBuilder) { + logger.error(`can't find finally block or dummy finally block.`); + continue; + } + const { bfsBlocks: tryBfsBlocks, tailBlocks: tryTailBlocks } = this.getAllBlocksBFS( + blockBuilderToCfgBlock, + blockBuilderContainTry, + finallyBlockBuilder + ); + let catchBfsBlocks: BasicBlock[] = []; + let catchTailBlocks: BasicBlock[] = []; + const catchBlockBuilder = tryStmtBuilder.catchStatement?.block; + if (catchBlockBuilder) { + ({ bfsBlocks: catchBfsBlocks, tailBlocks: catchTailBlocks } = this.getAllBlocksBFS(blockBuilderToCfgBlock, catchBlockBuilder)); + } + const finallyStmts = finallyBlockBuilder.stmts; + const blockBuilderAfterFinally = tryStmtBuilder.afterFinal?.block; + if (!blockBuilderAfterFinally) { + logger.error(`can't find block after try...catch.`); + continue; + } + if (finallyStmts.length === 1 && finallyStmts[0].code === 'dummyFinally') { + // no finally block + const trapsIfNoFinally = this.buildTrapsIfNoFinally( + tryBfsBlocks, + tryTailBlocks, + catchBfsBlocks, + catchTailBlocks, + finallyBlockBuilder, + blockBuilderAfterFinally, + basicBlockSet, + blockBuilderToCfgBlock + ); + if (trapsIfNoFinally) { + traps.push(...trapsIfNoFinally); + } + } else { + const trapsIfFinallyExist = this.buildTrapsIfFinallyExist( + tryBfsBlocks, + tryTailBlocks, + catchBfsBlocks, + catchTailBlocks, + finallyBlockBuilder, + blockBuilderAfterFinally, + basicBlockSet, + arkIRTransformer, + blockBuilderToCfgBlock + ); + traps.push(...trapsIfFinallyExist); + } + } + return traps; + } + + private buildTrapsIfNoFinally( + tryBfsBlocks: BasicBlock[], + tryTailBlocks: BasicBlock[], + catchBfsBlocks: BasicBlock[], + catchTailBlocks: BasicBlock[], + finallyBlockBuilder: BlockBuilder, + blockBuilderAfterFinally: BlockBuilder, + basicBlockSet: Set, + blockBuilderToCfgBlock: Map + ): Trap[] | null { + if (catchBfsBlocks.length === 0) { + logger.error(`catch block expected.`); + return null; + } + if (!blockBuilderToCfgBlock.has(blockBuilderAfterFinally)) { + logger.error(`can't find basicBlock corresponding to the blockBuilder.`); + return null; + } + let blockAfterFinally: BasicBlock = blockBuilderToCfgBlock.get(blockBuilderAfterFinally)!; + if (!blockBuilderToCfgBlock.has(finallyBlockBuilder)) { + logger.error(`can't find basicBlock corresponding to the blockBuilder.`); + return null; + } + const finallyBlock = blockBuilderToCfgBlock.get(finallyBlockBuilder)!; + let dummyFinallyIdxInPredecessors = -1; + for (let i = 0; i < blockAfterFinally.getPredecessors().length; i++) { + if (blockAfterFinally.getPredecessors()[i] === finallyBlock) { + dummyFinallyIdxInPredecessors = i; + break; + } + } + if (dummyFinallyIdxInPredecessors === -1) { + return null; + } + blockAfterFinally.getPredecessors().splice(dummyFinallyIdxInPredecessors, 1); + for (const tryTailBlock of tryTailBlocks) { + tryTailBlock.setSuccessorBlock(0, blockAfterFinally); + blockAfterFinally.addPredecessorBlock(tryTailBlock); + } + basicBlockSet.delete(finallyBlock); + + for (const catchTailBlock of catchTailBlocks) { + catchTailBlock.addSuccessorBlock(blockAfterFinally); + blockAfterFinally.addPredecessorBlock(catchTailBlock); + } + for (const tryTailBlock of tryTailBlocks) { + tryTailBlock.addExceptionalSuccessorBlock(catchBfsBlocks[0]); + } + return [new Trap(tryBfsBlocks, catchBfsBlocks)]; + } + + private buildTrapsIfFinallyExist( + tryBfsBlocks: BasicBlock[], + tryTailBlocks: BasicBlock[], + catchBfsBlocks: BasicBlock[], + catchTailBlocks: BasicBlock[], + finallyBlockBuilder: BlockBuilder, + blockBuilderAfterFinally: BlockBuilder, + basicBlockSet: Set, + arkIRTransformer: ArkIRTransformer, + blockBuilderToCfgBlock: Map + ): Trap[] { + const { bfsBlocks: finallyBfsBlocks, tailBlocks: finallyTailBlocks } = this.getAllBlocksBFS( + blockBuilderToCfgBlock, + finallyBlockBuilder, + blockBuilderAfterFinally + ); + const copyFinallyBfsBlocks = this.copyFinallyBlocks(finallyBfsBlocks, finallyTailBlocks, basicBlockSet, arkIRTransformer, blockBuilderToCfgBlock); + const traps: Trap[] = []; + if (catchBfsBlocks.length !== 0) { + for (const catchTailBlock of catchTailBlocks) { + catchTailBlock.addSuccessorBlock(finallyBfsBlocks[0]); + finallyBfsBlocks[0].addPredecessorBlock(catchTailBlock); + } + // try -> catch trap + for (const tryTailBlock of tryTailBlocks) { + tryTailBlock.addExceptionalSuccessorBlock(catchBfsBlocks[0]); + } + traps.push(new Trap(tryBfsBlocks, catchBfsBlocks)); + // catch -> finally trap + for (const catchTailBlock of catchTailBlocks) { + catchTailBlock.addExceptionalSuccessorBlock(copyFinallyBfsBlocks[0]); + } + traps.push(new Trap(catchBfsBlocks, copyFinallyBfsBlocks)); + } else { + // try -> finally trap + for (const tryTailBlock of tryTailBlocks) { + tryTailBlock.addExceptionalSuccessorBlock(copyFinallyBfsBlocks[0]); + } + traps.push(new Trap(tryBfsBlocks, copyFinallyBfsBlocks)); + } + return traps; + } + + private getAllBlocksBFS( + blockBuilderToCfgBlock: Map, + startBlockBuilder: BlockBuilder, + endBlockBuilder?: BlockBuilder + ): { bfsBlocks: BasicBlock[]; tailBlocks: BasicBlock[] } { + const bfsBlocks: BasicBlock[] = []; + const tailBlocks: BasicBlock[] = []; + const queue: BlockBuilder[] = []; + const visitedBlockBuilders = new Set(); + queue.push(startBlockBuilder); + while (queue.length !== 0) { + const currBlockBuilder = queue.splice(0, 1)[0]; + if (visitedBlockBuilders.has(currBlockBuilder)) { + continue; + } + visitedBlockBuilders.add(currBlockBuilder); + if (!blockBuilderToCfgBlock.has(currBlockBuilder)) { + logger.error(`can't find basicBlock corresponding to the blockBuilder.`); + continue; + } + const currBlock = blockBuilderToCfgBlock.get(currBlockBuilder)!; + bfsBlocks.push(currBlock); + + const childList = currBlockBuilder.nexts; + if (childList.length === 0 || (childList.length !== 0 && childList[0] === endBlockBuilder)) { + if (childList[0] === endBlockBuilder) { + tailBlocks.push(currBlock); + continue; + } + } + if (childList.length !== 0) { + for (const child of childList) { + queue.push(child); + } + } + } + return { bfsBlocks, tailBlocks }; + } + + private copyFinallyBlocks( + finallyBfsBlocks: BasicBlock[], + finallyTailBlocks: BasicBlock[], + basicBlockSet: Set, + arkIRTransformer: ArkIRTransformer, + blockBuilderToCfgBlock: Map + ): BasicBlock[] { + const copyFinallyBfsBlocks = this.copyBlocks(finallyBfsBlocks); + const caughtExceptionRef = new ArkCaughtExceptionRef(UnknownType.getInstance()); + const { value: exceptionValue, stmts: exceptionAssignStmts } = arkIRTransformer.generateAssignStmtForValue(caughtExceptionRef, [FullPosition.DEFAULT]); + copyFinallyBfsBlocks[0].addHead(exceptionAssignStmts); + const finallyPredecessorsCnt = copyFinallyBfsBlocks[0].getPredecessors().length; + copyFinallyBfsBlocks[0].getPredecessors().splice(0, finallyPredecessorsCnt); + const throwStmt = new ArkThrowStmt(exceptionValue); + let copyFinallyTailBlocks = copyFinallyBfsBlocks.splice(copyFinallyBfsBlocks.length - finallyTailBlocks.length, finallyTailBlocks.length); + copyFinallyTailBlocks.forEach((copyFinallyTailBlock: BasicBlock) => { + const successorsCnt = copyFinallyTailBlock.getSuccessors().length; + copyFinallyTailBlock.getSuccessors().splice(0, successorsCnt); + }); + if (copyFinallyTailBlocks.length > 1) { + const newCopyFinallyTailBlock = new BasicBlock(); + copyFinallyTailBlocks.forEach((copyFinallyTailBlock: BasicBlock) => { + copyFinallyTailBlock.addSuccessorBlock(newCopyFinallyTailBlock); + newCopyFinallyTailBlock.addPredecessorBlock(copyFinallyTailBlock); + }); + copyFinallyTailBlocks = [newCopyFinallyTailBlock]; + } + copyFinallyTailBlocks[0]?.addStmt(throwStmt); + copyFinallyBfsBlocks.push(...copyFinallyTailBlocks); + copyFinallyBfsBlocks.forEach((copyFinallyBfsBlock: BasicBlock) => { + basicBlockSet.add(copyFinallyBfsBlock); + }); + return copyFinallyBfsBlocks; + } + + private copyBlocks(sourceBlocks: BasicBlock[]): BasicBlock[] { + const sourceToTarget = new Map(); + const targetBlocks: BasicBlock[] = []; + for (const sourceBlock of sourceBlocks) { + const targetBlock = new BasicBlock(); + for (const stmt of sourceBlock.getStmts()) { + targetBlock.addStmt(this.copyStmt(stmt)!); + } + sourceToTarget.set(sourceBlock, targetBlock); + targetBlocks.push(targetBlock); + } + for (const sourceBlock of sourceBlocks) { + const targetBlock = sourceToTarget.get(sourceBlock)!; + for (const predecessor of sourceBlock.getPredecessors()) { + const targetPredecessor = sourceToTarget.get(predecessor)!; + targetBlock.addPredecessorBlock(targetPredecessor); + } + for (const successor of sourceBlock.getSuccessors()) { + const targetSuccessor = sourceToTarget.get(successor)!; + targetBlock.addSuccessorBlock(targetSuccessor); + } + } + return targetBlocks; + } + + private copyStmt(sourceStmt: Stmt): Stmt | null { + if (sourceStmt instanceof ArkAssignStmt) { + return new ArkAssignStmt(sourceStmt.getLeftOp(), sourceStmt.getRightOp()); + } else if (sourceStmt instanceof ArkInvokeStmt) { + return new ArkInvokeStmt(sourceStmt.getInvokeExpr()); + } else if (sourceStmt instanceof ArkIfStmt) { + return new ArkIfStmt(sourceStmt.getConditionExpr()); + } else if (sourceStmt instanceof ArkReturnStmt) { + return new ArkReturnStmt(sourceStmt.getOp()); + } else if (sourceStmt instanceof ArkReturnVoidStmt) { + return new ArkReturnVoidStmt(); + } else if (sourceStmt instanceof ArkThrowStmt) { + return new ArkThrowStmt(sourceStmt.getOp()); + } + return null; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/graph/builder/ViewTreeBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/graph/builder/ViewTreeBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..bf8482f4c9ce1f780577f0e20ba4f495067668ad --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/graph/builder/ViewTreeBuilder.ts @@ -0,0 +1,1228 @@ +/* + * 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. + */ + +import { Constant } from '../../base/Constant'; +import { Decorator } from '../../base/Decorator'; +import { + AbstractInvokeExpr, + ArkConditionExpr, + ArkInstanceInvokeExpr, + ArkNewExpr, + ArkNormalBinopExpr, + ArkPtrInvokeExpr, + ArkStaticInvokeExpr, +} from '../../base/Expr'; +import { Local } from '../../base/Local'; +import { ArkArrayRef, ArkInstanceFieldRef, ArkThisRef } from '../../base/Ref'; +import { ArkAssignStmt, ArkInvokeStmt, Stmt } from '../../base/Stmt'; +import { ClassType, FunctionType, Type } from '../../base/Type'; +import { Value } from '../../base/Value'; +import { + BUILDER_DECORATOR, + BUILDER_PARAM_DECORATOR, + COMPONENT_BRANCH_FUNCTION, + COMPONENT_CREATE_FUNCTION, + COMPONENT_CUSTOMVIEW, + COMPONENT_FOR_EACH, + COMPONENT_IF, + COMPONENT_IF_BRANCH, + COMPONENT_LAZY_FOR_EACH, + COMPONENT_POP_FUNCTION, + COMPONENT_REPEAT, + isEtsContainerComponent, + SPECIAL_CONTAINER_COMPONENT, +} from '../../common/EtsConst'; +import { ArkClass, ClassCategory } from '../../model/ArkClass'; +import { ArkField } from '../../model/ArkField'; +import { ArkMethod } from '../../model/ArkMethod'; +import { ClassSignature, MethodSignature } from '../../model/ArkSignature'; +import { Cfg } from '../Cfg'; +import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; +import { ViewTree, ViewTreeNode } from '../ViewTree'; +import { ModelUtils } from '../../common/ModelUtils'; +import { Scene } from '../../../Scene'; +import { TEMP_LOCAL_PREFIX } from '../../common/Const'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ViewTreeBuilder'); +const COMPONENT_CREATE_FUNCTIONS: Set = new Set([COMPONENT_CREATE_FUNCTION, COMPONENT_BRANCH_FUNCTION]); + +function backtraceLocalInitValue(value: Local): Local | Value { + let stmt = value.getDeclaringStmt(); + if (stmt instanceof ArkAssignStmt) { + let rightOp = stmt.getRightOp(); + if (rightOp instanceof Local) { + return backtraceLocalInitValue(rightOp); + } else if (rightOp instanceof ArkInstanceFieldRef && rightOp.getBase().getName().startsWith(TEMP_LOCAL_PREFIX)) { + return backtraceLocalInitValue(rightOp.getBase()); + } else if (rightOp instanceof ArkArrayRef) { + return backtraceLocalInitValue(rightOp.getBase()); + } + return rightOp; + } + return value; +} + +type ObjectLiteralMap = Map; + +function parseObjectLiteral(objectLiteralCls: ArkClass | null, scene: Scene): ObjectLiteralMap { + let map: ObjectLiteralMap = new Map(); + if (objectLiteralCls?.getCategory() !== ClassCategory.OBJECT) { + return map; + } + objectLiteralCls?.getFields().forEach(field => { + let stmts = field.getInitializer(); + if (stmts.length === 0) { + return; + } + + let assignStmt = stmts[stmts.length - 1]; + if (!(assignStmt instanceof ArkAssignStmt)) { + return; + } + + let value = assignStmt.getRightOp(); + if (value instanceof Local) { + value = backtraceLocalInitValue(value); + } + + map.set(field, value); + if (value instanceof ArkNewExpr) { + let subCls = ModelUtils.getArkClassInBuild(scene, value.getClassType()); + let childMap = parseObjectLiteral(subCls, scene); + if (childMap) { + map.set(field, childMap); + } + } + }); + + return map; +} + +class StateValuesUtils { + private declaringArkClass: ArkClass; + + constructor(declaringArkClass: ArkClass) { + this.declaringArkClass = declaringArkClass; + } + + public static getInstance(declaringArkClass: ArkClass): StateValuesUtils { + return new StateValuesUtils(declaringArkClass); + } + + public parseStmtUsesStateValues( + stmt: Stmt, + uses: Set = new Set(), + wholeMethod: boolean = false, + visitor: Set = new Set() + ): Set { + if (visitor.has(stmt)) { + return uses; + } + visitor.add(stmt); + let values = stmt.getUses(); + if (stmt instanceof ArkAssignStmt) { + values.push(stmt.getLeftOp()); + } + + for (const v of values) { + this.parseValueUsesStateValues(v, uses, wholeMethod, visitor); + } + return uses; + } + + private objectLiteralMapUsedStateValues(uses: Set, map: ObjectLiteralMap): void { + for (const [_, value] of map) { + if (value instanceof ArkInstanceFieldRef) { + let srcField = this.declaringArkClass.getFieldWithName(value.getFieldName()); + let decorators = srcField?.getStateDecorators(); + if (srcField && decorators && decorators.length > 0) { + uses.add(srcField); + } + } else if (value instanceof Map) { + this.objectLiteralMapUsedStateValues(uses, value); + } else if (value instanceof ArkNormalBinopExpr || value instanceof ArkConditionExpr) { + this.parseValueUsesStateValues(value.getOp1(), uses); + this.parseValueUsesStateValues(value.getOp2(), uses); + } + } + } + + public parseObjectUsedStateValues(type: Type, uses: Set = new Set()): Set { + if (!(type instanceof ClassType)) { + return uses; + } + let cls = ModelUtils.getArkClassInBuild(this.declaringArkClass.getDeclaringArkFile().getScene(), type); + let map = parseObjectLiteral(cls, this.declaringArkClass.getDeclaringArkFile().getScene()); + this.objectLiteralMapUsedStateValues(uses, map); + return uses; + } + + private parseMethodUsesStateValues(methodSignature: MethodSignature, uses: Set, visitor: Set = new Set()): void { + if (visitor.has(methodSignature)) { + return; + } + visitor.add(methodSignature); + let method = this.declaringArkClass.getDeclaringArkFile().getScene().getMethod(methodSignature); + if (!method) { + return; + } + let stmts = method.getCfg()?.getStmts(); + if (!stmts) { + return; + } + for (const stmt of stmts) { + this.parseStmtUsesStateValues(stmt, uses, true, visitor); + } + } + + private parseValueUsesStateValues( + v: Value, + uses: Set = new Set(), + wholeMethod: boolean = false, + visitor: Set = new Set() + ): Set { + if (v instanceof ArkInstanceFieldRef) { + let field = this.declaringArkClass.getField(v.getFieldSignature()); + let decorators = field?.getStateDecorators(); + if (field && decorators && decorators.length > 0) { + uses.add(field); + } + } else if (v instanceof ArkInstanceInvokeExpr) { + this.parseMethodUsesStateValues(v.getMethodSignature(), uses, visitor); + } else if (v instanceof Local) { + if (v.getName() === 'this') { + return uses; + } + let type = v.getType(); + if (type instanceof FunctionType) { + this.parseMethodUsesStateValues(type.getMethodSignature(), uses, visitor); + return uses; + } + this.parseObjectUsedStateValues(type, uses); + let declaringStmt = v.getDeclaringStmt(); + if (!wholeMethod && declaringStmt) { + this.parseStmtUsesStateValues(declaringStmt, uses, wholeMethod, visitor); + } + } + + return uses; + } +} + +enum ViewTreeNodeType { + SystemComponent, + CustomComponent, + Builder, + BuilderParam, +} + +class ViewTreeNodeImpl implements ViewTreeNode { + name: string; + stmts: Map; + attributes: Map; + stateValues: Set; + parent: ViewTreeNode | null; + children: ViewTreeNodeImpl[]; + classSignature?: MethodSignature | ClassSignature | undefined; + signature?: MethodSignature | ClassSignature | undefined; + stateValuesTransfer?: Map | undefined; + builderParam?: ArkField | undefined; + builder?: MethodSignature | undefined; + private type: ViewTreeNodeType; + + constructor(name: string) { + this.name = name; + this.attributes = new Map(); + this.stmts = this.attributes; + this.stateValues = new Set(); + this.parent = null; + this.children = []; + this.type = ViewTreeNodeType.SystemComponent; + } + + /** + * Whether the node type is Builder. + * @returns true: node is Builder, false others. + */ + public isBuilder(): boolean { + return this.type === ViewTreeNodeType.Builder; + } + + /** + * @internal + */ + public isBuilderParam(): boolean { + return this.type === ViewTreeNodeType.BuilderParam; + } + + /** + * Whether the node type is custom component. + * @returns true: node is custom component, false others. + */ + public isCustomComponent(): boolean { + return this.type === ViewTreeNodeType.CustomComponent; + } + + /** + * walk node and node's children + * @param selector Node selector function, return true skipping the follow-up nodes. + * @returns + * - true: There are nodes that meet the selector. + * - false: does not exist. + */ + public walk(selector: (item: ViewTreeNode) => boolean, visitor: Set = new Set()): boolean { + if (visitor.has(this)) { + return false; + } + + let ret: boolean = selector(this); + visitor.add(this); + + for (const child of this.children) { + ret = ret || child.walk(selector, visitor); + if (ret) { + break; + } + } + return ret; + } + + public static createCustomComponent(): ViewTreeNodeImpl { + let instance = new ViewTreeNodeImpl(COMPONENT_CUSTOMVIEW); + instance.type = ViewTreeNodeType.CustomComponent; + return instance; + } + + public static createBuilderNode(): ViewTreeNodeImpl { + let instance = new ViewTreeNodeImpl(BUILDER_DECORATOR); + instance.type = ViewTreeNodeType.Builder; + return instance; + } + + public static createBuilderParamNode(): ViewTreeNodeImpl { + let instance = new ViewTreeNodeImpl(BUILDER_PARAM_DECORATOR); + instance.type = ViewTreeNodeType.BuilderParam; + return instance; + } + + public changeBuilderParam2BuilderNode(builder: ArkMethod): void { + this.name = BUILDER_DECORATOR; + this.type = ViewTreeNodeType.Builder; + this.signature = builder.getSignature(); + this.classSignature = this.signature; + const root = builder.getViewTree()?.getRoot(); + if (root) { + for (let child of root.children) { + this.children.push(child as ViewTreeNodeImpl); + } + } else { + logger.error(`ViewTree->changeBuilderParam2BuilderNode ${builder.getSignature().toString()} @Builder viewtree fail.`); + } + } + + public hasBuilderParam(): boolean { + return this.walk(item => { + return (item as ViewTreeNodeImpl).isBuilderParam(); + }); + } + + public clone(parent: ViewTreeNodeImpl, map: Map = new Map()): ViewTreeNodeImpl { + let newNode = new ViewTreeNodeImpl(this.name); + newNode.attributes = this.attributes; + newNode.stmts = newNode.attributes; + newNode.stateValues = this.stateValues; + newNode.parent = parent; + newNode.type = this.type; + newNode.signature = this.signature; + newNode.classSignature = newNode.signature; + newNode.builderParam = this.builderParam; + newNode.builder = this.builder; + map.set(this, newNode); + + for (const child of this.children) { + if (map.has(child)) { + newNode.children.push(map.get(child)!); + } else { + newNode.children.push(child.clone(newNode, map)); + } + } + + return newNode; + } + + public addStmt(tree: ViewTreeImpl, stmt: Stmt): void { + this.parseAttributes(stmt); + if (this.name !== COMPONENT_FOR_EACH && this.name !== COMPONENT_LAZY_FOR_EACH) { + this.parseStateValues(tree, stmt); + } + } + + private parseAttributes(stmt: Stmt): void { + let expr: AbstractInvokeExpr | undefined; + if (stmt instanceof ArkAssignStmt) { + let op = stmt.getRightOp(); + if (op instanceof ArkInstanceInvokeExpr) { + expr = op; + } else if (op instanceof ArkStaticInvokeExpr) { + expr = op; + } + } else if (stmt instanceof ArkInvokeStmt) { + let invoke = stmt.getInvokeExpr(); + if (invoke instanceof ArkInstanceInvokeExpr) { + expr = invoke; + } else if (invoke instanceof ArkStaticInvokeExpr) { + expr = invoke; + } + } + if (expr) { + let key = expr.getMethodSignature().getMethodSubSignature().getMethodName(); + let relationValues: (Constant | ArkInstanceFieldRef | MethodSignature)[] = []; + for (const arg of expr.getArgs()) { + if (arg instanceof Local) { + this.getBindValues(arg, relationValues); + } else if (arg instanceof Constant) { + relationValues.push(arg); + } + } + this.attributes.set(key, [stmt, relationValues]); + } + } + + private getBindValues(local: Local, relationValues: (Constant | ArkInstanceFieldRef | MethodSignature)[], visitor: Set = new Set()): void { + if (visitor.has(local)) { + return; + } + visitor.add(local); + const stmt = local.getDeclaringStmt(); + if (!stmt) { + let type = local.getType(); + if (type instanceof FunctionType) { + relationValues.push(type.getMethodSignature()); + } + return; + } + for (const v of stmt.getUses()) { + if (v instanceof Constant) { + relationValues.push(v); + } else if (v instanceof ArkInstanceFieldRef) { + relationValues.push(v); + } else if (v instanceof Local) { + this.getBindValues(v, relationValues, visitor); + } + } + } + + public parseStateValues(tree: ViewTreeImpl, stmt: Stmt): void { + let stateValues: Set = StateValuesUtils.getInstance(tree.getDeclaringArkClass()).parseStmtUsesStateValues(stmt); + stateValues.forEach(field => { + this.stateValues.add(field); + tree.addStateValue(field, this); + }, this); + } +} + +class TreeNodeStack { + protected root: ViewTreeNodeImpl | null = null; + protected stack: ViewTreeNodeImpl[]; + + constructor() { + this.stack = []; + } + + /** + * @internal + */ + public push(node: ViewTreeNodeImpl): void { + let parent = this.getParent(); + node.parent = parent; + this.stack.push(node); + if (parent === null || parent === undefined) { + this.root = node; + } else { + parent.children.push(node); + } + } + + /** + * @internal + */ + public pop(): void { + this.stack.pop(); + } + + /** + * @internal + */ + public top(): ViewTreeNodeImpl | null { + return this.isEmpty() ? null : this.stack[this.stack.length - 1]; + } + + /** + * @internal + */ + public isEmpty(): boolean { + return this.stack.length === 0; + } + + /** + * @internal + */ + public popAutomicComponent(name: string): void { + if (this.isEmpty()) { + return; + } + + let node = this.stack[this.stack.length - 1]; + if (name !== node.name && !this.isContainer(node.name)) { + this.stack.pop(); + } + } + + /** + * @internal + */ + public popComponentExpect(name: string): TreeNodeStack { + for (let i = this.stack.length - 1; i >= 0; i--) { + if (this.stack[i].name !== name) { + this.stack.pop(); + } else { + break; + } + } + return this; + } + + private getParent(): ViewTreeNodeImpl | null { + if (this.stack.length === 0) { + return null; + } + + let node = this.stack[this.stack.length - 1]; + if (!this.isContainer(node.name)) { + this.stack.pop(); + } + return this.stack[this.stack.length - 1]; + } + + protected isContainer(name: string): boolean { + return isEtsContainerComponent(name) || SPECIAL_CONTAINER_COMPONENT.has(name) || name === BUILDER_DECORATOR; + } +} + +export class ViewTreeImpl extends TreeNodeStack implements ViewTree { + private render: ArkMethod; + private buildViewStatus: boolean; + private stateValues: Map>; + private fieldTypes: Map; + + /** + * @internal + */ + constructor(render: ArkMethod) { + super(); + this.render = render; + this.stateValues = new Map(); + this.fieldTypes = new Map(); + this.buildViewStatus = false; + } + + /** + * ViewTree root node. + * @returns root node + */ + public getRoot(): ViewTreeNode | null { + this.buildViewTree(); + return this.root; + } + + /** + * Map of the component controlled by the state variable + * @returns + */ + public getStateValues(): Map> { + this.buildViewTree(); + return this.stateValues; + } + + /** + * @deprecated Use {@link getStateValues} instead. + */ + public isClassField(name: string): boolean { + return this.fieldTypes.has(name); + } + + /** + * @deprecated Use {@link getStateValues} instead. + */ + public getClassFieldType(name: string): Decorator | Type | undefined { + return this.fieldTypes.get(name); + } + + /** + * @internal + */ + private buildViewTree(): void { + if (!this.render || this.isInitialized()) { + return; + } + this.buildViewStatus = true; + this.loadClasssFieldTypes(); + + if (this.render.hasBuilderDecorator()) { + let node = ViewTreeNodeImpl.createBuilderNode(); + node.signature = this.render.getSignature(); + node.classSignature = node.signature; + this.push(node); + } + + if (this.render.getCfg()) { + this.buildViewTreeFromCfg(this.render.getCfg() as Cfg); + } + } + + /** + * @internal + */ + private isInitialized(): boolean { + return this.root != null || this.buildViewStatus; + } + + /** + * @internal + */ + public addStateValue(field: ArkField, node: ViewTreeNode): void { + if (!this.stateValues.has(field)) { + this.stateValues.set(field, new Set()); + } + let sets = this.stateValues.get(field); + sets?.add(node); + } + + /** + * @internal + */ + private isCreateFunc(name: string): boolean { + return COMPONENT_CREATE_FUNCTIONS.has(name); + } + + private loadClasssFieldTypes(): void { + for (const field of this.render.getDeclaringArkClass().getFields()) { + let decorators = field.getStateDecorators(); + if (decorators.length > 0) { + if (decorators.length === 1) { + this.fieldTypes.set(field.getName(), decorators[0]); + } else { + this.fieldTypes.set(field.getName(), decorators[0]); + } + } else { + this.fieldTypes.set(field.getName(), field.getSignature().getType()); + } + } + } + + /** + * @internal + */ + public getDeclaringArkClass(): ArkClass { + return this.render.getDeclaringArkClass(); + } + + /** + * @internal + */ + private findMethod(methodSignature: MethodSignature): ArkMethod | null { + let method = this.render.getDeclaringArkFile().getScene().getMethod(methodSignature); + if (method) { + return method; + } + + // class + method = this.getDeclaringArkClass().getMethod(methodSignature); + if (method) { + return method; + } + + return this.findMethodWithName(methodSignature.getMethodSubSignature().getMethodName()); + } + + /** + * @internal + */ + private findMethodWithName(name: string): ArkMethod | null { + let method = this.getDeclaringArkClass().getMethodWithName(name); + if (method) { + return method; + } + + // namespace + this.getDeclaringArkClass() + .getDeclaringArkNamespace() + ?.getAllMethodsUnderThisNamespace() + .forEach(value => { + if (value.getName() === name) { + method = value; + } + }); + if (method) { + return method; + } + + this.getDeclaringArkClass() + .getDeclaringArkFile() + .getAllNamespacesUnderThisFile() + .forEach(namespace => { + namespace.getAllMethodsUnderThisNamespace().forEach(value => { + if (value.getName() === name) { + method = value; + } + }); + }); + return method; + } + + /** + * @internal + */ + private findClass(classSignature: ClassSignature): ArkClass | null { + return ModelUtils.getClass(this.render, classSignature); + } + + private findBuilderMethod(value: Value): ArkMethod | undefined | null { + let method: ArkMethod | undefined | null; + if (value instanceof ArkInstanceFieldRef) { + method = this.findMethodWithName(value.getFieldName()); + } else if (value instanceof ArkStaticInvokeExpr) { + method = this.findMethod(value.getMethodSignature()); + } else if (value instanceof Local && value.getType() instanceof FunctionType) { + method = this.findMethod((value.getType() as FunctionType).getMethodSignature()); + } else if (value instanceof Local) { + method = this.findMethodWithName(value.getName()); + } + if (method && !method.hasBuilderDecorator()) { + method = this.findMethodInvokeBuilderMethod(method); + } + + return method; + } + + /** + * @internal + */ + private addBuilderNode(method: ArkMethod): ViewTreeNodeImpl { + let builderViewTree = method.getViewTree(); + if (!builderViewTree || !builderViewTree.getRoot()) { + logger.error(`ViewTree->addBuilderNode ${method.getSignature().toString()} build viewtree fail.`); + // add empty node + let node = ViewTreeNodeImpl.createBuilderNode(); + node.signature = method.getSignature(); + node.classSignature = node.signature; + this.push(node); + this.pop(); + return node; + } + + let root = builderViewTree.getRoot() as ViewTreeNodeImpl; + this.push(root); + if (method.getDeclaringArkClass() === this.render.getDeclaringArkClass()) { + for (const [field, nodes] of builderViewTree.getStateValues()) { + for (const node of nodes) { + this.addStateValue(field, node); + } + } + } + this.pop(); + return root; + } + + /** + * @internal + */ + private addCustomComponentNode(cls: ArkClass, arg: Value | undefined, builder: ArkMethod | undefined): ViewTreeNodeImpl { + let node = ViewTreeNodeImpl.createCustomComponent(); + node.signature = cls.getSignature(); + node.classSignature = node.signature; + node.stateValuesTransfer = this.parseObjectLiteralExpr(cls, arg, builder); + if (arg instanceof Local && arg.getType()) { + let stateValues = StateValuesUtils.getInstance(this.getDeclaringArkClass()).parseObjectUsedStateValues(arg.getType()); + stateValues.forEach(field => { + node.stateValues.add(field); + this.addStateValue(field, node); + }); + } + this.push(node); + let componentViewTree = cls.getViewTree(); + if (!componentViewTree || !componentViewTree.getRoot()) { + logger.error(`ViewTree->addCustomComponentNode ${cls.getSignature().toString()} build viewtree fail.`); + return node; + } + let root = componentViewTree.getRoot() as ViewTreeNodeImpl; + if (root.hasBuilderParam()) { + root = this.cloneBuilderParamNode(node, root); + } + node.children.push(root); + + return node; + } + + private cloneBuilderParamNode(node: ViewTreeNodeImpl, root: ViewTreeNodeImpl): ViewTreeNodeImpl { + root = root.clone(node); + if (node.stateValuesTransfer) { + root.walk(item => { + let child = item as ViewTreeNodeImpl; + if (!child.isBuilderParam() || !child.builderParam) { + return false; + } + let method = node.stateValuesTransfer?.get(child.builderParam) as ArkMethod; + if (method) { + child.changeBuilderParam2BuilderNode(method); + } + + return false; + }); + } + return root; + } + + /** + * @internal + */ + private addBuilderParamNode(field: ArkField): ViewTreeNodeImpl { + let node = ViewTreeNodeImpl.createBuilderParamNode(); + node.builderParam = field; + this.push(node); + this.pop(); + + return node; + } + + /** + * @internal + */ + private addSystemComponentNode(name: string): ViewTreeNodeImpl { + let node = new ViewTreeNodeImpl(name); + this.push(node); + + return node; + } + + private findMethodInvokeBuilderMethod(method: ArkMethod): ArkMethod | undefined { + let stmts = method.getCfg()?.getStmts(); + if (!stmts) { + return undefined; + } + for (const stmt of stmts) { + let expr: AbstractInvokeExpr | undefined; + + if (stmt instanceof ArkInvokeStmt) { + expr = stmt.getInvokeExpr(); + } else if (stmt instanceof ArkAssignStmt) { + let rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkInstanceInvokeExpr || rightOp instanceof ArkStaticInvokeExpr) { + expr = rightOp; + } + } + + if (expr === undefined) { + continue; + } + + let method = this.findMethod(expr.getMethodSignature()); + if (method?.hasBuilderDecorator()) { + return method; + } + } + return undefined; + } + + private parseFieldInObjectLiteral(field: ArkField, cls: ArkClass, transferMap: Map): void { + let dstField = cls.getFieldWithName(field.getName()); + if (dstField?.getStateDecorators().length === 0 && !dstField?.hasBuilderParamDecorator()) { + return; + } + + let stmts = field.getInitializer(); + if (stmts.length === 0) { + return; + } + + let assignStmt = stmts[stmts.length - 1]; + if (!(assignStmt instanceof ArkAssignStmt)) { + return; + } + + let value = assignStmt.getRightOp(); + if (value instanceof Local) { + value = backtraceLocalInitValue(value); + } + if (dstField?.hasBuilderParamDecorator()) { + let method = this.findBuilderMethod(value); + if (method) { + transferMap.set(dstField, method); + } + } else { + let srcField: ArkField | undefined | null; + if (value instanceof ArkInstanceFieldRef) { + srcField = this.getDeclaringArkClass().getFieldWithName(value.getFieldName()); + } + if (srcField && dstField) { + transferMap.set(dstField, srcField); + } + } + } + + private parseObjectLiteralExpr(cls: ArkClass, object: Value | undefined, builder: ArkMethod | undefined): Map | undefined { + let transferMap: Map = new Map(); + if (object instanceof Local && object.getType() instanceof ClassType) { + let anonymousSig = (object.getType() as ClassType).getClassSignature(); + let anonymous = this.findClass(anonymousSig); + anonymous?.getFields().forEach(field => { + this.parseFieldInObjectLiteral(field, cls, transferMap); + }); + } + // If the builder exists, there will be a unique BuilderParam + if (builder) { + cls.getFields().forEach(value => { + if (value.hasBuilderParamDecorator()) { + transferMap.set(value, builder); + } + }); + } + + if (transferMap.size === 0) { + return undefined; + } + return transferMap; + } + + private viewComponentCreationParser(name: string, stmt: Stmt, expr: AbstractInvokeExpr): ViewTreeNodeImpl | undefined { + let temp = expr.getArg(0) as Local; + let arg: Value | undefined; + temp.getUsedStmts().forEach(value => { + if (value instanceof ArkInvokeStmt) { + let invokerExpr = value.getInvokeExpr(); + let methodName = invokerExpr.getMethodSignature().getMethodSubSignature().getMethodName(); + if (methodName === 'constructor') { + arg = invokerExpr.getArg(0); + } + } + }); + + let builderMethod: ArkMethod | undefined; + let builder = expr.getArg(1) as Local; + if (builder) { + let method = this.findMethod((builder.getType() as FunctionType).getMethodSignature()); + if (!method?.hasBuilderDecorator()) { + method?.addDecorator(new Decorator(BUILDER_DECORATOR)); + } + if (!method?.hasViewTree()) { + method?.setViewTree(new ViewTreeImpl(method)); + } + if (method) { + builderMethod = method; + } + } + + let initValue = backtraceLocalInitValue(temp); + if (!(initValue instanceof ArkNewExpr)) { + return undefined; + } + + let clsSignature = (initValue.getType() as ClassType).getClassSignature(); + if (clsSignature) { + let cls = this.findClass(clsSignature); + if (cls && cls.hasComponentDecorator()) { + return this.addCustomComponentNode(cls, arg, builderMethod); + } else { + logger.error(`ViewTree->viewComponentCreationParser not found class ${clsSignature.toString()}. ${stmt.toString()}`); + } + } + return undefined; + } + + private waterFlowCreationParser(name: string, stmt: Stmt, expr: AbstractInvokeExpr): ViewTreeNodeImpl { + let node = this.addSystemComponentNode(name); + let object = expr.getArg(0); + if (object instanceof Local && object.getType() instanceof ClassType) { + let anonymousSig = (object.getType() as ClassType).getClassSignature(); + let anonymous = this.findClass(anonymousSig); + let footer = anonymous?.getFieldWithName('footer'); + if (!footer) { + return node; + } + let stmts = footer.getInitializer(); + let assignStmt = stmts[stmts.length - 1]; + if (!(assignStmt instanceof ArkAssignStmt)) { + return node; + } + + let value = assignStmt.getRightOp(); + let method = this.findBuilderMethod(value); + if (method?.hasBuilderDecorator()) { + return this.addBuilderNode(method); + } + } + + return node; + } + + private forEachCreationParser(name: string, stmt: Stmt, expr: AbstractInvokeExpr): ViewTreeNodeImpl { + let node = this.addSystemComponentNode(name); + let values = expr.getArg(0) as Local; + let declaringStmt = values?.getDeclaringStmt(); + if (declaringStmt) { + let stateValues = StateValuesUtils.getInstance(this.getDeclaringArkClass()).parseStmtUsesStateValues(declaringStmt); + stateValues.forEach(field => { + node.stateValues.add(field); + this.addStateValue(field, node); + }); + } + + let type = (expr.getArg(1) as Local).getType() as FunctionType; + let method = this.findMethod(type.getMethodSignature()); + if (method && method.getCfg()) { + this.buildViewTreeFromCfg(method.getCfg() as Cfg); + } + return node; + } + + private repeatCreationParser(name: string, stmt: Stmt, expr: AbstractInvokeExpr): ViewTreeNodeImpl { + let node = this.addSystemComponentNode(name); + let arg = expr.getArg(0) as Local; + let declaringStmt = arg?.getDeclaringStmt(); + if (declaringStmt) { + let stateValues = StateValuesUtils.getInstance(this.getDeclaringArkClass()).parseStmtUsesStateValues(declaringStmt); + stateValues.forEach(field => { + node.stateValues.add(field); + this.addStateValue(field, node); + }); + } + + return node; + } + + private ifBranchCreationParser(name: string, stmt: Stmt, expr: AbstractInvokeExpr): ViewTreeNodeImpl { + this.popComponentExpect(COMPONENT_IF); + return this.addSystemComponentNode(COMPONENT_IF_BRANCH); + } + + private COMPONENT_CREATE_PARSERS: Map ViewTreeNodeImpl | undefined> = new Map([ + ['ForEach.create', this.forEachCreationParser.bind(this)], + ['LazyForEach.create', this.forEachCreationParser.bind(this)], + ['Repeat.create', this.repeatCreationParser.bind(this)], + ['View.create', this.viewComponentCreationParser.bind(this)], + ['If.branch', this.ifBranchCreationParser.bind(this)], + ['WaterFlow.create', this.waterFlowCreationParser.bind(this)], + ]); + + private componentCreateParse(componentName: string, methodName: string, stmt: Stmt, expr: ArkStaticInvokeExpr): ViewTreeNodeImpl | undefined { + let parserFn = this.COMPONENT_CREATE_PARSERS.get(`${componentName}.${methodName}`); + if (parserFn) { + let node = parserFn(componentName, stmt, expr); + node?.addStmt(this, stmt); + return node; + } + this.popAutomicComponent(componentName); + let node = this.addSystemComponentNode(componentName); + node.addStmt(this, stmt); + return node; + } + + private parseStaticInvokeExpr(local2Node: Map, stmt: Stmt, expr: ArkStaticInvokeExpr): ViewTreeNodeImpl | undefined { + let methodSignature = expr.getMethodSignature(); + let method = this.findMethod(methodSignature); + if (method?.hasBuilderDecorator()) { + let node = this.addBuilderNode(method); + node.parseStateValues(this, stmt); + return node; + } + + let name = methodSignature.getDeclaringClassSignature().getClassName(); + let methodName = methodSignature.getMethodSubSignature().getMethodName(); + + if (this.isCreateFunc(methodName)) { + return this.componentCreateParse(name, methodName, stmt, expr); + } + + let currentNode = this.top(); + if (name === currentNode?.name) { + currentNode.addStmt(this, stmt); + if (methodName === COMPONENT_POP_FUNCTION) { + this.pop(); + } + return currentNode; + } else if (name === COMPONENT_IF && methodName === COMPONENT_POP_FUNCTION) { + this.popComponentExpect(COMPONENT_IF); + this.pop(); + } + return undefined; + } + + /** + * $temp4.margin({ top: 20 }); + * @param viewTree + * @param local2Node + * @param expr + */ + private parseInstanceInvokeExpr(local2Node: Map, stmt: Stmt, expr: ArkInstanceInvokeExpr): ViewTreeNodeImpl | undefined { + let temp = expr.getBase(); + if (local2Node.has(temp)) { + let component = local2Node.get(temp); + if (component?.name === COMPONENT_REPEAT && expr.getMethodSignature().getMethodSubSignature().getMethodName() === 'each') { + let arg = expr.getArg(0); + let type = arg.getType(); + if (type instanceof FunctionType) { + let method = this.findMethod(type.getMethodSignature()); + this.buildViewTreeFromCfg(method?.getCfg() as Cfg); + } + this.pop(); + } else { + component?.addStmt(this, stmt); + } + + return component; + } + + let name = expr.getBase().getName(); + if (name.startsWith(TEMP_LOCAL_PREFIX)) { + let initValue = backtraceLocalInitValue(expr.getBase()); + if (initValue instanceof ArkThisRef) { + name = 'this'; + } + } + + let methodName = expr.getMethodSignature().getMethodSubSignature().getMethodName(); + let field = this.getDeclaringArkClass().getFieldWithName(methodName); + if (name === 'this' && field?.hasBuilderParamDecorator()) { + return this.addBuilderParamNode(field); + } + + let method = this.findMethod(expr.getMethodSignature()); + if (name === 'this' && method?.hasBuilderDecorator()) { + return this.addBuilderNode(method); + } + + return undefined; + } + + private parsePtrInvokeExpr(local2Node: Map, stmt: Stmt, expr: ArkPtrInvokeExpr): ViewTreeNodeImpl | undefined { + let temp = expr.getFuncPtrLocal(); + if (temp instanceof Local && local2Node.has(temp)) { + let component = local2Node.get(temp); + if (component?.name === COMPONENT_REPEAT && expr.getMethodSignature().getMethodSubSignature().getMethodName() === 'each') { + let arg = expr.getArg(0); + let type = arg.getType(); + if (type instanceof FunctionType) { + let method = this.findMethod(type.getMethodSignature()); + this.buildViewTreeFromCfg(method?.getCfg() as Cfg); + } + this.pop(); + } else { + component?.addStmt(this, stmt); + } + + return component; + } else if (temp instanceof ArkInstanceFieldRef) { + let name = temp.getBase().getName(); + if (name.startsWith(TEMP_LOCAL_PREFIX)) { + let initValue = backtraceLocalInitValue(temp.getBase()); + if (initValue instanceof ArkThisRef) { + name = 'this'; + } + } + + let methodName = temp.getFieldName(); + let field = this.getDeclaringArkClass().getFieldWithName(methodName); + if (name === 'this' && field?.hasBuilderParamDecorator()) { + return this.addBuilderParamNode(field); + } + + let method = this.findMethod(expr.getMethodSignature()); + if (name === 'this' && method?.hasBuilderDecorator()) { + return this.addBuilderNode(method); + } + } + return undefined; + } + + /** + * $temp3 = View.create($temp2); + * $temp4 = View.pop(); + * $temp4.margin({ top: 20 }); + * + * $temp2 = List.create(); + * $temp5 = $temp2.width('100%'); + * $temp6 = $temp5.height('100%'); + * $temp6.backgroundColor('#FFDCDCDC'); + * @param viewTree + * @param local2Node + * @param stmt + * @returns + */ + private parseAssignStmt(local2Node: Map, stmt: ArkAssignStmt): void { + let left = stmt.getLeftOp(); + let right = stmt.getRightOp(); + + if (!(left instanceof Local)) { + return; + } + + let component: ViewTreeNodeImpl | undefined; + if (right instanceof ArkStaticInvokeExpr) { + component = this.parseStaticInvokeExpr(local2Node, stmt, right); + } else if (right instanceof ArkInstanceInvokeExpr) { + component = this.parseInstanceInvokeExpr(local2Node, stmt, right); + } else if (right instanceof ArkPtrInvokeExpr) { + component = this.parsePtrInvokeExpr(local2Node, stmt, right); + } + if (component) { + local2Node.set(left, component); + } + } + + private parseInvokeStmt(local2Node: Map, stmt: ArkInvokeStmt): void { + let expr = stmt.getInvokeExpr(); + if (expr instanceof ArkStaticInvokeExpr) { + this.parseStaticInvokeExpr(local2Node, stmt, expr); + } else if (expr instanceof ArkInstanceInvokeExpr) { + this.parseInstanceInvokeExpr(local2Node, stmt, expr); + } else if (expr instanceof ArkPtrInvokeExpr) { + this.parsePtrInvokeExpr(local2Node, stmt, expr); + } + } + + private buildViewTreeFromCfg(cfg: Cfg, local2Node: Map = new Map()): void { + if (!cfg) { + return; + } + let blocks = cfg.getBlocks(); + for (const block of blocks) { + for (const stmt of block.getStmts()) { + if (!(stmt instanceof ArkInvokeStmt || stmt instanceof ArkAssignStmt)) { + continue; + } + + if (stmt instanceof ArkAssignStmt) { + this.parseAssignStmt(local2Node, stmt); + } else if (stmt instanceof ArkInvokeStmt) { + this.parseInvokeStmt(local2Node, stmt); + } + } + } + } +} + +export function buildViewTree(render: ArkMethod): ViewTree { + return new ViewTreeImpl(render); +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkBaseModel.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkBaseModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..483acec423d0297182fcae9192ad3a5029f69d9f --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkBaseModel.ts @@ -0,0 +1,286 @@ +/* + * 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. + */ + +import ts from 'ohos-typescript'; +import { Decorator } from '../base/Decorator'; +import { COMPONENT_DECORATOR, ENTRY_DECORATOR, BUILDER_PARAM_DECORATOR, BUILDER_DECORATOR } from '../common/EtsConst'; +import { ArkError, ArkErrorCode } from '../common/ArkError'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { ArkMetadata, ArkMetadataKind, ArkMetadataType } from './ArkMetadata'; +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkBaseModel'); + +const COMPONENT_MEMBER_DECORATORS: Set = new Set([ + 'State', + 'Prop', + 'Link', + 'StorageProp', + 'StorageLink', + 'Provide', + 'Consume', + 'ObjectLink', + 'LocalStorageLink', + 'LocalStorageProp', + 'Local', + 'Param', + 'Event', + 'Provider', + 'Consumer', +]); + +export enum ModifierType { + PRIVATE = 1, + PROTECTED = 1 << 1, + PUBLIC = 1 << 2, + EXPORT = 1 << 3, + STATIC = 1 << 4, + ABSTRACT = 1 << 5, + ASYNC = 1 << 6, + CONST = 1 << 7, + ACCESSOR = 1 << 8, + DEFAULT = 1 << 9, + IN = 1 << 10, + READONLY = 1 << 11, + OUT = 1 << 12, + OVERRIDE = 1 << 13, + DECLARE = 1 << 14, +} + +export const MODIFIER_TYPE_MASK = 0xffff; + +const MODIFIER_TYPE_STRINGS = [ + 'private', + 'protected', + 'public', + 'export', + 'static', + 'abstract', + 'async', + 'const', + 'accessor', + 'default', + 'in', + 'readonly', + 'out', + 'override', + 'declare', +]; + +const MODIFIER_KIND_2_ENUM = new Map([ + [ts.SyntaxKind.AbstractKeyword, ModifierType.ABSTRACT], + [ts.SyntaxKind.AccessorKeyword, ModifierType.ACCESSOR], + [ts.SyntaxKind.AsyncKeyword, ModifierType.ASYNC], + [ts.SyntaxKind.ConstKeyword, ModifierType.CONST], + [ts.SyntaxKind.DeclareKeyword, ModifierType.DECLARE], + [ts.SyntaxKind.DefaultKeyword, ModifierType.DEFAULT], + [ts.SyntaxKind.ExportKeyword, ModifierType.EXPORT], + [ts.SyntaxKind.InKeyword, ModifierType.IN], + [ts.SyntaxKind.PrivateKeyword, ModifierType.PRIVATE], + [ts.SyntaxKind.ProtectedKeyword, ModifierType.PROTECTED], + [ts.SyntaxKind.PublicKeyword, ModifierType.PUBLIC], + [ts.SyntaxKind.ReadonlyKeyword, ModifierType.READONLY], + [ts.SyntaxKind.OutKeyword, ModifierType.OUT], + [ts.SyntaxKind.OverrideKeyword, ModifierType.OVERRIDE], + [ts.SyntaxKind.StaticKeyword, ModifierType.STATIC], +]); + +export function modifierKind2Enum(kind: ts.SyntaxKind): ModifierType { + return MODIFIER_KIND_2_ENUM.get(kind)!; +} + +export function modifiers2stringArray(modifiers: number): string[] { + let strs: string[] = []; + for (let idx = 0; idx < MODIFIER_TYPE_STRINGS.length; idx++) { + if (modifiers & 0x01) { + strs.push(MODIFIER_TYPE_STRINGS[idx]); + } + modifiers = modifiers >>> 1; + } + return strs; +} + +export abstract class ArkBaseModel { + protected modifiers?: number; + protected decorators?: Set; + protected metadata?: ArkMetadata; + + public getMetadata(kind: ArkMetadataKind): ArkMetadataType | undefined { + return this.metadata?.getMetadata(kind); + } + + public setMetadata(kind: ArkMetadataKind, value: ArkMetadataType): void { + if (!this.metadata) { + this.metadata = new ArkMetadata(); + } + return this.metadata?.setMetadata(kind, value); + } + + public getModifiers(): number { + if (!this.modifiers) { + return 0; + } + return this.modifiers; + } + + public setModifiers(modifiers: number): void { + if (modifiers !== 0) { + this.modifiers = modifiers; + } + } + + public addModifier(modifier: ModifierType | number): void { + this.modifiers = this.getModifiers() | modifier; + } + + public removeModifier(modifier: ModifierType): void { + if (!this.modifiers) { + return; + } + this.modifiers &= MODIFIER_TYPE_MASK ^ modifier; + } + + public isStatic(): boolean { + return this.containsModifier(ModifierType.STATIC); + } + + public isProtected(): boolean { + return this.containsModifier(ModifierType.PROTECTED); + } + + public isPrivate(): boolean { + return this.containsModifier(ModifierType.PRIVATE); + } + + public isPublic(): boolean { + return this.containsModifier(ModifierType.PUBLIC); + } + + public isReadonly(): boolean { + return this.containsModifier(ModifierType.READONLY); + } + + public isAbstract(): boolean { + return this.containsModifier(ModifierType.ABSTRACT); + } + + public isExport(): boolean { + return this.containsModifier(ModifierType.EXPORT); + } + + public isDefault(): boolean { + return this.containsModifier(ModifierType.DEFAULT); + } + + /** @deprecated Use {@link isExport} instead. */ + public isExported(): boolean { + return this.isExport(); + } + + public isDeclare(): boolean { + return this.containsModifier(ModifierType.DECLARE); + } + + public containsModifier(modifierType: ModifierType): boolean { + if (!this.modifiers) { + return false; + } + + return (this.modifiers & modifierType) === modifierType; + } + + public getDecorators(): Decorator[] { + if (this.decorators) { + return Array.from(this.decorators); + } + return []; + } + + public setDecorators(decorators: Set): void { + if (decorators.size > 0) { + this.decorators = decorators; + } + } + + public addDecorator(decorator: Decorator): void { + if (!this.decorators) { + this.decorators = new Set(); + } + this.decorators.add(decorator); + } + + public removeDecorator(kind: string): void { + this.decorators?.forEach(value => { + if (value.getKind() === kind) { + this.decorators?.delete(value); + } + }); + } + + public hasBuilderDecorator(): boolean { + return this.hasDecorator(BUILDER_DECORATOR); + } + + public getStateDecorators(): Decorator[] { + if (!this.decorators) { + return []; + } + return Array.from(this.decorators).filter(item => { + return COMPONENT_MEMBER_DECORATORS.has(item.getKind()); + }) as Decorator[]; + } + + public hasBuilderParamDecorator(): boolean { + return this.hasDecorator(BUILDER_PARAM_DECORATOR); + } + + public hasEntryDecorator(): boolean { + return this.hasDecorator(ENTRY_DECORATOR); + } + + public hasComponentDecorator(): boolean { + return this.hasDecorator(COMPONENT_DECORATOR); + } + + public hasDecorator(kind: string | Set): boolean { + let decorators = this.getDecorators(); + return ( + decorators.filter(value => { + if (kind instanceof Set) { + return kind.has(value.getKind()); + } + return value.getKind() === kind; + }).length !== 0 + ); + } + + protected validateFields(fields: string[]): ArkError { + let errs: string[] = []; + for (const field of fields) { + let value = Reflect.get(this, field); + if (!value) { + errs.push(field); + } + } + if (errs.length === 0) { + return { errCode: ArkErrorCode.OK }; + } + logger.error(`class fields: ${errs.join(',')} is undefined.`); + return { + errCode: ArkErrorCode.CLASS_INSTANCE_FIELD_UNDEFINDED, + errMsg: `${errs.join(',')} is undefined.`, + }; + } + + public abstract validate(): ArkError; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkBody.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkBody.ts new file mode 100644 index 0000000000000000000000000000000000000000..610a3a425f614dde5c4153e484f4cb5656802d7f --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkBody.ts @@ -0,0 +1,94 @@ +/* + * 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. + */ + +import { Local } from '../base/Local'; +import { Cfg } from '../graph/Cfg'; +import { AliasType } from '../base/Type'; +import { Trap } from '../base/Trap'; +import { Value } from '../base/Value'; +import { ArkAliasTypeDefineStmt } from '../base/Stmt'; +import { LocalSignature } from './ArkSignature'; + +export class ArkBody { + private locals: Map; + private usedGlobals?: Map; + private cfg: Cfg; + private aliasTypeMap?: Map; + private traps?: Trap[]; + + constructor(locals: Set, cfg: Cfg, aliasTypeMap?: Map, traps?: Trap[]) { + this.cfg = cfg; + this.aliasTypeMap = aliasTypeMap; + this.locals = new Map(); + locals.forEach(local => this.locals.set(local.getName(), local)); + this.traps = traps; + } + + public getLocals(): Map { + return this.locals; + } + + public setLocals(locals: Set): void { + if (!this.locals) { + this.locals = new Map(); + } + locals.forEach(local => this.locals.set(local.getName(), local)); + } + + public addLocal(name: string, local: Local): void { + this.locals.set(name, local); + } + + public getUsedGlobals(): Map | undefined { + return this.usedGlobals; + } + + public setUsedGlobals(globals: Map): void { + this.usedGlobals = globals; + } + + public getCfg(): Cfg { + return this.cfg; + } + + public setCfg(cfg: Cfg): void { + this.cfg = cfg; + } + + public getAliasTypeMap(): Map | undefined { + return this.aliasTypeMap; + } + + public getAliasTypeByName(name: string): AliasType | null { + const aliasTypeInfo: [AliasType, ArkAliasTypeDefineStmt] | undefined = this.aliasTypeMap?.get(name); + if (aliasTypeInfo) { + return aliasTypeInfo[0]; + } + return null; + } + + public getTraps(): Trap[] | undefined { + return this.traps; + } + + public getExportLocalByName(name: string): Local | null { + const local = this.locals?.get(name); + if (local) { + local.setSignature(new LocalSignature(name, this.cfg.getDeclaringMethod().getSignature())); + return local; + } + return null; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkClass.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkClass.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b013ddbd55e8d55aac0d658007e9b709048d31d --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkClass.ts @@ -0,0 +1,533 @@ +/* + * 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. + */ + +import { ClassType, GenericType, Type } from '../base/Type'; +import { ViewTree } from '../graph/ViewTree'; +import { ArkField } from './ArkField'; +import { ArkFile, Language } from './ArkFile'; +import { ArkMethod } from './ArkMethod'; +import { ArkNamespace } from './ArkNamespace'; +import { ClassSignature, FieldSignature, FileSignature, MethodSignature, NamespaceSignature } from './ArkSignature'; +import { Local } from '../base/Local'; +import { ArkExport, ExportType } from './ArkExport'; +import { TypeInference } from '../common/TypeInference'; +import { ANONYMOUS_CLASS_PREFIX, DEFAULT_ARK_CLASS_NAME, NAME_DELIMITER, NAME_PREFIX } from '../common/Const'; +import { getColNo, getLineNo, LineCol, setCol, setLine } from '../base/Position'; +import { ArkBaseModel } from './ArkBaseModel'; +import { ArkError } from '../common/ArkError'; + +export enum ClassCategory { + CLASS = 0, + STRUCT = 1, + INTERFACE = 2, + ENUM = 3, + TYPE_LITERAL = 4, + OBJECT = 5, +} + +/** + * @category core/model + */ +export class ArkClass extends ArkBaseModel implements ArkExport { + private category!: ClassCategory; + private code?: string; + private lineCol: LineCol = 0; + + private declaringArkFile!: ArkFile; + private declaringArkNamespace: ArkNamespace | undefined; + private classSignature!: ClassSignature; + /** + * The keys of the `heritageClasses` map represent the names of superclass and interfaces. + * The superclass name is placed first; if it does not exist, an empty string `''` will occupy this position. + * The values of the `heritageClasses` map will be replaced with `ArkClass` or `null` during type inference. + */ + private heritageClasses: Map = new Map(); + + private genericsTypes?: GenericType[]; + private realTypes?: Type[]; + private defaultMethod: ArkMethod | null = null; + + // name to model + private methods: Map = new Map(); + private fields: Map = new Map(); + private extendedClasses: Map = new Map(); + private staticMethods: Map = new Map(); + private staticFields: Map = new Map(); + + private instanceInitMethod: ArkMethod = new ArkMethod(); + private staticInitMethod: ArkMethod = new ArkMethod(); + + private anonymousMethodNumber: number = 0; + private indexSignatureNumber: number = 0; + + private viewTree?: ViewTree; + + constructor() { + super(); + } + + /** + * Returns the program language of the file where this class defined. + */ + public getLanguage(): Language { + return this.getDeclaringArkFile().getLanguage(); + } + + /** + * Returns the **string**name of this class. + * @returns The name of this class. + */ + public getName(): string { + return this.classSignature.getClassName(); + } + + /** + * Returns the codes of class as a **string.** + * @returns the codes of class. + */ + public getCode(): string | undefined { + return this.code; + } + + public setCode(code: string): void { + this.code = code; + } + + /** + * Returns the line position of this class. + * @returns The line position of this class. + */ + public getLine(): number { + return getLineNo(this.lineCol); + } + + public setLine(line: number): void { + this.lineCol = setLine(this.lineCol, line); + } + + /** + * Returns the column position of this class. + * @returns The column position of this class. + */ + public getColumn(): number { + return getColNo(this.lineCol); + } + + public setColumn(column: number): void { + this.lineCol = setCol(this.lineCol, column); + } + + public getCategory(): ClassCategory { + return this.category; + } + + public setCategory(category: ClassCategory): void { + this.category = category; + } + + /** + * Returns the declaring file. + * @returns A file defined by ArkAnalyzer. + * @example + * 1. Get the {@link ArkFile} which the ArkClass is in. + + ```typescript + const arkFile = arkClass.getDeclaringArkFile(); + ``` + */ + public getDeclaringArkFile(): ArkFile { + return this.declaringArkFile; + } + + public setDeclaringArkFile(declaringArkFile: ArkFile): void { + this.declaringArkFile = declaringArkFile; + } + + /** + * Returns the declaring namespace of this class, which may also be an **undefined**. + * @returns The declaring namespace (may be **undefined**) of this class. + */ + public getDeclaringArkNamespace(): ArkNamespace | undefined { + return this.declaringArkNamespace; + } + + public setDeclaringArkNamespace(declaringArkNamespace: ArkNamespace | undefined): void { + this.declaringArkNamespace = declaringArkNamespace; + } + + public isDefaultArkClass(): boolean { + return this.getName() === DEFAULT_ARK_CLASS_NAME; + } + + public isAnonymousClass(): boolean { + return this.getName().startsWith(ANONYMOUS_CLASS_PREFIX); + } + + /** + * Returns the signature of current class (i.e., {@link ClassSignature}). + * The {@link ClassSignature} can uniquely identify a class, according to which we can find the class from the scene. + * @returns The class signature. + */ + public getSignature(): ClassSignature { + return this.classSignature; + } + + public setSignature(classSig: ClassSignature): void { + this.classSignature = classSig; + } + + public getSuperClassName(): string { + return this.heritageClasses.keys().next().value || ''; + } + + public addHeritageClassName(className: string): void { + this.heritageClasses.set(className, undefined); + } + + /** + * Returns the superclass of this class. + * @returns The superclass of this class. + */ + public getSuperClass(): ArkClass | null { + const heritageClass = this.getHeritageClass(this.getSuperClassName()); + if (heritageClass && heritageClass.getCategory() !== ClassCategory.INTERFACE) { + return heritageClass; + } + return null; + } + + private getHeritageClass(heritageClassName: string): ArkClass | null { + if (!heritageClassName) { + return null; + } + let superClass = this.heritageClasses.get(heritageClassName); + if (superClass === undefined) { + let type = TypeInference.inferUnclearRefName(heritageClassName, this); + if (type) { + type = TypeInference.replaceAliasType(type); + } + if (type instanceof ClassType && (superClass = this.declaringArkFile.getScene().getClass(type.getClassSignature()))) { + superClass.addExtendedClass(this); + const realGenericTypes = type.getRealGenericTypes(); + if (realGenericTypes) { + this.realTypes = realGenericTypes; + } + } + this.heritageClasses.set(heritageClassName, superClass || null); + } + return superClass || null; + } + + public getAllHeritageClasses(): ArkClass[] { + const result: ArkClass[] = []; + this.heritageClasses.forEach((v, k) => { + const heritage = v ?? this.getHeritageClass(k); + if (heritage) { + result.push(heritage); + } + }); + return result; + } + + public getExtendedClasses(): Map { + return this.extendedClasses; + } + + public addExtendedClass(extendedClass: ArkClass): void { + this.extendedClasses.set(extendedClass.getName(), extendedClass); + } + + public getImplementedInterfaceNames(): string[] { + if (this.category === ClassCategory.INTERFACE) { + return []; + } + return Array.from(this.heritageClasses.keys()).slice(1); + } + + public hasImplementedInterface(interfaceName: string): boolean { + return this.heritageClasses.has(interfaceName) && this.getSuperClassName() !== interfaceName; + } + + public getImplementedInterface(interfaceName: string): ArkClass | null { + const heritageClass = this.getHeritageClass(interfaceName); + if (heritageClass && heritageClass.getCategory() === ClassCategory.INTERFACE) { + return heritageClass; + } + return null; + } + + /** + * Get the field according to its field signature. + * If no field cound be found, **null**will be returned. + * @param fieldSignature - the field's signature. + * @returns A field. If there is no field in this class, the return will be a **null**. + */ + public getField(fieldSignature: FieldSignature): ArkField | null { + const fieldName = fieldSignature.getFieldName(); + let fieldSearched: ArkField | null = this.getFieldWithName(fieldName); + if (!fieldSearched) { + fieldSearched = this.getStaticFieldWithName(fieldName); + } + return fieldSearched; + } + + public getFieldWithName(fieldName: string): ArkField | null { + return this.fields.get(fieldName) || null; + } + + public getStaticFieldWithName(fieldName: string): ArkField | null { + return this.staticFields.get(fieldName) || null; + } + + /** + * Returns an **array** of fields in the class. + * @returns an **array** of fields in the class. + */ + public getFields(): ArkField[] { + const allFields: ArkField[] = Array.from(this.fields.values()); + allFields.push(...this.staticFields.values()); + return allFields; + } + + public addField(field: ArkField): void { + if (field.isStatic()) { + this.staticFields.set(field.getName(), field); + } else { + this.fields.set(field.getName(), field); + } + } + + public addFields(fields: ArkField[]): void { + fields.forEach(field => { + this.addField(field); + }); + } + + public getRealTypes(): Type[] | undefined { + return this.realTypes ? Array.from(this.realTypes) : undefined; + } + + public getGenericsTypes(): GenericType[] | undefined { + return this.genericsTypes ? Array.from(this.genericsTypes) : undefined; + } + + public addGenericType(gType: GenericType): void { + if (!this.genericsTypes) { + this.genericsTypes = []; + } + this.genericsTypes.push(gType); + } + + /** + * Returns all methods defined in the specific class in the form of an array. + * @param generated - indicating whether this API returns the methods that are dynamically + * generated at runtime. If it is not specified as true or false, the return will not include the generated method. + * @returns An array of all methods in this class. + * @example + * 1. Get methods defined in class `BookService`. + + ```typescript + let classes: ArkClass[] = scene.getClasses(); + let serviceClass : ArkClass = classes[1]; + let methods: ArkMethod[] = serviceClass.getMethods(); + let methodNames: string[] = methods.map(mthd => mthd.name); + console.log(methodNames); + ``` + */ + public getMethods(generated?: boolean): ArkMethod[] { + const allMethods = Array.from(this.methods.values()).filter(f => (!generated && !f.isGenerated()) || generated); + allMethods.push(...this.staticMethods.values()); + return [...new Set(allMethods)]; + } + + public getMethod(methodSignature: MethodSignature): ArkMethod | null { + const methodName = methodSignature.getMethodSubSignature().getMethodName(); + const methodSearched = this.getMethodWithName(methodName) ?? this.getStaticMethodWithName(methodName); + if (methodSearched === null) { + return null; + } + const implSignature = methodSearched.getImplementationSignature(); + if (implSignature !== null && implSignature.isMatch(methodSignature)) { + return methodSearched; + } + const declareSignatures = methodSearched.getDeclareSignatures(); + if (declareSignatures !== null) { + for (let i = 0; i < declareSignatures.length; i++) { + if (declareSignatures[i].isMatch(methodSignature)) { + return methodSearched; + } + } + } + return null; + } + + public getMethodWithName(methodName: string): ArkMethod | null { + return this.methods.get(methodName) || null; + } + + public getStaticMethodWithName(methodName: string): ArkMethod | null { + return this.staticMethods.get(methodName) || null; + } + + /** + * add a method in class. + * when a nested method with declare name, add both the declare origin name and signature name + * %${declare name}$${outer method name} in class. + */ + public addMethod(method: ArkMethod, originName?: string): void { + const name = originName ?? method.getName(); + if (method.isStatic()) { + this.staticMethods.set(name, method); + } else { + this.methods.set(name, method); + } + if (!originName && !method.isAnonymousMethod() && name.startsWith(NAME_PREFIX)) { + const index = name.indexOf(NAME_DELIMITER); + if (index > 1) { + const originName = name.substring(1, index); + this.addMethod(method, originName); + } + } + } + + public setDefaultArkMethod(defaultMethod: ArkMethod): void { + this.defaultMethod = defaultMethod; + this.addMethod(defaultMethod); + } + + public getDefaultArkMethod(): ArkMethod | null { + return this.defaultMethod; + } + + public setViewTree(viewTree: ViewTree): void { + this.viewTree = viewTree; + } + + /** + * Returns the view tree of the ArkClass. + * @returns The view tree of the ArkClass. + * @example + * 1. get viewTree of ArkClass. + + ```typescript + for (let arkFiles of scene.getFiles()) { + for (let arkClasss of arkFiles.getClasses()) { + if (arkClasss.hasViewTree()) { + arkClasss.getViewTree(); + } + } + } + ``` + */ + public getViewTree(): ViewTree | undefined { + return this.viewTree; + } + + /** + * Check whether the view tree is defined. + * If it is defined, the return value is true, otherwise it is false. + * @returns True if the view tree is defined; false otherwise. + * @example + * 1. Judge viewTree of ArkClass. + + ```typescript + for (let arkFiles of scene.getFiles()) { + for (let arkClasss of arkFiles.getClasses()) { + if (arkClasss.hasViewTree()) { + arkClasss.getViewTree(); + } + } + } + ``` + */ + public hasViewTree(): boolean { + return this.viewTree !== undefined; + } + + public getStaticFields(classMap: Map): ArkField[] { + const fields: ArkField[] = []; + let classes: ArkClass[] = []; + if (this.declaringArkNamespace) { + classes = classMap.get(this.declaringArkNamespace.getNamespaceSignature())!; + } else { + classes = classMap.get(this.declaringArkFile.getFileSignature())!; + } + for (const arkClass of classes) { + for (const field of arkClass.getFields()) { + if (field.isStatic()) { + fields.push(field); + } + } + } + return fields; + } + + public getGlobalVariable(globalMap: Map): Local[] { + if (this.declaringArkNamespace) { + return globalMap.get(this.declaringArkNamespace.getNamespaceSignature())!; + } + return globalMap.get(this.declaringArkFile.getFileSignature())!; + } + + public getAnonymousMethodNumber(): number { + return this.anonymousMethodNumber++; + } + + public getIndexSignatureNumber(): number { + return this.indexSignatureNumber++; + } + + getExportType(): ExportType { + return ExportType.CLASS; + } + + public getInstanceInitMethod(): ArkMethod { + return this.instanceInitMethod; + } + + public getStaticInitMethod(): ArkMethod { + return this.staticInitMethod; + } + + public setInstanceInitMethod(arkMethod: ArkMethod): void { + this.instanceInitMethod = arkMethod; + } + + public setStaticInitMethod(arkMethod: ArkMethod): void { + this.staticInitMethod = arkMethod; + } + + public removeField(field: ArkField): boolean { + if (field.isStatic()) { + return this.staticFields.delete(field.getName()); + } + return this.fields.delete(field.getName()); + } + + public removeMethod(method: ArkMethod): boolean { + let rtn: boolean = false; + if (method.isStatic()) { + rtn = this.staticMethods.delete(method.getName()); + } else { + rtn = this.methods.delete(method.getName()); + } + rtn &&= this.getDeclaringArkFile().getScene().removeMethod(method); + return rtn; + } + + public validate(): ArkError { + return this.validateFields(['declaringArkFile', 'category', 'classSignature']); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkExport.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkExport.ts new file mode 100644 index 0000000000000000000000000000000000000000..8d02d8867fe6b123ed275a7df06a522c71e5f582 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkExport.ts @@ -0,0 +1,217 @@ +/* + * 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. + */ + +import { LineColPosition } from '../base/Position'; +import { ArkFile, Language } from './ArkFile'; +import { ArkSignature, ClassSignature, LocalSignature, MethodSignature, NamespaceSignature } from './ArkSignature'; +import { DEFAULT } from '../common/TSConst'; +import { ArkBaseModel, ModifierType } from './ArkBaseModel'; +import { ArkError } from '../common/ArkError'; +import { ArkMetadataKind, CommentsMetadata } from './ArkMetadata'; +import { ArkNamespace } from './ArkNamespace'; + +export type ExportSignature = NamespaceSignature | ClassSignature | MethodSignature | LocalSignature; + +export enum ExportType { + NAME_SPACE = 0, + CLASS = 1, + METHOD = 2, + LOCAL = 3, + TYPE = 4, + UNKNOWN = 9, +} + +export interface ArkExport extends ArkSignature { + getModifiers(): number; + containsModifier(modifierType: ModifierType): boolean; + + getName(): string; + + getExportType(): ExportType; +} + +export interface FromInfo { + isDefault(): boolean; + + getOriginName(): string; + + getFrom(): string | undefined; + + getDeclaringArkFile(): ArkFile; +} + +/** + * @category core/model + */ +export class ExportInfo extends ArkBaseModel implements FromInfo { + private _default?: boolean; + private nameBeforeAs?: string; + private exportClauseName: string = ''; + + private exportClauseType: ExportType = ExportType.UNKNOWN; + private arkExport?: ArkExport | null; + private exportFrom?: string; + + private originTsPosition?: LineColPosition; + private tsSourceCode?: string; + private declaringArkFile!: ArkFile; + private declaringArkNamespace?: ArkNamespace; + private constructor() { + super(); + } + + /** + * Returns the program language of the file where this export info defined. + */ + public getLanguage(): Language { + return this.getDeclaringArkFile().getLanguage(); + } + + public getFrom(): string | undefined { + return this.exportFrom; + } + + public getOriginName(): string { + return this.nameBeforeAs ?? this.exportClauseName; + } + + public getExportClauseName(): string { + return this.exportClauseName; + } + + public setExportClauseType(exportClauseType: ExportType): void { + this.exportClauseType = exportClauseType; + } + + public getExportClauseType(): ExportType { + return this.exportClauseType; + } + + public getNameBeforeAs(): string | undefined { + return this.nameBeforeAs; + } + + public setArkExport(value: ArkExport | null): void { + this.arkExport = value; + } + + public getArkExport(): ArkExport | undefined | null { + return this.arkExport; + } + + public isDefault(): boolean { + if (this.exportFrom) { + return this.nameBeforeAs === DEFAULT; + } + if (this._default === undefined) { + this._default = this.containsModifier(ModifierType.DEFAULT); + } + return this._default; + } + + public getOriginTsPosition(): LineColPosition { + return this.originTsPosition ?? LineColPosition.DEFAULT; + } + + public getTsSourceCode(): string { + return this.tsSourceCode ?? ''; + } + + public getDeclaringArkFile(): ArkFile { + return this.declaringArkFile; + } + + public getDeclaringArkNamespace(): ArkNamespace | undefined { + return this.declaringArkNamespace; + } + + public static Builder = class ArkExportBuilder { + exportInfo: ExportInfo = new ExportInfo(); + + public exportClauseName(exportClauseName: string): ArkExportBuilder { + this.exportInfo.exportClauseName = exportClauseName; + return this; + } + + public exportClauseType(exportClauseType: ExportType): ArkExportBuilder { + this.exportInfo.setExportClauseType(exportClauseType); + return this; + } + + public nameBeforeAs(nameBeforeAs: string): ArkExportBuilder { + this.exportInfo.nameBeforeAs = nameBeforeAs; + return this; + } + + public modifiers(modifiers: number): ArkExportBuilder { + this.exportInfo.modifiers = modifiers; + return this; + } + + public originTsPosition(originTsPosition: LineColPosition): ArkExportBuilder { + this.exportInfo.originTsPosition = originTsPosition; + return this; + } + + public tsSourceCode(tsSourceCode: string): ArkExportBuilder { + this.exportInfo.tsSourceCode = tsSourceCode; + return this; + } + + public declaringArkFile(value: ArkFile): ArkExportBuilder { + this.exportInfo.declaringArkFile = value; + return this; + } + + public declaringArkNamespace(value: ArkNamespace): ArkExportBuilder { + this.exportInfo.declaringArkNamespace = value; + return this; + } + + public arkExport(value: ArkExport): ArkExportBuilder { + this.exportInfo.arkExport = value; + return this; + } + + public exportFrom(exportFrom: string): ArkExportBuilder { + if (exportFrom !== '') { + this.exportInfo.exportFrom = exportFrom; + } + return this; + } + + public setLeadingComments(commentsMetadata: CommentsMetadata): ArkExportBuilder { + if (commentsMetadata.getComments().length > 0) { + this.exportInfo.setMetadata(ArkMetadataKind.LEADING_COMMENTS, commentsMetadata); + } + return this; + } + + public setTrailingComments(commentsMetadata: CommentsMetadata): ArkExportBuilder { + if (commentsMetadata.getComments().length > 0) { + this.exportInfo.setMetadata(ArkMetadataKind.TRAILING_COMMENTS, commentsMetadata); + } + return this; + } + + public build(): ExportInfo { + return this.exportInfo; + } + }; + + public validate(): ArkError { + return this.validateFields(['declaringArkFile']); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkField.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkField.ts new file mode 100644 index 0000000000000000000000000000000000000000..2fcfc43cedeea01220c84a1cba378882d59db1ff --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkField.ts @@ -0,0 +1,164 @@ +/* + * 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. + */ + +import { LineColPosition } from '../base/Position'; +import { Stmt } from '../base/Stmt'; +import { ArkClass, ClassCategory } from './ArkClass'; +import { FieldSignature } from './ArkSignature'; +import { Type } from '../base/Type'; +import { ArkBaseModel, ModifierType } from './ArkBaseModel'; +import { ArkError } from '../common/ArkError'; +import { Language } from './ArkFile'; + +export enum FieldCategory { + PROPERTY_DECLARATION = 0, + PROPERTY_ASSIGNMENT = 1, + SHORT_HAND_PROPERTY_ASSIGNMENT = 2, + SPREAD_ASSIGNMENT = 3, + PROPERTY_SIGNATURE = 4, + ENUM_MEMBER = 5, + INDEX_SIGNATURE = 6, + GET_ACCESSOR = 7, + PARAMETER_PROPERTY = 8, +} + +/** + * @category core/model + */ +export class ArkField extends ArkBaseModel { + private code: string = ''; + private category!: FieldCategory; + + private declaringClass!: ArkClass; + private questionToken: boolean = false; + private exclamationToken: boolean = false; + + private fieldSignature!: FieldSignature; + private originPosition?: LineColPosition; + + private initializer: Stmt[] = []; + + constructor() { + super(); + } + + /** + * Returns the program language of the file where this field's class defined. + */ + public getLanguage(): Language { + return this.getDeclaringArkClass().getLanguage(); + } + + public getDeclaringArkClass(): ArkClass { + return this.declaringClass; + } + + public setDeclaringArkClass(declaringClass: ArkClass): void { + this.declaringClass = declaringClass; + } + + /** + * Returns the codes of field as a **string.** + * @returns the codes of field. + */ + public getCode(): string { + return this.code; + } + + public setCode(code: string): void { + this.code = code; + } + + public getCategory(): FieldCategory { + return this.category; + } + + public setCategory(category: FieldCategory): void { + this.category = category; + } + + public getName(): string { + return this.fieldSignature.getFieldName(); + } + + public getType(): Type { + return this.fieldSignature.getType(); + } + + public getSignature(): FieldSignature { + return this.fieldSignature; + } + + public setSignature(fieldSig: FieldSignature): void { + this.fieldSignature = fieldSig; + } + + /** + * Returns an array of statements used for initialization. + * @returns An array of statements used for initialization. + */ + public getInitializer(): Stmt[] { + return this.initializer; + } + + public setInitializer(initializer: Stmt[]): void { + this.initializer = initializer; + } + + public setQuestionToken(questionToken: boolean): void { + this.questionToken = questionToken; + } + + public setExclamationToken(exclamationToken: boolean): void { + this.exclamationToken = exclamationToken; + } + + public getQuestionToken(): boolean { + return this.questionToken; + } + + public getExclamationToken(): boolean { + return this.exclamationToken; + } + + public setOriginPosition(position: LineColPosition): void { + this.originPosition = position; + } + + /** + * Returns the original position of the field at source code. + * @returns The original position of the field at source code. + */ + public getOriginPosition(): LineColPosition { + return this.originPosition ?? LineColPosition.DEFAULT; + } + + public validate(): ArkError { + return this.validateFields(['category', 'declaringClass', 'fieldSignature']); + } + + // For class field, it is default public if there is not any access modify + public isPublic(): boolean { + if ( + !this.containsModifier(ModifierType.PUBLIC) && + !this.containsModifier(ModifierType.PRIVATE) && + !this.containsModifier(ModifierType.PROTECTED) && + this.getDeclaringArkClass().getCategory() === ClassCategory.CLASS + ) { + return true; + } + return this.containsModifier(ModifierType.PUBLIC); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkFile.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkFile.ts new file mode 100644 index 0000000000000000000000000000000000000000..dc38b864b5403a93623b6445df1a4e52b9df4dcf --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkFile.ts @@ -0,0 +1,365 @@ +/* + * 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. + */ + +import { ModuleScene, Scene } from '../../Scene'; +import { ArkExport, ExportInfo } from './ArkExport'; +import { ImportInfo } from './ArkImport'; +import { ArkClass } from './ArkClass'; +import { ArkNamespace } from './ArkNamespace'; +import { AliasClassSignature, ClassSignature, FileSignature, NamespaceSignature } from './ArkSignature'; +import { ALL } from '../common/TSConst'; +import { NAME_DELIMITER } from '../common/Const'; + +export const notStmtOrExprKind = [ + 'ModuleDeclaration', + 'ClassDeclaration', + 'InterfaceDeclaration', + 'EnumDeclaration', + 'ExportDeclaration', + 'ExportAssignment', + 'MethodDeclaration', + 'Constructor', + 'FunctionDeclaration', + 'GetAccessor', + 'SetAccessor', + 'ArrowFunction', + 'FunctionExpression', + 'MethodSignature', + 'ConstructSignature', + 'CallSignature', +]; + +export enum Language { + TYPESCRIPT = 0, + ARKTS1_1 = 1, + ARKTS1_2 = 2, + JAVASCRIPT = 3, + UNKNOWN = -1, +} + +/** + * @category core/model + */ +export class ArkFile { + private language: Language; + private absoluteFilePath: string = ''; + private projectDir: string = ''; + private code: string = ''; + + private defaultClass!: ArkClass; + + // name to model + private namespaces: Map = new Map(); // don't contain nested namespaces + private classes: Map = new Map(); // don't contain class in namespace + + private importInfoMap: Map = new Map(); + private exportInfoMap: Map = new Map(); + + private scene!: Scene; + private moduleScene?: ModuleScene; + + private fileSignature: FileSignature = FileSignature.DEFAULT; + + private ohPackageJson5Path: string[] = []; + + private anonymousClassNumber: number = 0; + + constructor(language: Language) { + this.language = language; + } + + /** + * Returns the program language of the file. + */ + public getLanguage(): Language { + return this.language; + } + + public setLanguage(language: Language): void { + this.language = language; + } + + /** + * Returns the **string** name of the file, which also acts as the file's relative path. + * @returns The file's name (also means its relative path). + */ + public getName(): string { + return this.fileSignature.getFileName(); + } + + public setScene(scene: Scene): void { + this.scene = scene; + } + + /** + * Returns the scene (i.e., {@link Scene}) built for the project. The {@link Scene} is the core class of ArkAnalyzer, + * through which users can access all the information of the analyzed code (project), + * including file list, class list, method list, property list, etc. + * @returns The scene of the file. + */ + public getScene(): Scene { + return this.scene; + } + + public getModuleScene(): ModuleScene | undefined { + return this.moduleScene; + } + + public setModuleScene(moduleScene: ModuleScene): void { + this.moduleScene = moduleScene; + } + + public setProjectDir(projectDir: string): void { + this.projectDir = projectDir; + } + + public getProjectDir(): string { + return this.projectDir; + } + + /** + * Get a file path. + * @returns The absolute file path. + * @example + * 1. Read source code based on file path. + + ```typescript + let str = fs.readFileSync(arkFile.getFilePath(), 'utf8'); + ``` + */ + public getFilePath(): string { + return this.absoluteFilePath; + } + + public setFilePath(absoluteFilePath: string): void { + this.absoluteFilePath = absoluteFilePath; + } + + public setCode(code: string): void { + this.code = code; + } + + /** + * Returns the codes of file as a **string.** + * @returns the codes of file. + */ + public getCode(): string { + return this.code; + } + + public addArkClass(arkClass: ArkClass, originName?: string): void { + const name = originName ?? arkClass.getName(); + this.classes.set(name, arkClass); + if (!originName && !arkClass.isAnonymousClass()) { + const index = name.indexOf(NAME_DELIMITER); + if (index > 0) { + const originName = name.substring(0, index); + this.addArkClass(arkClass, originName); + } + } + } + + public getDefaultClass(): ArkClass { + return this.defaultClass; + } + + public setDefaultClass(defaultClass: ArkClass): void { + this.defaultClass = defaultClass; + } + + public getNamespace(namespaceSignature: NamespaceSignature): ArkNamespace | null { + const namespaceName = namespaceSignature.getNamespaceName(); + return this.getNamespaceWithName(namespaceName); + } + + public getNamespaceWithName(namespaceName: string): ArkNamespace | null { + return this.namespaces.get(namespaceName) || null; + } + + public getNamespaces(): ArkNamespace[] { + return Array.from(this.namespaces.values()); + } + + /** + * Returns the class based on its class signature. If the class could not be found, **null** will be returned. + * @param classSignature - the class signature. + * @returns A class. If there is no class, the return will be a **null**. + */ + public getClass(classSignature: ClassSignature): ArkClass | null { + const className = classSignature instanceof AliasClassSignature ? classSignature.getOriginName() : classSignature.getClassName(); + return this.getClassWithName(className); + } + + public getClassWithName(Class: string): ArkClass | null { + return this.classes.get(Class) || null; + } + + public getClasses(): ArkClass[] { + return Array.from(new Set(this.classes.values())); + } + + public addNamespace(namespace: ArkNamespace): void { + this.namespaces.set(namespace.getName(), namespace); + } + + /** + * Returns an **array** of import information. + * The import information includes: clause's name, type, modifiers, location where it is imported from, etc. + * @returns An **array** of import information. + */ + public getImportInfos(): ImportInfo[] { + return Array.from(this.importInfoMap.values()); + } + + public getImportInfoBy(name: string): ImportInfo | undefined { + return this.importInfoMap.get(name); + } + + public addImportInfo(importInfo: ImportInfo): void { + this.importInfoMap.set(importInfo.getImportClauseName(), importInfo); + } + + public removeImportInfo(importInfo: ImportInfo): boolean { + return this.importInfoMap.delete(importInfo.getImportClauseName()); + } + + public removeNamespace(namespace: ArkNamespace): boolean { + let rtn = this.namespaces.delete(namespace.getName()); + rtn &&= this.getScene().removeNamespace(namespace); + return rtn; + } + + public removeArkClass(arkClass: ArkClass): boolean { + let rtn = this.classes.delete(arkClass.getName()); + rtn &&= this.getScene().removeClass(arkClass); + return rtn; + } + + public getExportInfos(): ExportInfo[] { + const exportInfos: ExportInfo[] = []; + this.exportInfoMap.forEach((value, key) => { + if (key !== ALL || value.getFrom()) { + exportInfos.push(value); + } + }); + return exportInfos; + } + + /** + * Find out the {@link ExportInfo} of this {@link ArkFile} by the given export name. + * It returns an {@link ExportInfo} or 'undefined' if it failed to find. + * @param name + * @returns + * @example + ```typescript + // abc.ts ArkFile + export class A { + ... + } + + export namespace B { + export namespace C { + export class D {} + } + } + + // xyz.ts call getExportInfoBy + let arkFile = scene.getFile(fileSignature); + + // a is the export class A defined in abc.ts + let a = arkFile.getExportInfoBy('A'); + + // b is the export class D within namespace C defined in abc.ts + let b = arkFile.getExportInfoBy('B.C.D'); + ``` + */ + public getExportInfoBy(name: string): ExportInfo | undefined { + const separator = '.'; + const names = name.split(separator); + if (names.length === 1) { + return this.exportInfoMap.get(names[0]); + } + + let index = 0; + let currExportInfo = this.exportInfoMap.get(names[index]); + if (currExportInfo === undefined) { + return undefined; + } + + for (let i = 1; i < names.length; i++) { + const arkExport: ArkExport | null | undefined = currExportInfo.getArkExport(); + if (arkExport && arkExport instanceof ArkNamespace) { + currExportInfo = arkExport.getExportInfoBy(names[i]); + if (currExportInfo === undefined) { + return undefined; + } + } + } + return currExportInfo; + } + + public addExportInfo(exportInfo: ExportInfo, key?: string): void { + this.exportInfoMap.set(key ?? exportInfo.getExportClauseName(), exportInfo); + } + + public removeExportInfo(exportInfo: ExportInfo, key?: string): void { + if (key) { + this.exportInfoMap.delete(key); + return; + } + this.exportInfoMap.delete(exportInfo.getExportClauseName()); + } + + public getProjectName(): string { + return this.fileSignature.getProjectName(); + } + + public getModuleName(): string | undefined { + return this.moduleScene?.getModuleName(); + } + + public setOhPackageJson5Path(ohPackageJson5Path: string[]): void { + this.ohPackageJson5Path = ohPackageJson5Path; + } + + public getOhPackageJson5Path(): string[] { + return this.ohPackageJson5Path; + } + + /** + * Returns the file signature of this file. A file signature consists of project's name and file's name. + * @returns The file signature of this file. + */ + public getFileSignature(): FileSignature { + return this.fileSignature; + } + + public setFileSignature(fileSignature: FileSignature): void { + this.fileSignature = fileSignature; + } + + public getAllNamespacesUnderThisFile(): ArkNamespace[] { + let namespaces: ArkNamespace[] = []; + namespaces.push(...this.namespaces.values()); + this.namespaces.forEach(ns => { + namespaces.push(...ns.getAllNamespacesUnderThisNamespace()); + }); + return namespaces; + } + + public getAnonymousClassNumber(): number { + return this.anonymousClassNumber++; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkImport.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkImport.ts new file mode 100644 index 0000000000000000000000000000000000000000..8ff3ff50acd2f3c10cdee22d87c4f6994626bac8 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkImport.ts @@ -0,0 +1,147 @@ +/* + * 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. + */ + +import { ArkFile, Language } from './ArkFile'; +import { LineColPosition } from '../base/Position'; +import { ExportInfo, FromInfo } from './ArkExport'; +import { findExportInfo } from '../common/ModelUtils'; +import { ArkBaseModel } from './ArkBaseModel'; +import { ArkError } from '../common/ArkError'; + +/** + * @category core/model + */ +export class ImportInfo extends ArkBaseModel implements FromInfo { + private importClauseName: string = ''; + private importType: string = ''; + private importFrom?: string; + private nameBeforeAs?: string; + private declaringArkFile!: ArkFile; + + private originTsPosition?: LineColPosition; + private tsSourceCode?: string; + private lazyExportInfo?: ExportInfo | null; + + constructor() { + super(); + } + + /** + * Returns the program language of the file where this import info defined. + */ + public getLanguage(): Language { + return this.getDeclaringArkFile().getLanguage(); + } + + public build( + importClauseName: string, + importType: string, + importFrom: string, + originTsPosition: LineColPosition, + modifiers: number, + nameBeforeAs?: string + ): void { + this.setImportClauseName(importClauseName); + this.setImportType(importType); + this.setImportFrom(importFrom); + this.setOriginTsPosition(originTsPosition); + this.addModifier(modifiers); + this.setNameBeforeAs(nameBeforeAs); + } + + public getOriginName(): string { + return this.nameBeforeAs ?? this.importClauseName; + } + + /** + * Returns the export information, i.e., the actual reference generated at the time of call. + * The export information includes: clause's name, clause's type, modifiers, location + * where it is exported from, etc. If the export information could not be found, **null** will be returned. + * @returns The export information. If there is no export information, the return will be a **null**. + */ + public getLazyExportInfo(): ExportInfo | null { + if (this.lazyExportInfo === undefined) { + this.lazyExportInfo = findExportInfo(this); + } + return this.lazyExportInfo || null; + } + + public setDeclaringArkFile(declaringArkFile: ArkFile): void { + this.declaringArkFile = declaringArkFile; + } + + public getDeclaringArkFile(): ArkFile { + return this.declaringArkFile; + } + + public getImportClauseName(): string { + return this.importClauseName; + } + + public setImportClauseName(importClauseName: string): void { + this.importClauseName = importClauseName; + } + + public getImportType(): string { + return this.importType; + } + + public setImportType(importType: string): void { + this.importType = importType; + } + + public setImportFrom(importFrom: string): void { + this.importFrom = importFrom; + } + + public getNameBeforeAs(): string | undefined { + return this.nameBeforeAs; + } + + public setNameBeforeAs(nameBeforeAs: string | undefined): void { + this.nameBeforeAs = nameBeforeAs; + } + + public setOriginTsPosition(originTsPosition: LineColPosition): void { + this.originTsPosition = originTsPosition; + } + + public getOriginTsPosition(): LineColPosition { + return this.originTsPosition ?? LineColPosition.DEFAULT; + } + + public setTsSourceCode(tsSourceCode: string): void { + this.tsSourceCode = tsSourceCode; + } + + public getTsSourceCode(): string { + return this.tsSourceCode ?? ''; + } + + public getFrom(): string | undefined { + return this.importFrom; + } + + public isDefault(): boolean { + if (this.nameBeforeAs === 'default') { + return true; + } + return this.importType === 'Identifier'; + } + + public validate(): ArkError { + return this.validateFields(['declaringArkFile']); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkMetadata.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkMetadata.ts new file mode 100644 index 0000000000000000000000000000000000000000..80cbec966fc13586aeeedd49c2c55e0e45f54b23 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkMetadata.ts @@ -0,0 +1,65 @@ +/* + * 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. + */ + +import { FullPosition } from '../base/Position'; + +export enum ArkMetadataKind { + LEADING_COMMENTS, + TRAILING_COMMENTS, +} + +export interface ArkMetadataType {} + +/** + * ArkMetadata + * @example + * // get leading comments + * let stmt: Stmt = xxx; + * let comments = stmt.getMetadata(ArkMetadataKind.LEADING_COMMENTS) || []; + * comments.forEach((comment) => { + * logger.info(comment); + * }); + */ +export class ArkMetadata { + protected metadata?: Map; + + public getMetadata(kind: ArkMetadataKind): ArkMetadataType | undefined { + return this.metadata?.get(kind); + } + + public setMetadata(kind: ArkMetadataKind, value: ArkMetadataType): void { + if (!this.metadata) { + this.metadata = new Map(); + } + this.metadata.set(kind, value); + } +} + +export type CommentItem = { + content: string; + position: FullPosition; +}; + +export class CommentsMetadata implements ArkMetadataType { + private comments: CommentItem[] = []; + + constructor(comments: CommentItem[]) { + this.comments = comments; + } + + public getComments(): CommentItem[] { + return this.comments; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3476d3567b9c43686118ab0ebe8d4f1d266d61e --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkMethod.ts @@ -0,0 +1,724 @@ +/* + * 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. + */ + +import { ArkParameterRef, ArkThisRef } from '../base/Ref'; +import { ArkAssignStmt, ArkReturnStmt, Stmt } from '../base/Stmt'; +import { ClassType, EnumValueType, FunctionType, GenericType, LiteralType, Type, UnionType } from '../base/Type'; +import { Value } from '../base/Value'; +import { Cfg } from '../graph/Cfg'; +import { ViewTree } from '../graph/ViewTree'; +import { ArkBody } from './ArkBody'; +import { ArkClass, ClassCategory } from './ArkClass'; +import { MethodSignature, MethodSubSignature } from './ArkSignature'; +import { BodyBuilder } from './builder/BodyBuilder'; +import { ArkExport, ExportType } from './ArkExport'; +import { ANONYMOUS_METHOD_PREFIX, DEFAULT_ARK_METHOD_NAME } from '../common/Const'; +import { getColNo, getLineNo, LineCol, setCol, setLine } from '../base/Position'; +import { ArkBaseModel, ModifierType } from './ArkBaseModel'; +import { ArkError, ArkErrorCode } from '../common/ArkError'; +import { CALL_BACK } from '../common/EtsConst'; +import { Scene } from '../../Scene'; +import { Constant } from '../base/Constant'; +import { Local } from '../base/Local'; +import { ArkFile, Language } from './ArkFile'; +import { CONSTRUCTOR_NAME } from '../common/TSConst'; +import { MethodParameter } from './builder/ArkMethodBuilder'; + +export const arkMethodNodeKind = [ + 'MethodDeclaration', + 'Constructor', + 'FunctionDeclaration', + 'GetAccessor', + 'SetAccessor', + 'ArrowFunction', + 'FunctionExpression', + 'MethodSignature', + 'ConstructSignature', + 'CallSignature', +]; + +/** + * @category core/model + */ +export class ArkMethod extends ArkBaseModel implements ArkExport { + private code?: string; + private declaringArkClass!: ArkClass; + // used for the nested function to locate its outer function + private outerMethod?: ArkMethod; + + private genericTypes?: GenericType[]; + + private methodDeclareSignatures?: MethodSignature[]; + private methodDeclareLineCols?: LineCol[]; + + private methodSignature?: MethodSignature; + private lineCol?: LineCol; + + private body?: ArkBody; + private viewTree?: ViewTree; + + private bodyBuilder?: BodyBuilder; + + private isGeneratedFlag: boolean = false; + private asteriskToken: boolean = false; + private questionToken: boolean = false; + + constructor() { + super(); + } + + /** + * Returns the program language of the file where this method defined. + */ + public getLanguage(): Language { + return this.getDeclaringArkClass().getLanguage(); + } + + public getExportType(): ExportType { + return ExportType.METHOD; + } + + public getName(): string { + return this.getSignature().getMethodSubSignature().getMethodName(); + } + + /** + * Returns the codes of method as a **string.** + * @returns the codes of method. + */ + public getCode(): string | undefined { + return this.code; + } + + public setCode(code: string): void { + this.code = code; + } + + /** + * Get all lines of the method's declarations or null if the method has no seperated declaration. + * @returns null or the lines of the method's declarations with number type. + */ + public getDeclareLines(): number[] | null { + if (this.methodDeclareLineCols === undefined) { + return null; + } + let lines: number[] = []; + this.methodDeclareLineCols.forEach(lineCol => { + lines.push(getLineNo(lineCol)); + }); + return lines; + } + + /** + * Get all columns of the method's declarations or null if the method has no seperated declaration. + * @returns null or the columns of the method's declarations with number type. + */ + public getDeclareColumns(): number[] | null { + if (this.methodDeclareLineCols === undefined) { + return null; + } + let columns: number[] = []; + this.methodDeclareLineCols.forEach(lineCol => { + columns.push(getColNo(lineCol)); + }); + return columns; + } + + /** + * Set lines and columns of the declarations with number type inputs and then encoded them to LineCol type. + * The length of lines and columns should be the same otherwise they cannot be encoded together. + * @param lines - the number of lines. + * @param columns - the number of columns. + * @returns + */ + public setDeclareLinesAndCols(lines: number[], columns: number[]): void { + if (lines?.length !== columns?.length) { + return; + } + this.methodDeclareLineCols = []; + lines.forEach((line, index) => { + let lineCol: LineCol = 0; + lineCol = setLine(lineCol, line); + lineCol = setCol(lineCol, columns[index]); + (this.methodDeclareLineCols as LineCol[]).push(lineCol); + }); + } + + /** + * Set lineCols of the declarations directly with LineCol type input. + * @param lineCols - the encoded lines and columns with LineCol type. + * @returns + */ + public setDeclareLineCols(lineCols: LineCol[]): void { + this.methodDeclareLineCols = lineCols; + } + + /** + * Get encoded lines and columns of the method's declarations or null if the method has no seperated declaration. + * @returns null or the encoded lines and columns of the method's declarations with LineCol type. + */ + public getDeclareLineCols(): LineCol[] | null { + return this.methodDeclareLineCols ?? null; + } + + /** + * Get line of the method's implementation or null if the method has no implementation. + * @returns null or the number of the line. + */ + public getLine(): number | null { + if (this.lineCol === undefined) { + return null; + } + return getLineNo(this.lineCol); + } + + /** + * Set line of the implementation with line number input. + * The line number will be encoded together with the original column number. + * @param line - the line number of the method implementation. + * @returns + */ + public setLine(line: number): void { + if (this.lineCol === undefined) { + this.lineCol = 0; + } + this.lineCol = setLine(this.lineCol, line); + } + + /** + * Get column of the method's implementation or null if the method has no implementation. + * @returns null or the number of the column. + */ + public getColumn(): number | null { + if (this.lineCol === undefined) { + return null; + } + return getColNo(this.lineCol); + } + + /** + * Set column of the implementation with column number input. + * The column number will be encoded together with the original line number. + * @param column - the column number of the method implementation. + * @returns + */ + public setColumn(column: number): void { + if (this.lineCol === undefined) { + this.lineCol = 0; + } + this.lineCol = setCol(this.lineCol, column); + } + + /** + * Get encoded line and column of the method's implementation or null if the method has no implementation. + * @returns null or the encoded line and column of the method's implementation with LineCol type. + */ + public getLineCol(): LineCol | null { + return this.lineCol ?? null; + } + + /** + * Set lineCol of the implementation directly with LineCol type input. + * @param lineCol - the encoded line and column with LineCol type. + * @returns + */ + public setLineCol(lineCol: LineCol): void { + this.lineCol = lineCol; + } + + /** + * Returns the declaring class of the method. + * @returns The declaring class of the method. + */ + public getDeclaringArkClass(): ArkClass { + return this.declaringArkClass; + } + + public setDeclaringArkClass(declaringArkClass: ArkClass): void { + this.declaringArkClass = declaringArkClass; + } + + public getDeclaringArkFile(): ArkFile { + return this.declaringArkClass.getDeclaringArkFile(); + } + + public isDefaultArkMethod(): boolean { + return this.getName() === DEFAULT_ARK_METHOD_NAME; + } + + public isAnonymousMethod(): boolean { + return this.getName().startsWith(ANONYMOUS_METHOD_PREFIX); + } + + public getParameters(): MethodParameter[] { + return this.getSignature().getMethodSubSignature().getParameters(); + } + + public getReturnType(): Type { + return this.getSignature().getType(); + } + + /** + * Get all declare signatures. + * The results could be null if there is no seperated declaration of the method. + * @returns null or the method declare signatures. + */ + public getDeclareSignatures(): MethodSignature[] | null { + return this.methodDeclareSignatures ?? null; + } + + /** + * Get the index of the matched method declare signature among all declare signatures. + * The index will be -1 if there is no matched signature found. + * @param targetSignature - the target declare signature want to search. + * @returns -1 or the index of the matched signature. + */ + public getDeclareSignatureIndex(targetSignature: MethodSignature): number { + let declareSignatures = this.methodDeclareSignatures; + if (declareSignatures === undefined) { + return -1; + } + for (let i = 0; i < declareSignatures.length; i++) { + if (declareSignatures[i].isMatch(targetSignature)) { + return i; + } + } + return -1; + } + + /** + * Get the method signature of the implementation. + * The signature could be null if the method is only a declaration which body is undefined. + * @returns null or the method implementation signature. + */ + public getImplementationSignature(): MethodSignature | null { + return this.methodSignature ?? null; + } + + /** + * Get the method signature of the implementation or the first declaration if there is no implementation. + * For a method, the implementation and declaration signatures must not be undefined at the same time. + * A {@link MethodSignature} includes: + * - Class Signature: indicates which class this method belong to. + * - Method SubSignature: indicates the detail info of this method such as method name, parameters, returnType, etc. + * @returns The method signature. + * @example + * 1. Get the signature of method mtd. + + ```typescript + let signature = mtd.getSignature(); + // ... ... + ``` + */ + public getSignature(): MethodSignature { + return this.methodSignature ?? (this.methodDeclareSignatures as MethodSignature[])[0]; + } + + /** + * Set signatures of all declarations. + * It will reset the declaration signatures if they are already defined before. + * @param signatures - one signature or a list of signatures. + * @returns + */ + public setDeclareSignatures(signatures: MethodSignature | MethodSignature[]): void { + if (Array.isArray(signatures)) { + this.methodDeclareSignatures = signatures; + } else { + this.methodDeclareSignatures = [signatures]; + } + } + + /** + * Reset signature of one declaration with the specified index. + * Will do nothing if the index doesn't exist. + * @param signature - new signature want to set. + * @param index - index of signature want to set. + * @returns + */ + public setDeclareSignatureWithIndex(signature: MethodSignature, index: number): void { + if (this.methodDeclareSignatures === undefined || this.methodDeclareSignatures.length <= index) { + return; + } + this.methodDeclareSignatures[index] = signature; + } + + /** + * Set signature of implementation. + * It will reset the implementation signature if it is already defined before. + * @param signature - signature of implementation. + * @returns + */ + public setImplementationSignature(signature: MethodSignature): void { + this.methodSignature = signature; + } + + public getSubSignature(): MethodSubSignature { + return this.getSignature().getMethodSubSignature(); + } + + public getGenericTypes(): GenericType[] | undefined { + return this.genericTypes; + } + + public isGenericsMethod(): boolean { + return this.genericTypes !== undefined; + } + + public setGenericTypes(genericTypes: GenericType[]): void { + this.genericTypes = genericTypes; + } + + public getBodyBuilder(): BodyBuilder | undefined { + return this.bodyBuilder; + } + + /** + * Get {@link ArkBody} of a Method. + * A {@link ArkBody} contains the CFG and actual instructions or operations to be executed for a method. + * It is analogous to the body of a function or method in high-level programming languages, + * which contains the statements and expressions that define what the function does. + * @returns The {@link ArkBody} of a method. + * @example + * 1. Get cfg or stmt through ArkBody. + + ```typescript + let cfg = this.scene.getMethod()?.getBody().getCfg(); + const body = arkMethod.getBody() + ``` + + 2. Get local variable through ArkBody. + + ```typescript + arkClass.getDefaultArkMethod()?.getBody().getLocals.forEach(local=>{...}) + let locals = arkFile().getDefaultClass().getDefaultArkMethod()?.getBody()?.getLocals(); + ``` + */ + public getBody(): ArkBody | undefined { + return this.body; + } + + public setBody(body: ArkBody): void { + this.body = body; + } + + /** + * Get the CFG (i.e., control flow graph) of a method. + * The CFG is a graphical representation of all possible control flow paths within a method's body. + * A CFG consists of blocks, statements and goto control jumps. + * @returns The CFG (i.e., control flow graph) of a method. + * @example + * 1. get stmt through ArkBody cfg. + + ```typescript + body = arkMethod.getBody(); + const cfg = body.getCfg(); + for (const threeAddressStmt of cfg.getStmts()) { + ... ... + } + ``` + + 2. get blocks through ArkBody cfg. + + ```typescript + const body = arkMethod.getBody(); + const blocks = [...body.getCfg().getBlocks()]; + for (let i=0; i stmts.push(stmt)); + } + let results: Value[] = []; + for (let stmt of stmts) { + if (stmt instanceof ArkAssignStmt) { + if (stmt.getRightOp() instanceof ArkParameterRef) { + results.push((stmt as ArkAssignStmt).getLeftOp()); + } + } + if (results.length === this.getParameters().length) { + return results; + } + } + return results; + } + + public getThisInstance(): Value | null { + // 获取方法体中This实例 + let stmts: Stmt[] = []; + if (this.getCfg()) { + const cfg = this.getCfg() as Cfg; + cfg.getStmts().forEach(stmt => stmts.push(stmt)); + } + for (let stmt of stmts) { + if (stmt instanceof ArkAssignStmt) { + if (stmt.getRightOp() instanceof ArkThisRef) { + return stmt.getLeftOp(); + } + } + } + return null; + } + + public getReturnValues(): Value[] { + // 获取方法体中return值实例 + let resultValues: Value[] = []; + this.getCfg() + ?.getStmts() + .forEach(stmt => { + if (stmt instanceof ArkReturnStmt) { + resultValues.push(stmt.getOp()); + } + }); + return resultValues; + } + + public getReturnStmt(): Stmt[] { + return this.getCfg()! + .getStmts() + .filter(stmt => stmt instanceof ArkReturnStmt); + } + + public setViewTree(viewTree: ViewTree): void { + this.viewTree = viewTree; + } + + public getViewTree(): ViewTree | undefined { + return this.viewTree; + } + + public hasViewTree(): boolean { + return this.viewTree !== undefined; + } + + public setBodyBuilder(bodyBuilder: BodyBuilder): void { + this.bodyBuilder = bodyBuilder; + if (this.getDeclaringArkFile().getScene().buildClassDone()) { + this.buildBody(); + } + } + + public freeBodyBuilder(): void { + this.bodyBuilder = undefined; + } + + public buildBody(): void { + if (this.bodyBuilder) { + const arkBody: ArkBody | null = this.bodyBuilder.build(); + if (arkBody) { + this.setBody(arkBody); + arkBody.getCfg().setDeclaringMethod(this); + if (this.getOuterMethod() === undefined) { + this.bodyBuilder.handleGlobalAndClosure(); + } + } + } + } + + public isGenerated(): boolean { + return this.isGeneratedFlag; + } + + public setIsGeneratedFlag(isGeneratedFlag: boolean): void { + this.isGeneratedFlag = isGeneratedFlag; + } + + public getAsteriskToken(): boolean { + return this.asteriskToken; + } + + public setAsteriskToken(asteriskToken: boolean): void { + this.asteriskToken = asteriskToken; + } + + public validate(): ArkError { + const declareSignatures = this.getDeclareSignatures(); + const declareLineCols = this.getDeclareLineCols(); + const signature = this.getImplementationSignature(); + const lineCol = this.getLineCol(); + + if (declareSignatures === null && signature === null) { + return { + errCode: ArkErrorCode.METHOD_SIGNATURE_UNDEFINED, + errMsg: 'methodDeclareSignatures and methodSignature are both undefined.', + }; + } + if ((declareSignatures === null) !== (declareLineCols === null)) { + return { + errCode: ArkErrorCode.METHOD_SIGNATURE_LINE_UNMATCHED, + errMsg: 'methodDeclareSignatures and methodDeclareLineCols are not matched.', + }; + } + if (declareSignatures !== null && declareLineCols !== null && declareSignatures.length !== declareLineCols.length) { + return { + errCode: ArkErrorCode.METHOD_SIGNATURE_LINE_UNMATCHED, + errMsg: 'methodDeclareSignatures and methodDeclareLineCols are not matched.', + }; + } + if ((signature === null) !== (lineCol === null)) { + return { + errCode: ArkErrorCode.METHOD_SIGNATURE_LINE_UNMATCHED, + errMsg: 'methodSignature and lineCol are not matched.', + }; + } + return this.validateFields(['declaringArkClass']); + } + + public matchMethodSignature(args: Value[]): MethodSignature { + const signatures = this.methodDeclareSignatures?.filter(f => { + const parameters = f.getMethodSubSignature().getParameters(); + const max = parameters.length; + let min = 0; + while (min < max && !parameters[min].isOptional()) { + min++; + } + return args.length >= min && args.length <= max; + }); + const scene = this.getDeclaringArkFile().getScene(); + return ( + signatures?.find(p => { + const parameters = p.getMethodSubSignature().getParameters(); + for (let i = 0; i < parameters.length; i++) { + if (!args[i]) { + return parameters[i].isOptional(); + } + const isMatched = this.matchParam(parameters[i].getType(), args[i], scene); + if (!isMatched) { + return false; + } + } + return true; + }) ?? + signatures?.[0] ?? + this.getSignature() + ); + } + + private matchParam(paramType: Type, arg: Value, scene: Scene): boolean { + const argType = arg.getType(); + if (arg instanceof Local) { + const stmt = arg.getDeclaringStmt(); + if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof Constant) { + arg = stmt.getRightOp(); + } + } + if (paramType instanceof UnionType) { + let matched = false; + for (const e of paramType.getTypes()) { + if (argType.constructor === e.constructor) { + matched = true; + break; + } + } + return matched; + } else if (argType instanceof FunctionType && paramType instanceof FunctionType) { + return argType.getMethodSignature().getParamLength() === paramType.getMethodSignature().getParamLength(); + } else if (paramType instanceof ClassType && paramType.getClassSignature().getClassName().includes(CALL_BACK)) { + return argType instanceof FunctionType; + } else if (paramType instanceof LiteralType && arg instanceof Constant) { + return ( + arg.getValue().replace(/[\"|\']/g, '') === + paramType + .getLiteralName() + .toString() + .replace(/[\"|\']/g, '') + ); + } else if (paramType instanceof ClassType && argType instanceof EnumValueType) { + return paramType.getClassSignature() === argType.getFieldSignature().getDeclaringSignature(); + } else if (paramType instanceof EnumValueType) { + if (argType instanceof EnumValueType) { + return paramType.getFieldSignature() === argType.getFieldSignature(); + } else if (argType.constructor === paramType.getConstant()?.getType().constructor && arg instanceof Constant) { + return paramType.getConstant()?.getValue() === arg.getValue(); + } + } + return argType.constructor === paramType.constructor; + } + + public getOuterMethod(): ArkMethod | undefined { + return this.outerMethod; + } + + public setOuterMethod(method: ArkMethod): void { + this.outerMethod = method; + } + + public getFunctionLocal(name: string): Local | null { + const local = this.getBody()?.getLocals().get(name); + return local?.getType() instanceof FunctionType ? local : null; + } + + public setQuestionToken(questionToken: boolean): void { + this.questionToken = questionToken; + } + + public getQuestionToken(): boolean { + return this.questionToken; + } + + // For class method, if there is no public/private/protected access modifier, it is actually public + public isPublic(): boolean { + if ( + !this.containsModifier(ModifierType.PUBLIC) && + !this.containsModifier(ModifierType.PRIVATE) && + !this.containsModifier(ModifierType.PROTECTED) && + !this.getDeclaringArkClass().isDefaultArkClass() && + !this.isGenerated() && + !this.isAnonymousMethod() && + this.getName() !== CONSTRUCTOR_NAME && + this.getDeclaringArkClass().getCategory() === ClassCategory.CLASS + ) { + return true; + } + return this.containsModifier(ModifierType.PUBLIC); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkNamespace.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkNamespace.ts new file mode 100644 index 0000000000000000000000000000000000000000..683ed796f314abdecf57d7919204898c8ccc980c --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkNamespace.ts @@ -0,0 +1,280 @@ +/* + * 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. + */ + +import { ArkExport, ExportInfo, ExportType } from './ArkExport'; +import { ArkClass } from './ArkClass'; +import { ArkFile, Language } from './ArkFile'; +import { ArkMethod } from './ArkMethod'; +import { AliasClassSignature, ClassSignature, NamespaceSignature } from './ArkSignature'; +import { ALL } from '../common/TSConst'; +import { getColNo, getLineNo, LineCol, setCol, setLine, setLineCol } from '../base/Position'; +import { ArkBaseModel } from './ArkBaseModel'; +import { ArkError } from '../common/ArkError'; +import { NAME_DELIMITER } from '../common/Const'; + +/** + * @category core/model + */ +export class ArkNamespace extends ArkBaseModel implements ArkExport { + private sourceCodes: string[] = ['']; + private lineCols: LineCol[] = []; + + private declaringArkFile!: ArkFile; + private declaringArkNamespace: ArkNamespace | null = null; + + private declaringInstance!: ArkFile | ArkNamespace; + + private exportInfos: Map = new Map(); + + private defaultClass!: ArkClass; + + // name to model + private namespaces: Map = new Map(); // don't contain nested namespace + private classes: Map = new Map(); + + private namespaceSignature!: NamespaceSignature; + + private anonymousClassNumber: number = 0; + + constructor() { + super(); + } + + /** + * Returns the program language of the file where this namespace defined. + */ + public getLanguage(): Language { + return this.getDeclaringArkFile().getLanguage(); + } + + public addNamespace(namespace: ArkNamespace): void { + this.namespaces.set(namespace.getName(), namespace); + } + + public getNamespace(namespaceSignature: NamespaceSignature): ArkNamespace | null { + const namespaceName = namespaceSignature.getNamespaceName(); + return this.getNamespaceWithName(namespaceName); + } + + public getNamespaceWithName(namespaceName: string): ArkNamespace | null { + return this.namespaces.get(namespaceName) || null; + } + + public getNamespaces(): ArkNamespace[] { + return Array.from(this.namespaces.values()); + } + + public setSignature(namespaceSignature: NamespaceSignature): void { + this.namespaceSignature = namespaceSignature; + } + + public getSignature(): NamespaceSignature { + return this.namespaceSignature; + } + + public getNamespaceSignature(): NamespaceSignature { + return this.namespaceSignature; + } + + public getName(): string { + return this.namespaceSignature.getNamespaceName(); + } + + public getCode(): string { + return this.sourceCodes[0]; + } + + public setCode(sourceCode: string): void { + this.sourceCodes[0] = sourceCode; + } + + /* + * Get multiple sourceCodes when the arkNamespace is merged from multiple namespace with the same name + */ + public getCodes(): string[] { + return this.sourceCodes; + } + + /* + * Set multiple sourceCodes when the arkNamespace is merged from multiple namespace with the same name + */ + public setCodes(sourceCodes: string[]): void { + this.sourceCodes = []; + this.sourceCodes.push(...sourceCodes); + } + + public addCode(sourceCode: string): void { + this.sourceCodes.push(sourceCode); + } + + public getLine(): number { + return getLineNo(this.lineCols[0]); + } + + public setLine(line: number): void { + this.lineCols[0] = setLine(this.lineCols[0], line); + } + + public getColumn(): number { + return getColNo(this.lineCols[0]); + } + + public setColumn(column: number): void { + this.lineCols[0] = setCol(this.lineCols[0], column); + } + + public getLineColPairs(): [number, number][] { + const lineColPairs: [number, number][] = []; + this.lineCols.forEach(lineCol => { + lineColPairs.push([getLineNo(lineCol), getColNo(lineCol)]); + }); + return lineColPairs; + } + + public setLineCols(lineColPairs: [number, number][]): void { + this.lineCols = []; + lineColPairs.forEach(lineColPair => { + this.lineCols.push(setLineCol(lineColPair[0], lineColPair[1])); + }); + } + + public getDeclaringInstance(): ArkNamespace | ArkFile { + return this.declaringInstance; + } + + public setDeclaringInstance(declaringInstance: ArkFile | ArkNamespace): void { + this.declaringInstance = declaringInstance; + } + + public getDeclaringArkFile(): ArkFile { + return this.declaringArkFile; + } + + public setDeclaringArkFile(declaringArkFile: ArkFile): void { + this.declaringArkFile = declaringArkFile; + } + + public getDeclaringArkNamespace(): ArkNamespace | null { + return this.declaringArkNamespace; + } + + public setDeclaringArkNamespace(declaringArkNamespace: ArkNamespace): void { + this.declaringArkNamespace = declaringArkNamespace; + } + + public getClass(classSignature: ClassSignature): ArkClass | null { + const className = classSignature instanceof AliasClassSignature ? classSignature.getOriginName() : classSignature.getClassName(); + return this.getClassWithName(className); + } + + public getClassWithName(Class: string): ArkClass | null { + return this.classes.get(Class) || null; + } + + public getClasses(): ArkClass[] { + return Array.from(new Set(this.classes.values())); + } + + public addArkClass(arkClass: ArkClass, originName?: string): void { + const name = originName ?? arkClass.getName(); + this.classes.set(name, arkClass); + if (!originName && !arkClass.isAnonymousClass()) { + const index = name.indexOf(NAME_DELIMITER); + if (index > 0) { + const originName = name.substring(0, index); + this.addArkClass(arkClass, originName); + } + } + } + + public getExportInfos(): ExportInfo[] { + const exportInfos: ExportInfo[] = []; + this.exportInfos.forEach((value, key) => { + if (key !== ALL || value.getFrom()) { + exportInfos.push(value); + } + }); + return exportInfos; + } + + public getExportInfoBy(name: string): ExportInfo | undefined { + return this.exportInfos.get(name); + } + + public addExportInfo(exportInfo: ExportInfo): void { + this.exportInfos.set(exportInfo.getExportClauseName(), exportInfo); + } + + public getDefaultClass(): ArkClass { + return this.defaultClass; + } + + public setDefaultClass(defaultClass: ArkClass): void { + this.defaultClass = defaultClass; + } + + public getAllMethodsUnderThisNamespace(): ArkMethod[] { + let methods: ArkMethod[] = []; + this.classes.forEach(cls => { + methods.push(...cls.getMethods()); + }); + this.namespaces.forEach(ns => { + methods.push(...ns.getAllMethodsUnderThisNamespace()); + }); + return methods; + } + + public getAllClassesUnderThisNamespace(): ArkClass[] { + let classes: ArkClass[] = []; + classes.push(...this.classes.values()); + this.namespaces.forEach(ns => { + classes.push(...ns.getAllClassesUnderThisNamespace()); + }); + return classes; + } + + public getAllNamespacesUnderThisNamespace(): ArkNamespace[] { + let namespaces: ArkNamespace[] = []; + namespaces.push(...this.namespaces.values()); + this.namespaces.forEach(ns => { + namespaces.push(...ns.getAllNamespacesUnderThisNamespace()); + }); + return namespaces; + } + + public getAnonymousClassNumber(): number { + return this.anonymousClassNumber++; + } + + getExportType(): ExportType { + return ExportType.NAME_SPACE; + } + + public removeArkClass(arkClass: ArkClass): boolean { + let rtn = this.classes.delete(arkClass.getName()); + rtn &&= this.getDeclaringArkFile().getScene().removeClass(arkClass); + return rtn; + } + + public removeNamespace(namespace: ArkNamespace): boolean { + let rtn = this.namespaces.delete(namespace.getName()); + rtn &&= this.getDeclaringArkFile().getScene().removeNamespace(namespace); + return rtn; + } + + public validate(): ArkError { + return this.validateFields(['declaringArkFile', 'declaringInstance', 'namespaceSignature', 'defaultClass']); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/ArkSignature.ts b/ets2panda/linter/arkanalyzer/src/core/model/ArkSignature.ts new file mode 100644 index 0000000000000000000000000000000000000000..16fa6a76b8a27a4c3c88229da70fba5b4bffe483 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/ArkSignature.ts @@ -0,0 +1,490 @@ +/* + * 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. + */ + +import path from 'path'; +import { transfer2UnixPath } from '../../utils/pathTransfer'; +import { ClassType, Type } from '../base/Type'; +import { MethodParameter } from './builder/ArkMethodBuilder'; +import { + ANONYMOUS_CLASS_PREFIX, + LEXICAL_ENV_NAME_PREFIX, + NAME_DELIMITER, + UNKNOWN_CLASS_NAME, + UNKNOWN_FILE_NAME, + UNKNOWN_NAMESPACE_NAME, + UNKNOWN_PROJECT_NAME, +} from '../common/Const'; +import { CryptoUtils } from '../../utils/crypto_utils'; + +export type Signature = FileSignature | NamespaceSignature | ClassSignature | MethodSignature | FieldSignature | LocalSignature | AliasTypeSignature; + +export interface ArkSignature { + getSignature(): Signature; +} + +/** + * @category core/model + */ +export class FileSignature { + private projectName: string; + private fileName: string; + private hashcode: number; + + public static readonly DEFAULT: FileSignature = new FileSignature(UNKNOWN_PROJECT_NAME, UNKNOWN_FILE_NAME); + + constructor(projectName: string, fileName: string) { + this.projectName = projectName; + this.fileName = transfer2UnixPath(fileName); + this.hashcode = CryptoUtils.hashcode(this.toString()); + } + + public getProjectName(): string { + return this.projectName; + } + + public getFileName(): string { + return this.fileName; + } + + public toString(): string { + return `@${this.projectName}/${this.fileName}: `; + } + + public toMapKey(): string { + return `${this.hashcode}${path.basename(this.fileName)}`; + } +} + +export class NamespaceSignature { + private namespaceName: string; + private declaringFileSignature: FileSignature; + private declaringNamespaceSignature: NamespaceSignature | null; + + public static readonly DEFAULT: NamespaceSignature = new NamespaceSignature(UNKNOWN_NAMESPACE_NAME, FileSignature.DEFAULT, null); + + constructor(namespaceName: string, declaringFileSignature: FileSignature, declaringNamespaceSignature: NamespaceSignature | null = null) { + this.namespaceName = namespaceName; + this.declaringFileSignature = declaringFileSignature; + this.declaringNamespaceSignature = declaringNamespaceSignature; + } + + public getNamespaceName(): string { + return this.namespaceName; + } + + public getDeclaringFileSignature(): FileSignature { + return this.declaringFileSignature; + } + + public getDeclaringNamespaceSignature(): NamespaceSignature | null { + return this.declaringNamespaceSignature; + } + + public toString(): string { + if (this.declaringNamespaceSignature) { + return this.declaringNamespaceSignature.toString() + '.' + this.namespaceName; + } else { + return this.declaringFileSignature.toString() + this.namespaceName; + } + } + + public toMapKey(): string { + if (this.declaringNamespaceSignature) { + return this.declaringNamespaceSignature.toMapKey() + '.' + this.namespaceName; + } else { + return this.declaringFileSignature.toMapKey() + this.namespaceName; + } + } +} + +export class ClassSignature { + private declaringFileSignature: FileSignature; + private declaringNamespaceSignature: NamespaceSignature | null; + private className: string; + + public static readonly DEFAULT: ClassSignature = new ClassSignature(UNKNOWN_CLASS_NAME, FileSignature.DEFAULT, null); + + constructor(className: string, declaringFileSignature: FileSignature, declaringNamespaceSignature: NamespaceSignature | null = null) { + this.className = className; + this.declaringFileSignature = declaringFileSignature; + this.declaringNamespaceSignature = declaringNamespaceSignature; + } + + /** + * Returns the declaring file signature. + * @returns The declaring file signature. + */ + public getDeclaringFileSignature(): FileSignature { + return this.declaringFileSignature; + } + + /** + * Get the declaring namespace's signature. + * @returns the declaring namespace's signature. + */ + public getDeclaringNamespaceSignature(): NamespaceSignature | null { + return this.declaringNamespaceSignature; + } + + /** + * Get the **string** name of class from the the class signature. The default value is `""`. + * @returns The name of this class. + */ + public getClassName(): string { + return this.className; + } + + /** + * + * @returns The name of the declare class. + */ + public getDeclaringClassName(): string { + if (this.className.startsWith(ANONYMOUS_CLASS_PREFIX)) { + let temp = this.className; + do { + temp = temp.substring(temp.indexOf(NAME_DELIMITER) + 1, temp.lastIndexOf('.')); + } while (temp.startsWith(ANONYMOUS_CLASS_PREFIX)); + return temp; + } + return this.className; + } + + public setClassName(className: string): void { + this.className = className; + } + + public getType(): ClassType { + return new ClassType(this); + } + + public toString(): string { + if (this.declaringNamespaceSignature) { + return this.declaringNamespaceSignature.toString() + '.' + this.className; + } else { + return this.declaringFileSignature.toString() + this.className; + } + } + + public toMapKey(): string { + if (this.declaringNamespaceSignature) { + return this.declaringNamespaceSignature.toMapKey() + '.' + this.className; + } else { + return this.declaringFileSignature.toMapKey() + this.className; + } + } +} + +/** + * `AliasClassSignature` is used to extend `ClassSignature`, preserving the actual name used during invocation. + */ +export class AliasClassSignature extends ClassSignature { + private readonly aliasName: string; + + constructor(aliasName: string, signature: ClassSignature) { + super(signature.getClassName(), signature.getDeclaringFileSignature(), signature.getDeclaringNamespaceSignature()); + this.aliasName = aliasName; + } + + /** + * Returns the name used in the code. + */ + public getClassName(): string { + return this.aliasName; + } + + /** + * Return the original name of declared class + */ + public getOriginName(): string { + return super.getClassName(); + } +} + +export type BaseSignature = ClassSignature | NamespaceSignature; + +export class FieldSignature { + private declaringSignature: BaseSignature; + private fieldName: string; + private type: Type; + private staticFlag: boolean; + + constructor(fieldName: string, declaringSignature: BaseSignature, type: Type, staticFlag: boolean = false) { + this.fieldName = fieldName; + this.declaringSignature = declaringSignature; + this.type = type; + this.staticFlag = staticFlag; + } + + public getDeclaringSignature(): BaseSignature { + return this.declaringSignature; + } + + public getBaseName(): string { + return this.declaringSignature instanceof ClassSignature ? this.declaringSignature.getClassName() : this.declaringSignature.getNamespaceName(); + } + + public getFieldName(): string { + return this.fieldName; + } + + public getType(): Type { + return this.type; + } + + public isStatic(): boolean { + return this.staticFlag; + } + + // temp for being compatible with existing type inference + public setType(type: Type): void { + this.type = type; + } + + // temp for being compatible with existing type inference + public setStaticFlag(flag: boolean): void { + this.staticFlag = flag; + } + + public toString(): string { + let tmpSig = this.fieldName; + if (this.isStatic()) { + tmpSig = '[static]' + tmpSig; + } + return this.getDeclaringSignature().toString() + '.' + tmpSig; + } +} + +export class MethodSubSignature { + private methodName: string; + private parameters: MethodParameter[]; + private returnType: Type; + private staticFlag: boolean; + + constructor(methodName: string, parameters: MethodParameter[], returnType: Type, staticFlag: boolean = false) { + this.methodName = methodName; + this.parameters = parameters; + this.returnType = returnType; + this.staticFlag = staticFlag; + } + + public getMethodName(): string { + return this.methodName; + } + + public getParameters(): MethodParameter[] { + return this.parameters; + } + + public getParameterTypes(): Type[] { + const parameterTypes: Type[] = []; + this.parameters.forEach(parameter => { + parameterTypes.push(parameter.getType()); + }); + return parameterTypes; + } + + public getReturnType(): Type { + return this.returnType; + } + + public setReturnType(returnType: Type): void { + this.returnType = returnType; + } + + public isStatic(): boolean { + return this.staticFlag; + } + + public toString(ptrName?: string): string { + let paraStr = ''; + this.getParameterTypes().forEach(parameterType => { + paraStr += parameterType.toString() + ', '; + }); + paraStr = paraStr.replace(/, $/, ''); + let tmpSig = `${ptrName ?? this.getMethodName()}(${paraStr})`; + if (this.isStatic()) { + tmpSig = '[static]' + tmpSig; + } + return tmpSig; + } +} + +/** + * @category core/model + */ +export class MethodSignature { + private declaringClassSignature: ClassSignature; + private methodSubSignature: MethodSubSignature; + + constructor(declaringClassSignature: ClassSignature, methodSubSignature: MethodSubSignature) { + this.declaringClassSignature = declaringClassSignature; + this.methodSubSignature = methodSubSignature; + } + + /** + * Return the declaring class signature. + * A {@link ClassSignature} includes: + * - File Signature: including the **string** names of the project and file, respectively. + * The default value of project's name is "%unk" and the default value of file's name is "%unk". + * - Namespace Signature | **null**: it may be a namespace signature or **null**. + * A namespace signature can indicate its **string** name of namespace and its file signature. + * - Class Name: the **string** name of this class. + * @returns The declaring class signature. + * @example + * 1. get class signature from ArkMethod. + + ```typescript + let methodSignature = expr.getMethodSignature(); + let name = methodSignature.getDeclaringClassSignature().getClassName(); + ``` + * + */ + public getDeclaringClassSignature(): ClassSignature { + return this.declaringClassSignature; + } + + /** + * Returns the sub-signature of this method signature. + * The sub-signature is part of the method signature, which is used to + * identify the name of the method, its parameters and the return value type. + * @returns The sub-signature of this method signature. + */ + public getMethodSubSignature(): MethodSubSignature { + return this.methodSubSignature; + } + + public getType(): Type { + return this.methodSubSignature.getReturnType(); + } + + public toString(ptrName?: string): string { + return this.declaringClassSignature.toString() + '.' + this.methodSubSignature.toString(ptrName); + } + + public toMapKey(): string { + return this.declaringClassSignature.toMapKey() + '.' + this.methodSubSignature.toString(); + } + + public isMatch(signature: MethodSignature): boolean { + return this.toString() === signature.toString() && this.getType().toString() === signature.getType().toString(); + } + + public getParamLength(): number { + return this.methodSubSignature.getParameters().filter(p => !p.getName().startsWith(LEXICAL_ENV_NAME_PREFIX)).length; + } +} + +export class LocalSignature { + private name: string; + private declaringMethodSignature: MethodSignature; + + constructor(name: string, declaringMethodSignature: MethodSignature) { + this.name = name; + this.declaringMethodSignature = declaringMethodSignature; + } + + public getName(): string { + return this.name; + } + + public getDeclaringMethodSignature(): MethodSignature { + return this.declaringMethodSignature; + } + + public toString(): string { + return this.declaringMethodSignature.toString() + '#' + this.name; + } +} + +export class AliasTypeSignature { + private name: string; + private declaringMethodSignature: MethodSignature; + + constructor(name: string, declaringMethodSignature: MethodSignature) { + this.name = name; + this.declaringMethodSignature = declaringMethodSignature; + } + + public getName(): string { + return this.name; + } + + public getDeclaringMethodSignature(): MethodSignature { + return this.declaringMethodSignature; + } + + public toString(): string { + return this.declaringMethodSignature.toString() + '#' + this.name; + } +} + +//TODO, reconstruct +export function fieldSignatureCompare(leftSig: FieldSignature, rightSig: FieldSignature): boolean { + if (leftSig.getDeclaringSignature().toString() === rightSig.getDeclaringSignature().toString() && leftSig.getFieldName() === rightSig.getFieldName()) { + return true; + } + return false; +} + +export function methodSignatureCompare(leftSig: MethodSignature, rightSig: MethodSignature): boolean { + if ( + classSignatureCompare(leftSig.getDeclaringClassSignature(), rightSig.getDeclaringClassSignature()) && + methodSubSignatureCompare(leftSig.getMethodSubSignature(), rightSig.getMethodSubSignature()) + ) { + return true; + } + return false; +} + +export function methodSubSignatureCompare(leftSig: MethodSubSignature, rightSig: MethodSubSignature): boolean { + if ( + leftSig.getMethodName() === rightSig.getMethodName() && + arrayCompare(leftSig.getParameterTypes(), rightSig.getParameterTypes()) && + leftSig.getReturnType() === rightSig.getReturnType() + ) { + return true; + } + return false; +} + +export function classSignatureCompare(leftSig: ClassSignature, rightSig: ClassSignature): boolean { + if (fileSignatureCompare(leftSig.getDeclaringFileSignature(), rightSig.getDeclaringFileSignature()) && leftSig.getClassName() === rightSig.getClassName()) { + return true; + } + return false; +} + +export function fileSignatureCompare(leftSig: FileSignature, rightSig: FileSignature): boolean { + if (leftSig.getFileName() === rightSig.getFileName() && leftSig.getProjectName() === rightSig.getProjectName()) { + return true; + } + return false; +} + +function arrayCompare(leftArray: any[], rightArray: any[]): boolean { + if (leftArray.length !== rightArray.length) { + return false; + } + for (let i = 0; i < leftArray.length; i++) { + if (leftArray[i] !== rightArray[i]) { + return false; + } + } + return true; +} + +export function genSignature4ImportClause(arkFileName: string, importClauseName: string): string { + return `<${arkFileName}>.<${importClauseName}>`; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkClassBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkClassBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..7c3f16938470b32b10ed1636e6a0354baa1baa73 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkClassBuilder.ts @@ -0,0 +1,517 @@ +/* + * 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. + */ + +import { ArkField, FieldCategory } from '../ArkField'; +import { ArkFile } from '../ArkFile'; +import { ArkMethod } from '../ArkMethod'; +import { ArkNamespace } from '../ArkNamespace'; +import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; +import ts, { ParameterDeclaration } from 'ohos-typescript'; +import { ArkClass, ClassCategory } from '../ArkClass'; +import { buildArkMethodFromArkClass, buildDefaultArkMethodFromArkClass, buildInitMethod, checkAndUpdateMethod } from './ArkMethodBuilder'; +import { buildDecorators, buildGenericType, buildHeritageClauses, buildModifiers, buildTypeParameters, tsNode2Type } from './builderUtils'; +import { buildGetAccessor2ArkField, buildIndexSignature2ArkField, buildProperty2ArkField } from './ArkFieldBuilder'; +import { ArkIRTransformer } from '../../common/ArkIRTransformer'; +import { ArkAssignStmt, ArkInvokeStmt, Stmt } from '../../base/Stmt'; +import { ArkInstanceFieldRef } from '../../base/Ref'; +import { + ANONYMOUS_CLASS_DELIMITER, + ANONYMOUS_CLASS_PREFIX, + DEFAULT_ARK_CLASS_NAME, + INSTANCE_INIT_METHOD_NAME, + STATIC_BLOCK_METHOD_NAME_PREFIX, + STATIC_INIT_METHOD_NAME, +} from '../../common/Const'; +import { IRUtils } from '../../common/IRUtils'; +import { ClassSignature, FieldSignature, MethodSignature, MethodSubSignature } from '../ArkSignature'; +import { ArkSignatureBuilder } from './ArkSignatureBuilder'; +import { FullPosition, LineColPosition } from '../../base/Position'; +import { Type, UnknownType, VoidType } from '../../base/Type'; +import { BodyBuilder } from './BodyBuilder'; +import { ArkStaticInvokeExpr } from '../../base/Expr'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkClassBuilder'); + +export type ClassLikeNode = + | ts.ClassDeclaration + | ts.InterfaceDeclaration + | ts.EnumDeclaration + | ts.ClassExpression + | ts.TypeLiteralNode + | ts.StructDeclaration + | ts.ObjectLiteralExpression; + +type ClassLikeNodeWithMethod = + | ts.ClassDeclaration + | ts.InterfaceDeclaration + | ts.EnumDeclaration + | ts.ClassExpression + | ts.TypeLiteralNode + | ts.StructDeclaration; + +export function buildDefaultArkClassFromArkFile(arkFile: ArkFile, defaultClass: ArkClass, astRoot: ts.SourceFile): void { + defaultClass.setDeclaringArkFile(arkFile); + defaultClass.setCategory(ClassCategory.CLASS); + buildDefaultArkClass(defaultClass, astRoot); +} + +export function buildDefaultArkClassFromArkNamespace( + arkNamespace: ArkNamespace, + defaultClass: ArkClass, + nsNode: ts.ModuleDeclaration, + sourceFile: ts.SourceFile +): void { + defaultClass.setDeclaringArkNamespace(arkNamespace); + defaultClass.setDeclaringArkFile(arkNamespace.getDeclaringArkFile()); + buildDefaultArkClass(defaultClass, sourceFile, nsNode); +} + +export function buildNormalArkClassFromArkMethod(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { + const namespace = cls.getDeclaringArkNamespace(); + if (namespace) { + buildNormalArkClassFromArkNamespace(clsNode, namespace, cls, sourceFile, declaringMethod); + } else { + buildNormalArkClassFromArkFile(clsNode, cls.getDeclaringArkFile(), cls, sourceFile, declaringMethod); + } +} + +export function buildNormalArkClassFromArkFile( + clsNode: ClassLikeNode, + arkFile: ArkFile, + cls: ArkClass, + sourceFile: ts.SourceFile, + declaringMethod?: ArkMethod +): void { + cls.setDeclaringArkFile(arkFile); + cls.setCode(clsNode.getText(sourceFile)); + const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, clsNode.getStart(sourceFile)); + cls.setLine(line + 1); + cls.setColumn(character + 1); + + buildNormalArkClass(clsNode, cls, sourceFile, declaringMethod); + arkFile.addArkClass(cls); +} + +export function buildNormalArkClassFromArkNamespace( + clsNode: ClassLikeNode, + arkNamespace: ArkNamespace, + cls: ArkClass, + sourceFile: ts.SourceFile, + declaringMethod?: ArkMethod +): void { + cls.setDeclaringArkNamespace(arkNamespace); + cls.setDeclaringArkFile(arkNamespace.getDeclaringArkFile()); + cls.setCode(clsNode.getText(sourceFile)); + const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, clsNode.getStart(sourceFile)); + cls.setLine(line + 1); + cls.setColumn(character + 1); + + buildNormalArkClass(clsNode, cls, sourceFile, declaringMethod); + arkNamespace.addArkClass(cls); +} + +function buildDefaultArkClass(cls: ArkClass, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration): void { + const defaultArkClassSignature = new ClassSignature( + DEFAULT_ARK_CLASS_NAME, + cls.getDeclaringArkFile().getFileSignature(), + cls.getDeclaringArkNamespace()?.getSignature() || null + ); + cls.setSignature(defaultArkClassSignature); + + genDefaultArkMethod(cls, sourceFile, node); +} + +function genDefaultArkMethod(cls: ArkClass, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration): void { + let defaultMethod = new ArkMethod(); + buildDefaultArkMethodFromArkClass(cls, defaultMethod, sourceFile, node); + cls.setDefaultArkMethod(defaultMethod); +} + +export function buildNormalArkClass(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { + switch (clsNode.kind) { + case ts.SyntaxKind.StructDeclaration: + buildStruct2ArkClass(clsNode, cls, sourceFile, declaringMethod); + break; + case ts.SyntaxKind.ClassDeclaration: + buildClass2ArkClass(clsNode, cls, sourceFile, declaringMethod); + break; + case ts.SyntaxKind.ClassExpression: + buildClass2ArkClass(clsNode, cls, sourceFile, declaringMethod); + break; + case ts.SyntaxKind.InterfaceDeclaration: + buildInterface2ArkClass(clsNode, cls, sourceFile, declaringMethod); + break; + case ts.SyntaxKind.EnumDeclaration: + buildEnum2ArkClass(clsNode, cls, sourceFile, declaringMethod); + break; + case ts.SyntaxKind.TypeLiteral: + buildTypeLiteralNode2ArkClass(clsNode, cls, sourceFile, declaringMethod); + break; + case ts.SyntaxKind.ObjectLiteralExpression: + buildObjectLiteralExpression2ArkClass(clsNode, cls, sourceFile, declaringMethod); + break; + default: + } + IRUtils.setComments(cls, clsNode, sourceFile, cls.getDeclaringArkFile().getScene().getOptions()); +} + +function init4InstanceInitMethod(cls: ArkClass): void { + const instanceInit = new ArkMethod(); + instanceInit.setDeclaringArkClass(cls); + instanceInit.setIsGeneratedFlag(true); + const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(INSTANCE_INIT_METHOD_NAME); + methodSubSignature.setReturnType(VoidType.getInstance()); + const methodSignature = new MethodSignature(instanceInit.getDeclaringArkClass().getSignature(), methodSubSignature); + instanceInit.setImplementationSignature(methodSignature); + instanceInit.setLineCol(0); + + checkAndUpdateMethod(instanceInit, cls); + cls.addMethod(instanceInit); + cls.setInstanceInitMethod(instanceInit); +} + +function init4StaticInitMethod(cls: ArkClass): void { + const staticInit = new ArkMethod(); + staticInit.setDeclaringArkClass(cls); + staticInit.setIsGeneratedFlag(true); + const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(STATIC_INIT_METHOD_NAME); + methodSubSignature.setReturnType(VoidType.getInstance()); + const methodSignature = new MethodSignature(staticInit.getDeclaringArkClass().getSignature(), methodSubSignature); + staticInit.setImplementationSignature(methodSignature); + staticInit.setLineCol(0); + + checkAndUpdateMethod(staticInit, cls); + cls.addMethod(staticInit); + cls.setStaticInitMethod(staticInit); +} + +function buildStruct2ArkClass(clsNode: ts.StructDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { + const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + cls.setSignature(classSignature); + + if (clsNode.typeParameters) { + buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach(typeParameter => { + cls.addGenericType(typeParameter); + }); + } + + initHeritage(buildHeritageClauses(clsNode.heritageClauses), cls); + + cls.setModifiers(buildModifiers(clsNode)); + cls.setDecorators(buildDecorators(clsNode, sourceFile)); + + cls.setCategory(ClassCategory.STRUCT); + init4InstanceInitMethod(cls); + init4StaticInitMethod(cls); + buildArkClassMembers(clsNode, cls, sourceFile); +} + +function buildClass2ArkClass(clsNode: ts.ClassDeclaration | ts.ClassExpression, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { + const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + cls.setSignature(classSignature); + + if (clsNode.typeParameters) { + buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach(typeParameter => { + cls.addGenericType(typeParameter); + }); + } + + initHeritage(buildHeritageClauses(clsNode.heritageClauses), cls); + + cls.setModifiers(buildModifiers(clsNode)); + cls.setDecorators(buildDecorators(clsNode, sourceFile)); + + cls.setCategory(ClassCategory.CLASS); + init4InstanceInitMethod(cls); + init4StaticInitMethod(cls); + buildArkClassMembers(clsNode, cls, sourceFile); +} + +function initHeritage(heritageClauses: Map, cls: ArkClass): void { + let superName = ''; + for (let [key, value] of heritageClauses) { + if (value === ts.SyntaxKind[ts.SyntaxKind.ExtendsKeyword]) { + superName = key; + break; + } + } + cls.addHeritageClassName(superName); + for (let key of heritageClauses.keys()) { + cls.addHeritageClassName(key); + } +} + +function buildInterface2ArkClass(clsNode: ts.InterfaceDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { + const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + cls.setSignature(classSignature); + + if (clsNode.typeParameters) { + buildTypeParameters(clsNode.typeParameters, sourceFile, cls).forEach(typeParameter => { + cls.addGenericType(typeParameter); + }); + } + + initHeritage(buildHeritageClauses(clsNode.heritageClauses), cls); + + cls.setModifiers(buildModifiers(clsNode)); + cls.setDecorators(buildDecorators(clsNode, sourceFile)); + + cls.setCategory(ClassCategory.INTERFACE); + + buildArkClassMembers(clsNode, cls, sourceFile); +} + +function buildEnum2ArkClass(clsNode: ts.EnumDeclaration, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { + const className = genClassName(clsNode.name ? clsNode.name.text : '', cls, declaringMethod); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + cls.setSignature(classSignature); + + cls.setModifiers(buildModifiers(clsNode)); + cls.setDecorators(buildDecorators(clsNode, sourceFile)); + + cls.setCategory(ClassCategory.ENUM); + + init4StaticInitMethod(cls); + buildArkClassMembers(clsNode, cls, sourceFile); +} + +function buildTypeLiteralNode2ArkClass(clsNode: ts.TypeLiteralNode, cls: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): void { + const className = genClassName('', cls, declaringMethod); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + cls.setSignature(classSignature); + + cls.setCategory(ClassCategory.TYPE_LITERAL); + if (ts.isTypeAliasDeclaration(clsNode.parent) && clsNode.parent.typeParameters) { + buildTypeParameters(clsNode.parent.typeParameters, sourceFile, cls).forEach(typeParameter => { + cls.addGenericType(typeParameter); + }); + } + buildArkClassMembers(clsNode, cls, sourceFile); +} + +function buildObjectLiteralExpression2ArkClass( + clsNode: ts.ObjectLiteralExpression, + cls: ArkClass, + sourceFile: ts.SourceFile, + declaringMethod?: ArkMethod +): void { + const className = genClassName('', cls, declaringMethod); + const classSignature = new ClassSignature(className, cls.getDeclaringArkFile().getFileSignature(), cls.getDeclaringArkNamespace()?.getSignature() || null); + cls.setSignature(classSignature); + + cls.setCategory(ClassCategory.OBJECT); + + let arkMethods: ArkMethod[] = []; + + init4InstanceInitMethod(cls); + const instanceIRTransformer = new ArkIRTransformer(sourceFile, cls.getInstanceInitMethod()); + const instanceFieldInitializerStmts: Stmt[] = []; + clsNode.properties.forEach(property => { + if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isSpreadAssignment(property)) { + const arkField = buildProperty2ArkField(property, sourceFile, cls); + if (ts.isPropertyAssignment(property)) { + getInitStmts(instanceIRTransformer, arkField, property.initializer); + arkField.getInitializer().forEach(stmt => instanceFieldInitializerStmts.push(stmt)); + } + } else { + let arkMethod = new ArkMethod(); + arkMethod.setDeclaringArkClass(cls); + buildArkMethodFromArkClass(property, cls, arkMethod, sourceFile); + } + }); + buildInitMethod(cls.getInstanceInitMethod(), instanceFieldInitializerStmts, instanceIRTransformer.getThisLocal()); + arkMethods.forEach(mtd => { + checkAndUpdateMethod(mtd, cls); + cls.addMethod(mtd); + }); +} + +function genClassName(declaringName: string, cls: ArkClass, declaringMethod?: ArkMethod): string { + if (!declaringName) { + const declaringArkNamespace = cls.getDeclaringArkNamespace(); + const num = declaringArkNamespace ? declaringArkNamespace.getAnonymousClassNumber() : cls.getDeclaringArkFile().getAnonymousClassNumber(); + declaringName = ANONYMOUS_CLASS_PREFIX + num; + } + const suffix = declaringMethod ? ANONYMOUS_CLASS_DELIMITER + declaringMethod.getDeclaringArkClass().getName() + '.' + declaringMethod.getName() : ''; + return declaringName + suffix; +} + +function buildArkClassMembers(clsNode: ClassLikeNode, cls: ArkClass, sourceFile: ts.SourceFile): void { + if (ts.isObjectLiteralExpression(clsNode)) { + return; + } + buildMethodsForClass(clsNode, cls, sourceFile); + const staticBlockMethodSignatures = buildStaticBlocksForClass(clsNode, cls, sourceFile); + let instanceIRTransformer: ArkIRTransformer; + let staticIRTransformer: ArkIRTransformer; + if (ts.isClassDeclaration(clsNode) || ts.isClassExpression(clsNode) || ts.isStructDeclaration(clsNode)) { + instanceIRTransformer = new ArkIRTransformer(sourceFile, cls.getInstanceInitMethod()); + staticIRTransformer = new ArkIRTransformer(sourceFile, cls.getStaticInitMethod()); + } + if (ts.isEnumDeclaration(clsNode)) { + staticIRTransformer = new ArkIRTransformer(sourceFile, cls.getStaticInitMethod()); + } + const staticInitStmts: Stmt[] = []; + const instanceInitStmts: Stmt[] = []; + let staticBlockId = 0; + clsNode.members.forEach(member => { + if (ts.isPropertyDeclaration(member) || ts.isPropertySignature(member)) { + const arkField = buildProperty2ArkField(member, sourceFile, cls); + if (ts.isClassDeclaration(clsNode) || ts.isClassExpression(clsNode) || ts.isStructDeclaration(clsNode)) { + if (arkField.isStatic()) { + getInitStmts(staticIRTransformer, arkField, member.initializer); + arkField.getInitializer().forEach(stmt => staticInitStmts.push(stmt)); + } else { + if (!instanceIRTransformer) { + console.log(clsNode.getText(sourceFile)); + } + getInitStmts(instanceIRTransformer, arkField, member.initializer); + arkField.getInitializer().forEach(stmt => instanceInitStmts.push(stmt)); + } + } + } else if (ts.isEnumMember(member)) { + const arkField = buildProperty2ArkField(member, sourceFile, cls); + getInitStmts(staticIRTransformer, arkField, member.initializer); + arkField.getInitializer().forEach(stmt => staticInitStmts.push(stmt)); + } else if (ts.isIndexSignatureDeclaration(member)) { + buildIndexSignature2ArkField(member, sourceFile, cls); + } else if (ts.isClassStaticBlockDeclaration(member)) { + const currStaticBlockMethodSig = staticBlockMethodSignatures[staticBlockId++]; + const staticBlockInvokeExpr = new ArkStaticInvokeExpr(currStaticBlockMethodSig, []); + staticInitStmts.push(new ArkInvokeStmt(staticBlockInvokeExpr)); + } else if (ts.isSemicolonClassElement(member)) { + logger.debug('Skip these members.'); + } else { + logger.warn('Please contact developers to support new member type!'); + } + }); + if (ts.isClassDeclaration(clsNode) || ts.isClassExpression(clsNode) || ts.isStructDeclaration(clsNode)) { + buildInitMethod(cls.getInstanceInitMethod(), instanceInitStmts, instanceIRTransformer!.getThisLocal()); + buildInitMethod(cls.getStaticInitMethod(), staticInitStmts, staticIRTransformer!.getThisLocal()); + } + if (ts.isEnumDeclaration(clsNode)) { + buildInitMethod(cls.getStaticInitMethod(), staticInitStmts, staticIRTransformer!.getThisLocal()); + } +} + +function buildMethodsForClass(clsNode: ClassLikeNodeWithMethod, cls: ArkClass, sourceFile: ts.SourceFile): void { + clsNode.members.forEach(member => { + if ( + ts.isMethodDeclaration(member) || + ts.isConstructorDeclaration(member) || + ts.isMethodSignature(member) || + ts.isConstructSignatureDeclaration(member) || + ts.isAccessor(member) || + ts.isCallSignatureDeclaration(member) + ) { + let mthd: ArkMethod = new ArkMethod(); + buildArkMethodFromArkClass(member, cls, mthd, sourceFile); + if (ts.isGetAccessor(member)) { + buildGetAccessor2ArkField(member, mthd, sourceFile); + } else if (ts.isConstructorDeclaration(member)) { + buildParameterProperty2ArkField(member.parameters, cls, sourceFile); + } + } + }); +} + +// params of constructor method may have modifiers such as public or private to directly define class properties with constructor +function buildParameterProperty2ArkField(params: ts.NodeArray, cls: ArkClass, sourceFile: ts.SourceFile): void { + if (params.length === 0) { + return; + } + params.forEach(parameter => { + if (parameter.modifiers === undefined || !ts.isIdentifier(parameter.name)) { + return; + } + let field = new ArkField(); + field.setDeclaringArkClass(cls); + + field.setCode(parameter.getText(sourceFile)); + field.setCategory(FieldCategory.PARAMETER_PROPERTY); + field.setOriginPosition(LineColPosition.buildFromNode(parameter, sourceFile)); + + let fieldName = parameter.name.text; + let fieldType: Type; + if (parameter.type) { + fieldType = buildGenericType(tsNode2Type(parameter.type, sourceFile, field), field); + } else { + fieldType = UnknownType.getInstance(); + } + const fieldSignature = new FieldSignature(fieldName, cls.getSignature(), fieldType, false); + field.setSignature(fieldSignature); + field.setModifiers(buildModifiers(parameter)); + cls.addField(field); + }); +} + +function buildStaticBlocksForClass(clsNode: ClassLikeNodeWithMethod, cls: ArkClass, sourceFile: ts.SourceFile): MethodSignature[] { + let staticInitBlockId = 0; + const staticBlockMethodSignatures: MethodSignature[] = []; + clsNode.members.forEach(member => { + if (ts.isClassStaticBlockDeclaration(member)) { + const staticBlockMethod = new ArkMethod(); + staticBlockMethod.setDeclaringArkClass(cls); + staticBlockMethod.setIsGeneratedFlag(true); + staticBlockMethod.setCode(member.getText(sourceFile)); + const methodName = STATIC_BLOCK_METHOD_NAME_PREFIX + staticInitBlockId++; + const methodSubSignature = new MethodSubSignature(methodName, [], VoidType.getInstance(), true); + const methodSignature = new MethodSignature(cls.getSignature(), methodSubSignature); + staticBlockMethodSignatures.push(methodSignature); + staticBlockMethod.setImplementationSignature(methodSignature); + const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, member.getStart(sourceFile)); + staticBlockMethod.setLine(line + 1); + staticBlockMethod.setColumn(character + 1); + + let bodyBuilder = new BodyBuilder(staticBlockMethod.getSignature(), member, staticBlockMethod, sourceFile); + staticBlockMethod.setBodyBuilder(bodyBuilder); + + cls.addMethod(staticBlockMethod); + } + }); + return staticBlockMethodSignatures; +} + +function getInitStmts(transformer: ArkIRTransformer, field: ArkField, initNode?: ts.Node): void { + if (initNode) { + const stmts: Stmt[] = []; + let { value: initValue, valueOriginalPositions: initPositions, stmts: initStmts } = transformer.tsNodeToValueAndStmts(initNode); + initStmts.forEach(stmt => stmts.push(stmt)); + if (IRUtils.moreThanOneAddress(initValue)) { + ({ value: initValue, valueOriginalPositions: initPositions, stmts: initStmts } = transformer.generateAssignStmtForValue(initValue, initPositions)); + initStmts.forEach(stmt => stmts.push(stmt)); + } + + const fieldRef = new ArkInstanceFieldRef(transformer.getThisLocal(), field.getSignature()); + const fieldRefPositions = [FullPosition.DEFAULT, FullPosition.DEFAULT]; + const assignStmt = new ArkAssignStmt(fieldRef, initValue); + assignStmt.setOperandOriginalPositions([...fieldRefPositions, ...initPositions]); + stmts.push(assignStmt); + + const fieldSourceCode = field.getCode(); + const fieldOriginPosition = field.getOriginPosition(); + for (const stmt of stmts) { + stmt.setOriginPositionInfo(fieldOriginPosition); + stmt.setOriginalText(fieldSourceCode); + } + field.setInitializer(stmts); + if (field.getType() instanceof UnknownType) { + field.getSignature().setType(initValue.getType()); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkExportBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkExportBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..c66aa142a4cac9f052943f4685d1709fbe3fde04 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkExportBuilder.ts @@ -0,0 +1,218 @@ +/* + * 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. + */ + +import ts from 'ohos-typescript'; +import { LineColPosition } from '../../base/Position'; +import { ArkExport, ExportInfo, ExportType, FromInfo } from '../ArkExport'; +import { buildModifiers } from './builderUtils'; +import { ArkFile } from '../ArkFile'; +import { ALL, DEFAULT } from '../../common/TSConst'; +import { ArkBaseModel, ModifierType } from '../ArkBaseModel'; +import { IRUtils } from '../../common/IRUtils'; +import { ArkClass } from '../ArkClass'; +import { buildNormalArkClassFromArkFile } from './ArkClassBuilder'; +import { ArkNamespace } from '../ArkNamespace'; + +export { buildExportInfo, buildExportAssignment, buildExportDeclaration }; + +function buildExportInfo(arkInstance: ArkExport, arkFile: ArkFile, line: LineColPosition): ExportInfo { + let exportClauseName: string; + if (arkInstance instanceof ArkBaseModel && arkInstance.isDefault()) { + exportClauseName = DEFAULT; + } else { + exportClauseName = arkInstance.getName(); + } + return new ExportInfo.Builder() + .exportClauseName(exportClauseName) + .exportClauseType(arkInstance.getExportType()) + .modifiers(arkInstance.getModifiers()) + .arkExport(arkInstance) + .originTsPosition(line) + .declaringArkFile(arkFile) + .build(); +} + +export function buildDefaultExportInfo(im: FromInfo, file: ArkFile, arkExport?: ArkExport): ExportInfo { + return new ExportInfo.Builder() + .exportClauseType(arkExport?.getExportType() ?? ExportType.CLASS) + .exportClauseName(im.getOriginName()) + .declaringArkFile(file) + .arkExport(arkExport ?? file.getDefaultClass()) + .build(); +} + +function buildExportDeclaration(node: ts.ExportDeclaration, sourceFile: ts.SourceFile, arkFile: ArkFile): ExportInfo[] { + const originTsPosition = LineColPosition.buildFromNode(node, sourceFile); + const tsSourceCode = node.getText(sourceFile); + const modifiers = node.modifiers ? buildModifiers(node) : 0; + let exportFrom = ''; + if (node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) { + exportFrom = node.moduleSpecifier.text; + } + let exportInfos: ExportInfo[] = []; + // just like: export {xxx as x} from './yy' + if (node.exportClause && ts.isNamedExports(node.exportClause) && node.exportClause.elements) { + node.exportClause.elements.forEach(element => { + let builder = new ExportInfo.Builder() + .exportClauseType(ExportType.UNKNOWN) + .exportClauseName(element.name.text) + .tsSourceCode(tsSourceCode) + .exportFrom(exportFrom) + .originTsPosition(originTsPosition) + .declaringArkFile(arkFile) + .setLeadingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), true)) + .setTrailingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), false)) + .modifiers(modifiers); + if (element.propertyName && ts.isIdentifier(element.propertyName)) { + builder.nameBeforeAs(element.propertyName.text); + } + exportInfos.push(builder.build()); + }); + return exportInfos; + } + + let builder1 = new ExportInfo.Builder() + .exportClauseType(ExportType.UNKNOWN) + .nameBeforeAs(ALL) + .modifiers(modifiers) + .tsSourceCode(tsSourceCode) + .exportFrom(exportFrom) + .declaringArkFile(arkFile) + .setLeadingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), true)) + .setTrailingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), false)) + .originTsPosition(originTsPosition); + if (node.exportClause && ts.isNamespaceExport(node.exportClause) && ts.isIdentifier(node.exportClause.name)) { + // just like: export * as xx from './yy' + exportInfos.push(builder1.exportClauseName(node.exportClause.name.text).build()); + } else if (!node.exportClause && node.moduleSpecifier) { + // just like: export * from './yy' + exportInfos.push(builder1.exportClauseName(ALL).build()); + } + return exportInfos; +} + +function buildExportAssignment(node: ts.ExportAssignment, sourceFile: ts.SourceFile, arkFile: ArkFile): ExportInfo[] { + let exportInfos: ExportInfo[] = []; + if (!node.expression) { + return exportInfos; + } + const originTsPosition = LineColPosition.buildFromNode(node, sourceFile); + const tsSourceCode = node.getText(sourceFile); + let modifiers = buildModifiers(node); + + if (isKeyword(node.getChildren(sourceFile), ts.SyntaxKind.DefaultKeyword) || node.isExportEquals) { + modifiers |= ModifierType.DEFAULT; + } + + let exportInfo = new ExportInfo.Builder() + .exportClauseType(ExportType.UNKNOWN) + .modifiers(modifiers) + .tsSourceCode(tsSourceCode) + .originTsPosition(originTsPosition) + .declaringArkFile(arkFile) + .exportClauseName(DEFAULT) + .setLeadingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), true)) + .setTrailingComments(IRUtils.getCommentsMetadata(node, sourceFile, arkFile.getScene().getOptions(), false)); + + if (ts.isNewExpression(node.expression) && ts.isClassExpression(node.expression.expression)) { + let cls: ArkClass = new ArkClass(); + buildNormalArkClassFromArkFile(node.expression.expression, arkFile, cls, sourceFile); + } + + if (ts.isIdentifier(node.expression)) { + // just like: export default xx + exportInfo.nameBeforeAs(node.expression.text); + } else if (ts.isAsExpression(node.expression)) { + // just like: export default xx as YY + exportInfo.nameBeforeAs(node.expression.expression.getText(sourceFile)); + } + exportInfos.push(exportInfo.build()); + + return exportInfos; +} + +/** + * export const c = '', b = 1; + * @param node + * @param sourceFile + * @param arkFile + */ +export function buildExportVariableStatement(node: ts.VariableStatement, sourceFile: ts.SourceFile, arkFile: ArkFile, namespace?: ArkNamespace): ExportInfo[] { + let exportInfos: ExportInfo[] = []; + const originTsPosition = LineColPosition.buildFromNode(node, sourceFile); + const modifiers = node.modifiers ? buildModifiers(node) : 0; + const tsSourceCode = node.getText(sourceFile); + node.declarationList.declarations.forEach(dec => { + const exportInfoBuilder = new ExportInfo.Builder() + .exportClauseName(dec.name.getText(sourceFile)) + .exportClauseType(ExportType.LOCAL) + .modifiers(modifiers) + .tsSourceCode(tsSourceCode) + .originTsPosition(originTsPosition) + .declaringArkFile(arkFile); + if (namespace) { + exportInfoBuilder.declaringArkNamespace(namespace); + } + exportInfos.push(exportInfoBuilder.build()); + }); + return exportInfos; +} + +/** + * export type MyType = string; + * @param node + * @param sourceFile + * @param arkFile + */ +export function buildExportTypeAliasDeclaration(node: ts.TypeAliasDeclaration, sourceFile: ts.SourceFile, arkFile: ArkFile): ExportInfo[] { + let exportInfos: ExportInfo[] = []; + const originTsPosition = LineColPosition.buildFromNode(node, sourceFile); + const modifiers = node.modifiers ? buildModifiers(node) : 0; + const tsSourceCode = node.getText(sourceFile); + const exportInfo = new ExportInfo.Builder() + .exportClauseName(node.name.text) + .exportClauseType(ExportType.TYPE) + .tsSourceCode(tsSourceCode) + .modifiers(modifiers) + .originTsPosition(originTsPosition) + .declaringArkFile(arkFile) + .build(); + exportInfos.push(exportInfo); + return exportInfos; +} + +export function isExported(modifierArray: ts.NodeArray | undefined): boolean { + if (!modifierArray) { + return false; + } + for (let child of modifierArray) { + if (child.kind === ts.SyntaxKind.ExportKeyword) { + return true; + } + } + return false; +} + +function isKeyword(modifierArray: ts.Node[] | undefined, keyword: ts.SyntaxKind): boolean { + if (!modifierArray) { + return false; + } + for (let child of modifierArray) { + if (child.kind === keyword) { + return true; + } + } + return false; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFieldBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFieldBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..ede55e7c9373fe86d87b73f0907a24c8e4cc9157 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFieldBuilder.ts @@ -0,0 +1,174 @@ +/* + * 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. + */ + +import ts from 'ohos-typescript'; +import { ArkField, FieldCategory } from '../ArkField'; +import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; +import { ArkClass } from '../ArkClass'; +import { ArkMethod } from '../ArkMethod'; +import { buildDecorators, buildGenericType, buildModifiers, handlePropertyAccessExpression, tsNode2Type } from './builderUtils'; +import { FieldSignature } from '../ArkSignature'; +import { ClassType, Type, UnknownType } from '../../base/Type'; +import { LineColPosition } from '../../base/Position'; +import { ModifierType } from '../ArkBaseModel'; +import { IRUtils } from '../../common/IRUtils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkFieldBuilder'); + +export type PropertyLike = ts.PropertyDeclaration | ts.PropertyAssignment; + +export function buildProperty2ArkField( + member: ts.PropertyDeclaration | ts.PropertyAssignment | ts.ShorthandPropertyAssignment | ts.SpreadAssignment | ts.PropertySignature | ts.EnumMember, + sourceFile: ts.SourceFile, + cls: ArkClass +): ArkField { + let field = new ArkField(); + field.setCategory(mapSyntaxKindToFieldOriginType(member.kind) as FieldCategory); + field.setCode(member.getText(sourceFile)); + field.setDeclaringArkClass(cls); + field.setOriginPosition(LineColPosition.buildFromNode(member, sourceFile)); + + let fieldName = member.getText(sourceFile); + if (member.name && ts.isComputedPropertyName(member.name)) { + if (ts.isIdentifier(member.name.expression)) { + fieldName = member.name.expression.text; + } else if (ts.isPropertyAccessExpression(member.name.expression)) { + fieldName = handlePropertyAccessExpression(member.name.expression); + } else { + logger.warn('Other property expression type found!'); + } + } else if (member.name && (ts.isIdentifier(member.name) || ts.isLiteralExpression(member.name))) { + fieldName = member.name.text; + } else if (member.name && ts.isPrivateIdentifier(member.name)) { + let propertyName = member.name.text; + fieldName = propertyName.substring(1); + field.addModifier(ModifierType.PRIVATE); + } else { + logger.warn('Other type of property name found!'); + } + + let fieldType: Type = UnknownType.getInstance(); + if (ts.isPropertyDeclaration(member) || ts.isPropertySignature(member)) { + if (member.modifiers) { + field.addModifier(buildModifiers(member)); + } + field.addModifier(0); + field.setDecorators(buildDecorators(member, sourceFile)); + field.setQuestionToken(member.questionToken !== undefined); + + if (member.type) { + fieldType = buildGenericType(tsNode2Type(member.type, sourceFile, cls), field); + } + } + + if (ts.isEnumMember(member)) { + field.addModifier(ModifierType.STATIC); + fieldType = new ClassType(cls.getSignature()); + } + field.setSignature(new FieldSignature(fieldName, cls.getSignature(), fieldType, field.isStatic())); + + if (ts.isPropertyDeclaration(member) && member.exclamationToken) { + field.setExclamationToken(true); + } + IRUtils.setComments(field, member, sourceFile, cls.getDeclaringArkFile().getScene().getOptions()); + cls.addField(field); + return field; +} + +export function buildIndexSignature2ArkField(member: ts.IndexSignatureDeclaration, sourceFile: ts.SourceFile, cls: ArkClass): void { + const field = new ArkField(); + field.setCode(member.getText(sourceFile)); + field.setCategory(mapSyntaxKindToFieldOriginType(member.kind) as FieldCategory); + field.setDeclaringArkClass(cls); + + field.setOriginPosition(LineColPosition.buildFromNode(member, sourceFile)); + + if (member.modifiers) { + let modifier = buildModifiers(member); + field.addModifier(modifier); + } + + const fieldName = '[' + member.parameters[0].getText(sourceFile) + ']'; + const fieldType = buildGenericType(tsNode2Type(member.type, sourceFile, field), field); + const fieldSignature = new FieldSignature(fieldName, cls.getSignature(), fieldType, true); + field.setSignature(fieldSignature); + IRUtils.setComments(field, member, sourceFile, cls.getDeclaringArkFile().getScene().getOptions()); + cls.addField(field); +} + +export function buildGetAccessor2ArkField(member: ts.GetAccessorDeclaration, mthd: ArkMethod, sourceFile: ts.SourceFile): void { + let cls = mthd.getDeclaringArkClass(); + let field = new ArkField(); + field.setDeclaringArkClass(cls); + + field.setCode(member.getText(sourceFile)); + field.setCategory(mapSyntaxKindToFieldOriginType(member.kind) as FieldCategory); + field.setOriginPosition(LineColPosition.buildFromNode(member, sourceFile)); + + let fieldName = member.getText(sourceFile); + if (ts.isIdentifier(member.name) || ts.isLiteralExpression(member.name)) { + fieldName = member.name.text; + } else if (ts.isComputedPropertyName(member.name)) { + if (ts.isIdentifier(member.name.expression)) { + let propertyName = member.name.expression.text; + fieldName = propertyName; + } else if (ts.isPropertyAccessExpression(member.name.expression)) { + fieldName = handlePropertyAccessExpression(member.name.expression); + } else if (ts.isLiteralExpression(member.name.expression)) { + fieldName = member.name.expression.text; + } else { + logger.warn('Other type of computed property name found!'); + } + } else { + logger.warn('Please contact developers to support new type of GetAccessor name!'); + } + + const fieldType = mthd.getReturnType(); + const fieldSignature = new FieldSignature(fieldName, cls.getSignature(), fieldType, false); + field.setSignature(fieldSignature); + cls.addField(field); +} + +function mapSyntaxKindToFieldOriginType(syntaxKind: ts.SyntaxKind): FieldCategory | null { + let fieldOriginType: FieldCategory | null = null; + switch (syntaxKind) { + case ts.SyntaxKind.PropertyDeclaration: + fieldOriginType = FieldCategory.PROPERTY_DECLARATION; + break; + case ts.SyntaxKind.PropertyAssignment: + fieldOriginType = FieldCategory.PROPERTY_ASSIGNMENT; + break; + case ts.SyntaxKind.ShorthandPropertyAssignment: + fieldOriginType = FieldCategory.SHORT_HAND_PROPERTY_ASSIGNMENT; + break; + case ts.SyntaxKind.SpreadAssignment: + fieldOriginType = FieldCategory.SPREAD_ASSIGNMENT; + break; + case ts.SyntaxKind.PropertySignature: + fieldOriginType = FieldCategory.PROPERTY_SIGNATURE; + break; + case ts.SyntaxKind.EnumMember: + fieldOriginType = FieldCategory.ENUM_MEMBER; + break; + case ts.SyntaxKind.IndexSignature: + fieldOriginType = FieldCategory.INDEX_SIGNATURE; + break; + case ts.SyntaxKind.GetAccessor: + fieldOriginType = FieldCategory.GET_ACCESSOR; + break; + default: + } + return fieldOriginType; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFileBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFileBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..1e201453b195b0a2bc6bc66d515215471dc277dc --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkFileBuilder.ts @@ -0,0 +1,166 @@ +/* + * 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. + */ + +import fs from 'fs'; +import path from 'path'; +import ts from 'ohos-typescript'; +import { ArkFile, Language } from '../ArkFile'; +import { ArkNamespace } from '../ArkNamespace'; +import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; +import { buildDefaultArkClassFromArkFile, buildNormalArkClassFromArkFile } from './ArkClassBuilder'; +import { buildArkMethodFromArkClass } from './ArkMethodBuilder'; +import { buildImportInfo } from './ArkImportBuilder'; +import { + buildExportAssignment, + buildExportDeclaration, + buildExportInfo, + buildExportTypeAliasDeclaration, + buildExportVariableStatement, + isExported, +} from './ArkExportBuilder'; +import { buildArkNamespace, mergeNameSpaces } from './ArkNamespaceBuilder'; +import { ArkClass } from '../ArkClass'; +import { ArkMethod } from '../ArkMethod'; +import { LineColPosition } from '../../base/Position'; +import { ETS_COMPILER_OPTIONS } from '../../common/EtsConst'; +import { FileSignature } from '../ArkSignature'; +import { ARKTS_STATIC_MARK } from '../../common/Const'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkFileBuilder'); + +export const notStmtOrExprKind = [ + 'ModuleDeclaration', + 'ClassDeclaration', + 'InterfaceDeclaration', + 'EnumDeclaration', + 'ExportDeclaration', + 'ExportAssignment', + 'MethodDeclaration', + 'Constructor', + 'FunctionDeclaration', + 'GetAccessor', + 'SetAccessor', + 'ArrowFunction', + 'FunctionExpression', + 'MethodSignature', + 'ConstructSignature', + 'CallSignature', +]; + +/** + * Entry of building ArkFile instance + * + * @param arkFile + * @returns + */ +export function buildArkFileFromFile(absoluteFilePath: string, projectDir: string, arkFile: ArkFile, projectName: string): void { + arkFile.setFilePath(absoluteFilePath); + arkFile.setProjectDir(projectDir); + + const fileSignature = new FileSignature(projectName, path.relative(projectDir, absoluteFilePath)); + arkFile.setFileSignature(fileSignature); + + arkFile.setCode(fs.readFileSync(arkFile.getFilePath(), 'utf8')); + const sourceFile = ts.createSourceFile(arkFile.getName(), arkFile.getCode(), ts.ScriptTarget.Latest, true, undefined, ETS_COMPILER_OPTIONS); + genDefaultArkClass(arkFile, sourceFile); + buildArkFile(arkFile, sourceFile); +} + +/** + * Building ArkFile instance + * + * @param arkFile + * @param astRoot + * @returns + */ +function buildArkFile(arkFile: ArkFile, astRoot: ts.SourceFile): void { + const statements = astRoot.statements; + const namespaces: ArkNamespace[] = []; + statements.forEach(child => { + if (ts.isModuleDeclaration(child)) { + let ns: ArkNamespace = new ArkNamespace(); + ns.setDeclaringArkFile(arkFile); + + buildArkNamespace(child, arkFile, ns, astRoot); + namespaces.push(ns); + if (ns.isExported()) { + arkFile.addExportInfo(buildExportInfo(ns, arkFile, LineColPosition.buildFromNode(child, astRoot))); + } + } else if (ts.isClassDeclaration(child) || ts.isInterfaceDeclaration(child) || ts.isEnumDeclaration(child) || ts.isStructDeclaration(child)) { + let cls: ArkClass = new ArkClass(); + + buildNormalArkClassFromArkFile(child, arkFile, cls, astRoot); + arkFile.addArkClass(cls); + + if (cls.isExported()) { + arkFile.addExportInfo(buildExportInfo(cls, arkFile, LineColPosition.buildFromNode(child, astRoot))); + } + } + // TODO: Check + else if (ts.isMethodDeclaration(child)) { + logger.warn('This is a MethodDeclaration in ArkFile.'); + let mthd: ArkMethod = new ArkMethod(); + + buildArkMethodFromArkClass(child, arkFile.getDefaultClass(), mthd, astRoot); + + if (mthd.isExported()) { + arkFile.addExportInfo(buildExportInfo(mthd, arkFile, LineColPosition.buildFromNode(child, astRoot))); + } + } else if (ts.isFunctionDeclaration(child)) { + let mthd: ArkMethod = new ArkMethod(); + + buildArkMethodFromArkClass(child, arkFile.getDefaultClass(), mthd, astRoot); + + if (mthd.isExported()) { + arkFile.addExportInfo(buildExportInfo(mthd, arkFile, LineColPosition.buildFromNode(child, astRoot))); + } + } else if (ts.isImportEqualsDeclaration(child) || ts.isImportDeclaration(child)) { + let importInfos = buildImportInfo(child, astRoot, arkFile); + importInfos?.forEach(element => { + element.setDeclaringArkFile(arkFile); + arkFile.addImportInfo(element); + }); + } else if (ts.isExportDeclaration(child)) { + buildExportDeclaration(child, astRoot, arkFile).forEach(item => arkFile.addExportInfo(item)); + } else if (ts.isExportAssignment(child)) { + buildExportAssignment(child, astRoot, arkFile).forEach(item => arkFile.addExportInfo(item)); + } else if (ts.isVariableStatement(child) && isExported(child.modifiers)) { + buildExportVariableStatement(child, astRoot, arkFile).forEach(item => arkFile.addExportInfo(item)); + } else if (ts.isTypeAliasDeclaration(child) && isExported(child.modifiers)) { + buildExportTypeAliasDeclaration(child, astRoot, arkFile).forEach(item => arkFile.addExportInfo(item)); + } else if (ts.isExpressionStatement(child) && ts.isStringLiteral(child.expression)) { + child.expression.text.trim() === ARKTS_STATIC_MARK && arkFile.setLanguage(Language.ARKTS1_2); + } else { + logger.info('Child joined default method of arkFile: ', ts.SyntaxKind[child.kind]); + } + }); + + const mergedNameSpaces = mergeNameSpaces(namespaces); + mergedNameSpaces.forEach(mergedNameSpace => { + arkFile.addNamespace(mergedNameSpace); + if (mergedNameSpace.isExport()) { + const linCol = new LineColPosition(mergedNameSpace.getLine(), mergedNameSpace.getColumn()); + arkFile.addExportInfo(buildExportInfo(mergedNameSpace, arkFile, linCol)); + } + }); +} + +function genDefaultArkClass(arkFile: ArkFile, astRoot: ts.SourceFile): void { + let defaultClass = new ArkClass(); + + buildDefaultArkClassFromArkFile(arkFile, defaultClass, astRoot); + arkFile.setDefaultClass(defaultClass); + arkFile.addArkClass(defaultClass); +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkImportBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkImportBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..432f64acd19435dde5f28cd92d02bee9ba521dca --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkImportBuilder.ts @@ -0,0 +1,139 @@ +/* + * 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. + */ + +import ts from 'ohos-typescript'; +import { LineColPosition } from '../../base/Position'; +import { ImportInfo } from '../ArkImport'; +import { buildModifiers } from './builderUtils'; +import { IRUtils } from '../../common/IRUtils'; +import { ArkFile } from '../ArkFile'; + +export function buildImportInfo(node: ts.ImportEqualsDeclaration | ts.ImportDeclaration, sourceFile: ts.SourceFile, arkFile: ArkFile): ImportInfo[] { + if (ts.isImportDeclaration(node)) { + return buildImportDeclarationNode(node, sourceFile, arkFile); + } else if (ts.isImportEqualsDeclaration(node)) { + return buildImportEqualsDeclarationNode(node, sourceFile, arkFile); + } + return []; +} + +function buildImportDeclarationNode(node: ts.ImportDeclaration, sourceFile: ts.SourceFile, arkFile: ArkFile): ImportInfo[] { + const originTsPosition = LineColPosition.buildFromNode(node, sourceFile); + const tsSourceCode = node.getText(sourceFile); + + let importInfos: ImportInfo[] = []; + let importFrom: string = ''; + if (ts.isStringLiteral(node.moduleSpecifier)) { + importFrom = node.moduleSpecifier.text; + } + + let modifiers = 0; + if (node.modifiers) { + modifiers = buildModifiers(node); + } + + // just like: import '../xxx' + if (!node.importClause) { + let importClauseName = ''; + let importType = ''; + let importInfo = new ImportInfo(); + importInfo.build(importClauseName, importType, importFrom, originTsPosition, modifiers); + importInfo.setTsSourceCode(tsSourceCode); + IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); + importInfos.push(importInfo); + } + + //just like: import fs from 'fs' + if (node.importClause && node.importClause.name && ts.isIdentifier(node.importClause.name)) { + let importClauseName = node.importClause.name.text; + const pos = LineColPosition.buildFromNode(node.importClause.name, sourceFile); + let importType = 'Identifier'; + let importInfo = new ImportInfo(); + importInfo.build(importClauseName, importType, importFrom, pos, modifiers); + importInfo.setTsSourceCode(tsSourceCode); + IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); + importInfos.push(importInfo); + } + + // just like: import {xxx} from './yyy' + if (node.importClause && node.importClause.namedBindings && ts.isNamedImports(node.importClause.namedBindings)) { + let importType = 'NamedImports'; + if (node.importClause.namedBindings.elements) { + node.importClause.namedBindings.elements.forEach(element => { + if (element.name && ts.isIdentifier(element.name)) { + let importClauseName = element.name.text; + const pos = LineColPosition.buildFromNode(element, sourceFile); + if (element.propertyName && ts.isIdentifier(element.propertyName)) { + let importInfo = new ImportInfo(); + importInfo.build(importClauseName, importType, importFrom, pos, modifiers, element.propertyName.text); + importInfo.setTsSourceCode(tsSourceCode); + IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); + importInfos.push(importInfo); + } else { + let importInfo = new ImportInfo(); + importInfo.build(importClauseName, importType, importFrom, pos, modifiers); + importInfo.setTsSourceCode(tsSourceCode); + IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); + importInfos.push(importInfo); + } + } + }); + } + } + + // just like: import * as ts from 'ohos-typescript' + if (node.importClause && node.importClause.namedBindings && ts.isNamespaceImport(node.importClause.namedBindings)) { + let importType = 'NamespaceImport'; + if (node.importClause.namedBindings.name && ts.isIdentifier(node.importClause.namedBindings.name)) { + let importClauseName = node.importClause.namedBindings.name.text; + let importInfo = new ImportInfo(); + let nameBeforeAs = '*'; + const pos = LineColPosition.buildFromNode(node.importClause.namedBindings.name, sourceFile); + importInfo.build(importClauseName, importType, importFrom, pos, modifiers, nameBeforeAs); + importInfo.setTsSourceCode(tsSourceCode); + IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); + importInfos.push(importInfo); + } + } + + return importInfos; +} + +function buildImportEqualsDeclarationNode(node: ts.ImportEqualsDeclaration, sourceFile: ts.SourceFile, arkFile: ArkFile): ImportInfo[] { + const originTsPosition = LineColPosition.buildFromNode(node, sourceFile); + const tsSourceCode = node.getText(sourceFile); + + let importInfos: ImportInfo[] = []; + let importType = 'EqualsImport'; + let modifiers = 0; + if (node.modifiers) { + modifiers = buildModifiers(node); + } + if ( + node.moduleReference && + ts.isExternalModuleReference(node.moduleReference) && + node.moduleReference.expression && + ts.isStringLiteral(node.moduleReference.expression) + ) { + let importFrom = node.moduleReference.expression.text; + let importClauseName = node.name.text; + let importInfo = new ImportInfo(); + importInfo.build(importClauseName, importType, importFrom, originTsPosition, modifiers); + importInfo.setTsSourceCode(tsSourceCode); + IRUtils.setComments(importInfo, node, sourceFile, arkFile.getScene().getOptions()); + importInfos.push(importInfo); + } + return importInfos; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..29221c377c4737302b92774d61b2e79941b2246d --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkMethodBuilder.ts @@ -0,0 +1,515 @@ +/* + * 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. + */ + +import { ClassType, Type, UnknownType } from '../../base/Type'; +import { BodyBuilder } from './BodyBuilder'; +import { buildViewTree } from '../../graph/builder/ViewTreeBuilder'; +import { ArkClass, ClassCategory } from '../ArkClass'; +import { ArkMethod } from '../ArkMethod'; +import ts from 'ohos-typescript'; +import { + buildDecorators, + buildGenericType, + buildModifiers, + buildParameters, + buildReturnType, + buildTypeParameters, + handlePropertyAccessExpression, +} from './builderUtils'; +import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; +import { ArkParameterRef, ArkThisRef, ClosureFieldRef } from '../../base/Ref'; +import { ArkBody } from '../ArkBody'; +import { Cfg } from '../../graph/Cfg'; +import { ArkInstanceInvokeExpr, ArkStaticInvokeExpr } from '../../base/Expr'; +import { MethodSignature, MethodSubSignature } from '../ArkSignature'; +import { ArkAssignStmt, ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, Stmt } from '../../base/Stmt'; +import { BasicBlock } from '../../graph/BasicBlock'; +import { Local } from '../../base/Local'; +import { Value } from '../../base/Value'; +import { CONSTRUCTOR_NAME, SUPER_NAME, THIS_NAME } from '../../common/TSConst'; +import { ANONYMOUS_METHOD_PREFIX, CALL_SIGNATURE_NAME, DEFAULT_ARK_CLASS_NAME, DEFAULT_ARK_METHOD_NAME, NAME_DELIMITER, NAME_PREFIX } from '../../common/Const'; +import { ArkSignatureBuilder } from './ArkSignatureBuilder'; +import { IRUtils } from '../../common/IRUtils'; +import { ArkErrorCode } from '../../common/ArkError'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkMethodBuilder'); + +export type MethodLikeNode = + | ts.FunctionDeclaration + | ts.MethodDeclaration + | ts.ConstructorDeclaration + | ts.ArrowFunction + | ts.AccessorDeclaration + | ts.FunctionExpression + | ts.MethodSignature + | ts.ConstructSignatureDeclaration + | ts.CallSignatureDeclaration + | ts.FunctionTypeNode; + +export function buildDefaultArkMethodFromArkClass(declaringClass: ArkClass, mtd: ArkMethod, sourceFile: ts.SourceFile, node?: ts.ModuleDeclaration): void { + mtd.setDeclaringArkClass(declaringClass); + + const methodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(DEFAULT_ARK_METHOD_NAME, true); + const methodSignature = new MethodSignature(mtd.getDeclaringArkClass().getSignature(), methodSubSignature); + mtd.setImplementationSignature(methodSignature); + mtd.setLineCol(0); + + const defaultMethodNode = node ? node : sourceFile; + + let bodyBuilder = new BodyBuilder(mtd.getSignature(), defaultMethodNode, mtd, sourceFile); + mtd.setBodyBuilder(bodyBuilder); +} + +export function buildArkMethodFromArkClass( + methodNode: MethodLikeNode, + declaringClass: ArkClass, + mtd: ArkMethod, + sourceFile: ts.SourceFile, + declaringMethod?: ArkMethod +): void { + mtd.setDeclaringArkClass(declaringClass); + declaringMethod !== undefined && mtd.setOuterMethod(declaringMethod); + + ts.isFunctionDeclaration(methodNode) && mtd.setAsteriskToken(methodNode.asteriskToken !== undefined); + + // All MethodLikeNode except FunctionTypeNode have questionToken. + !ts.isFunctionTypeNode(methodNode) && mtd.setQuestionToken(methodNode.questionToken !== undefined); + + mtd.setCode(methodNode.getText(sourceFile)); + mtd.setModifiers(buildModifiers(methodNode)); + mtd.setDecorators(buildDecorators(methodNode, sourceFile)); + + if (methodNode.typeParameters) { + mtd.setGenericTypes(buildTypeParameters(methodNode.typeParameters, sourceFile, mtd)); + } + + // build methodDeclareSignatures and methodSignature as well as corresponding positions + const methodName = buildMethodName(methodNode, declaringClass, sourceFile, declaringMethod); + const methodParameters: MethodParameter[] = []; + buildParameters(methodNode.parameters, mtd, sourceFile).forEach(parameter => { + buildGenericType(parameter.getType(), mtd); + methodParameters.push(parameter); + }); + let returnType = UnknownType.getInstance(); + if (methodNode.type) { + returnType = buildGenericType(buildReturnType(methodNode.type, sourceFile, mtd), mtd); + } + const methodSubSignature = new MethodSubSignature(methodName, methodParameters, returnType, mtd.isStatic()); + const methodSignature = new MethodSignature(mtd.getDeclaringArkClass().getSignature(), methodSubSignature); + const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, methodNode.getStart(sourceFile)); + if (isMethodImplementation(methodNode)) { + mtd.setImplementationSignature(methodSignature); + mtd.setLine(line + 1); + mtd.setColumn(character + 1); + } else { + mtd.setDeclareSignatures(methodSignature); + mtd.setDeclareLinesAndCols([line + 1], [character + 1]); + } + + let bodyBuilder = new BodyBuilder(mtd.getSignature(), methodNode, mtd, sourceFile); + mtd.setBodyBuilder(bodyBuilder); + + if (mtd.hasBuilderDecorator()) { + mtd.setViewTree(buildViewTree(mtd)); + } else if (declaringClass.hasComponentDecorator() && mtd.getSubSignature().toString() === 'build()' && !mtd.isStatic()) { + declaringClass.setViewTree(buildViewTree(mtd)); + } + checkAndUpdateMethod(mtd, declaringClass); + declaringClass.addMethod(mtd); + IRUtils.setComments(mtd, methodNode, sourceFile, mtd.getDeclaringArkFile().getScene().getOptions()); +} + +function buildMethodName(node: MethodLikeNode, declaringClass: ArkClass, sourceFile: ts.SourceFile, declaringMethod?: ArkMethod): string { + let name: string = ''; + if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) { + name = node.name ? node.name.text : buildAnonymousMethodName(node, declaringClass); + } else if (ts.isFunctionTypeNode(node)) { + //TODO: check name type + name = node.name ? node.name.getText(sourceFile) : buildAnonymousMethodName(node, declaringClass); + } else if (ts.isMethodDeclaration(node) || ts.isMethodSignature(node)) { + if (ts.isIdentifier(node.name)) { + name = (node.name as ts.Identifier).text; + } else if (ts.isComputedPropertyName(node.name)) { + if (ts.isIdentifier(node.name.expression)) { + name = node.name.expression.text; + } else if (ts.isPropertyAccessExpression(node.name.expression)) { + name = handlePropertyAccessExpression(node.name.expression); + } else { + logger.warn('Other method ComputedPropertyName found!'); + } + } else { + logger.warn('Other method declaration type found!'); + } + } + //TODO, hard code + else if (ts.isConstructorDeclaration(node)) { + name = CONSTRUCTOR_NAME; + } else if (ts.isConstructSignatureDeclaration(node)) { + name = 'construct-signature'; + } else if (ts.isCallSignatureDeclaration(node)) { + name = CALL_SIGNATURE_NAME; + } else if (ts.isGetAccessor(node) && ts.isIdentifier(node.name)) { + name = 'Get-' + node.name.text; + } else if (ts.isSetAccessor(node) && ts.isIdentifier(node.name)) { + name = 'Set-' + node.name.text; + } else if (ts.isArrowFunction(node)) { + name = buildAnonymousMethodName(node, declaringClass); + } + + if (declaringMethod !== undefined && !declaringMethod.isDefaultArkMethod()) { + name = buildNestedMethodName(name, declaringMethod.getName()); + } + return name; +} + +function buildAnonymousMethodName(node: MethodLikeNode, declaringClass: ArkClass): string { + return `${ANONYMOUS_METHOD_PREFIX}${declaringClass.getAnonymousMethodNumber()}`; +} + +function buildNestedMethodName(originName: string, declaringMethodName: string): string { + if (originName.startsWith(NAME_PREFIX)) { + return `${originName}${NAME_DELIMITER}${declaringMethodName}`; + } + return `${NAME_PREFIX}${originName}${NAME_DELIMITER}${declaringMethodName}`; +} + +export class ObjectBindingPatternParameter { + private propertyName: string = ''; + private name: string = ''; + private optional: boolean = false; + + constructor() {} + + public getName(): string { + return this.name; + } + + public setName(name: string): void { + this.name = name; + } + + public getPropertyName(): string { + return this.propertyName; + } + + public setPropertyName(propertyName: string): void { + this.propertyName = propertyName; + } + + public isOptional(): boolean { + return this.optional; + } + + public setOptional(optional: boolean): void { + this.optional = optional; + } +} + +export class ArrayBindingPatternParameter { + private propertyName: string = ''; + private name: string = ''; + private optional: boolean = false; + + constructor() {} + + public getName(): string { + return this.name; + } + + public setName(name: string): void { + this.name = name; + } + + public getPropertyName(): string { + return this.propertyName; + } + + public setPropertyName(propertyName: string): void { + this.propertyName = propertyName; + } + + public isOptional(): boolean { + return this.optional; + } + + public setOptional(optional: boolean): void { + this.optional = optional; + } +} + +export class MethodParameter implements Value { + private name: string = ''; + private type!: Type; + private optional: boolean = false; + private dotDotDotToken: boolean = false; + private objElements: ObjectBindingPatternParameter[] = []; + private arrayElements: ArrayBindingPatternParameter[] = []; + + constructor() {} + + public getName(): string { + return this.name; + } + + public setName(name: string): void { + this.name = name; + } + + public getType(): Type { + return this.type; + } + + public setType(type: Type): void { + this.type = type; + } + + public isOptional(): boolean { + return this.optional; + } + + public setOptional(optional: boolean): void { + this.optional = optional; + } + + public hasDotDotDotToken(): boolean { + return this.dotDotDotToken; + } + + public setDotDotDotToken(dotDotDotToken: boolean): void { + this.dotDotDotToken = dotDotDotToken; + } + + public addObjElement(element: ObjectBindingPatternParameter): void { + this.objElements.push(element); + } + + public getObjElements(): ObjectBindingPatternParameter[] { + return this.objElements; + } + + public setObjElements(objElements: ObjectBindingPatternParameter[]): void { + this.objElements = objElements; + } + + public addArrayElement(element: ArrayBindingPatternParameter): void { + this.arrayElements.push(element); + } + + public getArrayElements(): ArrayBindingPatternParameter[] { + return this.arrayElements; + } + + public setArrayElements(arrayElements: ArrayBindingPatternParameter[]): void { + this.arrayElements = arrayElements; + } + + public getUses(): Value[] { + return []; + } +} + +function needDefaultConstructorInClass(arkClass: ArkClass): boolean { + const originClassType = arkClass.getCategory(); + return ( + arkClass.getMethodWithName(CONSTRUCTOR_NAME) === null && + (originClassType === ClassCategory.CLASS || originClassType === ClassCategory.OBJECT) && + arkClass.getName() !== DEFAULT_ARK_CLASS_NAME && + !arkClass.isDeclare() + ); +} + +function recursivelyCheckAndBuildSuperConstructor(arkClass: ArkClass): void { + let superClass: ArkClass | null = arkClass.getSuperClass(); + while (superClass !== null) { + if (superClass.getMethodWithName(CONSTRUCTOR_NAME) === null) { + buildDefaultConstructor(superClass); + } + superClass = superClass.getSuperClass(); + } +} + +export function buildDefaultConstructor(arkClass: ArkClass): boolean { + if (!needDefaultConstructorInClass(arkClass)) { + return false; + } + + recursivelyCheckAndBuildSuperConstructor(arkClass); + + const defaultConstructor: ArkMethod = new ArkMethod(); + defaultConstructor.setDeclaringArkClass(arkClass); + defaultConstructor.setCode(''); + defaultConstructor.setIsGeneratedFlag(true); + defaultConstructor.setLineCol(0); + + const thisLocal = new Local(THIS_NAME, new ClassType(arkClass.getSignature())); + const locals: Set = new Set([thisLocal]); + const basicBlock = new BasicBlock(); + basicBlock.setId(0); + + let parameters: MethodParameter[] = []; + let parameterArgs: Value[] = []; + const superConstructor = arkClass.getSuperClass()?.getMethodWithName(CONSTRUCTOR_NAME); + if (superConstructor) { + parameters = superConstructor.getParameters(); + + for (let index = 0; index < parameters.length; index++) { + const parameterRef = new ArkParameterRef(index, parameters[index].getType()); + const parameterLocal = new Local(parameters[index].getName(), parameterRef.getType()); + locals.add(parameterLocal); + parameterArgs.push(parameterLocal); + basicBlock.addStmt(new ArkAssignStmt(parameterLocal, parameterRef)); + index++; + } + } + + basicBlock.addStmt(new ArkAssignStmt(thisLocal, new ArkThisRef(new ClassType(arkClass.getSignature())))); + + if (superConstructor) { + const superMethodSubSignature = new MethodSubSignature(SUPER_NAME, parameters, superConstructor.getReturnType()); + const superMethodSignature = new MethodSignature(arkClass.getSignature(), superMethodSubSignature); + const superInvokeExpr = new ArkStaticInvokeExpr(superMethodSignature, parameterArgs); + basicBlock.addStmt(new ArkInvokeStmt(superInvokeExpr)); + } + + const methodSubSignature = new MethodSubSignature(CONSTRUCTOR_NAME, parameters, thisLocal.getType(), defaultConstructor.isStatic()); + defaultConstructor.setImplementationSignature(new MethodSignature(arkClass.getSignature(), methodSubSignature)); + basicBlock.addStmt(new ArkReturnStmt(thisLocal)); + + const cfg = new Cfg(); + cfg.addBlock(basicBlock); + cfg.setStartingStmt(basicBlock.getHead()!); + cfg.setDeclaringMethod(defaultConstructor); + cfg.getStmts().forEach(s => s.setCfg(cfg)); + + defaultConstructor.setBody(new ArkBody(locals, cfg)); + checkAndUpdateMethod(defaultConstructor, arkClass); + arkClass.addMethod(defaultConstructor); + + return true; +} + +export function buildInitMethod(initMethod: ArkMethod, fieldInitializerStmts: Stmt[], thisLocal: Local): void { + const classType = new ClassType(initMethod.getDeclaringArkClass().getSignature()); + const assignStmt = new ArkAssignStmt(thisLocal, new ArkThisRef(classType)); + const block = new BasicBlock(); + block.setId(0); + block.addStmt(assignStmt); + const locals: Set = new Set([thisLocal]); + for (const stmt of fieldInitializerStmts) { + block.addStmt(stmt); + if (stmt.getDef() && stmt.getDef() instanceof Local) { + locals.add(stmt.getDef() as Local); + } + } + block.addStmt(new ArkReturnVoidStmt()); + const cfg = new Cfg(); + cfg.addBlock(block); + for (const stmt of block.getStmts()) { + stmt.setCfg(cfg); + } + cfg.setStartingStmt(assignStmt); + cfg.buildDefUseStmt(locals); + cfg.setDeclaringMethod(initMethod); + initMethod.setBody(new ArkBody(locals, cfg)); +} + +export function addInitInConstructor(constructor: ArkMethod): void { + const thisLocal = constructor.getBody()?.getLocals().get(THIS_NAME); + if (!thisLocal) { + return; + } + const blocks = constructor.getCfg()?.getBlocks(); + if (!blocks) { + return; + } + const firstBlockStmts = [...blocks][0].getStmts(); + let index = 0; + for (let i = 0; i < firstBlockStmts.length; i++) { + const stmt = firstBlockStmts[i]; + if (stmt instanceof ArkInvokeStmt && stmt.getInvokeExpr().getMethodSignature().getMethodSubSignature().getMethodName() === SUPER_NAME) { + index++; + continue; + } + if (stmt instanceof ArkAssignStmt) { + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef || rightOp instanceof ArkThisRef || rightOp instanceof ClosureFieldRef) { + index++; + continue; + } + } + break; + } + const initInvokeStmt = new ArkInvokeStmt( + new ArkInstanceInvokeExpr(thisLocal, constructor.getDeclaringArkClass().getInstanceInitMethod().getSignature(), []) + ); + firstBlockStmts.splice(index, 0, initInvokeStmt); +} + +export function isMethodImplementation(node: MethodLikeNode): boolean { + if ( + ts.isFunctionDeclaration(node) || + ts.isMethodDeclaration(node) || + ts.isConstructorDeclaration(node) || + ts.isGetAccessorDeclaration(node) || + ts.isSetAccessorDeclaration(node) || + ts.isFunctionExpression(node) || + ts.isArrowFunction(node) + ) { + if (node.body !== undefined) { + return true; + } + } + return false; +} + +export function checkAndUpdateMethod(method: ArkMethod, cls: ArkClass): void { + let presentMethod: ArkMethod | null; + if (method.isStatic()) { + presentMethod = cls.getStaticMethodWithName(method.getName()); + } else { + presentMethod = cls.getMethodWithName(method.getName()); + } + if (presentMethod === null) { + return; + } + + if (method.validate().errCode !== ArkErrorCode.OK || presentMethod.validate().errCode !== ArkErrorCode.OK) { + return; + } + const presentDeclareSignatures = presentMethod.getDeclareSignatures(); + const presentDeclareLineCols = presentMethod.getDeclareLineCols(); + const presentImplSignature = presentMethod.getImplementationSignature(); + const newDeclareSignature = method.getDeclareSignatures(); + const newDeclareLineCols = method.getDeclareLineCols(); + const newImplSignature = method.getImplementationSignature(); + + if (presentDeclareSignatures !== null && presentImplSignature === null) { + if (newDeclareSignature === null || presentMethod.getDeclareSignatureIndex(newDeclareSignature[0]) >= 0) { + method.setDeclareSignatures(presentDeclareSignatures); + method.setDeclareLineCols(presentDeclareLineCols as number[]); + } else { + method.setDeclareSignatures(presentDeclareSignatures.concat(newDeclareSignature)); + method.setDeclareLineCols((presentDeclareLineCols as number[]).concat(newDeclareLineCols as number[])); + } + return; + } + if (presentDeclareSignatures === null && presentImplSignature !== null) { + if (newImplSignature === null) { + method.setImplementationSignature(presentImplSignature); + method.setLineCol(presentMethod.getLineCol() as number); + } + return; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkNamespaceBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkNamespaceBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..930a0bba21cd77dab5d45b67ebc9b3a897842fef --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkNamespaceBuilder.ts @@ -0,0 +1,185 @@ +/* + * 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. + */ + +import { LineColPosition } from '../../base/Position'; +import { buildDefaultArkClassFromArkNamespace, buildNormalArkClassFromArkNamespace } from './ArkClassBuilder'; +import { ArkFile } from '../ArkFile'; +import { buildArkMethodFromArkClass } from './ArkMethodBuilder'; +import ts from 'ohos-typescript'; +import { ArkNamespace } from '../ArkNamespace'; +import { buildDecorators, buildModifiers } from './builderUtils'; +import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; +import { buildExportAssignment, buildExportDeclaration, buildExportInfo, buildExportVariableStatement, isExported } from './ArkExportBuilder'; +import { ArkClass } from '../ArkClass'; +import { ArkMethod } from '../ArkMethod'; +import { NamespaceSignature } from '../ArkSignature'; +import { IRUtils } from '../../common/IRUtils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkNamespaceBuilder'); + +export function buildArkNamespace(node: ts.ModuleDeclaration, declaringInstance: ArkFile | ArkNamespace, ns: ArkNamespace, sourceFile: ts.SourceFile): void { + // modifiers + if (node.modifiers) { + ns.setModifiers(buildModifiers(node)); + ns.setDecorators(buildDecorators(node, sourceFile)); + } + + if (declaringInstance instanceof ArkFile) { + ns.setDeclaringArkFile(declaringInstance); + } else { + ns.setDeclaringArkNamespace(declaringInstance); + ns.setDeclaringArkFile(declaringInstance.getDeclaringArkFile()); + } + ns.setDeclaringInstance(declaringInstance); + const namespaceName = node.name.text; + const namespaceSignature = new NamespaceSignature( + namespaceName, + ns.getDeclaringArkFile().getFileSignature(), + ns.getDeclaringArkNamespace()?.getSignature() || null + ); + ns.setSignature(namespaceSignature); + + // TODO: whether needed? + ns.setCode(node.getText(sourceFile)); + + // set line and column + const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, node.getStart(sourceFile)); + ns.setLine(line + 1); + ns.setColumn(character + 1); + + genDefaultArkClass(ns, node, sourceFile); + + // build ns member + if (node.body) { + if (ts.isModuleBlock(node.body)) { + buildNamespaceMembers(node.body, ns, sourceFile); + } + // NamespaceDeclaration extends ModuleDeclaration + //TODO: Check + else if (ts.isModuleDeclaration(node.body)) { + logger.warn('This ModuleBody is an NamespaceDeclaration.'); + let childNs: ArkNamespace = new ArkNamespace(); + buildArkNamespace(node.body, ns, childNs, sourceFile); + ns.addNamespace(childNs); + } else if (ts.isIdentifier(node.body)) { + logger.warn('ModuleBody is Identifier.'); + } else { + logger.warn('JSDocNamespaceDeclaration found.'); + } + } else { + logger.warn('JSDocNamespaceDeclaration found.'); + } + IRUtils.setComments(ns, node, sourceFile, ns.getDeclaringArkFile().getScene().getOptions()); +} + +// TODO: check and update +function buildNamespaceMembers(node: ts.ModuleBlock, namespace: ArkNamespace, sourceFile: ts.SourceFile): void { + const statements = node.statements; + const nestedNamespaces: ArkNamespace[] = []; + statements.forEach(child => { + if (ts.isModuleDeclaration(child)) { + let childNs: ArkNamespace = new ArkNamespace(); + childNs.setDeclaringArkNamespace(namespace); + childNs.setDeclaringArkFile(namespace.getDeclaringArkFile()); + + buildArkNamespace(child, namespace, childNs, sourceFile); + nestedNamespaces.push(childNs); + } else if (ts.isClassDeclaration(child) || ts.isInterfaceDeclaration(child) || ts.isEnumDeclaration(child) || ts.isStructDeclaration(child)) { + let cls: ArkClass = new ArkClass(); + + buildNormalArkClassFromArkNamespace(child, namespace, cls, sourceFile); + namespace.addArkClass(cls); + + if (cls.isExported()) { + namespace.addExportInfo(buildExportInfo(cls, namespace.getDeclaringArkFile(), LineColPosition.buildFromNode(child, sourceFile))); + } + } + // TODO: Check + else if (ts.isMethodDeclaration(child)) { + logger.warn('This is a MethodDeclaration in ArkNamespace.'); + let mthd: ArkMethod = new ArkMethod(); + + buildArkMethodFromArkClass(child, namespace.getDefaultClass(), mthd, sourceFile); + + if (mthd.isExported()) { + namespace.addExportInfo(buildExportInfo(mthd, namespace.getDeclaringArkFile(), LineColPosition.buildFromNode(child, sourceFile))); + } + } else if (ts.isFunctionDeclaration(child)) { + let mthd: ArkMethod = new ArkMethod(); + + buildArkMethodFromArkClass(child, namespace.getDefaultClass(), mthd, sourceFile); + + if (mthd.isExported()) { + namespace.addExportInfo(buildExportInfo(mthd, namespace.getDeclaringArkFile(), LineColPosition.buildFromNode(child, sourceFile))); + } + } else if (ts.isExportDeclaration(child)) { + buildExportDeclaration(child, sourceFile, namespace.getDeclaringArkFile()).forEach(item => namespace.addExportInfo(item)); + } else if (ts.isExportAssignment(child)) { + buildExportAssignment(child, sourceFile, namespace.getDeclaringArkFile()).forEach(item => namespace.addExportInfo(item)); + } else if (ts.isVariableStatement(child) && isExported(child.modifiers)) { + buildExportVariableStatement(child, sourceFile, namespace.getDeclaringArkFile(), namespace).forEach(item => namespace.addExportInfo(item)); + } else { + logger.info('Child joined default method of arkFile: ', ts.SyntaxKind[child.kind]); + // join default method + } + }); + + const nestedMergedNameSpaces = mergeNameSpaces(nestedNamespaces); + nestedMergedNameSpaces.forEach(nestedNameSpace => { + namespace.addNamespace(nestedNameSpace); + if (nestedNameSpace.isExport()) { + const linCol = new LineColPosition(nestedNameSpace.getLine(), nestedNameSpace.getColumn()); + namespace.addExportInfo(buildExportInfo(nestedNameSpace, namespace.getDeclaringArkFile(), linCol)); + } + }); +} + +function genDefaultArkClass(ns: ArkNamespace, node: ts.ModuleDeclaration, sourceFile: ts.SourceFile): void { + let defaultClass = new ArkClass(); + + buildDefaultArkClassFromArkNamespace(ns, defaultClass, node, sourceFile); + ns.setDefaultClass(defaultClass); + ns.addArkClass(defaultClass); +} + +export function mergeNameSpaces(arkNamespaces: ArkNamespace[]): ArkNamespace[] { + const namespaceMap = new Map(); + for (let i = 0; i < arkNamespaces.length; i++) { + const currNamespace = arkNamespaces[i]; + const currName = currNamespace.getName(); + if (namespaceMap.has(currName)) { + const prevNamespace = namespaceMap.get(currName)!; + const nestedPrevNamespaces = prevNamespace.getNamespaces(); + const nestedCurrNamespaces = currNamespace.getNamespaces(); + const nestedMergedNameSpaces = mergeNameSpaces([...nestedPrevNamespaces, ...nestedCurrNamespaces]); + nestedMergedNameSpaces.forEach(nestedNameSpace => { + prevNamespace.addNamespace(nestedNameSpace); + }); + const classes = currNamespace.getClasses(); + classes.forEach(cls => { + prevNamespace.addArkClass(cls); + }); + const preSourceCodes = prevNamespace.getCodes(); + const currSourceCodes = currNamespace.getCodes(); + prevNamespace.setCodes([...preSourceCodes, ...currSourceCodes]); + const prevLineColPairs = prevNamespace.getLineColPairs(); + const currLineColPairs = currNamespace.getLineColPairs(); + prevNamespace.setLineCols([...prevLineColPairs, ...currLineColPairs]); + } else { + namespaceMap.set(currName, currNamespace); + } + } + return [...namespaceMap.values()]; +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkSignatureBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkSignatureBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..4804a8136c2257a9e7f379e0f23baf6479e6706b --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/ArkSignatureBuilder.ts @@ -0,0 +1,42 @@ +/* + * 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. + */ + +import { ClassSignature, FieldSignature, FileSignature, MethodSignature, MethodSubSignature } from '../ArkSignature'; +import { UnknownType } from '../../base/Type'; + +export class ArkSignatureBuilder { + public static buildMethodSignatureFromClassNameAndMethodName(className: string, methodName: string, staticFlag: boolean = false): MethodSignature { + const classSignature = this.buildClassSignatureFromClassName(className); + const methodSubSignature = this.buildMethodSubSignatureFromMethodName(methodName, staticFlag); + return new MethodSignature(classSignature, methodSubSignature); + } + + public static buildMethodSignatureFromMethodName(methodName: string, staticFlag: boolean = false): MethodSignature { + const methodSubSignature = this.buildMethodSubSignatureFromMethodName(methodName, staticFlag); + return new MethodSignature(ClassSignature.DEFAULT, methodSubSignature); + } + + public static buildMethodSubSignatureFromMethodName(methodName: string, staticFlag: boolean = false): MethodSubSignature { + return new MethodSubSignature(methodName, [], UnknownType.getInstance(), staticFlag); + } + + public static buildClassSignatureFromClassName(className: string): ClassSignature { + return new ClassSignature(className, FileSignature.DEFAULT); + } + + public static buildFieldSignatureFromFieldName(fieldName: string, staticFlag: boolean = false): FieldSignature { + return new FieldSignature(fieldName, ClassSignature.DEFAULT, UnknownType.getInstance(), staticFlag); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/BodyBuilder.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/BodyBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..77b28a411fc80b6884620cdf50e2d5e564b93a81 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/BodyBuilder.ts @@ -0,0 +1,598 @@ +/* + * 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. + */ + +import { ArkBody } from '../ArkBody'; +import { ArkMethod } from '../ArkMethod'; +import { FieldSignature, MethodSignature, methodSignatureCompare, MethodSubSignature } from '../ArkSignature'; +import { CfgBuilder } from '../../graph/builder/CfgBuilder'; +import * as ts from 'ohos-typescript'; +import { Local } from '../../base/Local'; +import { MethodParameter } from './ArkMethodBuilder'; +import { LEXICAL_ENV_NAME_PREFIX, NAME_DELIMITER, NAME_PREFIX } from '../../common/Const'; +import { ArkParameterRef, ArkStaticFieldRef, ClosureFieldRef, GlobalRef } from '../../base/Ref'; +import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkInvokeStmt, ArkReturnStmt } from '../../base/Stmt'; +import { AliasType, ArrayType, ClosureType, FunctionType, LexicalEnvType, Type, UnclearReferenceType, UnionType } from '../../base/Type'; +import { AbstractInvokeExpr, ArkPtrInvokeExpr } from '../../base/Expr'; + +type NestedMethodChain = { + parent: ArkMethod; + children: NestedMethodChain[] | null; +}; + +export class BodyBuilder { + private cfgBuilder: CfgBuilder; + private globals?: Map; + + constructor(methodSignature: MethodSignature, sourceAstNode: ts.Node, declaringMethod: ArkMethod, sourceFile: ts.SourceFile) { + this.cfgBuilder = new CfgBuilder(sourceAstNode, methodSignature.getMethodSubSignature().getMethodName(), declaringMethod, sourceFile); + } + + public build(): ArkBody | null { + this.cfgBuilder.buildCfgBuilder(); + if (!this.cfgBuilder.isBodyEmpty()) { + const { cfg, locals, globals, aliasTypeMap, traps } = this.cfgBuilder.buildCfg(); + if (globals !== null) { + this.setGlobals(globals); + } + cfg.buildDefUseStmt(locals); + + return new ArkBody(locals, cfg, aliasTypeMap, traps.length ? traps : undefined); + } + return null; + } + + public getCfgBuilder(): CfgBuilder { + return this.cfgBuilder; + } + + public getGlobals(): Map | undefined { + return this.globals; + } + + public setGlobals(globals: Map): void { + this.globals = globals; + } + + /** + * Find out all locals in the parent method which are used by the childrenChain, these locals are the closures of the root node of the childrenChain. + * childrenChain contains all nested method from the root node of the childrenChain. + * baseLocals are all locals defined in the outer function. + * allNestedLocals are collect all locals defined in all outer functions of this childrenChain. + * Only the globals of the root of the childrenChain, which are in the baseLocals but not in the allNestedLocals are the actual closures that in baseLocals. + */ + private findClosuresUsedInNested(childrenChain: NestedMethodChain, baseLocals: Map, allNestedLocals: Map): Local[] | null { + let closuresRes: Local[] = []; + + const nestedMethod = childrenChain.parent; + let nestedGlobals = nestedMethod.getBodyBuilder()?.getGlobals(); + if (nestedGlobals !== undefined) { + for (let global of nestedGlobals.values()) { + const nestedLocal = allNestedLocals.get(global.getName()); + const closure = baseLocals.get(global.getName()); + if (nestedLocal === undefined && closure !== undefined) { + closuresRes.push(closure); + } + } + } + const children = childrenChain.children; + if (children === null) { + return closuresRes; + } + for (let chain of children) { + const nestedLocals = nestedMethod.getBody()?.getLocals(); + if (nestedLocals !== undefined) { + nestedLocals.forEach((value, key) => { + allNestedLocals.set(key, value); + }); + } + const closures = this.findClosuresUsedInNested(chain, baseLocals, allNestedLocals); + if (closures) { + closuresRes.push(...closures); + } + } + return closuresRes; + } + + /** + * 1. Find out all locals in the parent method which are used by the childrenChain, these locals are the closures of the root node of the childrenChain. + * 2. Create a lexical env local in the parent method, and pass it to root node of the childrenChain through the method signature. + * 3. Update the root node of the childrenChain to add parameterRef assign stmt and closureRef assign stmt. + * 4. Recursively do this for all nested method level by level. + */ + private buildLexicalEnv(childrenChain: NestedMethodChain, baseLocals: Map, index: number): number { + let usedClosures = this.findClosuresUsedInNested(childrenChain, baseLocals, new Map()); + const nestedMethod = childrenChain.parent; + const nestedSignature = nestedMethod.getImplementationSignature(); + if (nestedSignature !== null && usedClosures !== null && usedClosures.length > 0) { + let lexicalEnv = new LexicalEnvType(nestedSignature, usedClosures); + const closuresLocal = new Local(`${LEXICAL_ENV_NAME_PREFIX}${index++}`, lexicalEnv); + baseLocals.set(closuresLocal.getName(), closuresLocal); + this.updateNestedMethodWithClosures(nestedMethod, closuresLocal); + } else if (usedClosures === null || usedClosures.length === 0) { + this.moveCurrentMethodLocalToGlobal(nestedMethod); + } + + const nextNestedChains = childrenChain.children; + if (nextNestedChains === null) { + return index; + } + for (let nextChain of nextNestedChains) { + const newBaseLocals = nestedMethod.getBody()?.getLocals(); + if (newBaseLocals === undefined) { + return index; + } + index = this.buildLexicalEnv(nextChain, newBaseLocals, index); + } + return index; + } + + /** + * Find out and tag all closures from globals, and remove closures from both globals and locals. + * Precondition: body build has been done. All locals, globals and closures are both set as Local in body, + * while potential globals and closures are also recorded in bodybuilder. + * Constraint: only the outermost function can call this method to recursively handle closures of itself as well as all nested methods. + */ + public handleGlobalAndClosure(): void { + /** + * Step1: Handle the outermost function, take it as Level 0. + * There must be no closures in Level 0. So only need to remove the locals which with the same name as the ones in globals. + */ + let outerMethod = this.getCfgBuilder().getDeclaringMethod(); + let outerGlobals = outerMethod.getBodyBuilder()?.getGlobals(); + outerMethod.freeBodyBuilder(); + let outerLocals = outerMethod.getBody()?.getLocals(); + if (outerGlobals !== undefined && outerLocals !== undefined) { + outerGlobals.forEach((value, key) => { + const local = outerLocals!.get(key); + if (local !== undefined) { + value.addUsedStmts(local.getUsedStmts()); + outerLocals!.delete(key); + } + }); + if (outerGlobals.size > 0) { + outerMethod.getBody()?.setUsedGlobals(outerGlobals); + } + } + + let nestedMethodChains = this.generateNestedMethodChains(outerMethod).children; + if (nestedMethodChains === null || outerLocals === undefined) { + return; + } + let closuresIndex = 0; + for (let nestedChain of nestedMethodChains) { + /** + * Step2: Handle each nested function in Level 1 one by one. + * Find out all closures from Level 0 used by these Level 1 functions as well as all their children nested functions. + * This will be done level by level recursively. + */ + closuresIndex = this.buildLexicalEnv(nestedChain, outerLocals, closuresIndex); + + /** + * Step3: Delete old globals which are recognized as closures, then the rest globals are the true globals. + * The redundancy locals should be deleted but the used stmts of them should be restored to globals. + * This will be done level by level recursively. + */ + this.reorganizeGlobalAndLocal(nestedChain); + + /** + * Step4: Infer UnclearReferenceType to check whether it is the type alias define in its parent function.. + */ + this.inferTypesDefineInOuter(outerMethod, nestedChain); + + /** + * Step5: For each nested function, find out whether it is called by its parent function and update the related locals, globals and stmts. + */ + this.updateNestedMethodUsedInOuter(nestedChain); + + this.freeBodyBuilder(nestedChain); + } + } + + private freeBodyBuilder(nestedChain: NestedMethodChain): void { + nestedChain.parent.freeBodyBuilder(); + const childrenChains = nestedChain.children; + if (childrenChains === null) { + return; + } + for (const chain of childrenChains) { + this.freeBodyBuilder(chain); + } + } + + private updateLocalTypesWithTypeAlias(locals: Map, typeAliases: Map): void { + for (let local of locals.values()) { + const newType = this.inferUnclearReferenceTypeWithTypeAlias(local.getType(), typeAliases); + if (newType !== null) { + local.setType(newType); + } + } + } + + private inferUnclearReferenceTypeWithTypeAlias(localType: Type, typeAliases: Map): Type | null { + if (localType instanceof ArrayType && localType.getBaseType() instanceof UnclearReferenceType) { + const typeAlias = typeAliases.get((localType.getBaseType() as UnclearReferenceType).getName()); + if (typeAlias !== undefined) { + localType.setBaseType(typeAlias[0]); + return localType; + } + return null; + } + if (localType instanceof UnionType) { + const optionTypes = localType.getTypes(); + for (let i = 0; i < optionTypes.length; i++) { + const newType = this.inferUnclearReferenceTypeWithTypeAlias(optionTypes[i], typeAliases); + if (newType !== null) { + optionTypes[i] = newType; + } + } + return localType; + } + if (localType instanceof UnclearReferenceType) { + const typeAlias = typeAliases.get(localType.getName()); + if (typeAlias !== undefined) { + return typeAlias[0]; + } + } + return null; + } + + private generateNestedMethodChains(outerMethod: ArkMethod): NestedMethodChain { + let candidateMethods: ArkMethod[] = []; + outerMethod + .getDeclaringArkClass() + .getMethods() + .forEach(method => { + if (method.getName().startsWith(NAME_PREFIX) && method.getName().endsWith(`${NAME_DELIMITER}${outerMethod.getName()}`)) { + candidateMethods.push(method); + } + }); + const childrenChains = this.getNestedChildrenChains(outerMethod, candidateMethods); + if (childrenChains.length > 0) { + return { parent: outerMethod, children: childrenChains }; + } + return { parent: outerMethod, children: null }; + } + + private getNestedChildrenChains(parentMethod: ArkMethod, candidateMethods: ArkMethod[]): NestedMethodChain[] { + let nestedMethodChain: NestedMethodChain[] = []; + for (let method of candidateMethods) { + const outerMethodSignature = method.getOuterMethod()?.getSignature(); + if (outerMethodSignature !== undefined && methodSignatureCompare(parentMethod.getSignature(), outerMethodSignature)) { + const childrenChains = this.getNestedChildrenChains(method, candidateMethods); + if (childrenChains.length > 0) { + nestedMethodChain.push({ parent: method, children: childrenChains }); + } else { + nestedMethodChain.push({ parent: method, children: null }); + } + } + } + return nestedMethodChain; + } + + private moveCurrentMethodLocalToGlobal(method: ArkMethod): void { + const globals = method.getBodyBuilder()?.getGlobals(); + const locals = method.getBody()?.getLocals(); + if (locals === undefined || globals === undefined) { + return; + } + globals.forEach((value, key) => { + const local = locals.get(key); + if (local !== undefined) { + value.addUsedStmts(local.getUsedStmts()); + locals.delete(key); + } + }); + + if (globals.size > 0) { + method.getBody()?.setUsedGlobals(globals); + } + } + + private reorganizeGlobalAndLocal(nestedChain: NestedMethodChain): void { + const nestedMethod = nestedChain.parent; + const params = nestedMethod.getSubSignature().getParameters(); + const globals = nestedMethod.getBodyBuilder()?.getGlobals(); + if (params.length > 0 && params[0].getType() instanceof LexicalEnvType && globals !== undefined) { + const closures = (params[0].getType() as LexicalEnvType).getClosures(); + for (let closure of closures) { + globals.delete(closure.getName()); + } + } + + this.moveCurrentMethodLocalToGlobal(nestedMethod); + + const childrenChains = nestedChain.children; + if (childrenChains === null) { + return; + } + for (const chain of childrenChains) { + this.reorganizeGlobalAndLocal(chain); + } + } + + // 对嵌套函数中的UnclearReferenceType类型的变量进行类型推导,类型是否为外层函数中定义的类型别名 + private inferTypesDefineInOuter(outerMethod: ArkMethod, childrenChain: NestedMethodChain): void { + const typeAliases = outerMethod.getBody()?.getAliasTypeMap(); + const nestedLocals = childrenChain.parent.getBody()?.getLocals(); + if (typeAliases !== undefined && nestedLocals !== undefined) { + this.updateLocalTypesWithTypeAlias(nestedLocals, typeAliases); + } + const childrenChains = childrenChain.children; + if (childrenChains === null) { + return; + } + for (const chain of childrenChains) { + this.inferTypesDefineInOuter(childrenChain.parent, chain); + } + } + + private updateNestedMethodUsedInOuter(nestedChain: NestedMethodChain): void { + const nestedMethod = nestedChain.parent; + const outerMethod = nestedMethod.getOuterMethod(); + if (outerMethod === undefined) { + return; + } + const outerLocals = outerMethod.getBody()?.getLocals(); + if (outerLocals !== undefined) { + for (let local of outerLocals.values()) { + if ( + local.getType() instanceof LexicalEnvType && + methodSignatureCompare((local.getType() as LexicalEnvType).getNestedMethod(), nestedMethod.getSignature()) + ) { + this.updateOuterMethodWithClosures(outerMethod, nestedMethod, local); + break; + } + } + } + + const nestedMethodName = nestedMethod.getName(); + const originalMethodName = this.getOriginalNestedMethodName(nestedMethodName) ?? ''; + const outerGlobals = outerMethod.getBody()?.getUsedGlobals(); + const callGlobal = outerGlobals?.get(nestedMethodName) ?? outerGlobals?.get(originalMethodName); + if (callGlobal !== undefined && callGlobal instanceof GlobalRef && callGlobal.getRef() === null) { + const fieldSignature = new FieldSignature( + nestedMethodName, + nestedMethod.getDeclaringArkClass().getSignature(), + new FunctionType(nestedMethod.getSignature()) + ); + callGlobal.setRef(new ArkStaticFieldRef(fieldSignature)); + } + + const childrenChains = nestedChain.children; + if (childrenChains === null) { + return; + } + for (const chain of childrenChains) { + this.updateNestedMethodUsedInOuter(chain); + } + } + + private updateNestedMethodWithClosures(nestedMethod: ArkMethod, closuresLocal: Local): void { + if (!(closuresLocal.getType() instanceof LexicalEnvType)) { + return; + } + + const declareSignatures = nestedMethod.getDeclareSignatures(); + declareSignatures?.forEach((signature, index) => { + nestedMethod.setDeclareSignatureWithIndex(this.createNewSignatureWithClosures(closuresLocal, signature), index); + }); + + const implementSignature = nestedMethod.getImplementationSignature(); + if (implementSignature !== null) { + nestedMethod.setImplementationSignature(this.createNewSignatureWithClosures(closuresLocal, implementSignature)); + } + + this.addClosureParamsAssignStmts(closuresLocal, nestedMethod); + } + + private updateOuterMethodWithClosures(outerMethod: ArkMethod, nestedMethod: ArkMethod, closuresLocal: Local): void { + const nestedMethodName = nestedMethod.getName(); + const nestedMethodLocal = outerMethod.getBody()?.getLocals().get(nestedMethodName); + if (nestedMethodLocal !== undefined) { + this.updateLocalInfoWithClosures(nestedMethodLocal, outerMethod, nestedMethod, closuresLocal); + } else { + const nestedMethodGlobal = outerMethod.getBody()?.getUsedGlobals()?.get(nestedMethodName); + if (nestedMethodGlobal !== undefined && nestedMethodGlobal instanceof GlobalRef) { + this.updateGlobalInfoWithClosures(nestedMethodGlobal, outerMethod, nestedMethod, closuresLocal); + } + } + + const originalMethodName = this.getOriginalNestedMethodName(nestedMethodName); + if (originalMethodName === null) { + return; + } + const originalMethodLocal = outerMethod.getBody()?.getLocals().get(originalMethodName); + if (originalMethodLocal !== undefined) { + this.updateLocalInfoWithClosures(originalMethodLocal, outerMethod, nestedMethod, closuresLocal); + } else { + const originalMethodGlobal = outerMethod.getBody()?.getUsedGlobals()?.get(originalMethodName); + if (originalMethodGlobal !== undefined && originalMethodGlobal instanceof GlobalRef) { + this.updateGlobalInfoWithClosures(originalMethodGlobal, outerMethod, nestedMethod, closuresLocal); + } + } + } + + private getOriginalNestedMethodName(nestedMethodName: string): string | null { + if (nestedMethodName.startsWith(NAME_PREFIX) && nestedMethodName.includes(NAME_DELIMITER)) { + const nameComponents = nestedMethodName.slice(1).split(NAME_DELIMITER); + if (nameComponents.length > 1) { + return nameComponents[0]; + } + } + return null; + } + + private updateGlobalInfoWithClosures(globalRef: GlobalRef, outerMethod: ArkMethod, nestedMethod: ArkMethod, closuresLocal: Local): void { + if (globalRef.getRef() !== null) { + return; + } + const methodSignature = nestedMethod.getImplementationSignature(); + if (methodSignature === null) { + return; + } + const lexicalEnv = closuresLocal.getType(); + if (!(lexicalEnv instanceof LexicalEnvType)) { + return; + } + const fieldSignature = new FieldSignature( + methodSignature.getMethodSubSignature().getMethodName(), + methodSignature.getDeclaringClassSignature(), + new ClosureType(lexicalEnv, methodSignature) + ); + globalRef.setRef(new ArkStaticFieldRef(fieldSignature)); + this.updateAbstractInvokeExprWithClosures(globalRef, outerMethod.getSignature(), nestedMethod.getSignature(), closuresLocal); + } + + private updateLocalInfoWithClosures(local: Local, outerMethod: ArkMethod, nestedMethod: ArkMethod, closuresLocal: Local): void { + const localType = local.getType(); + if (!(localType instanceof FunctionType)) { + return; + } + + const lexicalEnv = closuresLocal.getType(); + if (!(lexicalEnv instanceof LexicalEnvType)) { + return; + } + + // 更新local的类型为ClosureType,methodSignature为内层嵌套函数 + const nestedMethodSignature = nestedMethod.getImplementationSignature(); + if (nestedMethodSignature !== null) { + local.setType(new ClosureType(lexicalEnv, nestedMethodSignature, localType.getRealGenericTypes())); + } else { + local.setType(new ClosureType(lexicalEnv, localType.getMethodSignature(), localType.getRealGenericTypes())); + } + + this.updateAbstractInvokeExprWithClosures(local, outerMethod.getSignature(), nestedMethod.getSignature(), closuresLocal); + } + + // 更新所有stmt中调用内层函数处的AbstractInvokeExpr中的函数签名和实参args,加入闭包参数 + // 更新所有stmt中定义的函数指针的usedStmt中的函数签名和实参args,加入闭包参数 + private updateAbstractInvokeExprWithClosures( + value: Local | GlobalRef, + outerMethodSignature: MethodSignature, + nestedMethodSignature: MethodSignature, + closuresLocal: Local + ): void { + for (const usedStmt of value.getUsedStmts()) { + if (usedStmt instanceof ArkInvokeStmt) { + this.updateSignatureAndArgsInArkInvokeExpr(usedStmt, nestedMethodSignature, closuresLocal); + } else if (usedStmt instanceof ArkAssignStmt) { + const rightOp = usedStmt.getRightOp(); + if (rightOp instanceof AbstractInvokeExpr) { + this.updateSignatureAndArgsInArkInvokeExpr(usedStmt, nestedMethodSignature, closuresLocal); + } + const leftOp = usedStmt.getLeftOp(); + if (leftOp instanceof Local) { + leftOp.setType(rightOp.getType()); + } + } else if (usedStmt instanceof ArkReturnStmt) { + outerMethodSignature.getMethodSubSignature().setReturnType(value.getType()); + } + const defValue = usedStmt.getDef(); + if (defValue === null) { + continue; + } + if ((defValue instanceof Local || defValue instanceof GlobalRef) && defValue.getType() instanceof FunctionType) { + this.updateAbstractInvokeExprWithClosures(defValue, outerMethodSignature, nestedMethodSignature, closuresLocal); + } + } + } + + private createNewSignatureWithClosures(closuresLocal: Local, oldSignature: MethodSignature): MethodSignature { + let oldSubSignature = oldSignature.getMethodSubSignature(); + const params = oldSubSignature.getParameters(); + const closuresParam = new MethodParameter(); + closuresParam.setName(closuresLocal.getName()); + closuresParam.setType(closuresLocal.getType()); + params.unshift(closuresParam); + let newSubSignature = new MethodSubSignature(oldSubSignature.getMethodName(), params, oldSubSignature.getReturnType(), oldSubSignature.isStatic()); + return new MethodSignature(oldSignature.getDeclaringClassSignature(), newSubSignature); + } + + private updateSignatureAndArgsInArkInvokeExpr(stmt: ArkInvokeStmt | ArkAssignStmt, methodSignature: MethodSignature, closuresLocal: Local): void { + let expr: AbstractInvokeExpr; + if (stmt instanceof ArkInvokeStmt) { + expr = stmt.getInvokeExpr(); + } else { + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof AbstractInvokeExpr)) { + return; + } + expr = rightOp; + } + const exprMethodName = expr.getMethodSignature().getMethodSubSignature().getMethodName(); + const nestedMethodName = methodSignature.getMethodSubSignature().getMethodName(); + if (exprMethodName === nestedMethodName) { + expr.setMethodSignature(this.createNewSignatureWithClosures(closuresLocal, methodSignature)); + expr.getArgs().unshift(closuresLocal); + closuresLocal.addUsedStmt(stmt); + return; + } + + const originalMethodName = this.getOriginalNestedMethodName(nestedMethodName); + if (originalMethodName !== null) { + if (exprMethodName === originalMethodName || expr instanceof ArkPtrInvokeExpr) { + expr.setMethodSignature(methodSignature); + expr.getArgs().unshift(closuresLocal); + closuresLocal.addUsedStmt(stmt); + } + } + } + + private addClosureParamsAssignStmts(closuresParam: Local, method: ArkMethod): void { + const lexicalEnv = closuresParam.getType(); + if (!(lexicalEnv instanceof LexicalEnvType)) { + return; + } + const closures = lexicalEnv.getClosures(); + if (closures.length === 0) { + return; + } + const oldParamRefs = method.getParameterRefs(); + let body = method.getBody(); + if (body === undefined) { + return; + } + let stmts = Array.from(body.getCfg().getBlocks())[0].getStmts(); + let index = 0; + const parameterRef = new ArkParameterRef(index, lexicalEnv); + const closuresLocal = new Local(closuresParam.getName(), lexicalEnv); + body.addLocal(closuresLocal.getName(), closuresLocal); + let assignStmt = new ArkAssignStmt(closuresLocal, parameterRef); + stmts.splice(index, 0, assignStmt); + closuresLocal.setDeclaringStmt(assignStmt); + + oldParamRefs?.forEach(paramRef => { + index++; + paramRef.setIndex(index); + }); + + for (let closure of closures) { + let local = body.getLocals().get(closure.getName()); + if (local === undefined) { + local = new Local(closure.getName(), closure.getType()); + body.addLocal(local.getName(), local); + } else { + local.setType(closure.getType()); + } + index++; + const closureFieldRef = new ClosureFieldRef(closuresParam, closure.getName(), closure.getType()); + let assignStmt = new ArkAssignStmt(local, closureFieldRef); + stmts.splice(index, 0, assignStmt); + local.setDeclaringStmt(assignStmt); + closuresLocal.addUsedStmt(assignStmt); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/core/model/builder/builderUtils.ts b/ets2panda/linter/arkanalyzer/src/core/model/builder/builderUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e5c218116d6583bbdbc6250544992cce55f5b01 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/core/model/builder/builderUtils.ts @@ -0,0 +1,590 @@ +/* + * 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. + */ + +import ts, { HeritageClause, ParameterDeclaration, TypeNode, TypeParameterDeclaration } from 'ohos-typescript'; +import { + AliasType, + ArrayType, + ClassType, + FunctionType, + GenericType, + IntersectionType, + TupleType, + Type, + UnclearReferenceType, + UnionType, + UnknownType, +} from '../../base/Type'; +import { TypeInference } from '../../common/TypeInference'; +import { ArkField } from '../ArkField'; +import Logger, { LOG_MODULE_TYPE } from '../../../utils/logger'; +import { ArkClass } from '../ArkClass'; +import { ArkMethod } from '../ArkMethod'; +import { Decorator } from '../../base/Decorator'; +import { ArrayBindingPatternParameter, buildArkMethodFromArkClass, MethodParameter, ObjectBindingPatternParameter } from './ArkMethodBuilder'; +import { buildNormalArkClassFromArkMethod } from './ArkClassBuilder'; +import { Builtin } from '../../common/Builtin'; +import { modifierKind2Enum } from '../ArkBaseModel'; +import { ArkValueTransformer } from '../../common/ArkValueTransformer'; +import { KeyofTypeExpr, TypeQueryExpr } from '../../base/TypeExpr'; +import { + ANY_KEYWORD, + BIGINT_KEYWORD, + BOOLEAN_KEYWORD, + NEVER_KEYWORD, + NULL_KEYWORD, + NUMBER_KEYWORD, + STRING_KEYWORD, + THIS_NAME, + UNDEFINED_KEYWORD, + VOID_KEYWORD, +} from '../../common/TSConst'; +import { ArkSignatureBuilder } from './ArkSignatureBuilder'; +import { ArkInstanceFieldRef } from '../../base/Ref'; +import { Local } from '../../base/Local'; +import { Value } from '../../base/Value'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'builderUtils'); + +export function handleQualifiedName(node: ts.QualifiedName): string { + let right = (node.right as ts.Identifier).text; + let left: string = ''; + if (node.left.kind === ts.SyntaxKind.Identifier) { + left = (node.left as ts.Identifier).text; + } else if (node.left.kind === ts.SyntaxKind.QualifiedName) { + left = handleQualifiedName(node.left as ts.QualifiedName); + } + let qualifiedName = left + '.' + right; + return qualifiedName; +} + +export function handlePropertyAccessExpression(node: ts.PropertyAccessExpression): string { + let right = (node.name as ts.Identifier).text; + let left: string = ''; + if (ts.SyntaxKind[node.expression.kind] === 'Identifier') { + left = (node.expression as ts.Identifier).text; + } else if (ts.isStringLiteral(node.expression)) { + left = node.expression.text; + } else if (ts.isPropertyAccessExpression(node.expression)) { + left = handlePropertyAccessExpression(node.expression as ts.PropertyAccessExpression); + } + let propertyAccessExpressionName = left + '.' + right; + return propertyAccessExpressionName; +} + +export function buildDecorators(node: ts.Node, sourceFile: ts.SourceFile): Set { + let decorators: Set = new Set(); + ts.getAllDecorators(node).forEach(decoratorNode => { + let decorator = parseDecorator(decoratorNode); + if (decorator) { + decorator.setContent(decoratorNode.expression.getText(sourceFile)); + decorators.add(decorator); + } + }); + return decorators; +} + +function parseDecorator(node: ts.Decorator): Decorator | undefined { + if (!node.expression) { + return undefined; + } + + let expression = node.expression; + if (ts.isIdentifier(expression)) { + return new Decorator(expression.text); + } + if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression)) { + return undefined; + } + + let decorator = new Decorator(expression.expression.text); + + if (expression.arguments.length > 0) { + const arg = expression.arguments[0]; + if (ts.isArrowFunction(arg) && ts.isIdentifier(arg.body)) { + decorator.setParam(arg.body.text); + } + } + + return decorator; +} + +export function buildModifiers(node: ts.Node): number { + let modifiers: number = 0; + + if (ts.canHaveModifiers(node)) { + ts.getModifiers(node)?.forEach(modifier => { + modifiers |= modifierKind2Enum(modifier.kind); + }); + } + + return modifiers; +} + +export function buildHeritageClauses(heritageClauses?: ts.NodeArray): Map { + let heritageClausesMap: Map = new Map(); + heritageClauses?.forEach(heritageClause => { + heritageClause.types.forEach(type => { + let heritageClauseName: string = ''; + if (type.typeArguments) { + heritageClauseName = type.getText(); + } else if (ts.isIdentifier(type.expression)) { + heritageClauseName = (type.expression as ts.Identifier).text; + } else if (ts.isPropertyAccessExpression(type.expression)) { + heritageClauseName = handlePropertyAccessExpression(type.expression); + } else { + heritageClauseName = type.getText(); + } + heritageClausesMap.set(heritageClauseName, ts.SyntaxKind[heritageClause.token]); + }); + }); + return heritageClausesMap; +} + +export function buildTypeParameters( + typeParameters: ts.NodeArray, + sourceFile: ts.SourceFile, + arkInstance: ArkMethod | ArkClass +): GenericType[] { + const genericTypes: GenericType[] = []; + let index = 0; + if (arkInstance instanceof ArkMethod) { + const len = arkInstance.getDeclaringArkClass().getGenericsTypes()?.length; + if (len) { + index = len; + } + } + typeParameters.forEach(typeParameter => { + const genericType = tsNode2Type(typeParameter, sourceFile, arkInstance); + if (genericType instanceof GenericType) { + genericType.setIndex(index++); + genericTypes.push(genericType); + } + + if (typeParameter.modifiers) { + logger.warn('This typeparameter has modifiers.'); + } + + if (typeParameter.expression) { + logger.warn('This typeparameter has expression.'); + } + }); + return genericTypes; +} + +function buildObjectBindingPatternParam(methodParameter: MethodParameter, paramNameNode: ts.ObjectBindingPattern): void { + methodParameter.setName('ObjectBindingPattern'); + let elements: ObjectBindingPatternParameter[] = []; + paramNameNode.elements.forEach(element => { + let paraElement = new ObjectBindingPatternParameter(); + if (element.propertyName) { + if (ts.isIdentifier(element.propertyName)) { + paraElement.setPropertyName(element.propertyName.text); + } else { + logger.warn('New propertyName of ObjectBindingPattern found, please contact developers to support this!'); + } + } + + if (element.name) { + if (ts.isIdentifier(element.name)) { + paraElement.setName(element.name.text); + } else { + logger.warn('New name of ObjectBindingPattern found, please contact developers to support this!'); + } + } + + if (element.initializer) { + logger.warn('TODO: support ObjectBindingPattern initializer.'); + } + + if (element.dotDotDotToken) { + paraElement.setOptional(true); + } + elements.push(paraElement); + }); + methodParameter.setObjElements(elements); +} + +function buildBindingElementOfBindingPatternParam(element: ts.BindingElement, paraElement: ArrayBindingPatternParameter): void { + if (element.propertyName) { + if (ts.isIdentifier(element.propertyName)) { + paraElement.setPropertyName(element.propertyName.text); + } else { + logger.warn('New propertyName of ArrayBindingPattern found, please contact developers to support this!'); + } + } + + if (element.name) { + if (ts.isIdentifier(element.name)) { + paraElement.setName(element.name.text); + } else { + logger.warn('New name of ArrayBindingPattern found, please contact developers to support this!'); + } + } + + if (element.initializer) { + logger.warn('TODO: support ArrayBindingPattern initializer.'); + } + + if (element.dotDotDotToken) { + paraElement.setOptional(true); + } +} + +function buildArrayBindingPatternParam(methodParameter: MethodParameter, paramNameNode: ts.ArrayBindingPattern): void { + methodParameter.setName('ArrayBindingPattern'); + let elements: ArrayBindingPatternParameter[] = []; + paramNameNode.elements.forEach(element => { + let paraElement = new ArrayBindingPatternParameter(); + if (ts.isBindingElement(element)) { + buildBindingElementOfBindingPatternParam(element, paraElement); + } else if (ts.isOmittedExpression(element)) { + logger.warn('TODO: support OmittedExpression for ArrayBindingPattern parameter name.'); + } + elements.push(paraElement); + }); + methodParameter.setArrayElements(elements); +} + +export function buildParameters(params: ts.NodeArray, arkInstance: ArkMethod | ArkField, sourceFile: ts.SourceFile): MethodParameter[] { + let parameters: MethodParameter[] = []; + params.forEach(parameter => { + let methodParameter = new MethodParameter(); + + // name + if (ts.isIdentifier(parameter.name)) { + methodParameter.setName(parameter.name.text); + } else if (ts.isObjectBindingPattern(parameter.name)) { + buildObjectBindingPatternParam(methodParameter, parameter.name); + } else if (ts.isArrayBindingPattern(parameter.name)) { + buildArrayBindingPatternParam(methodParameter, parameter.name); + } else { + logger.warn('Parameter name is not identifier, ObjectBindingPattern nor ArrayBindingPattern, please contact developers to support this!'); + } + + // questionToken + if (parameter.questionToken) { + methodParameter.setOptional(true); + } + + // type + if (parameter.type) { + methodParameter.setType(buildGenericType(tsNode2Type(parameter.type, sourceFile, arkInstance), arkInstance)); + } else { + methodParameter.setType(UnknownType.getInstance()); + } + + // initializer + if (parameter.initializer) { + //TODO? + } + + // dotDotDotToken + if (parameter.dotDotDotToken) { + methodParameter.setDotDotDotToken(true); + } + + // modifiers + if (parameter.modifiers) { + // + } + + parameters.push(methodParameter); + }); + return parameters; +} + +export function buildGenericType(type: Type, arkInstance: ArkMethod | ArkField | AliasType): Type { + function replace(urType: UnclearReferenceType): Type { + const typeName = urType.getName(); + let gType; + if (arkInstance instanceof AliasType) { + gType = arkInstance.getGenericTypes()?.find(f => f.getName() === typeName); + } else { + if (arkInstance instanceof ArkMethod) { + gType = arkInstance.getGenericTypes()?.find(f => f.getName() === typeName); + } + if (!gType) { + gType = arkInstance + .getDeclaringArkClass() + .getGenericsTypes() + ?.find(f => f.getName() === typeName); + } + } + if (gType) { + return gType; + } + const types = urType.getGenericTypes(); + for (let i = 0; i < types.length; i++) { + const mayType = types[i]; + if (mayType instanceof UnclearReferenceType) { + types[i] = replace(mayType); + } + } + return urType; + } + + if (type instanceof UnclearReferenceType) { + return replace(type); + } else if (type instanceof ClassType && arkInstance instanceof AliasType) { + type.setRealGenericTypes(arkInstance.getGenericTypes()); + } else if (type instanceof UnionType || type instanceof TupleType) { + const types = type.getTypes(); + for (let i = 0; i < types.length; i++) { + const mayType = types[i]; + if (mayType instanceof UnclearReferenceType) { + types[i] = replace(mayType); + } + } + } else if (type instanceof ArrayType) { + const baseType = type.getBaseType(); + if (baseType instanceof UnclearReferenceType) { + type.setBaseType(replace(baseType)); + } + } else if (type instanceof FunctionType) { + const returnType = type.getMethodSignature().getType(); + if (returnType instanceof UnclearReferenceType) { + type.getMethodSignature().getMethodSubSignature().setReturnType(replace(returnType)); + } + } + return type; +} + +export function buildReturnType(node: TypeNode, sourceFile: ts.SourceFile, method: ArkMethod): Type { + if (node) { + return tsNode2Type(node, sourceFile, method); + } else { + return UnknownType.getInstance(); + } +} + +export function tsNode2Type( + typeNode: ts.TypeNode | ts.TypeParameterDeclaration, + sourceFile: ts.SourceFile, + arkInstance: ArkMethod | ArkClass | ArkField +): Type { + if (ts.isTypeReferenceNode(typeNode)) { + const genericTypes: Type[] = []; + if (typeNode.typeArguments) { + for (const typeArgument of typeNode.typeArguments) { + genericTypes.push(tsNode2Type(typeArgument, sourceFile, arkInstance)); + } + } + let referenceNodeName = typeNode.typeName; + if (ts.isQualifiedName(referenceNodeName)) { + let parameterTypeStr = handleQualifiedName(referenceNodeName as ts.QualifiedName); + return new UnclearReferenceType(parameterTypeStr, genericTypes); + } else { + let parameterTypeStr = referenceNodeName.text; + if (parameterTypeStr === Builtin.OBJECT) { + return Builtin.OBJECT_CLASS_TYPE; + } + return new UnclearReferenceType(parameterTypeStr, genericTypes); + } + } else if (ts.isUnionTypeNode(typeNode) || ts.isIntersectionTypeNode(typeNode)) { + let multipleTypePara: Type[] = []; + typeNode.types.forEach(tmpType => { + multipleTypePara.push(tsNode2Type(tmpType, sourceFile, arkInstance)); + }); + if (ts.isUnionTypeNode(typeNode)) { + return new UnionType(multipleTypePara); + } else { + return new IntersectionType(multipleTypePara); + } + } else if (ts.isLiteralTypeNode(typeNode)) { + return ArkValueTransformer.resolveLiteralTypeNode(typeNode, sourceFile); + } else if (ts.isTypeLiteralNode(typeNode)) { + let cls: ArkClass = new ArkClass(); + let declaringClass: ArkClass; + + if (arkInstance instanceof ArkMethod) { + declaringClass = arkInstance.getDeclaringArkClass(); + } else if (arkInstance instanceof ArkField) { + declaringClass = arkInstance.getDeclaringArkClass(); + } else { + declaringClass = arkInstance; + } + if (declaringClass.getDeclaringArkNamespace()) { + cls.setDeclaringArkNamespace(declaringClass.getDeclaringArkNamespace()); + cls.setDeclaringArkFile(declaringClass.getDeclaringArkFile()); + } else { + cls.setDeclaringArkFile(declaringClass.getDeclaringArkFile()); + } + buildNormalArkClassFromArkMethod(typeNode, cls, sourceFile); + + return new ClassType(cls.getSignature()); + } else if (ts.isFunctionTypeNode(typeNode)) { + let mtd: ArkMethod = new ArkMethod(); + let cls: ArkClass; + if (arkInstance instanceof ArkMethod) { + cls = arkInstance.getDeclaringArkClass(); + } else if (arkInstance instanceof ArkClass) { + cls = arkInstance; + } else { + cls = arkInstance.getDeclaringArkClass(); + } + buildArkMethodFromArkClass(typeNode, cls, mtd, sourceFile); + return new FunctionType(mtd.getSignature()); + } else if (ts.isTypeParameterDeclaration(typeNode)) { + const name = typeNode.name.text; + let defaultType; + if (typeNode.default) { + defaultType = tsNode2Type(typeNode.default, sourceFile, arkInstance); + } + let constraint; + if (typeNode.constraint) { + constraint = tsNode2Type(typeNode.constraint, sourceFile, arkInstance); + } + return new GenericType(name, defaultType, constraint); + } else if (ts.isTupleTypeNode(typeNode)) { + const types: Type[] = []; + typeNode.elements.forEach(element => { + types.push(tsNode2Type(element, sourceFile, arkInstance)); + }); + return new TupleType(types); + } else if (ts.isArrayTypeNode(typeNode)) { + return new ArrayType(tsNode2Type((typeNode as ts.ArrayTypeNode).elementType, sourceFile, arkInstance), 1); + } else if (ts.isParenthesizedTypeNode(typeNode)) { + return tsNode2Type(typeNode.type, sourceFile, arkInstance); + } else if (ts.isTypeOperatorNode(typeNode)) { + return buildTypeFromTypeOperator(typeNode as ts.TypeOperatorNode, sourceFile, arkInstance); + } else if (ts.isTypeQueryNode(typeNode)) { + return buildTypeFromTypeQuery(typeNode as ts.TypeQueryNode, sourceFile, arkInstance); + } else if (typeNode.kind === ts.SyntaxKind.ObjectKeyword) { + // TODO: type object which is different from Object is needed to support, such as let a: object = {} + return new UnclearReferenceType('object'); + } else { + return buildTypeFromPreStr(ts.SyntaxKind[typeNode.kind]); + } +} + +export function buildTypeFromPreStr(preStr: string): Type { + let postStr = ''; + switch (preStr) { + case 'BooleanKeyword': + postStr = BOOLEAN_KEYWORD; + break; + case 'FalseKeyword': + postStr = BOOLEAN_KEYWORD; + break; + case 'TrueKeyword': + postStr = BOOLEAN_KEYWORD; + break; + case 'NumberKeyword': + postStr = NUMBER_KEYWORD; + break; + case 'NumericLiteral': + postStr = NUMBER_KEYWORD; + break; + case 'FirstLiteralToken': + postStr = NUMBER_KEYWORD; + break; + case 'StringKeyword': + postStr = STRING_KEYWORD; + break; + case 'StringLiteral': + postStr = STRING_KEYWORD; + break; + case 'UndefinedKeyword': + postStr = UNDEFINED_KEYWORD; + break; + case 'NullKeyword': + postStr = NULL_KEYWORD; + break; + case 'AnyKeyword': + postStr = ANY_KEYWORD; + break; + case 'VoidKeyword': + postStr = VOID_KEYWORD; + break; + case 'NeverKeyword': + postStr = NEVER_KEYWORD; + break; + case 'BigIntKeyword': + postStr = BIGINT_KEYWORD; + break; + default: + postStr = preStr; + } + return TypeInference.buildTypeFromStr(postStr); +} + +function buildTypeFromTypeOperator(typeOperatorNode: ts.TypeOperatorNode, sourceFile: ts.SourceFile, arkInstance: ArkMethod | ArkClass | ArkField): Type { + const typeNode = typeOperatorNode.type; + let type = tsNode2Type(typeNode, sourceFile, arkInstance); + + switch (typeOperatorNode.operator) { + case ts.SyntaxKind.ReadonlyKeyword: { + if (type instanceof ArrayType || type instanceof TupleType) { + type.setReadonlyFlag(true); + } + return type; + } + case ts.SyntaxKind.KeyOfKeyword: + return new KeyofTypeExpr(type); + case ts.SyntaxKind.UniqueKeyword: + return UnknownType.getInstance(); + default: + return UnknownType.getInstance(); + } +} + +function buildTypeFromTypeQuery(typeQueryNode: ts.TypeQueryNode, sourceFile: ts.SourceFile, arkInstance: ArkMethod | ArkClass | ArkField): Type { + const exprNameNode = typeQueryNode.exprName; + let opValue: Value; + if (ts.isQualifiedName(exprNameNode)) { + if (exprNameNode.left.getText(sourceFile) === THIS_NAME) { + const fieldName = exprNameNode.right.getText(sourceFile); + if (arkInstance instanceof ArkMethod) { + const fieldSignature = + arkInstance.getDeclaringArkClass().getFieldWithName(fieldName)?.getSignature() ?? + ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName); + const baseLocal = + arkInstance.getBody()?.getLocals().get(THIS_NAME) ?? + new Local( + THIS_NAME, + new ClassType(arkInstance.getDeclaringArkClass().getSignature(), arkInstance.getDeclaringArkClass().getGenericsTypes()) + ); + opValue = new ArkInstanceFieldRef(baseLocal, fieldSignature); + } else if (arkInstance instanceof ArkClass) { + const fieldSignature = + arkInstance.getFieldWithName(fieldName)?.getSignature() ?? ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName); + const baseLocal = new Local(THIS_NAME, new ClassType(arkInstance.getSignature(), arkInstance.getGenericsTypes())); + opValue = new ArkInstanceFieldRef(baseLocal, fieldSignature); + } else { + const fieldSignature = arkInstance.getSignature(); + const baseLocal = new Local( + THIS_NAME, + new ClassType(arkInstance.getDeclaringArkClass().getSignature(), arkInstance.getDeclaringArkClass().getGenericsTypes()) + ); + opValue = new ArkInstanceFieldRef(baseLocal, fieldSignature); + } + } else { + const exprName = exprNameNode.getText(sourceFile); + opValue = new Local(exprName, UnknownType.getInstance()); + } + } else { + const exprName = exprNameNode.escapedText.toString(); + opValue = new Local(exprName, UnknownType.getInstance()); + } + + let expr = new TypeQueryExpr(opValue); + if (typeQueryNode.typeArguments) { + for (const typeArgument of typeQueryNode.typeArguments) { + expr.addGenericType(tsNode2Type(typeArgument, sourceFile, arkInstance)); + } + } + return expr; +} diff --git a/ets2panda/linter/arkanalyzer/src/index.ts b/ets2panda/linter/arkanalyzer/src/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..cb13b2d8122c94855817b096f06b53a8d54f3632 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/index.ts @@ -0,0 +1,126 @@ +/* + * 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. + */ + +// callgraph/algorithm +export { AbstractAnalysis } from './callgraph/algorithm/AbstractAnalysis'; +export { ClassHierarchyAnalysis } from './callgraph/algorithm/ClassHierarchyAnalysis'; +export { RapidTypeAnalysis } from './callgraph/algorithm/RapidTypeAnalysis'; + +// callgraph/common +export { PTAStat, PAGStat, CGStat } from './callgraph/common/Statistics'; + +// callgraph/model +export * from './callgraph/model/CallGraph'; +export { CallGraphBuilder } from './callgraph/model/builder/CallGraphBuilder'; + +// callgraph/pointerAnalysis +export { KLimitedContextSensitive } from './callgraph/pointerAnalysis/Context'; +export { DummyCallCreator } from './callgraph/pointerAnalysis/DummyCallCreator'; +export * from './callgraph/pointerAnalysis/Pag'; +export { CSFuncID, PagBuilder } from './callgraph/pointerAnalysis/PagBuilder'; +export { PointerAnalysis } from './callgraph/pointerAnalysis/PointerAnalysis'; +export { PointerAnalysisConfig } from './callgraph/pointerAnalysis/PointerAnalysisConfig'; +export { PtsSet, DiffPTData } from './callgraph/pointerAnalysis/PtsDS'; + +export { DVFG } from './VFG/DVFG'; +export { DVFGBuilder } from './VFG/builder/DVFGBuilder'; + +// core/base +export { Constant } from './core/base/Constant'; +export { Decorator } from './core/base/Decorator'; +export { DefUseChain } from './core/base/DefUseChain'; +export * from './core/base/Expr'; +export { Local } from './core/base/Local'; +export { LineColPosition, FullPosition } from './core/base/Position'; +export * from './core/base/Ref'; +export * from './core/base/Stmt'; +export * from './core/base/Type'; +export { Value } from './core/base/Value'; + +// core/common +export { ModelUtils } from './core/common/ModelUtils'; +export * from './core/common/Const'; +export { DummyMainCreater } from './core/common/DummyMainCreater'; +export * from './core/common/EtsConst'; +export { ExprUseReplacer } from './core/common/ExprUseReplacer'; +export { IRUtils } from './core/common/IRUtils'; +export { RefUseReplacer } from './core/common/RefUseReplacer'; +export { StmtUseReplacer } from './core/common/StmtUseReplacer'; +export * from './core/common/TSConst'; +export { TypeInference } from './core/common/TypeInference'; +export { ValueUtil } from './core/common/ValueUtil'; +export { VisibleValue, Scope } from './core/common/VisibleValue'; + +// core/dataflow +export { DataflowProblem, FlowFunction } from './core/dataflow/DataflowProblem'; +export { DataflowResult } from './core/dataflow/DataflowResult'; +export { DataflowSolver } from './core/dataflow/DataflowSolver'; +export { PathEdgePoint, PathEdge } from './core/dataflow/Edge'; +export { Fact } from './core/dataflow/Fact'; +export { UndefinedVariableChecker, UndefinedVariableSolver } from './core/dataflow/UndefinedVariable'; + +// core/graph +export { BasicBlock } from './core/graph/BasicBlock'; +export { Cfg } from './core/graph/Cfg'; +export { ViewTree, ViewTreeNode } from './core/graph/ViewTree'; +export { DominanceFinder } from './core/graph/DominanceFinder'; +export { DominanceTree } from './core/graph/DominanceTree'; +export { NodeID, Kind, BaseEdge, BaseNode, BaseExplicitGraph } from './core/graph/BaseExplicitGraph'; +export { SCCDetection } from './core/graph/Scc'; + +// core/model +export { ArkFile } from './core/model/ArkFile'; +export { ArkNamespace } from './core/model/ArkNamespace'; +export { ArkClass } from './core/model/ArkClass'; +export { ArkMethod } from './core/model/ArkMethod'; +export { ArkField } from './core/model/ArkField'; +export { ExportInfo } from './core/model/ArkExport'; +export { ImportInfo } from './core/model/ArkImport'; +export { ArkBody } from './core/model/ArkBody'; +export * from './core/model/ArkSignature'; +export * from './core/model/builder/ArkSignatureBuilder'; + +export { SceneConfig } from './Config'; +export { Scene } from './Scene'; + +// save +export { Printer } from './save/Printer'; +export { PrinterBuilder } from './save/PrinterBuilder'; +export { DotMethodPrinter, DotClassPrinter, DotNamespacePrinter, DotFilePrinter } from './save/DotPrinter'; +export { SourceMethod as SourceMethodPrinter } from './save/source/SourceMethod'; +export { SourceClass as SourceClassPrinter } from './save/source/SourceClass'; +export { SourceNamespace as SourceNamespacePrinter } from './save/source/SourceNamespace'; +export { SourceFilePrinter } from './save/source/SourceFilePrinter'; +export { JsonPrinter } from './save/JsonPrinter'; +export { GraphPrinter } from './save/GraphPrinter'; +export { ViewTreePrinter } from './save/ViewTreePrinter'; + +// transformer +export * from './transformer/StaticSingleAssignmentFormer'; + +// utils +export * from './utils/callGraphUtils'; +export * from './utils/entryMethodUtils'; +export * from './utils/FileUtils'; +export * from './utils/getAllFiles'; +export * from './utils/json5parser'; +export * from './utils/pathTransfer'; +export * from './utils/AstTreeUtils'; +export { LOG_LEVEL, LOG_MODULE_TYPE } from './utils/logger'; +export { default as Logger } from './utils/logger'; + +//ohos-typescript +import ts from 'ohos-typescript'; +export { ts }; diff --git a/ets2panda/linter/arkanalyzer/src/save/ArkStream.ts b/ets2panda/linter/arkanalyzer/src/save/ArkStream.ts new file mode 100644 index 0000000000000000000000000000000000000000..a3db074cec3ebb2557c81cd009e5202aad60d1eb --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/ArkStream.ts @@ -0,0 +1,97 @@ +/* + * 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. + */ + +import fs from 'fs'; + +export class ArkCodeBuffer { + output: string[] = []; + indent: string = ''; + + constructor(indent: string = '') { + this.indent = indent; + } + + public write(s: string): this { + this.output.push(s); + return this; + } + + public writeLine(s: string): this { + this.write(s); + this.write('\n'); + return this; + } + + public writeSpace(s: string): this { + if (s.length === 0) { + return this; + } + this.write(s); + this.write(' '); + return this; + } + + public writeStringLiteral(s: string): this { + this.write(`'${s}'`); + return this; + } + + public writeIndent(): this { + this.write(this.indent); + return this; + } + + public incIndent(): this { + this.indent += ' '; + return this; + } + + public decIndent(): this { + if (this.indent.length >= 2) { + this.indent = this.indent.substring(0, this.indent.length - 2); + } + return this; + } + + public getIndent(): string { + return this.indent; + } + + public toString(): string { + return this.output.join(''); + } + + public clear(): void { + this.output = []; + } +} + +export class ArkStream extends ArkCodeBuffer { + streamOut: fs.WriteStream; + + constructor(streamOut: fs.WriteStream) { + super(''); + this.streamOut = streamOut; + } + + public write(s: string): this { + this.streamOut.write(s); + return this; + } + + public close(): void { + this.streamOut.close(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/DotPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/DotPrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..e4f218352f779db764e3cfb83bcbb5df7c9b49c2 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/DotPrinter.ts @@ -0,0 +1,203 @@ +/* + * 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. + */ + +import { BasicBlock } from '../core/graph/BasicBlock'; +import { ArkClass } from '../core/model/ArkClass'; +import { ArkFile } from '../core/model/ArkFile'; +import { ArkMethod } from '../core/model/ArkMethod'; +import { ArkNamespace } from '../core/model/ArkNamespace'; +import { Printer } from './Printer'; +import { Cfg } from '../core/graph/Cfg'; + +/** + * @category save + */ +export class DotMethodPrinter extends Printer { + method: ArkMethod; + nesting: boolean; + + constructor(method: ArkMethod, nesting: boolean = false) { + super(); + this.method = method; + this.nesting = nesting; + } + + public dump(): string { + this.printer.clear(); + if (this.nesting) { + this.printer.writeIndent().writeLine(`subgraph "cluster_${this.method.getSignature()}" {`); + } else { + this.printer.writeIndent().writeLine(`digraph "${this.method.getSignature()}" {`); + } + this.printer.incIndent(); + this.printer.writeIndent().writeLine(`label="${this.method.getSignature()}";`); + + let blocks = (this.method.getCfg() as Cfg)?.getBlocks(); + let prefix = `Node${this.stringHashCode(this.method.getSignature().toString())}`; + this.printBlocks(blocks, prefix); + + this.printer.decIndent(); + this.printer.writeIndent().writeLine('}'); + + return this.printer.toString(); + } + + protected stringHashCode(name: string): number { + let hashCode = 0; + for (let i = 0; i < name.length; i++) { + hashCode += name.charCodeAt(i); + } + return Math.abs(hashCode); + } + + private printBlocks(blocks: Set, prefix: string): void { + if (!blocks) { + return; + } + let blockToNode: Map = new Map(); + let index = 0; + for (let block of blocks) { + let name = prefix + index++; + blockToNode.set(block, name); + /** Node0 [label="entry"]; */ + this.printer.writeIndent().writeLine(`${name} [label="${this.getBlockContent(block, this.printer.getIndent())}"];`); + } + + for (let block of blocks) { + for (let nextBlock of block.getSuccessors()) { + // Node0 -> Node1; + this.printer.writeIndent().writeLine(`${blockToNode.get(block)} -> ${blockToNode.get(nextBlock)};`); + } + + let exceptionalNextBlock = block.getExceptionalSuccessorBlocks(); + if (!exceptionalNextBlock) { + continue; + } + for (const nextBlock of exceptionalNextBlock) { + this.printer.writeIndent().writeLine(`${blockToNode.get(block)} -> ${blockToNode.get(nextBlock)}[style="dotted"];`); + } + } + } + + private getBlockContent(block: BasicBlock, indent: string): string { + let content: string[] = [`id:${block.getId()}`]; + for (let stmt of block.getStmts()) { + content.push(stmt.toString().replace(/"/g, '\\"')); + } + return content.join('\n ' + indent); + } +} + +/** + * @category save + */ +export class DotClassPrinter extends Printer { + cls: ArkClass; + nesting: boolean; + + constructor(cls: ArkClass, nesting: boolean = false) { + super(); + this.cls = cls; + this.nesting = nesting; + } + + public dump(): string { + this.printer.clear(); + if (!this.nesting) { + this.printer.writeLine(`digraph "${this.cls.getName()}" {`); + this.printer.incIndent(); + } + + for (let method of this.cls.getMethods()) { + let mtd = new DotMethodPrinter(method, true); + this.printer.write(mtd.dump()); + } + + if (!this.nesting) { + this.printer.decIndent(); + this.printer.writeLine(`}`); + } + + return this.printer.toString(); + } +} + +/** + * @category save + */ +export class DotNamespacePrinter extends Printer { + ns: ArkNamespace; + nesting: boolean; + + constructor(ns: ArkNamespace, nesting: boolean = false) { + super(); + this.ns = ns; + this.nesting = nesting; + } + + public dump(): string { + this.printer.clear(); + if (!this.nesting) { + this.printer.writeLine(`digraph "${this.ns.getName()}" {`); + this.printer.incIndent(); + } + + for (let method of this.ns.getAllMethodsUnderThisNamespace()) { + let mtd = new DotMethodPrinter(method, true); + this.printer.write(mtd.dump()); + } + + if (!this.nesting) { + this.printer.decIndent(); + this.printer.writeLine(`}`); + } + + return this.printer.toString(); + } +} + +/** + * @category save + */ +export class DotFilePrinter extends Printer { + arkFile: ArkFile; + + constructor(arkFile: ArkFile) { + super(); + this.arkFile = arkFile; + } + + public dump(): string { + this.printer.clear(); + this.printer.writeLine(`digraph "${this.arkFile.getName()}" {`); + this.printer.incIndent(); + + for (let ns of this.arkFile.getNamespaces()) { + let nsPrinter = new DotNamespacePrinter(ns, true); + this.printer.write(nsPrinter.dump()); + } + + // print class + for (let cls of this.arkFile.getClasses()) { + let clsPrinter = new DotClassPrinter(cls, true); + this.printer.write(clsPrinter.dump()); + } + + this.printer.decIndent(); + this.printer.writeLine('}'); + + return this.printer.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/GraphPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/GraphPrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..7016d14036bdc6f7a4d0e21ee0d0963c195e1974 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/GraphPrinter.ts @@ -0,0 +1,149 @@ +/* + * 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. + */ + +import { BaseEdge, BaseNode, NodeID } from '../core/graph/BaseExplicitGraph'; +import { GraphTraits } from '../core/graph/GraphTraits'; +import { Printer } from './Printer'; + +function escapeStr(input: string): string { + let str = input; + for (let i = 0; i < str.length; ++i) { + switch (str[i]) { + case '\n': + str = str.substring(0, i) + '\\n' + str.substring(i + 1); + ++i; + break; + case '\t': + str = str.substring(0, i) + ' ' + str.substring(i + 1); + ++i; + break; + case '\\': + if (i + 1 < str.length) { + switch (str[i + 1]) { + case 'l': + continue; // don't disturb \l + case '|': + case '{': + case '}': + str = str.substring(0, i) + str.substring(i + 1); + continue; + default: + break; + } + } + str = str.substring(0, i) + '\\\\' + str.substring(i + 1); + ++i; + break; + case '{': + case '}': + case '<': + case '>': + case '|': + case '"': + str = str.substring(0, i) + '\\' + str[i] + str.substring(i + 1); + ++i; + break; + default: + } + } + return str; +} + +export class GraphPrinter> extends Printer { + graph: GraphType; + title!: string; + startID: NodeID | undefined = undefined; + + constructor(g: GraphType, t?: string) { + super(); + this.graph = g; + if (t) { + this.title = t; + } + } + + public setStartID(n: NodeID): void { + this.startID = n; + } + + public dump(): string { + this.printer.clear(); + this.writeGraph(); + return this.printer.toString(); + } + + public writeGraph(): void { + this.writeHeader(); + this.writeNodes(); + this.writeFooter(); + } + + public writeNodes(): void { + let itor: IterableIterator = this.graph.nodesItor(); + if (this.startID) { + // from start id + let nodes = new Set(); + let startNode = this.graph.getNode(this.startID)!; + let worklist = [startNode]; + while (worklist.length > 0) { + let n = worklist.shift()!; + if (nodes.has(n)) { + continue; + } + nodes.add(n); + n.getOutgoingEdges()?.forEach(e => worklist.push(e.getDstNode())); + } + itor = nodes.values(); + } + + for (let node of itor) { + let nodeAttr = node.getDotAttr(); + if (nodeAttr === '') { + continue; + } + let nodeLabel = escapeStr(node.getDotLabel()); + + this.printer.writeLine(`\tNode${node.getID()} [shape=recode,${nodeAttr},label="${nodeLabel}"];`); + + for (let edge of node.getOutgoingEdges()) { + this.writeEdge(edge); + } + } + } + + public writeEdge(edge: BaseEdge): void { + let edgeAttr = edge.getDotAttr(); + if (edgeAttr === '') { + return; + } + this.printer.writeLine(`\tNode${edge.getSrcID()} -> Node${edge.getDstID()}[${edgeAttr}]`); + } + + public writeHeader(): void { + const GraphName = this.graph.getGraphName(); + + let graphNameStr = `digraph "${escapeStr(this.title || GraphName || 'unnamed')}" {\n`; + this.printer.writeLine(graphNameStr); + + let labelStr = `\tlabel="${escapeStr(this.title || GraphName)}";\n`; + this.printer.writeLine(labelStr); + + // TODO: need graph attr? + } + + public writeFooter(): void { + this.printer.writeLine('}\n'); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/JsonPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/JsonPrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..283de26011aae158e95d678fccdac4a6ceed70b4 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/JsonPrinter.ts @@ -0,0 +1,606 @@ +/* + * 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. + */ + +import { Printer } from './Printer'; +import { ArkFile } from '../core/model/ArkFile'; +import { ArkMethod } from '../core/model/ArkMethod'; +import { ArkNamespace } from '../core/model/ArkNamespace'; +import { ArkClass } from '../core/model/ArkClass'; +import { ArkField } from '../core/model/ArkField'; +import { + AliasType, + AnnotationNamespaceType, + AnnotationType, + AnnotationTypeQueryType, + AnyType, + ArrayType, + BigIntType, + BooleanType, + ClassType, + FunctionType, + GenericType, + LiteralType, + NeverType, + NullType, + NumberType, + PrimitiveType, + StringType, + TupleType, + Type, + UnclearReferenceType, + UndefinedType, + UnionType, + UnknownType, + VoidType, +} from '../core/base/Type'; +import { Value } from '../core/base/Value'; +import { ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, ArkThrowStmt, Stmt } from '../core/base/Stmt'; +import { + AbstractBinopExpr, + AbstractExpr, + AbstractInvokeExpr, + ArkAwaitExpr, + ArkCastExpr, + ArkConditionExpr, + ArkDeleteExpr, + ArkInstanceInvokeExpr, + ArkInstanceOfExpr, + ArkNewArrayExpr, + ArkNewExpr, + ArkNormalBinopExpr, + ArkPhiExpr, + ArkPtrInvokeExpr, + ArkStaticInvokeExpr, + ArkTypeOfExpr, + ArkUnopExpr, + ArkYieldExpr, +} from '../core/base/Expr'; +import { Constant } from '../core/base/Constant'; +import { MethodParameter } from '../core/model/builder/ArkMethodBuilder'; +import { ImportInfo } from '../core/model/ArkImport'; +import { ExportInfo } from '../core/model/ArkExport'; +import { AliasTypeSignature, ClassSignature, FieldSignature, FileSignature, MethodSignature, NamespaceSignature } from '../core/model/ArkSignature'; +import { LineColPosition } from '../core/base/Position'; +import { AbstractFieldRef, AbstractRef, ArkArrayRef, ArkInstanceFieldRef, ArkParameterRef, ArkStaticFieldRef, ArkThisRef } from '../core/base/Ref'; +import { Local } from '../core/base/Local'; +import { Cfg } from '../core/graph/Cfg'; +import { BasicBlock } from '../core/graph/BasicBlock'; +import { ArkBody } from '../core/model/ArkBody'; +import { Decorator } from '../core/base/Decorator'; +import util from 'util'; + +export class JsonPrinter extends Printer { + constructor(private arkFile: ArkFile) { + super(); + } + + public dump(): string { + const jsonObject = this.serializeArkFile(this.arkFile); + return JSON.stringify(jsonObject, null, 2); + } + + private serializeArkFile(file: ArkFile): object { + return { + signature: this.serializeFileSignature(file.getFileSignature()), + namespaces: file.getNamespaces().map(ns => this.serializeNamespace(ns)), + classes: file.getClasses().map(cls => this.serializeClass(cls)), + importInfos: file.getImportInfos().map(info => this.serializeImportInfo(info)), + exportInfos: file.getExportInfos().map(info => this.serializeExportInfo(info)), + }; + } + + private serializeNamespace(namespace: ArkNamespace): object { + return { + signature: this.serializeNamespaceSignature(namespace.getSignature()), + classes: namespace.getClasses().map(cls => this.serializeClass(cls)), + namespaces: namespace.getNamespaces().map(ns => this.serializeNamespace(ns)), + }; + } + + private serializeClass(clazz: ArkClass): object { + return { + signature: this.serializeClassSignature(clazz.getSignature()), + modifiers: clazz.getModifiers(), + decorators: clazz.getDecorators().map(decorator => this.serializeDecorator(decorator)), + typeParameters: clazz.getGenericsTypes()?.map(type => this.serializeType(type)), + superClassName: clazz.getSuperClassName(), + implementedInterfaceNames: clazz.getImplementedInterfaceNames(), + fields: clazz.getFields().map(field => this.serializeField(field)), + methods: clazz.getMethods(true).map(method => this.serializeMethod(method)), + }; + } + + private serializeField(field: ArkField): object { + return { + signature: this.serializeFieldSignature(field.getSignature()), + modifiers: field.getModifiers(), + decorators: field.getDecorators().map(decorator => this.serializeDecorator(decorator)), + questionToken: field.getQuestionToken(), + exclamationToken: field.getExclamationToken(), + }; + } + + private serializeMethod(method: ArkMethod): object { + let body = method.getBody(); + return { + signature: this.serializeMethodSignature(method.getSignature()), + modifiers: method.getModifiers(), + decorators: method.getDecorators().map(decorator => this.serializeDecorator(decorator)), + typeParameters: method.getGenericTypes()?.map(type => this.serializeType(type)), + body: body && this.serializeMethodBody(body), + }; + } + + private serializeMethodBody(body: ArkBody): object { + return { + locals: Array.from(body.getLocals().values()).map(local => this.serializeLocal(local)), + cfg: this.serializeCfg(body.getCfg()), + }; + } + + private serializeMethodParameter(parameter: MethodParameter): object { + return { + name: parameter.getName(), + type: this.serializeType(parameter.getType()), + isOptional: parameter.isOptional(), + }; + } + + private serializeImportInfo(importInfo: ImportInfo): object { + return { + importClauseName: importInfo.getImportClauseName(), + importType: importInfo.getImportType(), + importFrom: importInfo.getFrom(), + nameBeforeAs: importInfo.getNameBeforeAs(), + modifiers: importInfo.getModifiers(), + originTsPosition: this.serializeLineColPosition(importInfo.getOriginTsPosition()), + }; + } + + private serializeExportInfo(exportInfo: ExportInfo): object { + return { + exportClauseName: exportInfo.getExportClauseName(), + exportClauseType: exportInfo.getExportClauseType(), + exportFrom: exportInfo.getFrom(), + nameBeforeAs: exportInfo.getNameBeforeAs(), + isDefault: exportInfo.isDefault(), + modifiers: exportInfo.getModifiers(), + originTsPosition: this.serializeLineColPosition(exportInfo.getOriginTsPosition()), + }; + } + + private serializeDecorator(decorator: Decorator): object { + return { + kind: decorator.getKind(), + }; + } + + private serializeLineColPosition(position: LineColPosition): object { + return { + line: position.getLineNo(), + col: position.getColNo(), + }; + } + + private serializeType(type: Type): object { + if (type === undefined) { + throw new Error('Type is undefined'); + } + + if (type instanceof AnyType) { + return { + _: 'AnyType', + }; + } else if (type instanceof UnknownType) { + return { + _: 'UnknownType', + }; + } else if (type instanceof VoidType) { + return { + _: 'VoidType', + }; + } else if (type instanceof NeverType) { + return { + _: 'NeverType', + }; + } else if (type instanceof UnionType) { + return { + _: 'UnionType', + types: type.getTypes().map(type => this.serializeType(type)), + }; + } else if (type instanceof TupleType) { + return { + _: 'TupleType', + types: type.getTypes().map(type => this.serializeType(type)), + }; + } else if (type instanceof BooleanType) { + return { + _: 'BooleanType', + }; + } else if (type instanceof NumberType) { + return { + _: 'NumberType', + }; + } else if (type instanceof BigIntType) { + return { + _: 'BigIntType', + }; + } else if (type instanceof StringType) { + return { + _: 'StringType', + }; + } else if (type instanceof NullType) { + return { + _: 'NullType', + }; + } else if (type instanceof UndefinedType) { + return { + _: 'UndefinedType', + }; + } else if (type instanceof LiteralType) { + return { + _: 'LiteralType', + literal: type.getLiteralName(), + }; + } else if (type instanceof PrimitiveType) { + throw new Error('Unhandled PrimitiveType: ' + util.inspect(type, { showHidden: true, depth: null })); + } else if (type instanceof ClassType) { + return { + _: 'ClassType', + signature: this.serializeClassSignature(type.getClassSignature()), + typeParameters: type.getRealGenericTypes()?.map(type => this.serializeType(type)), + }; + } else if (type instanceof FunctionType) { + return { + _: 'FunctionType', + signature: this.serializeMethodSignature(type.getMethodSignature()), + typeParameters: type.getRealGenericTypes()?.map(type => this.serializeType(type)), + }; + } else if (type instanceof ArrayType) { + return { + _: 'ArrayType', + elementType: this.serializeType(type.getBaseType()), + dimensions: type.getDimension(), + }; + } else if (type instanceof UnclearReferenceType) { + return { + _: 'UnclearReferenceType', + name: type.getName(), + typeParameters: type.getGenericTypes().map(type => this.serializeType(type)), + }; + } else if (type instanceof GenericType) { + let defaultType = type.getDefaultType(); + let constraint = type.getConstraint(); + return { + _: 'GenericType', + name: type.getName(), + defaultType: defaultType && this.serializeType(defaultType), + constraint: constraint && this.serializeType(constraint), + }; + } else if (type instanceof AliasType) { + return { + _: 'AliasType', + name: type.getName(), + originalType: this.serializeType(type.getOriginalType()), + signature: this.serializeAliasTypeSignature(type.getSignature()), + }; + } else if (type instanceof AnnotationNamespaceType) { + return { + _: 'AnnotationNamespaceType', + originType: type.getOriginType(), + namespaceSignature: this.serializeNamespaceSignature(type.getNamespaceSignature()), + }; + } else if (type instanceof AnnotationTypeQueryType) { + return { + _: 'AnnotationTypeQueryType', + originType: type.getOriginType(), + }; + } else if (type instanceof AnnotationType) { + throw new Error('Unhandled AnnotationType: ' + util.inspect(type, { showHidden: true, depth: null })); + } else { + throw new Error('Unhandled Type: ' + util.inspect(type, { showHidden: true, depth: null })); + } + } + + private serializeFileSignature(file: FileSignature): object { + return { + projectName: file.getProjectName(), + fileName: file.getFileName(), + }; + } + + private serializeNamespaceSignature(namespace: NamespaceSignature): object { + let dns = namespace.getDeclaringNamespaceSignature(); + return { + name: namespace.getNamespaceName(), + declaringFile: this.serializeFileSignature(namespace.getDeclaringFileSignature()), + declaringNamespace: dns && this.serializeNamespaceSignature(dns), + }; + } + + private serializeClassSignature(clazz: ClassSignature): object { + let dns = clazz.getDeclaringNamespaceSignature(); + return { + name: clazz.getClassName(), + declaringFile: this.serializeFileSignature(clazz.getDeclaringFileSignature()), + declaringNamespace: dns && this.serializeNamespaceSignature(dns), + }; + } + + private serializeFieldSignature(field: FieldSignature): object { + let declaringSignature: ClassSignature | NamespaceSignature = field.getDeclaringSignature(); + let declaringClass; + if (declaringSignature instanceof ClassSignature) { + declaringClass = this.serializeClassSignature(declaringSignature); + } else { + declaringClass = this.serializeNamespaceSignature(declaringSignature); + } + return { + declaringClass, + name: field.getFieldName(), + type: this.serializeType(field.getType()), + }; + } + + private serializeMethodSignature(method: MethodSignature): object { + return { + declaringClass: this.serializeClassSignature(method.getDeclaringClassSignature()), + name: method.getMethodSubSignature().getMethodName(), + parameters: method + .getMethodSubSignature() + .getParameters() + .map(param => this.serializeMethodParameter(param)), + returnType: this.serializeType(method.getType()), + }; + } + + private serializeAliasTypeSignature(signature: AliasTypeSignature): object { + return { + name: signature.getName(), + method: this.serializeMethodSignature(signature.getDeclaringMethodSignature()), + }; + } + + private serializeCfg(cfg: Cfg): object { + const visited = new Set(); + const stack: BasicBlock[] = []; + const startingBlock = cfg.getStartingBlock(); + if (startingBlock) { + stack.push(startingBlock); + } + let id = 0; + while (stack.length > 0) { + const block = stack.pop()!; + if (visited.has(block)) { + continue; + } + visited.add(block); + block.setId(id++); + stack.push(...block.getSuccessors()); + } + return { + blocks: Array.from(visited).map(block => this.serializeBasicBlock(block)), + }; + } + + private serializeBasicBlock(block: BasicBlock): object { + const successors = block.getSuccessors().map(succ => succ.getId()); + successors.sort((a, b) => a - b); + const predecessors = block.getPredecessors().map(pred => pred.getId()); + predecessors.sort((a, b) => a - b); + return { + id: block.getId(), + successors, + predecessors, + stmts: block.getStmts().map(stmt => this.serializeStmt(stmt)), + }; + } + + private serializeLocal(local: Local): object { + return { + name: local.getName(), + type: this.serializeType(local.getType()), + }; + } + + private serializeValue(value: Value): object { + if (value === undefined) { + throw new Error('Value is undefined'); + } + + if (value instanceof Local) { + return { + _: 'Local', + ...this.serializeLocal(value), + }; + } else if (value instanceof Constant) { + return { + _: 'Constant', + value: value.getValue(), + type: this.serializeType(value.getType()), + }; + } else if (value instanceof ArkNewExpr) { + return { + _: 'NewExpr', + classType: this.serializeType(value.getClassType()), + }; + } else if (value instanceof ArkNewArrayExpr) { + return { + _: 'NewArrayExpr', + elementType: this.serializeType(value.getBaseType()), + size: this.serializeValue(value.getSize()), + }; + } else if (value instanceof ArkDeleteExpr) { + return { + _: 'DeleteExpr', + arg: this.serializeValue(value.getField()), + }; + } else if (value instanceof ArkAwaitExpr) { + return { + _: 'AwaitExpr', + arg: this.serializeValue(value.getPromise()), + }; + } else if (value instanceof ArkYieldExpr) { + return { + _: 'YieldExpr', + arg: this.serializeValue(value.getYieldValue()), + }; + } else if (value instanceof ArkTypeOfExpr) { + return { + _: 'TypeOfExpr', + arg: this.serializeValue(value.getOp()), + }; + } else if (value instanceof ArkInstanceOfExpr) { + return { + _: 'InstanceOfExpr', + arg: this.serializeValue(value.getOp()), + checkType: this.serializeType(value.getCheckType()), + }; + } else if (value instanceof ArkCastExpr) { + return { + _: 'CastExpr', + arg: this.serializeValue(value.getOp()), + type: this.serializeType(value.getType()), + }; + } else if (value instanceof ArkPhiExpr) { + const args = value.getArgs(); + const argToBlock = value.getArgToBlock(); + return { + _: 'PhiExpr', + args: args.map(arg => this.serializeValue(arg)), + blocks: args.map(arg => argToBlock.get(arg)!.getId()), + type: this.serializeType(value.getType()), + }; + } else if (value instanceof ArkConditionExpr) { + return { + _: 'ConditionExpr', + op: value.getOperator(), + left: this.serializeValue(value.getOp1()), + right: this.serializeValue(value.getOp2()), + type: this.serializeType(value.getType()), + }; + } else if (value instanceof ArkNormalBinopExpr) { + return { + _: 'BinopExpr', + op: value.getOperator(), + left: this.serializeValue(value.getOp1()), + right: this.serializeValue(value.getOp2()), + }; + } else if (value instanceof AbstractBinopExpr) { + return new Error('Unhandled BinopExpr: ' + util.inspect(value, { showHidden: true, depth: null })); + } else if (value instanceof ArkUnopExpr) { + return { + _: 'UnopExpr', + op: value.getOperator(), + arg: this.serializeValue(value.getOp()), + }; + } else if (value instanceof ArkInstanceInvokeExpr) { + return { + _: 'InstanceCallExpr', + instance: this.serializeValue(value.getBase()), + method: this.serializeMethodSignature(value.getMethodSignature()), + args: value.getArgs().map(arg => this.serializeValue(arg)), + }; + } else if (value instanceof ArkStaticInvokeExpr) { + return { + _: 'StaticCallExpr', + method: this.serializeMethodSignature(value.getMethodSignature()), + args: value.getArgs().map(arg => this.serializeValue(arg)), + }; + } else if (value instanceof ArkPtrInvokeExpr) { + return { + _: 'PtrCallExpr', + ptr: this.serializeValue(value.getFuncPtrLocal()), + method: this.serializeMethodSignature(value.getMethodSignature()), + args: value.getArgs().map(arg => this.serializeValue(arg)), + }; + } else if (value instanceof AbstractInvokeExpr) { + throw new Error('Unhandled CallExpr: ' + util.inspect(value, { showHidden: true, depth: null })); + } else if (value instanceof ArkThisRef) { + return { + _: 'ThisRef', + type: this.serializeType(value.getType()), + }; + } else if (value instanceof ArkParameterRef) { + return { + _: 'ParameterRef', + index: value.getIndex(), + type: this.serializeType(value.getType()), + }; + } else if (value instanceof ArkArrayRef) { + return { + _: 'ArrayRef', + array: this.serializeValue(value.getBase()), + index: this.serializeValue(value.getIndex()), + type: this.serializeType(value.getType()), + }; + } else if (value instanceof ArkInstanceFieldRef) { + return { + _: 'InstanceFieldRef', + instance: this.serializeValue(value.getBase()), + field: this.serializeFieldSignature(value.getFieldSignature()), + }; + } else if (value instanceof ArkStaticFieldRef) { + return { + _: 'StaticFieldRef', + field: this.serializeFieldSignature(value.getFieldSignature()), + }; + } else if (value instanceof AbstractFieldRef) { + throw new Error('Unhandled FieldRef: ' + util.inspect(value, { showHidden: true, depth: null })); + } else if (value instanceof AbstractRef) { + throw new Error('Unhandled Ref: ' + util.inspect(value, { showHidden: true, depth: null })); + } else if (value instanceof AbstractExpr) { + throw new Error('Unhandled Expr: ' + util.inspect(value, { showHidden: true, depth: null })); + } else { + throw new Error('Unhandled Value: ' + util.inspect(value, { showHidden: true, depth: null })); + } + } + + private serializeStmt(stmt: Stmt): object { + if (stmt instanceof ArkAssignStmt) { + return { + _: 'AssignStmt', + left: this.serializeValue(stmt.getLeftOp()), + right: this.serializeValue(stmt.getRightOp()), + }; + } else if (stmt instanceof ArkInvokeStmt) { + return { + _: 'CallStmt', + expr: this.serializeValue(stmt.getInvokeExpr()), + }; + } else if (stmt instanceof ArkIfStmt) { + return { + _: 'IfStmt', + condition: this.serializeValue(stmt.getConditionExpr()), + }; + } else if (stmt instanceof ArkReturnVoidStmt) { + return { + _: 'ReturnVoidStmt', + }; + } else if (stmt instanceof ArkReturnStmt) { + return { + _: 'ReturnStmt', + arg: this.serializeValue(stmt.getOp()), + }; + } else if (stmt instanceof ArkThrowStmt) { + return { + _: 'ThrowStmt', + arg: this.serializeValue(stmt.getOp()), + }; + } else { + throw new Error('Unhandled Stmt: ' + util.inspect(stmt, { showHidden: true, depth: null })); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/Printer.ts b/ets2panda/linter/arkanalyzer/src/save/Printer.ts new file mode 100644 index 0000000000000000000000000000000000000000..fe5087b3f73b85e47e98aeba756b5b8cd58771d7 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/Printer.ts @@ -0,0 +1,32 @@ +/* + * 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. + */ + +import { ArkCodeBuffer } from './ArkStream'; + +/** + * @category save + */ +export abstract class Printer { + protected printer: ArkCodeBuffer; + + public constructor(indent: string = '') { + this.printer = new ArkCodeBuffer(indent); + } + + /** + * ArkIR dump + */ + public abstract dump(): string; +} diff --git a/ets2panda/linter/arkanalyzer/src/save/PrinterBuilder.ts b/ets2panda/linter/arkanalyzer/src/save/PrinterBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..196d9b77ff4ab7f8e5c07fa4843bb2fe1cdcacdb --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/PrinterBuilder.ts @@ -0,0 +1,163 @@ +/* + * 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. + */ + +import fs from 'fs'; +import path from 'path'; +import { ArkFile } from '../core/model/ArkFile'; +import { DotFilePrinter } from './DotPrinter'; +import { SourceFilePrinter } from './source/SourceFilePrinter'; +import { Printer } from './Printer'; +import { JsonPrinter } from './JsonPrinter'; +import { ArkIRFilePrinter } from './arkir/ArkIRFilePrinter'; +import { Scene } from '../Scene'; +import { PrinterOptions, setPrinterOptions } from './base/BasePrinter'; + +/** + * @example + * // dump method IR to ts source + * let method: Method = xx; + * let srcPrinter = new SourceMethodPrinter(method); + * PrinterBuilder.dump(srcPrinter, 'output.ts'); + * + * + * // dump method cfg to dot + * let dotPrinter = new DotMethodPrinter(method); + * PrinterBuilder.dump(dotPrinter, 'output.dot'); + * + * // dump project + * let printer = new PrinterBuilder('output'); + * for (let f of scene.getFiles()) { + * printer.dumpToTs(f); + * } + * + * @category save + */ +export class PrinterBuilder { + outputDir: string; + constructor(outputDir: string = '') { + this.outputDir = outputDir; + } + + public static dump(source: Printer, output: string): void { + fs.writeFileSync(output, source.dump()); + } + + protected getOutputDir(arkFile: ArkFile): string { + if (this.outputDir === '') { + return path.join(arkFile.getProjectDir(), '..', 'output'); + } else { + return path.join(this.outputDir); + } + } + + public dumpToDot(arkFile: ArkFile, output: string | undefined = undefined): void { + let filename = output; + if (filename === undefined) { + filename = path.join(this.getOutputDir(arkFile), arkFile.getName() + '.dot'); + } + fs.mkdirSync(path.dirname(filename), { recursive: true }); + + let printer: Printer = new DotFilePrinter(arkFile); + PrinterBuilder.dump(printer, filename as string); + } + + public dumpToTs(arkFile: ArkFile, output: string | undefined = undefined): void { + let filename = output; + if (filename === undefined) { + filename = path.join(this.getOutputDir(arkFile), arkFile.getName()); + } + if (path.extname(filename) === '') { + filename += '.ts'; + } + fs.mkdirSync(path.dirname(filename), { recursive: true }); + + let printer: Printer = new SourceFilePrinter(arkFile); + PrinterBuilder.dump(printer, filename); + } + + public dumpToJson(arkFile: ArkFile, output: string | undefined = undefined): void { + let filename = output; + if (filename === undefined) { + filename = path.join(this.getOutputDir(arkFile), arkFile.getName() + '.json'); + } + fs.mkdirSync(path.dirname(filename), { recursive: true }); + + let printer: Printer = new JsonPrinter(arkFile); + PrinterBuilder.dump(printer, filename); + } + + public dumpToIR(arkFile: ArkFile, output: string | undefined = undefined): void { + let filename = output; + if (filename === undefined) { + filename = path.join(this.getOutputDir(arkFile), arkFile.getName()); + } + + filename += '.ir'; + + fs.mkdirSync(path.dirname(filename), { recursive: true }); + + let printer: Printer = new ArkIRFilePrinter(arkFile); + PrinterBuilder.dump(printer, filename); + } +} + +/** + * @example + * // dump scene + * let scenePrinter = new ScenePrinter(scene, 'output'); + * scenePrinter.dumpToTs(); + * scenePrinter.dumpToIR(); + * + * @category save + */ +export class ScenePrinter { + scene: Scene; + outputDir: string; + printer: PrinterBuilder; + + constructor(scene: Scene, outputDir: string, option?: PrinterOptions) { + this.scene = scene; + this.outputDir = outputDir; + this.printer = new PrinterBuilder(outputDir); + if (option) { + setPrinterOptions(option); + } + } + + public dumpToDot(): void { + for (let f of this.scene.getFiles()) { + this.printer.dumpToDot(f); + } + } + + public dumpToTs(): void { + for (let f of this.scene.getFiles()) { + let relativePath = path.relative(f.getProjectDir(), f.getFilePath()); + this.printer.dumpToTs(f, path.join(this.outputDir, relativePath)); + } + } + + public dumpToJson(): void { + for (let f of this.scene.getFiles()) { + this.printer.dumpToJson(f); + } + } + + public dumpToIR(): void { + for (let f of this.scene.getFiles()) { + this.printer.dumpToIR(f); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/ViewTreePrinter.ts b/ets2panda/linter/arkanalyzer/src/save/ViewTreePrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e5cf2f07bb3775909dcddb05a8d34927d310a48 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/ViewTreePrinter.ts @@ -0,0 +1,154 @@ +/* + * 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. + */ + +import { COMPONENT_POP_FUNCTION } from '../core/common/EtsConst'; +import { ViewTree, ViewTreeNode } from '../core/graph/ViewTree'; +import { ClassSignature, MethodSignature } from '../core/model/ArkSignature'; +import { Printer } from './Printer'; + +const DOT_FILE_HEADER = `digraph G { + graph [nodesep=0.1] + node [shape=box] + edge [arrowhead=vee] +`; + +export class ViewTreePrinter extends Printer { + private viewTree: ViewTree; + private dupCnt: number; + + constructor(viewTree: ViewTree) { + super(); + this.viewTree = viewTree; + this.dupCnt = 0; + } + + public dump(): string { + this.printer.clear(); + + let root = this.viewTree.getRoot(); + if (!root) { + return this.printer.toString(); + } + + this.printer.write(DOT_FILE_HEADER); + this.walk(root, root.parent); + this.printer.write('}'); + + return this.printer.toString(); + } + + private walk(item: ViewTreeNode, parent: ViewTreeNode | null, map: Map = new Map()): void { + let skipChildren = this.writeNode(item, parent, map); + if (skipChildren) { + return; + } + for (const child of item.children) { + this.walk(child, item, map); + } + } + + private escapeDotLabel(content: string[]): string { + const MAX_LABEL_LEN = 64; + const PRE_FIX_LEN = 5; + let label = content.join('|'); + if (label.length > MAX_LABEL_LEN) { + return label.substring(0, PRE_FIX_LEN) + '...' + label.substring(label.length - MAX_LABEL_LEN + PRE_FIX_LEN); + } + return label; + } + + private writeNode(item: ViewTreeNode, parent: ViewTreeNode | null, map: Map): boolean { + let id = `Node${map.size}`; + let hasSameNode = map.has(item) || map.has(item.signature!); + + if (hasSameNode) { + id = `${id}_${this.dupCnt++}`; + this.printer.write(` ${id} [label="${item.name}" style=filled color="green"]\n`); + } else { + this.printer.write(` ${id} [label="${item.name}"]\n`); + } + + if (parent) { + this.printer.write(` ${map.get(parent)!} -> ${id}\n`); + } + + this.writeNodeStateValues(item, id); + this.writeNodeAttributes(item, id); + this.writeNodeSignature(item, id); + + if (map.get(item)) { + this.printer.write(` {rank="same"; ${id};${map.get(item)};}\n`); + this.printer.write(` ${id} -> ${map.get(item)}[style=dotted]\n`); + return true; + } else if (map.get(item.signature!)) { + this.printer.write(` {rank="same"; ${id};${map.get(item.signature!)};}\n`); + this.printer.write(` ${id} -> ${map.get(item.signature!)}[style=dotted]\n`); + return true; + } + + map.set(item, id); + if (item.signature && !map.has(item.signature)) { + map.set(item.signature, id); + } + return false; + } + + private writeNodeStateValues(item: ViewTreeNode, id: string): void { + if (item.stateValues.size > 0) { + let stateValuesId = `${id}val`; + let content: string[] = []; + item.stateValues.forEach(value => { + content.push(value.getName()); + }); + + this.printer.write( + ` ${stateValuesId} [shape=ellipse label="StateValues\n ${this.escapeDotLabel( + content + )}" fontsize=10 height=.1 style=filled color=".7 .3 1.0" ]\n` + ); + this.printer.write(` ${id} -> ${stateValuesId}\n`); + } + } + + private writeNodeAttributes(item: ViewTreeNode, id: string): void { + if (item.attributes.size > 0) { + let attributesId = `${id}attributes`; + let content: string[] = []; + for (const [key, _] of item.attributes) { + if (key !== COMPONENT_POP_FUNCTION) { + content.push(key); + } + } + if (content.length > 0) { + this.printer.write( + ` ${attributesId} [shape=ellipse label="property|Event\n${this.escapeDotLabel( + content + )}" fontsize=10 height=.1 style=filled color=".7 .3 1.0" ]\n` + ); + this.printer.write(` ${id} -> ${attributesId}\n`); + } + } + } + private writeNodeSignature(item: ViewTreeNode, id: string): void { + if (item.signature) { + let signatureId = `${id}signature`; + let content = [item.signature.toString()]; + this.printer.write( + ` ${signatureId} [shape=ellipse label="signature\n${this.escapeDotLabel(content)}" fontsize=10 height=.1 style=filled color=".7 .3 1.0" ]\n` + ); + this.printer.write(` ${id} -> ${signatureId}\n`); + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRClassPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRClassPrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..c67d7e45261130711423ff4d3a853a8f4392636b --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRClassPrinter.ts @@ -0,0 +1,112 @@ +/* + * 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 { ArkClass } from '../../core/model/ArkClass'; +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { BasePrinter, Dump } from '../base/BasePrinter'; +import { ArkIRFieldPrinter } from './ArkIRFieldPrinter'; +import { ArkIRMethodPrinter } from './ArkIRMethodPrinter'; + +/** + * @category save + */ +export class ArkIRClassPrinter extends BasePrinter { + protected cls: ArkClass; + + public constructor(cls: ArkClass, indent: string = '') { + super(indent); + this.cls = cls; + } + + public getLine(): number { + return this.cls.getLine(); + } + + public dump(): string { + this.printer.clear(); + + const commentsMetadata = this.cls.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + this.printComments(commentsMetadata); + } + + this.printDecorator(this.cls.getDecorators()); + // print export class name<> + extends c0 implements x1, x2 { + this.printer + .writeIndent() + .writeSpace(this.modifiersToString(this.cls.getModifiers())) + .write(`${this.classOriginTypeToString(this.cls.getCategory())} `); + + this.printer.write(this.cls.getName()); + + const genericsTypes = this.cls.getGenericsTypes(); + if (genericsTypes) { + this.printer.write(`<${genericsTypes.map(v => v.toString()).join(', ')}>`); + } + if (this.cls.getSuperClassName() && !this.cls.hasComponentDecorator()) { + this.printer.write(` extends ${this.cls.getSuperClassName()}`); + } + if (this.cls.getImplementedInterfaceNames().length > 0) { + this.printer.write(` implements ${this.cls.getImplementedInterfaceNames().join(', ')}`); + } + + this.printer.writeLine(' {'); + this.printer.incIndent(); + let items: Dump[] = []; + + let fieldItems = this.printFields(); + fieldItems.sort((a, b) => a.getLine() - b.getLine()); + items.push(...fieldItems); + + let methodItems = this.printMethods(); + methodItems.sort((a, b) => a.getLine() - b.getLine()); + items.push(...methodItems); + let isFirstMethod = true; + let hasField = false; + items.forEach((v): void => { + if (v instanceof ArkIRMethodPrinter) { + if (!isFirstMethod || hasField) { + this.printer.writeLine(''); + } else { + isFirstMethod = false; + } + } else if (v instanceof ArkIRFieldPrinter) { + hasField = true; + } + this.printer.write(v.dump()); + }); + + this.printer.decIndent(); + this.printer.writeIndent().writeLine('}'); + + return this.printer.toString(); + } + + protected printMethods(): Dump[] { + let items: Dump[] = []; + for (let method of this.cls.getMethods(true)) { + items.push(new ArkIRMethodPrinter(method, this.printer.getIndent())); + } + return items; + } + + private printFields(): Dump[] { + let items: Dump[] = []; + for (let field of this.cls.getFields()) { + items.push(new ArkIRFieldPrinter(field, this.printer.getIndent())); + } + return items; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRFieldPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRFieldPrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..61bbecfb3867a24259d1bd5347c5733776dc8383 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRFieldPrinter.ts @@ -0,0 +1,68 @@ +/* + * 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 { ArkField, FieldCategory } from '../../core/model/ArkField'; +import { UnknownType } from '../../core/base/Type'; +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { BasePrinter } from '../base/BasePrinter'; + +/** + * @category save + */ +export class ArkIRFieldPrinter extends BasePrinter { + private field: ArkField; + + public constructor(field: ArkField, indent: string = '') { + super(indent); + this.field = field; + } + + public getLine(): number { + return this.field.getOriginPosition().getLineNo(); + } + public dump(): string { + this.printer.clear(); + const commentsMetadata = this.field.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + this.printComments(commentsMetadata); + } + this.printDecorator(this.field.getDecorators()); + this.printer.writeIndent(); + if (this.field.getCategory() !== FieldCategory.ENUM_MEMBER) { + this.printer.writeSpace(this.modifiersToString(this.field.getModifiers())); + } + + this.printer.write(this.field.getName()); + + if (this.field.getQuestionToken()) { + this.printer.write('?'); + } + if (this.field.getExclamationToken()) { + this.printer.write('!'); + } + + // property.getInitializer() PropertyAccessExpression ArrowFunction ClassExpression FirstLiteralToken StringLiteral + if (!(this.field.getType() instanceof UnknownType) && this.field.getCategory() !== FieldCategory.ENUM_MEMBER) { + this.printer.write(`: ${this.field.getType().toString()}`); + } + + if (this.field.getCategory() === FieldCategory.ENUM_MEMBER) { + this.printer.writeLine(','); + } else { + this.printer.writeLine(''); + } + return this.printer.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRFilePrinter.ts b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRFilePrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..990dc467f2fef1813e8e3a8cf5ab1245fdcdd23d --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRFilePrinter.ts @@ -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. + */ + +import { ArkFile } from '../../core/model/ArkFile'; +import { Dump } from '../base/BasePrinter'; +import { Printer } from '../Printer'; +import { ArkIRClassPrinter } from './ArkIRClassPrinter'; +import { ExportPrinter } from '../base/ExportPrinter'; +import { printImports } from '../base/ImportPrinter'; +import { ArkIRNamespacePrinter } from './ArkIRNamespacePrinter'; + +/** + * @category save + */ +export class ArkIRFilePrinter extends Printer { + arkFile: ArkFile; + items: Dump[] = []; + + constructor(arkFile: ArkFile) { + super(); + this.arkFile = arkFile; + } + + public dump(): string { + // print imports + this.items.push(...printImports(this.arkFile.getImportInfos(), this.printer.getIndent())); + + // print namespace + for (let ns of this.arkFile.getNamespaces()) { + this.items.push(new ArkIRNamespacePrinter(ns)); + } + // print class + for (let cls of this.arkFile.getClasses()) { + this.items.push(new ArkIRClassPrinter(cls)); + } + + // print export + for (let info of this.arkFile.getExportInfos()) { + this.items.push(new ExportPrinter(info)); + } + + this.items.sort((a, b) => a.getLine() - b.getLine()); + this.items.forEach((v): void => { + this.printer.write(v.dump()); + }); + + return this.printer.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRMethodPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRMethodPrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..7b8f7c8b9725bd33f8143a17c8cb3dcccb327b58 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRMethodPrinter.ts @@ -0,0 +1,175 @@ +/* + * 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 { ArkMethod } from '../../core/model/ArkMethod'; +import { ArkCodeBuffer } from '../ArkStream'; + +import { ArkIfStmt, Stmt } from '../../core/base/Stmt'; +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { BasePrinter } from '../base/BasePrinter'; +import { Cfg } from '../../core/graph/Cfg'; +import { BasicBlock } from '../../core/graph/BasicBlock'; + +/** + * @category save + */ +export class ArkIRMethodPrinter extends BasePrinter { + private method: ArkMethod; + + public constructor(method: ArkMethod, indent: string = '') { + super(indent); + this.method = method; + } + + public dump(): string { + this.printer.clear(); + const commentsMetadata = this.method.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + this.printComments(commentsMetadata); + } + + this.printMethod(this.method); + + return this.printer.toString(); + } + + public getLine(): number { + let line = this.method.getLine(); + if (line === null) { + line = 0; + } + if (line > 0) { + return line; + } + + const stmts: Stmt[] = []; + const cfg = this.method.getCfg(); + if (cfg) { + cfg.getStmts() + .reverse() + .forEach(stmt => stmts.push(stmt)); + } + for (const stmt of stmts) { + if (stmt.getOriginPositionInfo().getLineNo() > 0) { + return stmt.getOriginPositionInfo().getLineNo(); + } + } + + return line; + } + + private printMethod(method: ArkMethod): void { + this.printDecorator(method.getDecorators()); + this.printer.writeIndent().write(this.methodProtoToString(method)); + // abstract function no body + if (!method.getBody()) { + this.printer.writeLine(''); + return; + } + + this.printer.writeLine(' {'); + this.printer.incIndent(); + this.printBody(method); + this.printer.decIndent(); + this.printer.writeIndent().writeLine('}'); + } + + private printBody(method: ArkMethod): void { + if (method.getCfg()) { + this.printCfg(method.getCfg()!); + } + } + + protected methodProtoToString(method: ArkMethod): string { + let code = new ArkCodeBuffer(); + code.writeSpace(this.modifiersToString(method.getModifiers())); + + if (method.getAsteriskToken()) { + code.writeSpace('*'); + } + code.write(this.resolveMethodName(method.getName())); + + const genericTypes = method.getGenericTypes(); + if (genericTypes && genericTypes.length > 0) { + let typeParameters: string[] = []; + genericTypes.forEach(genericType => { + typeParameters.push(genericType.toString()); + }); + code.write(`<${genericTypes.join(', ')}>`); + } + + let parameters: string[] = []; + method.getParameters().forEach(parameter => { + let str: string = parameter.getName(); + if (parameter.hasDotDotDotToken()) { + str = `...${parameter.getName()}`; + } + if (parameter.isOptional()) { + str += '?'; + } + if (parameter.getType()) { + str += ': ' + parameter.getType().toString(); + } + parameters.push(str); + }); + code.write(`(${parameters.join(', ')})`); + const returnType = method.getReturnType(); + code.write(`: ${returnType.toString()}`); + return code.toString(); + } + + private printCfg(cfg: Cfg): void { + let blocks = cfg.getBlocks(); + + let firstBB = true; + for (const block of blocks) { + if (!firstBB) { + this.printer.writeLine(''); + } + this.printBasicBlock(block); + if (firstBB) { + firstBB = false; + } + } + } + + private printBasicBlock(block: BasicBlock): void { + let successors = block.getSuccessors(); + + this.printer.writeIndent().writeLine(`label${block.getId()}:`); + this.printer.incIndent(); + + if (successors.length === 1) { + block.getStmts().map(stmt => { + this.printer.writeIndent().writeLine(stmt.toString()); + }); + this.printer.writeIndent().writeLine(`goto label${successors[0].getId()}`); + } else if (successors.length === 2) { + for (const stmt of block.getStmts()) { + if (stmt instanceof ArkIfStmt) { + this.printer.writeIndent().writeLine(`${stmt.toString()} goto label${successors[0].getId()} label${successors[1].getId()}`); + } else { + this.printer.writeIndent().writeLine(stmt.toString()); + } + } + } else { + block.getStmts().map(stmt => { + this.printer.writeIndent().writeLine(stmt.toString()); + }); + } + + this.printer.decIndent(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRNamespacePrinter.ts b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRNamespacePrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..6490cc7f731f217fb14bdc1a7b07208469ea12a4 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/arkir/ArkIRNamespacePrinter.ts @@ -0,0 +1,71 @@ +/* + * 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 { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { ArkNamespace } from '../../core/model/ArkNamespace'; + +import { BasePrinter, Dump } from '../base/BasePrinter'; +import { ArkIRClassPrinter } from './ArkIRClassPrinter'; +import { ExportPrinter } from '../base/ExportPrinter'; + +/** + * @category save + */ +export class ArkIRNamespacePrinter extends BasePrinter { + ns: ArkNamespace; + + public constructor(ns: ArkNamespace, indent: string = '') { + super(indent); + this.ns = ns; + } + + public getLine(): number { + return this.ns.getLine(); + } + + public dump(): string { + const commentsMetadata = this.ns.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + const comments = commentsMetadata.getComments(); + comments.forEach(comment => { + this.printer.writeIndent().writeLine(comment.content); + }); + } + this.printer.writeIndent().writeSpace(this.modifiersToString(this.ns.getModifiers())).writeLine(`namespace ${this.ns.getName()} {`); + this.printer.incIndent(); + + let items: Dump[] = []; + // print class + for (let cls of this.ns.getClasses()) { + items.push(new ArkIRClassPrinter(cls, this.printer.getIndent())); + } + // print namespace + for (let childNs of this.ns.getNamespaces()) { + items.push(new ArkIRNamespacePrinter(childNs, this.printer.getIndent())); + } + // print exportInfos + for (let exportInfo of this.ns.getExportInfos()) { + items.push(new ExportPrinter(exportInfo, this.printer.getIndent())); + } + + items.sort((a, b) => a.getLine() - b.getLine()); + items.forEach((v): void => { + this.printer.write(v.dump()); + }); + this.printer.decIndent(); + this.printer.writeIndent().writeLine('}'); + return this.printer.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/base/BasePrinter.ts b/ets2panda/linter/arkanalyzer/src/save/base/BasePrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..306f6301d4a44d70bb1e46f8375f6f1564c94890 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/base/BasePrinter.ts @@ -0,0 +1,88 @@ +/* + * 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 { Decorator } from '../../core/base/Decorator'; +import { modifiers2stringArray } from '../../core/model/ArkBaseModel'; +import { ClassCategory } from '../../core/model/ArkClass'; +import { CommentsMetadata } from '../../core/model/ArkMetadata'; +import { Printer } from '../Printer'; +import { PrinterUtils } from './PrinterUtils'; + +export interface Dump { + getLine(): number; + dump(): string; +} + +export interface PrinterOptions { + pureTs: boolean; // struct 转成class + noMethodBody: boolean; // 仅输出函数原型,不输出函数体 +} + +let printerOptions: PrinterOptions = { pureTs: false, noMethodBody: false }; +export function setPrinterOptions(options: PrinterOptions): void { + printerOptions = { ...printerOptions, ...options }; +} + +export abstract class BasePrinter extends Printer implements Dump { + public constructor(indent: string) { + super(indent); + } + abstract getLine(): number; + + protected printDecorator(docorator: Decorator[]): void { + docorator.forEach(value => { + this.printer.writeIndent().writeLine(value.toString()); + }); + } + + protected printComments(commentsMetadata: CommentsMetadata): void { + const comments = commentsMetadata.getComments(); + comments.forEach(comment => { + this.printer.writeIndent().writeLine(comment.content); + }); + } + + protected modifiersToString(modifiers: number): string { + let modifiersStr: string[] = modifiers2stringArray(modifiers); + return modifiersStr.join(' '); + } + + protected resolveMethodName(name: string): string { + if (name === '_Constructor') { + return 'constructor'; + } + if (name.startsWith('Get-')) { + return name.replace('Get-', 'get '); + } + if (name.startsWith('Set-')) { + return name.replace('Set-', 'set '); + } + return name; + } + + protected classOriginTypeToString(clsCategory: ClassCategory): string { + if (printerOptions.pureTs) { + if (clsCategory === ClassCategory.STRUCT) { + clsCategory = ClassCategory.CLASS; + } + } + + return PrinterUtils.classOriginTypeToString.get(clsCategory)!; + } + + public static getPrinterOptions(): PrinterOptions { + return printerOptions; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/base/ExportPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/base/ExportPrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..aa186fa49b0d5bc1df78e51b8a51c54b71978848 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/base/ExportPrinter.ts @@ -0,0 +1,68 @@ +/* + * 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 { ExportInfo, ExportType } from '../../core/model/ArkExport'; +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { BasePrinter } from './BasePrinter'; + +export class ExportPrinter extends BasePrinter { + info: ExportInfo; + + public constructor(info: ExportInfo, indent: string = '') { + super(indent); + this.info = info; + } + + public getLine(): number { + return this.info.getOriginTsPosition().getLineNo(); + } + + public dump(): string { + this.printer.clear(); + const commentsMetadata = this.info.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + this.printComments(commentsMetadata); + } + + if ( + !this.info.getFrom() && + (this.info.isExport() || this.info.getExportClauseType() === ExportType.LOCAL || this.info.getExportClauseType() === ExportType.TYPE) + ) { + return this.printer.toString(); + } + + if (this.info.getExportClauseName() === '*') { + // just like: export * as xx from './yy' + if (this.info.getNameBeforeAs() && this.info.getNameBeforeAs() !== '*') { + this.printer.writeIndent().write(`export ${this.info.getNameBeforeAs()} as ${this.info.getExportClauseName()}`); + } else { + this.printer.writeIndent().write(`export ${this.info.getExportClauseName()}`); + } + } else { + // just like: export {xxx as x} from './yy' + if (this.info.getNameBeforeAs()) { + this.printer.write(`export {${this.info.getNameBeforeAs()} as ${this.info.getExportClauseName()}}`); + } else { + this.printer.write(`export {${this.info.getExportClauseName()}}`); + } + } + if (this.info.getFrom()) { + this.printer.write(` from '${this.info.getFrom() as string}'`); + } + this.printer.writeLine(';'); + + return this.printer.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/base/ImportPrinter.ts b/ets2panda/linter/arkanalyzer/src/save/base/ImportPrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..def5cac29fa2962bcdb408cb2ba5415e9e5e6ec8 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/base/ImportPrinter.ts @@ -0,0 +1,94 @@ +/* + * 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 { ImportInfo } from '../../core/model/ArkImport'; +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { BasePrinter, Dump } from './BasePrinter'; + +export class ImportPrinter extends BasePrinter { + infos: ImportInfo[]; + + public constructor(infos: ImportInfo[], indent: string = '') { + super(indent); + this.infos = infos; + } + + public getLine(): number { + return this.infos[0].getOriginTsPosition().getLineNo(); + } + + public dump(): string { + const commentsMetadata = this.infos[0].getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + this.printComments(commentsMetadata); + } + let clauseNames: string[] = []; + let namedImports: string[] = []; + + for (const info of this.infos) { + if (info.getImportType() === 'Identifier') { + // sample: import fs from 'fs' + clauseNames.push(info.getImportClauseName()); + } else if (info.getImportType() === 'NamedImports') { + // sample: import {xxx} from './yyy' + if (info.getNameBeforeAs()) { + namedImports.push(`${info.getNameBeforeAs()} as ${info.getImportClauseName()}`); + } else { + namedImports.push(info.getImportClauseName()); + } + } else if (info.getImportType() === 'NamespaceImport') { + // sample: import * as ts from 'ohos-typescript' + clauseNames.push(`* as ${info.getImportClauseName()}`); + } else if (info.getImportType() === 'EqualsImport') { + // sample: import mmmm = require('./xxx') + this.printer.writeIndent().writeLine(`import ${info.getImportClauseName()} = require('${info.getFrom() as string}');`); + } else { + // sample: import '../xxx' + this.printer.writeIndent().writeLine(`import '${info.getFrom() as string}';`); + } + } + + if (namedImports.length > 0) { + clauseNames.push(`{${namedImports.join(', ')}}`); + } + + this.printer.writeIndent().writeLine(`import ${clauseNames.join(', ')} from '${this.infos[0].getFrom() as string}';`); + + return this.printer.toString(); + } +} + +function mergeImportInfos(infos: ImportInfo[]): Map { + let map = new Map(); + + for (let info of infos) { + let key = `${info.getOriginTsPosition().getLineNo()}-${info.getFrom()}`; + let merge = map.get(key) || []; + merge.push(info); + map.set(key, merge); + } + + return map; +} + +export function printImports(imports: ImportInfo[], indent: string): Dump[] { + let mergeImports = mergeImportInfos(imports); + let items: Dump[] = []; + + for (const [_, importInfos] of mergeImports) { + items.push(new ImportPrinter(importInfos, indent)); + } + return items; +} diff --git a/ets2panda/linter/arkanalyzer/src/save/base/PrinterUtils.ts b/ets2panda/linter/arkanalyzer/src/save/base/PrinterUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..0f92b23bdee278bd1c4ea6e73c06467de6a5ac64 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/base/PrinterUtils.ts @@ -0,0 +1,218 @@ +/* + * 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. + */ + +import { Constant } from '../../core/base/Constant'; +import { ArkInstanceInvokeExpr, ArkNormalBinopExpr, ArkStaticInvokeExpr, NormalBinaryOperator } from '../../core/base/Expr'; +import { Local } from '../../core/base/Local'; +import { ArkAssignStmt, Stmt } from '../../core/base/Stmt'; +import { + COMPONENT_BRANCH_FUNCTION, + COMPONENT_CREATE_FUNCTION, + COMPONENT_IF, + COMPONENT_POP_FUNCTION, + isEtsSystemComponent, + SPECIAL_CONTAINER_COMPONENT, +} from '../../core/common/EtsConst'; +import { ArkClass, ClassCategory } from '../../core/model/ArkClass'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { ANONYMOUS_CLASS_PREFIX, ANONYMOUS_METHOD_PREFIX, DEFAULT_ARK_CLASS_NAME } from '../../core/common/Const'; +import { ClassSignature } from '../../core/model/ArkSignature'; +import { ArkNamespace } from '../../core/model/ArkNamespace'; +import ts from 'ohos-typescript'; +import { TEMP_LOCAL_PREFIX } from '../../core/common/Const'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'PrinterUtils'); + +export const CLASS_CATEGORY_COMPONENT = 100; + +export class PrinterUtils { + public static classOriginTypeToString = new Map([ + [ClassCategory.CLASS, 'class'], + [ClassCategory.STRUCT, 'struct'], + [ClassCategory.INTERFACE, 'interface'], + [ClassCategory.ENUM, 'enum'], + [ClassCategory.TYPE_LITERAL, 'typeliteral'], + [ClassCategory.OBJECT, 'object'], + [CLASS_CATEGORY_COMPONENT, 'component'], + ]); + + public static isAnonymousClass(name: string): boolean { + return name.startsWith(ANONYMOUS_CLASS_PREFIX); + } + + public static isDefaultClass(name: string): boolean { + return name === DEFAULT_ARK_CLASS_NAME; + } + + public static isAnonymousMethod(name: string): boolean { + return name.startsWith(ANONYMOUS_METHOD_PREFIX); + } + + public static isConstructorMethod(name: string): boolean { + return name === 'constructor'; + } + + public static isDeIncrementStmt(stmt: Stmt | null, op: NormalBinaryOperator): boolean { + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + + let leftOp = stmt.getLeftOp(); + let rightOp = stmt.getRightOp(); + if (!(leftOp instanceof Local) || !(rightOp instanceof ArkNormalBinopExpr)) { + return false; + } + + let op1 = rightOp.getOp1(); + let op2 = rightOp.getOp2(); + let operator = rightOp.getOperator(); + if (!(op1 instanceof Local) || !(op2 instanceof Constant)) { + return false; + } + + return leftOp.getName() === op1.getName() && operator === op && op2.getValue() === '1'; + } + + public static isTemp(name: string): boolean { + return name.startsWith(TEMP_LOCAL_PREFIX); + } + + public static getOriginType(cls: ArkClass): number { + if (cls.hasComponentDecorator()) { + return CLASS_CATEGORY_COMPONENT; + } + return cls.getCategory(); + } + + public static isComponentPop(invokeExpr: ArkStaticInvokeExpr): boolean { + let className = invokeExpr.getMethodSignature().getDeclaringClassSignature().getClassName(); + let methodName = invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName(); + + if (methodName === COMPONENT_POP_FUNCTION && (isEtsSystemComponent(className) || SPECIAL_CONTAINER_COMPONENT.has(className))) { + return true; + } + + return false; + } + + public static isComponentCreate(invokeExpr: ArkStaticInvokeExpr): boolean { + let className = invokeExpr.getMethodSignature().getDeclaringClassSignature().getClassName(); + let methodName = invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName(); + + if (methodName === COMPONENT_CREATE_FUNCTION && (isEtsSystemComponent(className) || SPECIAL_CONTAINER_COMPONENT.has(className))) { + return true; + } + + return false; + } + + public static isComponentAttributeInvoke(invokeExpr: ArkInstanceInvokeExpr, visitor: Set = new Set()): boolean { + if (visitor.has(invokeExpr)) { + return false; + } + visitor.add(invokeExpr); + let base = invokeExpr.getBase(); + if (!(base instanceof Local)) { + logger.error(`PrinterUtils->isComponentAttributeInvoke illegal invoke expr ${invokeExpr}`); + return false; + } + let stmt = base.getDeclaringStmt(); + if (!stmt || !(stmt instanceof ArkAssignStmt)) { + return false; + } + + let rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkInstanceInvokeExpr) { + return PrinterUtils.isComponentAttributeInvoke(rightOp, visitor); + } + + if (rightOp instanceof ArkStaticInvokeExpr) { + return PrinterUtils.isComponentCreate(rightOp); + } + + return false; + } + + public static isComponentIfBranchInvoke(invokeExpr: ArkStaticInvokeExpr): boolean { + let className = invokeExpr.getMethodSignature().getDeclaringClassSignature().getClassName(); + let methodName = invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName(); + + if (className === COMPONENT_IF && methodName === COMPONENT_BRANCH_FUNCTION) { + return true; + } + return false; + } + + public static isComponentIfElseInvoke(invokeExpr: ArkStaticInvokeExpr): boolean { + let className = invokeExpr.getMethodSignature().getDeclaringClassSignature().getClassName(); + let methodName = invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName(); + + if (className === COMPONENT_IF && methodName === COMPONENT_BRANCH_FUNCTION) { + let arg0 = invokeExpr.getArg(0) as Constant; + if (arg0.getValue() === '1') { + return true; + } + } + return false; + } + + public static getStaticInvokeClassFullName(classSignature: ClassSignature, namespace?: ArkNamespace): string { + let code: string[] = []; + let declareNamespace = classSignature.getDeclaringNamespaceSignature(); + while (declareNamespace !== null) { + let namespaceName = declareNamespace.getNamespaceName(); + if (namespaceName.length > 0 && namespaceName !== namespace?.getName()) { + code.unshift(namespaceName); + declareNamespace = declareNamespace.getDeclaringNamespaceSignature(); + } else { + break; + } + } + + let className = classSignature.getClassName(); + if (className && className.length > 0 && !PrinterUtils.isDefaultClass(className)) { + code.push(className); + } + return code.join('.'); + } + + public static isIdentifierText(text: string): boolean { + let ch = text.charCodeAt(0); + if (!ts.isIdentifierStart(ch, ts.ScriptTarget.Latest)) { + return false; + } + + for (let i = 1; i < text.length; i++) { + if (!ts.isIdentifierPart(text.charCodeAt(i), ts.ScriptTarget.Latest)) { + return false; + } + } + + return true; + } + + public static escape(text: string): string { + return text + .replace(/\\/g, '\\\\') + .replace(/\f/g, `\\f`) + .replace(/\n/g, `\\n`) + .replace(/\r/g, '\\r') + .replace(/\t/g, '\\t') + .replace(/\v/g, '\\v') + .replace(/\?/g, '\\?') + .replace(/\'/g, "\\'") + .replace(/\"/g, '\\"'); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/serializeArkIR.ts b/ets2panda/linter/arkanalyzer/src/save/serializeArkIR.ts new file mode 100644 index 0000000000000000000000000000000000000000..dd859f8d3dfbadfac57cfb2ce3c92e2f665997da --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/serializeArkIR.ts @@ -0,0 +1,303 @@ +/* + * 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. + */ + +import path from 'path'; +import fs from 'fs'; +import { Command, InvalidArgumentError } from 'commander'; +import { PrinterBuilder } from './PrinterBuilder'; +import { SceneConfig } from '../Config'; +import { Scene } from '../Scene'; +import { ArkFile } from '../core/model/ArkFile'; +import { JsonPrinter } from './JsonPrinter'; +import { Printer } from './Printer'; +import { PointerAnalysis } from '../callgraph/pointerAnalysis/PointerAnalysis'; + +export function buildSceneFromSingleFile(filename: string, verbose: boolean = false): Scene { + if (verbose) { + console.log('Building scene...'); + } + const filepath = path.resolve(filename); + const projectDir = path.dirname(filepath); + const config = new SceneConfig(); + config.buildConfig('single-file', projectDir, []); + config.getProjectFiles().push(filepath); + const scene = new Scene(); + scene.buildSceneFromProjectDir(config); + return scene; +} + +export function buildSceneFromProjectDir(inputDir: string, verbose: boolean = false): Scene { + if (verbose) { + console.log('Building scene...'); + } + const config = new SceneConfig(); + config.buildFromProjectDir(inputDir); + const scene = new Scene(); + scene.buildSceneFromProjectDir(config); + return scene; +} + +export function serializeArkFile(arkFile: ArkFile, output?: string): void { + let filename = output; + if (filename === undefined) { + const outputDir = path.join(arkFile.getProjectDir(), '..', 'output'); + filename = path.join(outputDir, arkFile.getName() + '.json'); + } + fs.mkdirSync(path.dirname(filename), { recursive: true }); + let printer: Printer = new JsonPrinter(arkFile); + const fd = fs.openSync(filename, 'w'); + fs.writeFileSync(fd, printer.dump()); + fs.closeSync(fd); +} + +export function serializeScene(scene: Scene, outDir: string, verbose: boolean = false): void { + let files = scene.getFiles(); + console.log(`Serializing Scene with ${files.length} files to '${outDir}'...`); + for (let f of files) { + let filepath = f.getName(); + let outPath = path.join(outDir, filepath + '.json'); + if (verbose) { + console.log(`Serializing ArkIR for '${filepath}' to '${outPath}'...`); + } + serializeArkFile(f, outPath); + } + if (verbose) { + console.log(`All ${files.length} files in scene are serialized`); + } +} + +function serializeSingleTsFile(input: string, output: string, options: any): void { + options.verbose && console.log(`Serializing TS file to JSON: '${input}' -> '${output}'`); + + let filepath = path.resolve(input); + let projectDir = path.dirname(filepath); + + const scene = buildSceneFromSingleFile(filepath, options.verbose); + + let files = scene.getFiles(); + if (options.verbose) { + console.log(`Scene contains ${files.length} files`); + for (let f of files) { + console.log(`- '${f.getName()}'`); + } + } + + if (options.inferTypes) { + options.verbose && console.log('Inferring types...'); + scene.inferTypes(); + if (options.inferTypes > 1) { + for (let i = 1; i < options.inferTypes; i++) { + options.verbose && console.log(`Inferring types one more time (${i + 1} / ${options.inferTypes})...`); + scene.inferTypes(); + } + } + } + + if (options.entrypoint) { + options.verbose && console.log('Generating entrypoint...'); + PointerAnalysis.pointerAnalysisForWholeProject(scene); + } + + options.verbose && console.log('Extracting single ArkFile...'); + + if (files.length === 0) { + console.error(`ERROR: No files found in the project directory '${projectDir}'.`); + process.exit(1); + } + if (files.length > 1) { + console.error(`ERROR: More than one file found in the project directory '${projectDir}'.`); + process.exit(1); + } + // Note: we explicitly push a single path to the project files (in config), + // so we expect there is only *one* ArkFile in the scene. + let arkFile = scene.getFiles()[0]; + serializeFile(arkFile, output, options, scene); + + options.verbose && console.log('All done!'); +} + +function serializeFile(arkFile: ArkFile, output: string, options: any, scene: Scene): void { + let outPath: string; + if (fs.existsSync(output) && fs.statSync(output).isDirectory()) { + outPath = path.join(output, arkFile.getName() + '.json'); + } else if (!fs.existsSync(output) && output.endsWith('/')) { + outPath = path.join(output, arkFile.getName() + '.json'); + } else { + outPath = output; + } + + console.log(`Serializing ArkIR for '${arkFile.getName()}' to '${outPath}'...`); + let printer = new PrinterBuilder(); + printer.dumpToJson(arkFile, outPath); + + if (options.entrypoint) { + let arkFile = scene.getFiles()[1]; + let outPath: string; + if (fs.existsSync(output) && fs.statSync(output).isDirectory()) { + outPath = path.join(output, arkFile.getName() + '.json'); + } else if (!fs.existsSync(output) && output.endsWith('/')) { + outPath = path.join(output, arkFile.getName() + '.json'); + } else { + outPath = path.join(path.dirname(output), arkFile.getName() + '.json'); + } + console.log(`Serializing entrypoint to '${outPath}'...`); + printer.dumpToJson(arkFile, outPath); + } +} + +function serializeMultipleTsFiles(inputDir: string, outDir: string, options: any): void { + console.log(`Serializing multiple TS files to JSON: '${inputDir}' -> '${outDir}'`); + if (fs.existsSync(outDir) && !fs.statSync(outDir).isDirectory()) { + console.error(`ERROR: Output path must be a directory.`); + process.exit(1); + } + + if (options.verbose) { + console.log('Building scene...'); + } + let config = new SceneConfig(); + config.buildFromProjectDir(inputDir); + let scene = new Scene(); + scene.buildSceneFromProjectDir(config); + + let files = scene.getFiles(); + if (options.verbose) { + console.log(`Scene contains ${files.length} files`); + files.forEach(f => console.log(`- '${f.getName()}'`)); + } + + if (options.inferTypes) { + if (options.verbose) { + console.log('Inferring types...'); + } + scene.inferTypes(); + if (options.inferTypes > 1) { + for (let i = 1; i < options.inferTypes; i++) { + options.verbose && console.log(`Inferring types one more time (${i + 1} / ${options.inferTypes})...`); + scene.inferTypes(); + } + } + } + + if (options.entrypoint) { + if (options.verbose) { + console.log('Generating entrypoint...'); + } + PointerAnalysis.pointerAnalysisForWholeProject(scene); + files = scene.getFiles(); + } + + if (options.verbose) { + console.log('Serializing...'); + } + let printer = new PrinterBuilder(); + for (let f of files) { + let filepath = f.getName(); + let outPath = path.join(outDir, filepath + '.json'); + console.log(`Serializing ArkIR for '${filepath}' to '${outPath}'...`); + printer.dumpToJson(f, outPath); + } + console.log('All done!'); +} + +function serializeTsProject(inputDir: string, outDir: string, options: any): void { + console.log(`Serializing TS project to JSON: '${inputDir}' -> '${outDir}'`); + + if (fs.existsSync(outDir) && !fs.statSync(outDir).isDirectory()) { + console.error(`ERROR: Output path must be a directory.`); + process.exit(1); + } + + const scene = buildSceneFromProjectDir(inputDir, options.verbose); + + if (options.inferTypes) { + if (options.verbose) { + console.log('Inferring types...'); + } + scene.inferTypes(); + if (options.inferTypes > 1) { + for (let i = 1; i < options.inferTypes; i++) { + options.verbose && console.log(`Inferring types one more time (${i + 1} / ${options.inferTypes})...`); + scene.inferTypes(); + } + } + } + + if (options.entrypoint) { + if (options.verbose) { + console.log('Generating entrypoint...'); + } + PointerAnalysis.pointerAnalysisForWholeProject(scene); + } + + serializeScene(scene, outDir, options.verbose); + + if (options.verbose) { + console.log('All done!'); + } +} + +function myParseInt(value: string, _previous: number): number { + const parsedValue = parseInt(value, 10); + if (isNaN(parsedValue)) { + throw new InvalidArgumentError('Must be a number.'); + } + if (parsedValue < 1) { + throw new InvalidArgumentError('Must be greater than 0.'); + } + return parsedValue; +} + +export const program = new Command() + .name('serializeArkIR') + .description('Serialize ArkIR for TypeScript files or projects to JSON') + .argument('', 'Input file or directory') + .argument('', 'Output file or directory') + .option('-m, --multi', 'Flag to indicate the input is a directory', false) + .option('-p, --project', 'Flag to indicate the input is a project directory', false) + .option('-t, --infer-types [times]', 'Infer types in the ArkIR', myParseInt) + .option('-e, --entrypoint', 'Generate entrypoint for the files', false) + .option('-v, --verbose', 'Verbose output', false) + .action((input: any, output: any, options: any) => { + // Check for invalid combinations of flags + if (options.multi && options.project) { + console.error(`ERROR: You cannot provide both the '-m' and '-p' flags.`); + process.exit(1); + } + + // Ensure the input path exists + if (!fs.existsSync(input)) { + console.error(`ERROR: The input path '${input}' does not exist.`); + process.exit(1); + } + + // Handle the case where the input is a directory + if (fs.statSync(input).isDirectory() && !(options.multi || options.project)) { + console.error(`ERROR: If the input is a directory, you must provide the '-p' or '-m' flag.`); + process.exit(1); + } + + if (options.project) { + serializeTsProject(input, output, options); + } else if (options.multi) { + serializeMultipleTsFiles(input, output, options); + } else { + serializeSingleTsFile(input, output, options); + } + }); + +if (require.main === module) { + program.parse(process.argv); +} diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceBase.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceBase.ts new file mode 100644 index 0000000000000000000000000000000000000000..48e794b1eef7e6b86cb1d3a7cf690a0ce09a6931 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceBase.ts @@ -0,0 +1,79 @@ +/* + * 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. + */ + +import { ArkFile } from '../../core/model/ArkFile'; +import { ArkMethod } from '../../core/model/ArkMethod'; +import { ClassSignature, MethodSignature } from '../../core/model/ArkSignature'; +import { ArkClass } from '../../core/model/ArkClass'; +import { ArkCodeBuffer } from '../ArkStream'; +import { Local } from '../../core/base/Local'; +import { TransformerContext } from './SourceTransformer'; +import { ArkNamespace } from '../../core/model/ArkNamespace'; +import { BasePrinter } from '../base/BasePrinter'; + +export abstract class SourceBase extends BasePrinter implements TransformerContext { + protected arkFile: ArkFile; + protected inBuilder: boolean = false; + + public constructor(arkFile: ArkFile, indent: string = '') { + super(indent); + this.arkFile = arkFile; + } + + public getDeclaringArkNamespace(): ArkNamespace | undefined { + return undefined; + } + + public getArkFile(): ArkFile { + return this.arkFile; + } + + public getMethod(signature: MethodSignature): ArkMethod | null { + return this.getArkFile().getScene().getMethod(signature); + } + + public getClass(signature: ClassSignature): ArkClass | null { + return this.getArkFile().getScene().getClass(signature); + } + + public getPrinter(): ArkCodeBuffer { + return this.printer; + } + + public transTemp2Code(temp: Local): string { + return temp.getName(); + } + + public isInBuilderMethod(): boolean { + return this.inBuilder; + } + + protected resolveKeywordType(keywordStr: string): string { + // 'NumberKeyword | NullKeyword | + let types: string[] = []; + for (let keyword of keywordStr.split('|')) { + keyword = keyword.trim(); + if (keyword.length === 0) { + continue; + } + if (keyword.endsWith('Keyword')) { + keyword = keyword.substring(0, keyword.length - 'Keyword'.length).toLowerCase(); + } + types.push(keyword); + } + + return types.join(' | '); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceBody.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceBody.ts new file mode 100644 index 0000000000000000000000000000000000000000..b33546dce3edac6d742866e3c89ffdc14520ebb6 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceBody.ts @@ -0,0 +1,327 @@ +/* + * 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. + */ + +import { ArkInstanceInvokeExpr } from '../../core/base/Expr'; +import { Local } from '../../core/base/Local'; +import { ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, Stmt } from '../../core/base/Stmt'; +import { BasicBlock } from '../../core/graph/BasicBlock'; +import { ArkBody } from '../../core/model/ArkBody'; +import { ArkMethod } from '../../core/model/ArkMethod'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { ArkCodeBuffer } from '../ArkStream'; +import { + SourceBreakStmt, + SourceCatchStmt, + SourceCompoundEndStmt, + SourceContinueStmt, + SourceDoStmt, + SourceDoWhileStmt, + SourceElseStmt, + SourceFinallyStmt, + SourceForStmt, + SourceIfStmt, + SourceStmt, + SourceTryStmt, + SourceWhileStmt, + stmt2SourceStmt, + StmtPrinterContext, +} from './SourceStmt'; +import { AbstractFlowGraph, CodeBlockType } from '../../utils/CfgStructualAnalysis'; +import { ArkClass } from '../../core/model/ArkClass'; +import { ArkFile } from '../../core/model/ArkFile'; +import { ClassSignature, MethodSignature } from '../../core/model/ArkSignature'; +import { ModelUtils } from '../../core/common/ModelUtils'; +import { PrinterUtils } from '../base/PrinterUtils'; +import { ArkNamespace } from '../../core/model/ArkNamespace'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'SourceBody'); + +export class SourceBody implements StmtPrinterContext { + protected printer: ArkCodeBuffer; + private arkBody: ArkBody; + private stmts: SourceStmt[] = []; + private method: ArkMethod; + private cfgUtils: AbstractFlowGraph; + private tempCodeMap: Map; + private tempVisitor: Set; + private skipStmts: Set; + private stmtReader: StmtReader; + private definedLocals: Set; + private inBuilder: boolean; + private lastStmt: Stmt; + + public constructor(indent: string, method: ArkMethod, inBuilder: boolean) { + this.printer = new ArkCodeBuffer(indent); + this.method = method; + this.arkBody = method.getBody()!; + this.cfgUtils = new AbstractFlowGraph(method.getCfg()!, this.arkBody.getTraps()); + this.tempCodeMap = new Map(); + this.tempVisitor = new Set(); + this.definedLocals = new Set(); + this.inBuilder = inBuilder; + this.skipStmts = new Set(); + this.stmtReader = new StmtReader([]); + this.lastStmt = this.arkBody.getCfg().getStartingStmt(); + this.buildSourceStmt(); + } + setSkipStmt(stmt: Stmt): void { + this.skipStmts.add(stmt); + } + + isInBuilderMethod(): boolean { + return this.inBuilder; + } + isInDefaultMethod(): boolean { + return this.method.isDefaultArkMethod(); + } + public getArkFile(): ArkFile { + return this.method.getDeclaringArkFile(); + } + + public getDeclaringArkNamespace(): ArkNamespace | undefined { + return this.method.getDeclaringArkClass().getDeclaringArkNamespace(); + } + + public getMethod(signature: MethodSignature): ArkMethod | null { + let method = this.method.getDeclaringArkFile().getScene().getMethod(signature); + if (method) { + return method; + } + return this.method.getDeclaringArkClass().getMethodWithName(signature.getMethodSubSignature().getMethodName()); + } + + public getClass(signature: ClassSignature): ArkClass | null { + return ModelUtils.getClass(this.method, signature); + } + + public getLocals(): Map { + return this.arkBody.getLocals(); + } + + public defineLocal(local: Local): void { + this.definedLocals.add(local); + } + + public isLocalDefined(local: Local): boolean { + return this.definedLocals.has(local); + } + + public getStmtReader(): StmtReader { + return this.stmtReader; + } + + public setTempCode(temp: string, code: string): void { + this.tempCodeMap.set(temp, code); + } + + public transTemp2Code(temp: Local): string { + if (this.tempCodeMap.has(temp.getName()) && PrinterUtils.isTemp(temp.getName())) { + this.tempVisitor.add(temp.getName()); + return this.tempCodeMap.get(temp.getName())!; + } + + return temp.getName(); + } + + public getTempCodeMap(): Map { + return this.tempCodeMap; + } + + public hasTempVisit(temp: string): boolean { + return this.tempVisitor.has(temp); + } + + public setTempVisit(temp: string): void { + this.tempVisitor.add(temp); + } + + public getPrinter(): ArkCodeBuffer { + return this.printer; + } + + public dump(): string { + this.printStmts(); + return this.printer.toString(); + } + + private buildSourceStmt(): void { + this.cfgUtils.preOrder(this.cfgUtils.getEntry(), (block, type) => { + this.buildBasicBlock(block, type); + }); + } + + private buildBasicBlock(block: BasicBlock | undefined, type: CodeBlockType): void { + if (type === CodeBlockType.BREAK) { + this.pushStmt(new SourceBreakStmt(this, this.lastStmt)); + return; + } else if (type === CodeBlockType.CONTINUE) { + this.pushStmt(new SourceContinueStmt(this, this.lastStmt)); + } else if (type === CodeBlockType.COMPOUND_END) { + this.pushStmt(new SourceCompoundEndStmt(this, this.lastStmt, '}')); + } else if (type === CodeBlockType.ELSE) { + this.pushStmt(new SourceElseStmt(this, this.lastStmt)); + } else if (type === CodeBlockType.DO) { + this.pushStmt(new SourceDoStmt(this, this.lastStmt)); + } else if (type === CodeBlockType.TRY) { + this.pushStmt(new SourceTryStmt(this, this.lastStmt)); + } else if (type === CodeBlockType.CATCH) { + this.pushStmt(new SourceCatchStmt(this, this.lastStmt, block)); + // catch need read block first stmt, using return to void walk block twice. + return; + } else if (type === CodeBlockType.FINALLY) { + this.pushStmt(new SourceFinallyStmt(this, this.lastStmt)); + } + + if (!block) { + return; + } + + let originalStmts: Stmt[] = this.sortStmt(block.getStmts()); + this.stmtReader = new StmtReader(originalStmts); + while (this.stmtReader.hasNext()) { + let stmt = this.stmtReader.next(); + if (this.skipStmts.has(stmt)) { + continue; + } + if (stmt instanceof ArkIfStmt) { + if (type === CodeBlockType.IF) { + this.pushStmt(new SourceIfStmt(this, stmt)); + } else if (type === CodeBlockType.WHILE) { + this.pushStmt(new SourceWhileStmt(this, stmt, block)); + } else if (type === CodeBlockType.FOR) { + let inc = this.cfgUtils.getForIncBlock(block)!; + this.pushStmt(new SourceForStmt(this, stmt, block, inc)); + } else if (type === CodeBlockType.DO_WHILE) { + this.pushStmt(new SourceDoWhileStmt(this, stmt, block)); + } + } else { + this.pushStmt(stmt2SourceStmt(this, stmt)); + } + this.lastStmt = stmt; + } + } + + private printStmts(): void { + for (let stmt of this.stmts) { + if (this.skipStmts.has(stmt.original)) { + continue; + } + this.printer.write(stmt.dump()); + } + } + + public getStmts(): SourceStmt[] { + return this.stmts.filter(value => !this.skipStmts.has(value.original)); + } + + public pushStmt(stmt: SourceStmt): void { + let lastLine = this.getLastLine(); + if (stmt.getLine() < lastLine) { + stmt.setLine(lastLine + 0.1); + } + stmt.transfer2ts(); + this.stmts.push(stmt); + } + + private getLastLine(): number { + if (this.stmts.length > 0) { + return this.stmts[this.stmts.length - 1].getLine(); + } + + return 0; + } + + /* + * temp9 = new <>.<>(); temp10 = new Array(3); + * temp10 = new Array(3); temp10[0] = 'Cat'; + * temp10[0] = 'Cat'; ==> temp10[1] = 'Dog'; + * temp10[1] = 'Dog'; temp10[2] = 'Hamster'; + * temp10[2] = 'Hamster'; temp9 = new <>.<>(); + * temp9.constructor(temp10); temp9.constructor(temp10); + */ + private sortStmt(stmts: Stmt[]): Stmt[] { + for (let i = stmts.length - 1; i > 0; i--) { + if (stmts[i] instanceof ArkInvokeStmt && (stmts[i].getInvokeExpr() as ArkInstanceInvokeExpr)) { + let instanceInvokeExpr = stmts[i].getInvokeExpr() as ArkInstanceInvokeExpr; + if ('constructor' !== instanceInvokeExpr.getMethodSignature().getMethodSubSignature().getMethodName()) { + continue; + } + let localName = instanceInvokeExpr.getBase().getName(); + let newExprIdx = findNewExpr(i, localName); + if (newExprIdx >= 0 && newExprIdx < i - 1) { + moveStmt(i, newExprIdx); + } + } + } + return stmts; + + function findNewExpr(constructorIdx: number, name: string): number { + for (let j = constructorIdx - 1; j >= 0; j--) { + if (!(stmts[j] instanceof ArkAssignStmt)) { + continue; + } + const leftOp = (stmts[j] as ArkAssignStmt).getLeftOp(); + if (leftOp instanceof Local && leftOp.getName() === name) { + return j; + } + } + return -1; + } + + function moveStmt(constructorIdx: number, newExprIdx: number): void { + let back = stmts[newExprIdx]; + for (let i = newExprIdx; i < constructorIdx - 1; i++) { + stmts[i] = stmts[i + 1]; + } + stmts[constructorIdx - 1] = back; + } + } +} + +export class StmtReader { + private stmts: Stmt[] = []; + private pos: number; + + constructor(stmts: Stmt[]) { + this.stmts = stmts; + this.pos = 0; + } + + first(): Stmt { + return this.stmts[0]; + } + + hasNext(): boolean { + return this.pos < this.stmts.length; + } + + next(): Stmt { + if (!this.hasNext()) { + logger.error('SourceBody: StmtReader->next No more stmt.'); + throw new Error('No more stmt.'); + } + let stmt = this.stmts[this.pos]; + this.pos++; + return stmt; + } + + rollback(): void { + if (this.pos === 0) { + logger.error('SourceBody: StmtReader->rollback No more stmt to rollback.'); + throw new Error('No more stmt to rollback.'); + } + this.pos--; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceClass.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceClass.ts new file mode 100644 index 0000000000000000000000000000000000000000..99e3d05b88d34fec9a0681377077d113fe0fa28f --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceClass.ts @@ -0,0 +1,211 @@ +/* + * 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. + */ + +import { ArkClass, ClassCategory } from '../../core/model/ArkClass'; +import { SourceBase } from './SourceBase'; +import { SourceBody } from './SourceBody'; +import { SourceField } from './SourceField'; +import { SourceMethod } from './SourceMethod'; +import { SourceTransformer } from './SourceTransformer'; +import { PrinterUtils } from '../base/PrinterUtils'; +import { INSTANCE_INIT_METHOD_NAME, STATIC_INIT_METHOD_NAME } from '../../core/common/Const'; +import { ArkNamespace } from '../../core/model/ArkNamespace'; +import { FieldCategory } from '../../core/model/ArkField'; +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { Dump } from '../base/BasePrinter'; + +/** + * @category save + */ +export class SourceClass extends SourceBase { + protected cls: ArkClass; + private transformer: SourceTransformer; + + public constructor(cls: ArkClass, indent: string = '') { + super(cls.getDeclaringArkFile(), indent); + this.cls = cls; + this.transformer = new SourceTransformer(this); + } + + public getDeclaringArkNamespace(): ArkNamespace | undefined { + return this.cls.getDeclaringArkNamespace(); + } + + public getLine(): number { + return this.cls.getLine(); + } + + public dump(): string { + this.printer.clear(); + + if (this.cls.getCategory() === ClassCategory.OBJECT) { + return this.dumpObject(); + } + + if (this.cls.getCategory() === ClassCategory.TYPE_LITERAL) { + return this.dumpTypeLiteral(); + } + + const commentsMetadata = this.cls.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + const comments = commentsMetadata.getComments(); + comments.forEach(comment => { + this.printer.writeIndent().writeLine(comment.content); + }); + } + + this.printDecorator(this.cls.getDecorators()); + // print export class name<> + extends c0 implements x1, x2 { + this.printer + .writeIndent() + .writeSpace(this.modifiersToString(this.cls.getModifiers())) + .write(`${this.classOriginTypeToString(this.cls.getCategory())} `); + + if (!PrinterUtils.isAnonymousClass(this.cls.getName())) { + this.printer.write(this.cls.getName()); + } + const genericsTypes = this.cls.getGenericsTypes(); + if (genericsTypes) { + this.printer.write(`<${this.transformer.typeArrayToString(genericsTypes)}>`); + } + if (this.cls.getSuperClassName() && !this.cls.hasComponentDecorator()) { + this.printer.write(` extends ${this.cls.getSuperClassName()}`); + } + if (this.cls.getImplementedInterfaceNames().length > 0) { + this.printer.write(` implements ${this.cls.getImplementedInterfaceNames().join(', ')}`); + } + + this.printer.writeLine(' {'); + this.printer.incIndent(); + let items: Dump[] = []; + + items.push(...this.printFields()); + items.push(...this.printMethods()); + + items.sort((a, b) => a.getLine() - b.getLine()); + items.forEach((v): void => { + this.printer.write(v.dump()); + }); + + this.printer.decIndent(); + this.printer.writeIndent().write('}'); + if (!PrinterUtils.isAnonymousClass(this.cls.getName())) { + this.printer.writeLine(''); + } + return this.printer.toString(); + } + + private dumpObject(): string { + this.printer.write('{'); + + this.cls.getFields().forEach((field, index, array) => { + let name = PrinterUtils.escape(field.getName()); + if (PrinterUtils.isIdentifierText(field.getName())) { + this.printer.write(name); + } else { + this.printer.write(`'${name}'`); + } + + let instanceInitializer = this.parseFieldInitMethod(INSTANCE_INIT_METHOD_NAME); + if (instanceInitializer.has(field.getName())) { + this.printer.write(`: ${instanceInitializer.get(field.getName())}`); + } + + if (index !== array.length - 1) { + this.printer.write(`, `); + } + }); + this.printer.write('}'); + return this.printer.toString(); + } + + private dumpTypeLiteral(): string { + this.printer.write('{'); + + this.cls.getFields().forEach((field, index, array) => { + let name = PrinterUtils.escape(field.getName()); + if (PrinterUtils.isIdentifierText(field.getName())) { + this.printer.write(`${name}: ${this.transformer.typeToString(field.getType())}`); + } else { + this.printer.write(`'${name}': ${this.transformer.typeToString(field.getType())}`); + } + + if (index !== array.length - 1) { + this.printer.write(`, `); + } + }); + this.printer.write('}'); + return this.printer.toString(); + } + + protected printMethods(): Dump[] { + let items: Dump[] = []; + for (let method of this.cls.getMethods()) { + if (method.isGenerated() || (PrinterUtils.isConstructorMethod(method.getName()) && this.cls.hasViewTree())) { + continue; + } + + if (method.isDefaultArkMethod()) { + items.push(...new SourceMethod(method, this.printer.getIndent()).dumpDefaultMethod()); + } else if (!PrinterUtils.isAnonymousMethod(method.getName())) { + items.push(new SourceMethod(method, this.printer.getIndent())); + } + } + return items; + } + + private printFields(): Dump[] { + let instanceInitializer = this.parseFieldInitMethod(INSTANCE_INIT_METHOD_NAME); + let staticInitializer = this.parseFieldInitMethod(STATIC_INIT_METHOD_NAME); + let items: Dump[] = []; + for (let field of this.cls.getFields()) { + if (field.getCategory() === FieldCategory.GET_ACCESSOR) { + continue; + } + if (field.isStatic()) { + items.push(new SourceField(field, this.printer.getIndent(), staticInitializer)); + } else { + items.push(new SourceField(field, this.printer.getIndent(), instanceInitializer)); + } + } + return items; + } + + private parseFieldInitMethod(name: string): Map { + let method = this.cls.getMethodWithName(name); + if (!method || method?.getBody() === undefined) { + return new Map(); + } + + let srcBody = new SourceBody(this.printer.getIndent(), method, false); + srcBody.dump(); + return srcBody.getTempCodeMap(); + } +} + +export class SourceDefaultClass extends SourceClass { + public constructor(cls: ArkClass, indent: string = '') { + super(cls, indent); + } + + public getLine(): number { + return this.cls.getLine(); + } + + public dump(): string { + this.printMethods(); + return this.printer.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceField.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceField.ts new file mode 100644 index 0000000000000000000000000000000000000000..41b24a99426ec4feca8e18815affad79046377a6 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceField.ts @@ -0,0 +1,80 @@ +/* + * 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. + */ + +import { ArkField, FieldCategory } from '../../core/model/ArkField'; +import { SourceBase } from './SourceBase'; +import { SourceTransformer } from './SourceTransformer'; +import { UnknownType } from '../../core/base/Type'; +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; + +/** + * @category save + */ +export class SourceField extends SourceBase { + private field: ArkField; + private transformer: SourceTransformer; + private initializer: Map; + + public constructor(field: ArkField, indent: string = '', initializer: Map) { + super(field.getDeclaringArkClass().getDeclaringArkFile(), indent); + this.field = field; + this.transformer = new SourceTransformer(this); + this.initializer = initializer; + } + + public getLine(): number { + return this.field.getOriginPosition().getLineNo(); + } + public dump(): string { + this.printer.clear(); + const commentsMetadata = this.field.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + const comments = commentsMetadata.getComments(); + comments.forEach(comment => { + this.printer.writeIndent().writeLine(comment.content); + }); + } + this.printDecorator(this.field.getDecorators()); + this.printer.writeIndent(); + if (this.field.getCategory() !== FieldCategory.ENUM_MEMBER) { + this.printer.writeSpace(this.modifiersToString(this.field.getModifiers())); + } + + this.printer.write(this.field.getName()); + + if (this.field.getQuestionToken()) { + this.printer.write('?'); + } + if (this.field.getExclamationToken()) { + this.printer.write('!'); + } + + // property.getInitializer() PropertyAccessExpression ArrowFunction ClassExpression FirstLiteralToken StringLiteral + if (!(this.field.getType() instanceof UnknownType) && this.field.getCategory() !== FieldCategory.ENUM_MEMBER) { + this.printer.write(`: ${this.transformer.typeToString(this.field.getType())}`); + } + + if (this.initializer.has(this.field.getName())) { + this.printer.write(` = ${this.initializer.get(this.field.getName())}`); + } + + if (this.field.getCategory() === FieldCategory.ENUM_MEMBER) { + this.printer.writeLine(','); + } else { + this.printer.writeLine(';'); + } + return this.printer.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceFilePrinter.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceFilePrinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..c34fac39d2970fbb7f239108e965538c84ecd624 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceFilePrinter.ts @@ -0,0 +1,98 @@ +/* + * 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. + */ + +/* + * TODO: + * + * 1. Method parameter: + * a) default value 不支持 + * source: move(distanceInMeters = 5) + * parsed: move(distanceInMeters) + * c) string[] 类型解析为 ArrayType,无法还原 + * d) 构造函数Access Modifiers 不支持 + * constructor(public make: string, public model: string) { + * } + * + * 2. 泛型 + * a) field泛型<>类型丢失 + * class GenericNumber { + * private methods: Set; + * private calls: Map; + * } + */ +import { ArkFile } from '../../core/model/ArkFile'; +import { Dump } from '../base/BasePrinter'; +import { SourceClass } from './SourceClass'; +import { SourceMethod } from './SourceMethod'; +import { SourceNamespace } from './SourceNamespace'; +import { PrinterUtils } from '../base/PrinterUtils'; +import { printImports } from '../base/ImportPrinter'; +import { ExportPrinter } from '../base/ExportPrinter'; +import { Printer } from '../Printer'; +import { ArkClass } from '../../core/model/ArkClass'; + +/** + * @category save + */ +export class SourceFilePrinter extends Printer { + arkFile: ArkFile; + items: Dump[] = []; + + constructor(arkFile: ArkFile) { + super(); + this.arkFile = arkFile; + } + + private printDefaultClassInFile(cls: ArkClass): void { + for (let method of cls.getMethods()) { + if (method.isDefaultArkMethod()) { + this.items.push(...new SourceMethod(method, this.printer.getIndent()).dumpDefaultMethod()); + } else if (!PrinterUtils.isAnonymousMethod(method.getName())) { + this.items.push(new SourceMethod(method)); + } + } + } + + public dump(): string { + this.printer.clear(); + // print imports + this.items.push(...printImports(this.arkFile.getImportInfos(), this.printer.getIndent())); + + // print namespace + for (let ns of this.arkFile.getNamespaces()) { + this.items.push(new SourceNamespace(ns)); + } + + // print class + for (let cls of this.arkFile.getClasses()) { + if (cls.isDefaultArkClass()) { + this.printDefaultClassInFile(cls); + } else if (!PrinterUtils.isAnonymousClass(cls.getName())) { + this.items.push(new SourceClass(cls)); + } + } + // print export + for (let info of this.arkFile.getExportInfos()) { + this.items.push(new ExportPrinter(info)); + } + + this.items.sort((a, b) => a.getLine() - b.getLine()); + this.items.forEach((v): void => { + this.printer.write(v.dump()); + }); + + return this.printer.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceMethod.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceMethod.ts new file mode 100644 index 0000000000000000000000000000000000000000..3fff56c0d2316a07513fc87fc8571c6074fcfe28 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceMethod.ts @@ -0,0 +1,223 @@ +/* + * 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. + */ + +import { UnknownType } from '../../core/base/Type'; +import { ArkMethod } from '../../core/model/ArkMethod'; +import { ArkCodeBuffer } from '../ArkStream'; +import { SourceBase } from './SourceBase'; +import { SourceBody } from './SourceBody'; +import { SourceStmt } from './SourceStmt'; +import { SourceTransformer } from './SourceTransformer'; +import { PrinterUtils } from '../base/PrinterUtils'; +import { Stmt } from '../../core/base/Stmt'; +import { ArkNamespace } from '../../core/model/ArkNamespace'; +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { getLineNo } from '../../core/base/Position'; +import { MethodSignature } from '../../core/model/ArkSignature'; +import { LEXICAL_ENV_NAME_PREFIX } from '../../core/common/Const'; + +/** + * @category save + */ +export class SourceMethod extends SourceBase { + private method: ArkMethod; + private transformer: SourceTransformer; + + public constructor(method: ArkMethod, indent: string = '') { + super(method.getDeclaringArkFile(), indent); + this.method = method; + this.transformer = new SourceTransformer(this); + this.inBuilder = this.initInBuilder(); + } + + public getDeclaringArkNamespace(): ArkNamespace | undefined { + return this.method.getDeclaringArkClass().getDeclaringArkNamespace(); + } + + public setInBuilder(inBuilder: boolean): void { + this.inBuilder = inBuilder; + } + + public dump(): string { + this.printer.clear(); + const commentsMetadata = this.method.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + const comments = commentsMetadata.getComments(); + comments.forEach(comment => { + this.printer.writeIndent().writeLine(comment.content); + }); + } + if (!this.method.isDefaultArkMethod()) { + this.printMethod(this.method); + } else { + this.printBody(this.method); + } + return this.printer.toString(); + } + + public getLine(): number { + let line = this.method.getLine(); + if (line === null && this.method.getDeclareLineCols()) { + line = getLineNo(this.method.getDeclareLineCols()![0]); + } + if (line === null) { + line = 0; + } + if (line > 0) { + return line; + } + + const stmts: Stmt[] = []; + const cfg = this.method.getCfg(); + if (cfg) { + cfg.getStmts() + .reverse() + .forEach(stmt => stmts.push(stmt)); + } + for (const stmt of stmts) { + if (stmt.getOriginPositionInfo().getLineNo() > 0) { + return stmt.getOriginPositionInfo().getLineNo(); + } + } + + return line; + } + + public dumpDefaultMethod(): SourceStmt[] { + let srcBody = new SourceBody(this.printer.getIndent(), this.method, false); + return srcBody.getStmts(); + } + + private printMethod(method: ArkMethod): void { + this.printDecorator(method.getDecorators()); + + let implementationSig = method.getImplementationSignature(); + + if (this.method.getDeclareSignatures()) { + for (const methodSig of this.method.getDeclareSignatures()!) { + this.printer.writeIndent().writeLine(`${this.methodProtoToString(methodSig)};`); + } + } + + if (!implementationSig) { + return; + } + + this.printer.writeIndent().write(this.methodProtoToString(implementationSig!)); + + // abstract function no body + if (SourceMethod.getPrinterOptions().noMethodBody) { + this.printer.writeIndent().writeLine(`;`); + return; + } + + this.printer.writeLine(' {'); + this.printer.incIndent(); + this.printBody(method); + this.printer.decIndent(); + + this.printer.writeIndent(); + if (PrinterUtils.isAnonymousMethod(method.getName())) { + this.printer.write('}'); + } else { + this.printer.writeLine('}'); + } + } + + private printBody(method: ArkMethod): void { + let srcBody = new SourceBody(this.printer.getIndent(), method, this.inBuilder); + this.printer.write(srcBody.dump()); + } + + private methodProtoToString(methodSig: MethodSignature): string { + let code = new ArkCodeBuffer(); + code.writeSpace(this.modifiersToString(this.method.getModifiers())); + if (!PrinterUtils.isAnonymousMethod(methodSig.getMethodSubSignature().getMethodName())) { + if (this.method.getDeclaringArkClass()?.isDefaultArkClass()) { + code.writeSpace('function'); + } + if (this.method.getAsteriskToken()) { + code.writeSpace('*'); + } + code.write(this.resolveMethodName(methodSig.getMethodSubSignature().getMethodName())); + } + + const genericTypes = this.method.getGenericTypes(); + if (genericTypes && genericTypes.length > 0) { + code.write(`<${this.transformer.typeArrayToString(genericTypes)}>`); + } + + let parameters: string[] = []; + methodSig + .getMethodSubSignature() + .getParameters() + .forEach(parameter => { + let str: string = parameter.getName(); + if (parameter.hasDotDotDotToken()) { + str = `...${parameter.getName()}`; + } + if (parameter.isOptional()) { + str += '?'; + } + if (parameter.getType()) { + str += ': ' + this.transformer.typeToString(parameter.getType()); + } + if (!str.startsWith(LEXICAL_ENV_NAME_PREFIX)) { + parameters.push(str); + } + }); + code.write(`(${parameters.join(', ')})`); + const returnType = methodSig.getMethodSubSignature().getReturnType(); + if (methodSig.getMethodSubSignature().getMethodName() !== 'constructor' && !(returnType instanceof UnknownType)) { + code.write(`: ${this.transformer.typeToString(returnType)}`); + } + if (PrinterUtils.isAnonymousMethod(methodSig.getMethodSubSignature().getMethodName())) { + code.write(' =>'); + } + return code.toString(); + } + + public toArrowFunctionTypeString(): string { + let code = new ArkCodeBuffer(); + + let parameters: string[] = []; + this.method.getParameters().forEach(parameter => { + let str: string = parameter.getName(); + if (parameter.isOptional()) { + str += '?'; + } + if (parameter.getType()) { + str += ': ' + this.transformer.typeToString(parameter.getType()); + } + parameters.push(str); + }); + code.write(`(${parameters.join(', ')}) => `); + const returnType = this.method.getReturnType(); + if (!(returnType instanceof UnknownType)) { + code.writeSpace(`${this.transformer.typeToString(returnType)}`); + } + + return code.toString(); + } + + private initInBuilder(): boolean { + return ( + this.method.hasBuilderDecorator() || + ((this.method.getName() === 'build' || this.method.getName() === 'pageTransition') && + !this.method.isStatic() && + this.method.getDeclaringArkClass().hasViewTree()) + ); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceNamespace.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceNamespace.ts new file mode 100644 index 0000000000000000000000000000000000000000..4bbaaedc4b9e6687facb7f8d4c56d0e12d6697fb --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceNamespace.ts @@ -0,0 +1,91 @@ +/* + * 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. + */ + +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { ArkNamespace } from '../../core/model/ArkNamespace'; +import { SourceBase } from './SourceBase'; +import { SourceClass } from './SourceClass'; +import { SourceMethod } from './SourceMethod'; +import { PrinterUtils } from '../base/PrinterUtils'; +import { Dump } from '../base/BasePrinter'; +import { ExportPrinter } from '../base/ExportPrinter'; +import { ArkClass } from '../../core/model/ArkClass'; + +/** + * @category save + */ +export class SourceNamespace extends SourceBase { + ns: ArkNamespace; + + public constructor(ns: ArkNamespace, indent: string = '') { + super(ns.getDeclaringArkFile(), indent); + this.ns = ns; + } + + public getLine(): number { + return this.ns.getLine(); + } + + private printDefaultClassInNamespace(items: Dump[], cls: ArkClass): void { + for (let method of cls.getMethods()) { + if (method.isDefaultArkMethod()) { + items.push(...new SourceMethod(method, this.printer.getIndent()).dumpDefaultMethod()); + } else if (!PrinterUtils.isAnonymousMethod(method.getName())) { + items.push(new SourceMethod(method, this.printer.getIndent())); + } + } + } + + public dump(): string { + const commentsMetadata = this.ns.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + const comments = commentsMetadata.getComments(); + comments.forEach(comment => { + this.printer.writeIndent().writeLine(comment.content); + }); + } + this.printer.writeIndent().writeSpace(this.modifiersToString(this.ns.getModifiers())).writeLine(`namespace ${this.ns.getName()} {`); + this.printer.incIndent(); + + let items: Dump[] = []; + // print class + for (let cls of this.ns.getClasses()) { + if (PrinterUtils.isAnonymousClass(cls.getName())) { + continue; + } + if (cls.isDefaultArkClass()) { + this.printDefaultClassInNamespace(items, cls); + } else { + items.push(new SourceClass(cls, this.printer.getIndent())); + } + } + // print namespace + for (let childNs of this.ns.getNamespaces()) { + items.push(new SourceNamespace(childNs, this.printer.getIndent())); + } + // print exportInfos + for (let exportInfo of this.ns.getExportInfos()) { + items.push(new ExportPrinter(exportInfo, this.printer.getIndent())); + } + + items.sort((a, b) => a.getLine() - b.getLine()); + items.forEach((v): void => { + this.printer.write(v.dump()); + }); + this.printer.decIndent(); + this.printer.writeIndent().writeLine('}'); + return this.printer.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceStmt.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceStmt.ts new file mode 100644 index 0000000000000000000000000000000000000000..6f73ec3dc85405df20be70e1a3dd71bed1852d16 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceStmt.ts @@ -0,0 +1,942 @@ +/* + * 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. + */ + +import { Constant } from '../../core/base/Constant'; +import { ArkInstanceInvokeExpr, ArkNewArrayExpr, ArkNewExpr, ArkStaticInvokeExpr, NormalBinaryOperator } from '../../core/base/Expr'; +import { Local } from '../../core/base/Local'; +import { ArkArrayRef, ArkInstanceFieldRef, ArkParameterRef, ArkStaticFieldRef, ClosureFieldRef } from '../../core/base/Ref'; +import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkReturnVoidStmt, ArkThrowStmt, Stmt } from '../../core/base/Stmt'; +import { AliasType, ClassType, Type } from '../../core/base/Type'; +import { Value } from '../../core/base/Value'; +import { BasicBlock } from '../../core/graph/BasicBlock'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { ArkCodeBuffer } from '../ArkStream'; +import { StmtReader } from './SourceBody'; +import { SourceTransformer, TransformerContext } from './SourceTransformer'; +import { CLASS_CATEGORY_COMPONENT, PrinterUtils } from '../base/PrinterUtils'; +import { ValueUtil } from '../../core/common/ValueUtil'; +import { ArkClass, ClassCategory } from '../../core/model/ArkClass'; +import { modifiers2stringArray } from '../../core/model/ArkBaseModel'; +import { ArkMetadataKind, CommentsMetadata } from '../../core/model/ArkMetadata'; +import { ImportInfo } from '../../core/model/ArkImport'; +import { ArkMethod } from '../../core/model/ArkMethod'; +import { Dump } from '../base/BasePrinter'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'SourceStmt'); +const IGNOR_TYPES = new Set(['any', 'Map', 'Set']); + +export interface StmtPrinterContext extends TransformerContext { + getStmtReader(): StmtReader; + + setTempCode(temp: string, code: string): void; + + hasTempVisit(temp: string): boolean; + + setTempVisit(temp: string): void; + + setSkipStmt(stmt: Stmt): void; + + getLocals(): Map; + + defineLocal(local: Local): void; + + isLocalDefined(local: Local): boolean; + + isInDefaultMethod(): boolean; +} + +export abstract class SourceStmt implements Dump { + original: Stmt; + context: StmtPrinterContext; + line: number; + text: string = ''; + transformer: SourceTransformer; + + constructor(context: StmtPrinterContext, original: Stmt) { + this.original = original; + this.context = context; + this.line = original.getOriginPositionInfo().getLineNo(); + this.transformer = new SourceTransformer(context); + } + + public getLine(): number { + return this.line; + } + + public setLine(line: number): void { + this.line = line; + } + + public dump(): string { + this.beforeDump(); + let code = this.dumpTs(); + this.afterDump(); + return code; + } + + protected beforeDump(): void {} + + protected afterDump(): void {} + + protected dumpTs(): string { + let content: string[] = []; + const commentsMetadata = this.original.getMetadata(ArkMetadataKind.LEADING_COMMENTS); + if (commentsMetadata instanceof CommentsMetadata) { + const comments = commentsMetadata.getComments(); + comments.forEach(comment => { + content.push(`${this.printer.getIndent()}${comment.content}\n`); + }); + } + if (this.text.length > 0) { + content.push(`${this.printer.getIndent()}${this.text}\n`); + } + return content.join(''); + } + + protected get printer(): ArkCodeBuffer { + return this.context.getPrinter(); + } + + public toString(): string { + return this.text; + } + + protected setText(text: string): void { + this.text = text; + } + + protected getIntent(): string { + return this.context.getPrinter().getIndent(); + } + + public abstract transfer2ts(): void; + + protected isLocalTempValue(value: Value): boolean { + if (!(value instanceof Local)) { + return false; + } + + return PrinterUtils.isTemp(value.getName()); + } +} + +enum AssignStmtDumpType { + NORMAL, + TEMP_REPLACE, + COMPONENT_CREATE, +} + +export class SourceAssignStmt extends SourceStmt { + private leftOp: Value = ValueUtil.getUndefinedConst(); + private rightOp: Value = ValueUtil.getUndefinedConst(); + private leftCode: string = ''; + private rightCode: string = ''; + private dumpType?: AssignStmtDumpType; + private leftTypeCode: string; + + constructor(context: StmtPrinterContext, original: ArkAssignStmt) { + super(context, original); + this.leftTypeCode = ''; + } + + public transfer2ts(): void { + this.leftOp = (this.original as ArkAssignStmt).getLeftOp(); + this.rightOp = (this.original as ArkAssignStmt).getRightOp(); + + if ( + (this.leftOp instanceof Local && this.leftOp.getName() === 'this') || + (this.rightOp instanceof Constant && this.rightOp.getValue() === 'undefined') || + this.rightOp instanceof ArkParameterRef || + this.rightOp instanceof ClosureFieldRef + ) { + this.setText(''); + this.dumpType = AssignStmtDumpType.NORMAL; + return; + } + + this.leftCode = this.transformer.valueToString(this.leftOp); + + if (this.leftOp instanceof Local && this.rightOp instanceof ArkNewExpr) { + this.transferRightNewExpr(); + } else if (this.leftOp instanceof Local && this.rightOp instanceof ArkNewArrayExpr) { + this.transferRightNewArrayExpr(); + } else if (this.rightOp instanceof ArkStaticInvokeExpr && PrinterUtils.isComponentCreate(this.rightOp)) { + this.transferRightComponentCreate(); + } else if (this.rightOp instanceof ArkInstanceInvokeExpr && PrinterUtils.isComponentAttributeInvoke(this.rightOp)) { + this.transferRightComponentAttribute(); + } else { + this.rightCode = this.transformer.valueToString(this.rightOp); + } + + if (this.isLocalTempValue(this.leftOp)) { + this.context.setTempCode((this.leftOp as Local).getName(), this.rightCode); + } + + if ((this.leftOp instanceof ArkInstanceFieldRef && this.leftOp.getBase().getName() === 'this') || this.leftOp instanceof ArkStaticFieldRef) { + this.context.setTempCode(this.leftOp.getFieldName(), this.rightCode); + } + + if (this.dumpType === undefined) { + this.setText(`${this.leftCode} = ${this.rightCode}`); + this.dumpType = AssignStmtDumpType.TEMP_REPLACE; + } + + let leftOpType = this.leftOp.getType(); + if (leftOpType instanceof ClassType) { + let name = leftOpType.getClassSignature().getClassName(); + if (PrinterUtils.isAnonymousClass(name)) { + this.leftTypeCode = 'any'; + } else { + this.leftTypeCode = name; + } + } else { + this.leftTypeCode = this.transformer.typeToString(leftOpType); + } + if (IGNOR_TYPES.has(this.leftTypeCode)) { + this.leftTypeCode = ''; + } + } + + protected beforeDump(): void { + if (this.dumpType !== AssignStmtDumpType.TEMP_REPLACE) { + return; + } + + if (this.context.hasTempVisit(this.leftCode)) { + this.setText(''); + return; + } else if (PrinterUtils.isTemp(this.leftCode)) { + this.setText(`${this.rightCode};`); + return; + } + if (this.leftOp instanceof Local && this.context.getLocals().has(this.leftOp.getName()) && !this.isLocalTempValue(this.leftOp)) { + if (this.context.isLocalDefined(this.leftOp)) { + this.setText(`${this.leftCode} = ${this.rightCode};`); + return; + } + let flag = this.leftOp.getConstFlag() ? 'const' : 'let'; + if (this.context.getArkFile().getExportInfoBy(this.leftCode) && this.context.isInDefaultMethod()) { + this.setText(`export ${flag} ${this.leftCode} = ${this.rightCode};`); + } else { + if (this.leftTypeCode.length > 0) { + this.setText(`${flag} ${this.leftCode}: ${this.leftTypeCode} = ${this.rightCode};`); + } else { + this.setText(`${flag} ${this.leftCode} = ${this.rightCode};`); + } + } + this.context.defineLocal(this.leftOp); + } else { + this.setText(`${this.leftCode} = ${this.rightCode};`); + } + } + + protected afterDump(): void { + if (this.dumpType === AssignStmtDumpType.COMPONENT_CREATE) { + this.printer.incIndent(); + } + } + + private getClassOriginType(type: Type): number | undefined { + if (!(type instanceof ClassType)) { + return undefined; + } + + let signature = type.getClassSignature(); + let cls = this.context.getClass(signature); + if (!cls) { + return undefined; + } + return PrinterUtils.getOriginType(cls); + } + + /** + * temp1 = new Person + * temp1.constructor(10) + */ + private transferRightNewExpr(): void { + let originType = this.getClassOriginType(this.rightOp.getType()); + if (this.context.getStmtReader().hasNext()) { + let stmt = this.context.getStmtReader().next(); + let rollback = true; + if (stmt instanceof ArkInvokeStmt && (stmt.getInvokeExpr() as ArkInstanceInvokeExpr)) { + let instanceInvokeExpr = stmt.getInvokeExpr() as ArkInstanceInvokeExpr; + if ( + 'constructor' === instanceInvokeExpr.getMethodSignature().getMethodSubSignature().getMethodName() && + instanceInvokeExpr.getBase().getName() === (this.leftOp as Local).getName() + ) { + this.handleConstructorInvoke(instanceInvokeExpr, originType); + return; + } + } + if (rollback) { + this.context.getStmtReader().rollback(); + } + } + + if (originType === CLASS_CATEGORY_COMPONENT) { + this.rightCode = `${this.transformer.typeToString(this.rightOp.getType())}()`; + } else if (originType === ClassCategory.TYPE_LITERAL || originType === ClassCategory.OBJECT) { + this.rightCode = `${this.transformer.typeToString(this.rightOp.getType())}`; + } else { + this.rightCode = `new ${this.transformer.typeToString(this.rightOp.getType())}()`; + } + } + + private handleConstructorInvoke(instanceInvokeExpr: ArkInstanceInvokeExpr, originType?: number): void { + let args: string[] = []; + instanceInvokeExpr.getArgs().forEach(v => { + args.push(this.transformer.valueToString(v)); + }); + + if (originType === CLASS_CATEGORY_COMPONENT) { + this.rightCode = `${this.transformer.typeToString(this.rightOp.getType())}(${args.join(', ')})`; + } else if (originType === ClassCategory.TYPE_LITERAL || originType === ClassCategory.OBJECT) { + this.rightCode = `${this.transformer.literalObjectToString(this.rightOp.getType() as ClassType)}`; + } else { + this.rightCode = `new ${this.transformer.typeToString(this.rightOp.getType())}(${args.join(', ')})`; + } + } + + /** + * $temp0 = newarray[4] + * $temp0[0] = 1 + * $temp0[1] = 2 + * $temp0[2] = 3 + */ + private transferRightNewArrayExpr(): void { + let arrayExpr = new SourceNewArrayExpr(this.rightOp as ArkNewArrayExpr); + let localName = (this.leftOp as Local).getName(); + while (this.context.getStmtReader().hasNext()) { + let stmt = this.context.getStmtReader().next(); + if (stmt instanceof ArkAssignStmt) { + let left = stmt.getLeftOp(); + if (left instanceof ArkArrayRef && left.getBase().getName() === localName) { + arrayExpr.addInitValue(this.transformer.valueToString(stmt.getRightOp())); + } else { + this.context.getStmtReader().rollback(); + break; + } + } else { + this.context.getStmtReader().rollback(); + break; + } + } + this.rightCode = arrayExpr.toString(); + } + + private transferRightComponentCreate(): void { + this.rightCode = this.transformer.valueToString(this.rightOp); + if (this.context.getStmtReader().hasNext()) { + let stmt = this.context.getStmtReader().next(); + if (stmt instanceof ArkInvokeStmt) { + let expr = stmt.getInvokeExpr(); + if (expr instanceof ArkStaticInvokeExpr && PrinterUtils.isComponentPop(expr)) { + this.setText(`${this.rightCode}`); + this.dumpType = AssignStmtDumpType.NORMAL; + return; + } + } + + this.context.getStmtReader().rollback(); + } + this.setText(`${this.rightCode} {`); + this.dumpType = AssignStmtDumpType.COMPONENT_CREATE; + } + + private transferRightComponentAttribute(): void { + this.rightCode = this.transformer.valueToString(this.rightOp); + this.setText(`${this.rightCode}`); + this.dumpType = AssignStmtDumpType.NORMAL; + } +} + +export class SourceInvokeStmt extends SourceStmt { + constructor(context: StmtPrinterContext, original: ArkInvokeStmt) { + super(context, original); + } + + public transfer2ts(): void { + let invokeExpr = this.original.getInvokeExpr(); + let code = ''; + let isAttr = false; + if (invokeExpr instanceof ArkStaticInvokeExpr) { + if (PrinterUtils.isComponentPop(invokeExpr)) { + code = '}'; + isAttr = true; + } else { + code = this.transformer.staticInvokeExprToString(invokeExpr); + isAttr = PrinterUtils.isComponentIfElseInvoke(invokeExpr); + } + } else if (invokeExpr instanceof ArkInstanceInvokeExpr) { + code = this.transformer.instanceInvokeExprToString(invokeExpr); + isAttr = PrinterUtils.isComponentAttributeInvoke(invokeExpr); + } + + if (code.length > 0 && !isAttr) { + this.setText(`${code};`); + } else { + this.setText(`${code}`); + } + } + + protected beforeDump(): void { + let invokeExpr = this.original.getInvokeExpr(); + if ( + (invokeExpr instanceof ArkStaticInvokeExpr && PrinterUtils.isComponentPop(invokeExpr)) || + (invokeExpr instanceof ArkStaticInvokeExpr && PrinterUtils.isComponentIfElseInvoke(invokeExpr)) + ) { + this.printer.decIndent(); + return; + } + } + + protected afterDump(): void { + let invokeExpr = this.original.getInvokeExpr(); + if (invokeExpr instanceof ArkStaticInvokeExpr && PrinterUtils.isComponentIfElseInvoke(invokeExpr)) { + this.printer.incIndent(); + return; + } + } +} + +export class SourceIfStmt extends SourceStmt { + constructor(context: StmtPrinterContext, original: ArkIfStmt) { + super(context, original); + } + + public transfer2ts(): void { + let code: string; + let expr = (this.original as ArkIfStmt).getConditionExpr(); + code = `if (${this.transformer.valueToString(expr.getOp1())}`; + code += ` ${expr.getOperator()} `; + code += `${this.transformer.valueToString(expr.getOp2())}) {`; + this.setText(code); + } + + protected afterDump(): void { + this.printer.incIndent(); + } +} + +export class SourceWhileStmt extends SourceStmt { + block: BasicBlock; + + constructor(context: StmtPrinterContext, original: ArkIfStmt, block: BasicBlock) { + super(context, original); + this.block = block; + } + + protected afterDump(): void { + this.printer.incIndent(); + } + + /** + * $temp2 = $temp1.next() + * $temp3 = $temp2.done() + * if $temp3 === true + * $temp4 = $temp2.value + * $temp5 = <> cast + * @returns + */ + private forOf2ts(): boolean { + let expr = (this.original as ArkIfStmt).getConditionExpr(); + let temp3 = expr.getOp1(); + let op2 = expr.getOp2(); + let firstStmt = this.context.getStmtReader().first(); + if (!(firstStmt instanceof ArkAssignStmt)) { + return false; + } + + if (!(this.isLocalTempValue(temp3) && op2 instanceof Constant && (op2 as Constant).getValue() === 'true')) { + return false; + } + + let stmt = (temp3 as Local).getDeclaringStmt(); + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + + let done = stmt.getRightOp(); + if (!(done instanceof ArkInstanceFieldRef)) { + return false; + } + + if (done.getFieldSignature().toString() !== '@ES2015/BuiltinClass: IteratorResult.done') { + return false; + } + + let temp2 = done.getBase(); + if (!(temp2 instanceof Local)) { + return false; + } + + stmt = temp2.getDeclaringStmt(); + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + + let next = stmt.getRightOp(); + if (!(next instanceof ArkInstanceInvokeExpr)) { + return false; + } + + if (next.getMethodSignature().getMethodSubSignature().getMethodName() !== 'next') { + return false; + } + + let temp1 = next.getBase(); + if (!(temp1 instanceof Local)) { + return false; + } + + stmt = temp1.getDeclaringStmt(); + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + + let iterator = stmt.getRightOp(); + if (!(iterator instanceof ArkInstanceInvokeExpr)) { + return false; + } + + if (iterator.getMethodSignature().getMethodSubSignature().getMethodName() !== 'iterator') { + return false; + } + + let successors = this.block.getSuccessors(); + if (successors.length !== 2) { + return false; + } + + let stmts = successors[0].getStmts(); + if (stmts.length < 2) { + return false; + } + + stmt = stmts[1]; + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + + this.context.setSkipStmt(stmts[0]); + this.context.setSkipStmt(stmts[1]); + + while (this.context.getStmtReader().hasNext()) { + this.context.getStmtReader().next(); + } + + let v = stmt.getLeftOp() as Local; + let valueName = v.getName(); + if (!this.isLocalTempValue(v)) { + this.setText(`for (let ${valueName} of ${this.transformer.valueToString(iterator.getBase())}) {`); + this.context.setTempVisit((temp1 as Local).getName()); + this.context.setTempVisit((temp3 as Local).getName()); + return true; + } + + // iterate map 'for (let [key, value] of map)' + let stmtReader = new StmtReader(stmts); + stmtReader.next(); + stmtReader.next(); + + let arrayValueNames = []; + while (stmtReader.hasNext()) { + stmt = stmtReader.next(); + if (!(stmt instanceof ArkAssignStmt)) { + break; + } + let ref = stmt.getRightOp(); + if (!(ref instanceof ArkArrayRef)) { + break; + } + if (ref.getBase().getName() !== valueName) { + break; + } + let name = (stmt.getLeftOp() as Local).getName(); + arrayValueNames.push(name); + this.context.setTempVisit(name); + } + + this.setText(`for (let [${arrayValueNames.join(', ')}] of ${this.transformer.valueToString(iterator.getBase())}) {`); + this.context.setTempVisit((temp3 as Local).getName()); + + return true; + } + + public transfer2ts(): void { + if (this.forOf2ts()) { + return; + } + let code: string; + let expr = (this.original as ArkIfStmt).getConditionExpr(); + code = `while (${this.valueToString(expr.getOp1())}`; + code += ` ${expr.getOperator().trim()} `; + code += `${this.valueToString(expr.getOp2())}) {`; + this.setText(code); + } + + protected valueToString(value: Value): string { + if (!(value instanceof Local)) { + return this.transformer.valueToString(value); + } + + for (const stmt of this.block.getStmts()) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + if (PrinterUtils.isDeIncrementStmt(stmt, NormalBinaryOperator.Addition) && (stmt.getLeftOp() as Local).getName() === value.getName()) { + this.context.setSkipStmt(stmt); + return `${value.getName()}++`; + } + + if (PrinterUtils.isDeIncrementStmt(stmt, NormalBinaryOperator.Subtraction) && (stmt.getLeftOp() as Local).getName() === value.getName()) { + this.context.setSkipStmt(stmt); + return `${value.getName()}--`; + } + } + + return this.transformer.valueToString(value); + } +} + +export class SourceForStmt extends SourceWhileStmt { + incBlock: BasicBlock; + + constructor(context: StmtPrinterContext, original: ArkIfStmt, block: BasicBlock, incBlock: BasicBlock) { + super(context, original, block); + this.incBlock = incBlock; + } + + public transfer2ts(): void { + let code: string; + let expr = (this.original as ArkIfStmt).getConditionExpr(); + code = `for (; ${this.transformer.valueToString(expr.getOp1())}`; + code += ` ${expr.getOperator().trim()} `; + code += `${this.transformer.valueToString(expr.getOp2())}; `; + + let stmtReader = new StmtReader(this.incBlock.getStmts()); + while (stmtReader.hasNext()) { + let sourceStmt = stmt2SourceStmt(this.context, stmtReader.next()); + sourceStmt.transfer2ts(); + code += sourceStmt.toString(); + if (stmtReader.hasNext()) { + code += ', '; + } + } + code += `) {`; + this.setText(code); + } +} + +export class SourceDoStmt extends SourceStmt { + constructor(context: StmtPrinterContext, stmt: Stmt) { + super(context, stmt); + } + + public transfer2ts(): void { + this.setText('do {'); + } + + protected afterDump(): void { + this.printer.incIndent(); + } +} + +export class SourceDoWhileStmt extends SourceWhileStmt { + constructor(context: StmtPrinterContext, stmt: ArkIfStmt, block: BasicBlock) { + super(context, stmt, block); + } + + public transfer2ts(): void { + let code: string; + let expr = (this.original as ArkIfStmt).getConditionExpr(); + code = `} while (${this.valueToString(expr.getOp1())}`; + code += ` ${expr.getOperator().trim()} `; + code += `${this.valueToString(expr.getOp2())})`; + this.setText(code); + } + + protected beforeDump(): void { + this.printer.decIndent(); + } + + protected afterDump(): void {} +} + +export class SourceElseStmt extends SourceStmt { + constructor(context: StmtPrinterContext, original: Stmt) { + super(context, original); + } + + public transfer2ts(): void { + this.setText('} else {'); + } + + protected beforeDump(): void { + this.printer.decIndent(); + } + + protected afterDump(): void { + this.printer.incIndent(); + } +} + +export class SourceContinueStmt extends SourceStmt { + constructor(context: StmtPrinterContext, original: Stmt) { + super(context, original); + } + + // trans 2 break or continue + public transfer2ts(): void { + this.setText('continue;'); + } +} + +export class SourceBreakStmt extends SourceStmt { + constructor(context: StmtPrinterContext, original: Stmt) { + super(context, original); + } + + // trans 2 break or continue + public transfer2ts(): void { + this.setText('break;'); + } +} + +export class SourceReturnStmt extends SourceStmt { + constructor(context: StmtPrinterContext, original: ArkReturnStmt) { + super(context, original); + } + + public transfer2ts(): void { + this.setText(`return ${this.transformer.valueToString((this.original as ArkReturnStmt).getOp())};`); + } +} + +export class SourceReturnVoidStmt extends SourceStmt { + constructor(context: StmtPrinterContext, original: ArkReturnVoidStmt) { + super(context, original); + } + + public transfer2ts(): void { + if (this.original.getOriginPositionInfo().getLineNo() <= 0) { + this.setText(''); + } else { + this.setText('return;'); + } + } +} + +export class SourceCompoundEndStmt extends SourceStmt { + constructor(context: StmtPrinterContext, stmt: Stmt, text: string) { + super(context, stmt); + this.setText(text); + } + + public transfer2ts(): void {} + + protected beforeDump(): void { + this.printer.decIndent(); + } +} + +export class SourceCommonStmt extends SourceStmt { + constructor(context: StmtPrinterContext, stmt: Stmt) { + super(context, stmt); + } + + public transfer2ts(): void { + this.setText(this.original.toString()); + } +} + +export class SourceThrowStmt extends SourceStmt { + constructor(context: StmtPrinterContext, original: ArkThrowStmt) { + super(context, original); + } + + public transfer2ts(): void { + this.setText(`throw ${this.transformer.valueToString((this.original as ArkThrowStmt).getOp())};`); + } +} + +export class SourceTypeAliasStmt extends SourceStmt { + aliasType: AliasType; + constructor(context: StmtPrinterContext, original: Stmt, aliasType: AliasType) { + super(context, original); + this.aliasType = aliasType; + } + + public transfer2ts(): void { + let modifiersArray: string[] = modifiers2stringArray(this.aliasType.getModifiers()); + let modifier = modifiersArray.length > 0 ? `${modifiersArray.join(' ')} ` : ''; + + const expr = (this.original as ArkAliasTypeDefineStmt).getAliasTypeExpr(); + let typeOf = expr.getTransferWithTypeOf() ? 'typeof ' : ''; + let realGenericTypes = expr.getRealGenericTypes() ? `<${expr.getRealGenericTypes()!.join(', ')}>` : ''; + let genericTypes = this.aliasType.getGenericTypes() ? `<${this.transformer.typeArrayToString(this.aliasType.getGenericTypes()!)}>` : ''; + + let typeObject = expr.getOriginalObject(); + if (typeObject instanceof Type) { + if (typeObject instanceof AliasType) { + this.setText(`${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${typeObject.getName()}${realGenericTypes};`); + } else { + this.setText( + `${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${this.transformer.typeToString(typeObject)}${realGenericTypes};` + ); + } + return; + } + if (typeObject instanceof ImportInfo) { + let exprStr = `import('${typeObject.getFrom()}')`; + if (typeObject.getImportClauseName() !== '') { + exprStr = `${exprStr}.${typeObject.getImportClauseName()}`; + } + this.setText(`${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${exprStr}${realGenericTypes};`); + return; + } + if (typeObject instanceof Local) { + this.setText( + `${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${this.transformer.valueToString(typeObject)}${realGenericTypes};` + ); + return; + } + if (typeObject instanceof ArkClass) { + let classTS = this.generateClassTS(typeObject); + this.setText(`${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${classTS}${realGenericTypes};`); + return; + } + if (typeObject instanceof ArkMethod) { + this.setText(`${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${typeObject.getName()}${realGenericTypes};`); + return; + } + this.setText(`${modifier}type ${this.aliasType.getName()}${genericTypes} = ${typeOf}${typeObject.getName()}${realGenericTypes};`); + } + + private generateClassTS(arkClass: ArkClass): string { + let res = ''; + let classType = new ClassType(arkClass.getSignature()); + if (arkClass.getCategory() === ClassCategory.TYPE_LITERAL || arkClass.getCategory() === ClassCategory.OBJECT) { + res = this.transformer.literalObjectToString(classType); + } else { + res = this.transformer.typeToString(classType); + } + return res; + } +} + +export class SourceTryStmt extends SourceStmt { + constructor(context: StmtPrinterContext, stmt: Stmt) { + super(context, stmt); + } + + public transfer2ts(): void { + this.setText('try {'); + } + + protected afterDump(): void { + this.printer.incIndent(); + } +} + +export class SourceCatchStmt extends SourceStmt { + block: BasicBlock | undefined; + constructor(context: StmtPrinterContext, stmt: Stmt, block?: BasicBlock) { + super(context, stmt); + this.block = block; + } + + public transfer2ts(): void { + if (this.block) { + let stmt = this.block!.getStmts()[0]; + if (stmt instanceof ArkAssignStmt) { + if (stmt.getLeftOp() instanceof Local) { + let name = (stmt.getLeftOp() as Local).getName(); + this.setText(`} catch (${name}) {`); + this.context.setSkipStmt(stmt); + return; + } + } + } + this.setText('} catch (e) {'); + } + + protected beforeDump(): void { + this.printer.decIndent(); + } + + protected afterDump(): void { + this.printer.incIndent(); + } +} + +export class SourceFinallyStmt extends SourceStmt { + constructor(context: StmtPrinterContext, stmt: Stmt) { + super(context, stmt); + } + + public transfer2ts(): void { + this.setText('} finally {'); + } + + protected beforeDump(): void { + this.printer.decIndent(); + } + + protected afterDump(): void { + this.printer.incIndent(); + } +} + +export class SourceNewArrayExpr { + expr: ArkNewArrayExpr; + values: string[]; + + constructor(expr: ArkNewArrayExpr) { + this.expr = expr; + this.values = []; + } + + public addInitValue(value: string): void { + this.values.push(value); + } + + public toString(): string { + return `[${this.values.join(', ')}]`; + } +} + +export function stmt2SourceStmt(context: StmtPrinterContext, stmt: Stmt): SourceStmt { + if (stmt instanceof ArkAssignStmt) { + return new SourceAssignStmt(context, stmt); + } + if (stmt instanceof ArkInvokeStmt) { + return new SourceInvokeStmt(context, stmt); + } + if (stmt instanceof ArkReturnVoidStmt) { + return new SourceReturnVoidStmt(context, stmt); + } + if (stmt instanceof ArkReturnStmt) { + return new SourceReturnStmt(context, stmt); + } + if (stmt instanceof ArkThrowStmt) { + return new SourceThrowStmt(context, stmt); + } + if (stmt instanceof ArkAliasTypeDefineStmt) { + return new SourceTypeAliasStmt(context, stmt, stmt.getAliasType()); + } + logger.info(`stmt2SourceStmt ${stmt.constructor} not support.`); + return new SourceCommonStmt(context, stmt); +} diff --git a/ets2panda/linter/arkanalyzer/src/save/source/SourceTransformer.ts b/ets2panda/linter/arkanalyzer/src/save/source/SourceTransformer.ts new file mode 100644 index 0000000000000000000000000000000000000000..58c999d85b7244db2cb2093eca392863103849af --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/save/source/SourceTransformer.ts @@ -0,0 +1,549 @@ +/* + * 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. + */ + +import { Constant } from '../../core/base/Constant'; +import { + AbstractBinopExpr, + AbstractExpr, + ArkAwaitExpr, + ArkCastExpr, + ArkDeleteExpr, + ArkInstanceInvokeExpr, + ArkInstanceOfExpr, + ArkNewArrayExpr, + ArkNewExpr, + ArkNormalBinopExpr, + ArkStaticInvokeExpr, + ArkTypeOfExpr, + ArkUnopExpr, + ArkYieldExpr, + NormalBinaryOperator, +} from '../../core/base/Expr'; +import { Local } from '../../core/base/Local'; +import { ArkClass, ClassCategory } from '../../core/model/ArkClass'; +import { ArkMethod } from '../../core/model/ArkMethod'; +import { ClassSignature, MethodSignature } from '../../core/model/ArkSignature'; +import { ArkCodeBuffer } from '../ArkStream'; +import Logger, { LOG_MODULE_TYPE } from '../../utils/logger'; +import { PrinterUtils } from '../base/PrinterUtils'; +import { SourceMethod } from './SourceMethod'; +import { + AliasType, + ArrayType, + ClassType, + FunctionType, + GenericType, + IntersectionType, + LiteralType, + PrimitiveType, + StringType, + TupleType, + Type, + UnclearReferenceType, + UnionType, + UnknownType, + VoidType, +} from '../../core/base/Type'; +import { SourceClass } from './SourceClass'; +import { Value } from '../../core/base/Value'; +import { AbstractRef, ArkArrayRef, ArkInstanceFieldRef, ArkStaticFieldRef, ArkThisRef } from '../../core/base/Ref'; +import { ArkFile } from '../../core/model/ArkFile'; +import { COMPONENT_CREATE_FUNCTION, COMPONENT_CUSTOMVIEW, COMPONENT_IF, COMPONENT_POP_FUNCTION } from '../../core/common/EtsConst'; +import { INSTANCE_INIT_METHOD_NAME } from '../../core/common/Const'; +import { ArkAssignStmt } from '../../core/base/Stmt'; +import { ArkNamespace } from '../../core/model/ArkNamespace'; +import { AbstractTypeExpr, KeyofTypeExpr, TypeQueryExpr } from '../../core/base/TypeExpr'; +import { ArkBaseModel } from '../../core/model/ArkBaseModel'; +import { ArkField } from '../../core/model/ArkField'; +import { ExportInfo } from '../../core/model/ArkExport'; +import { ImportInfo } from '../../core/model/ArkImport'; +import { BIGINT_KEYWORD, SUPER_NAME } from '../../core/common/TSConst'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'SourceTransformer'); + +export interface TransformerContext { + getArkFile(): ArkFile; + + getDeclaringArkNamespace(): ArkNamespace | undefined; + + getMethod(signature: MethodSignature): ArkMethod | null; + + getClass(signature: ClassSignature): ArkClass | null; + + getPrinter(): ArkCodeBuffer; + + transTemp2Code(temp: Local): string; + + isInBuilderMethod(): boolean; +} + +export class SourceTransformer { + protected context: TransformerContext; + + constructor(context: TransformerContext) { + this.context = context; + } + + private anonymousMethodToString(method: ArkMethod, indent: string): string { + let mtdPrinter = new SourceMethod(method, indent); + mtdPrinter.setInBuilder(this.context.isInBuilderMethod()); + return mtdPrinter.dump().trimStart(); + } + + private anonymousClassToString(cls: ArkClass, indent: string): string { + let clsPrinter = new SourceClass(cls, indent); + return clsPrinter.dump().trimStart(); + } + + public instanceInvokeExprToString(invokeExpr: ArkInstanceInvokeExpr): string { + let methodName = invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName(); + if (methodName === INSTANCE_INIT_METHOD_NAME) { + return ''; + } + let args: string[] = []; + invokeExpr.getArgs().forEach(v => { + args.push(this.valueToString(v)); + }); + let genericCode = this.genericTypesToString(invokeExpr.getRealGenericTypes()); + + if (PrinterUtils.isComponentAttributeInvoke(invokeExpr) && this.context.isInBuilderMethod()) { + return `.${methodName}${genericCode}(${args.join(', ')})`; + } + + return `${this.valueToString(invokeExpr.getBase())}.${methodName}${genericCode}(${args.join(', ')})`; + } + + private transBuilderMethod(className: string, methodName: string, args: string[], invokeExpr: ArkStaticInvokeExpr, genericCode: string): string | null { + if (className === COMPONENT_CUSTOMVIEW) { + if (methodName === COMPONENT_CREATE_FUNCTION) { + // Anonymous @Builder method + if (args.length > 1) { + // remove the substring '() =>' or '(x, y): type =>' at the beginning of args[1] + const pattern = /^\([^)]*\)\s*:\s*\w*\s*=>\s*/; + args[1] = args[1].replace(pattern, ''); + } + return `${args.join(' ')}`; + } + if (methodName === COMPONENT_POP_FUNCTION) { + return ''; + } + } + + if (PrinterUtils.isComponentCreate(invokeExpr)) { + if (className === COMPONENT_IF) { + return `if (${args.join(', ')})`; + } + return `${className}${genericCode}(${args.join(', ')})`; + } + + if (PrinterUtils.isComponentIfBranchInvoke(invokeExpr)) { + let arg0 = invokeExpr.getArg(0) as Constant; + if (arg0.getValue() === '0') { + return ``; + } else { + return '} else {'; + } + } + + if (PrinterUtils.isComponentPop(invokeExpr)) { + return '}'; + } + + return null; + } + + public staticInvokeExprToString(invokeExpr: ArkStaticInvokeExpr): string { + let methodSignature = invokeExpr.getMethodSignature(); + let method = this.context.getMethod(methodSignature); + if (method && PrinterUtils.isAnonymousMethod(method.getName())) { + return this.anonymousMethodToString(method, this.context.getPrinter().getIndent()); + } + + let classSignature = methodSignature.getDeclaringClassSignature(); + let className = PrinterUtils.getStaticInvokeClassFullName(classSignature, this.context.getDeclaringArkNamespace()); + let methodName = methodSignature.getMethodSubSignature().getMethodName(); + let args: string[] = []; + invokeExpr.getArgs().forEach(v => { + args.push(this.valueToString(v)); + }); + + let genericCode = this.genericTypesToString(invokeExpr.getRealGenericTypes()); + + if (this.context.isInBuilderMethod()) { + const res = this.transBuilderMethod(className, methodName, args, invokeExpr, genericCode); + if (res !== null) { + return res; + } + } + + if (className && className.length > 0 && methodName !== SUPER_NAME) { + return `${className}.${methodName}${genericCode}(${args.join(', ')})`; + } + return `${methodName}${genericCode}(${args.join(', ')})`; + } + + private genericTypesToString(types: Type[] | undefined): string { + if (!types) { + return ''; + } + + let code = this.typeArrayToString(types); + if (code.length > 0) { + return `<${code}>`; + } + return ''; + } + + public typeArrayToString(types: Type[], split: string = ', '): string { + let typesStr: string[] = []; + types.forEach(t => { + typesStr.push(this.typeToString(t)); + }); + + return typesStr.join(split); + } + + public static constToString(value: Constant): string { + if (value.getType().toString() === 'string') { + return `'${PrinterUtils.escape(value.getValue())}'`; + } else if (value.getType().toString() === BIGINT_KEYWORD) { + return `${value.getValue()}n`; + } else { + return value.getValue(); + } + } + + private exprToString(expr: AbstractExpr): string { + if (expr instanceof ArkInstanceInvokeExpr) { + return `${this.instanceInvokeExprToString(expr)}`; + } + + if (expr instanceof ArkStaticInvokeExpr) { + return `${this.staticInvokeExprToString(expr)}`; + } + + if (expr instanceof ArkNewArrayExpr) { + return `new Array<${this.typeToString(expr.getBaseType())}>(${expr.getSize()})`; + } + + if (expr instanceof ArkNewExpr) { + return `new ${this.typeToString(expr.getType())}()`; + } + + if (expr instanceof ArkDeleteExpr) { + return `delete ${this.valueToString(expr.getField())}`; + } + + if (expr instanceof AbstractBinopExpr) { + let op1: Value = expr.getOp1(); + let op2: Value = expr.getOp2(); + let operator: string = expr.getOperator(); + + return `${this.valueToString(op1, operator)} ${operator} ${this.valueToString(op2, operator)}`; + } + + if (expr instanceof ArkTypeOfExpr) { + return `typeof(${this.valueToString(expr.getOp())})`; + } + + if (expr instanceof ArkInstanceOfExpr) { + return `${this.valueToString(expr.getOp())} instanceof ${this.typeToString(expr.getType())}`; + } + + if (expr instanceof ArkCastExpr) { + let baseOp = expr.getOp(); + return `${this.valueToString(baseOp)} as ${this.typeToString(expr.getType())}`; + } + + if (expr instanceof ArkUnopExpr) { + return `${expr.getOperator()}${this.valueToString(expr.getOp())}`; + } + + if (expr instanceof ArkAwaitExpr) { + return `await ${this.valueToString(expr.getPromise())}`; + } + + if (expr instanceof ArkYieldExpr) { + return `yield ${this.valueToString(expr.getYieldValue())}`; + } + + logger.info(`exprToString ${expr.constructor} not support.`); + // ArkPhiExpr + return `${expr}`; + } + + public refToString(value: AbstractRef): string { + if (value instanceof ArkInstanceFieldRef) { + return `${this.valueToString(value.getBase())}.${value.getFieldName()}`; + } + + if (value instanceof ArkStaticFieldRef) { + return `${value.getFieldSignature().getBaseName()}.${value.getFieldName()}`; + } + + if (value instanceof ArkArrayRef) { + let index = value.getIndex(); + if (index instanceof Constant && index.getType() instanceof StringType && PrinterUtils.isTemp(index.getValue())) { + return `${this.valueToString(value.getBase())}[${this.valueToString(new Local(index.getValue()))}]`; + } + return `${this.valueToString(value.getBase())}[${this.valueToString(value.getIndex())}]`; + } + + if (value instanceof ArkThisRef) { + return 'this'; + } + + // ArkCaughtExceptionRef + logger.info(`refToString ${value.constructor} not support.`); + return `${value}`; + } + + public valueToString(value: Value, operator?: string): string { + if (value instanceof AbstractExpr) { + return this.exprToString(value); + } + + if (value instanceof AbstractRef) { + return this.refToString(value); + } + + if (value instanceof Constant) { + return SourceTransformer.constToString(value); + } + + if (value instanceof Local) { + return this.localToString(value, operator); + } + + logger.info(`valueToString ${value.constructor} not support.`); + return `${value}`; + } + + private localToString(value: Local, operator?: string): string { + if (PrinterUtils.isAnonymousMethod(value.getName())) { + let methodSignature = (value.getType() as FunctionType).getMethodSignature(); + let anonymousMethod = this.context.getMethod(methodSignature); + if (anonymousMethod) { + return this.anonymousMethodToString(anonymousMethod, this.context.getPrinter().getIndent()); + } + } + if (PrinterUtils.isAnonymousClass(value.getName())) { + let clsSignature = (value.getType() as ClassType).getClassSignature(); + let cls = this.context.getClass(clsSignature); + if (cls) { + return this.anonymousClassToString(cls, this.context.getPrinter().getIndent()); + } + } + + if (operator === NormalBinaryOperator.Division || operator === NormalBinaryOperator.Multiplication || operator === NormalBinaryOperator.Remainder) { + if (PrinterUtils.isTemp(value.getName())) { + let stmt = value.getDeclaringStmt(); + if (stmt instanceof ArkAssignStmt && stmt.getRightOp() instanceof ArkNormalBinopExpr) { + return `(${this.context.transTemp2Code(value)})`; + } + } + } + + return this.context.transTemp2Code(value); + } + + public literalObjectToString(type: ClassType): string { + let name = type.getClassSignature().getClassName(); + if (PrinterUtils.isAnonymousClass(name)) { + let cls = this.context.getClass(type.getClassSignature()); + if (cls) { + return this.anonymousClassToString(cls, this.context.getPrinter().getIndent()); + } + } + return name; + } + + public typeToString(type: Type): string { + if (type instanceof LiteralType) { + return this.literalType2string(type); + } + + if (type instanceof PrimitiveType || type instanceof GenericType) { + return type.getName(); + } + + if (type instanceof UnionType || type instanceof IntersectionType) { + return this.multipleType2string(type); + } + + if (type instanceof UnknownType) { + return 'any'; + } + + if (type instanceof VoidType) { + return 'void'; + } + + if (type instanceof ClassType) { + return this.classType2string(type); + } + if (type instanceof ArrayType) { + return this.arrayType2string(type); + } + if (type instanceof TupleType) { + return this.tupleType2string(type); + } + + if (type instanceof FunctionType) { + let methodSignature = type.getMethodSignature(); + let method = this.context.getMethod(methodSignature); + if (method && PrinterUtils.isAnonymousMethod(method.getName())) { + return new SourceMethod(method).toArrowFunctionTypeString(); + } + } + + if (type instanceof UnclearReferenceType) { + return this.unclearReferenceType2string(type); + } + + if (type instanceof AliasType) { + return this.aliasType2string(type); + } + + if (type instanceof KeyofTypeExpr) { + return this.keyofTypeExpr2string(type); + } + + if (type instanceof TypeQueryExpr) { + return this.typeQueryExpr2string(type); + } + + if (!type) { + return 'any'; + } + + logger.info(`valueToString ${type.constructor} not support.`); + return type.toString(); + } + + private literalType2string(type: LiteralType): string { + let literalName = type.getLiteralName(); + if (typeof literalName === 'string' && literalName.endsWith('Keyword')) { + return literalName.substring(0, literalName.length - 'Keyword'.length).toLowerCase(); + } + return `${literalName}`; + } + + private multipleType2string(type: UnionType | IntersectionType): string { + let typesStr: string[] = []; + for (const member of type.getTypes()) { + if (member instanceof UnionType || member instanceof IntersectionType) { + typesStr.push(`(${this.typeToString(member)})`); + } else { + typesStr.push(this.typeToString(member)); + } + } + if (type instanceof UnionType) { + return typesStr.join(' | '); + } else { + return typesStr.join(' & '); + } + } + + private arrayType2string(type: ArrayType): string { + const readonly = type.getReadonlyFlag() ? 'readonly ' : ''; + const dimensions: string[] = []; + for (let i = 0; i < type.getDimension(); i++) { + dimensions.push('[]'); + } + + let baseType = type.getBaseType(); + if (baseType instanceof UnionType || baseType instanceof IntersectionType || baseType instanceof AbstractTypeExpr) { + return `${readonly}(${this.typeToString(baseType)})${dimensions.join('')}`; + } + return `${readonly}${this.typeToString(baseType)}${dimensions.join('')}`; + } + + private tupleType2string(type: TupleType): string { + const readonly = type.getReadonlyFlag() ? 'readonly ' : ''; + let typesStr: string[] = []; + for (const member of type.getTypes()) { + typesStr.push(this.typeToString(member)); + } + return `${readonly}[${typesStr.join(', ')}]`; + } + + private aliasType2string(type: AliasType): string { + let typesStr: string[] = []; + let genericTypes = type.getRealGenericTypes() ?? type.getGenericTypes(); + if (genericTypes) { + for (const gType of genericTypes) { + typesStr.push(this.typeToString(gType)); + } + } + if (typesStr.length > 0) { + return `${type.getName()}<${typesStr.join(', ')}>`; + } + return type.getName(); + } + + private keyofTypeExpr2string(type: KeyofTypeExpr): string { + if (type.getOpType() instanceof UnionType || type.getOpType() instanceof IntersectionType) { + return `keyof (${this.typeToString(type.getOpType())})`; + } + return `keyof ${this.typeToString(type.getOpType())}`; + } + + private typeQueryExpr2string(type: TypeQueryExpr): string { + const gTypes = type.getGenerateTypes(); + const genericStr = this.genericTypesToString(gTypes); + const opValue = type.getOpValue(); + if (opValue instanceof ArkBaseModel) { + if (opValue instanceof ArkClass || opValue instanceof ArkMethod || opValue instanceof ArkNamespace || opValue instanceof ArkField) { + return `typeof ${opValue.getName()}${genericStr}`; + } else if (opValue instanceof ExportInfo) { + return `typeof ${opValue.getExportClauseName()}${genericStr}`; + } else if (opValue instanceof ImportInfo) { + return `typeof ${opValue.getImportClauseName()}${genericStr}`; + } else { + return `typeof *invalid*`; + } + } else { + return `typeof ${this.valueToString(opValue)}${genericStr}`; + } + } + + private unclearReferenceType2string(type: UnclearReferenceType): string { + let genericTypes = type.getGenericTypes(); + if (genericTypes.length > 0) { + return `${type.getName()}<${genericTypes.map(value => this.typeToString(value)).join(', ')}>`; + } + return type.getName(); + } + + private classType2string(type: ClassType): string { + const name = PrinterUtils.getStaticInvokeClassFullName(type.getClassSignature()); + if (PrinterUtils.isDefaultClass(name)) { + return 'any'; + } + if (PrinterUtils.isAnonymousClass(name)) { + let cls = this.context.getClass(type.getClassSignature()); + if (cls && cls.getCategory() === ClassCategory.TYPE_LITERAL) { + return this.anonymousClassToString(cls, this.context.getPrinter().getIndent()); + } + return 'Object'; + } + let genericTypes = type.getRealGenericTypes(); + if (genericTypes && genericTypes.length > 0) { + return `${name}${this.genericTypesToString(genericTypes)}`; + } + return name; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/transformer/FunctionTransformer.ts b/ets2panda/linter/arkanalyzer/src/transformer/FunctionTransformer.ts new file mode 100644 index 0000000000000000000000000000000000000000..4cfc917d2cb294656aa6635c78bb354f4a280ef3 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/transformer/FunctionTransformer.ts @@ -0,0 +1,16 @@ +/* + * 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 FunctionTransformer extends Transformer {} diff --git a/ets2panda/linter/arkanalyzer/src/transformer/SceneTransformer.ts b/ets2panda/linter/arkanalyzer/src/transformer/SceneTransformer.ts new file mode 100644 index 0000000000000000000000000000000000000000..caeea5c2624b9e9721fb954fc3961d5d410e9301 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/transformer/SceneTransformer.ts @@ -0,0 +1,16 @@ +/* + * 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 SceneTransformer extends Transformer {} diff --git a/ets2panda/linter/arkanalyzer/src/transformer/StaticSingleAssignmentFormer.ts b/ets2panda/linter/arkanalyzer/src/transformer/StaticSingleAssignmentFormer.ts new file mode 100644 index 0000000000000000000000000000000000000000..2c7e78deec68bd3715c15e00bee27a851f6580d1 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/transformer/StaticSingleAssignmentFormer.ts @@ -0,0 +1,315 @@ +/* + * 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. + */ + +import { ArkPhiExpr } from '../core/base/Expr'; +import { Local } from '../core/base/Local'; +import { ArkAssignStmt, Stmt } from '../core/base/Stmt'; +import { BasicBlock } from '../core/graph/BasicBlock'; +import { Cfg } from '../core/graph/Cfg'; +import { DominanceFinder } from '../core/graph/DominanceFinder'; +import { DominanceTree } from '../core/graph/DominanceTree'; +import { ArkBody } from '../core/model/ArkBody'; + +export class StaticSingleAssignmentFormer { + public transformBody(body: ArkBody): void { + let cfg = body.getCfg(); + + let blockToDefs = new Map>(); + let localToBlocks = new Map>(); + for (const block of cfg.getBlocks()) { + let defs = new Set(); + for (const stmt of block.getStmts()) { + this.transformStmt(stmt, defs, localToBlocks, block); + } + blockToDefs.set(block, defs); + } + + let dominanceFinder = new DominanceFinder(cfg); + let blockToPhiStmts = this.decideBlockToPhiStmts(body, dominanceFinder, blockToDefs, localToBlocks); + this.addPhiStmts(blockToPhiStmts, cfg, blockToDefs); + let dominanceTree = new DominanceTree(dominanceFinder); + + this.renameLocals(body, dominanceTree, blockToPhiStmts); + } + + private transformStmt(stmt: Stmt, defs: Set, localToBlocks: Map>, block: BasicBlock): void { + if (stmt.getDef() != null && stmt.getDef() instanceof Local) { + let local = stmt.getDef() as Local; + defs.add(local); + if (localToBlocks.has(local)) { + localToBlocks.get(local)?.add(block); + } else { + let blcoks = new Set(); + blcoks.add(block); + localToBlocks.set(local, blcoks); + } + } + } + + private decideBlockToPhiStmts( + body: ArkBody, + dominanceFinder: DominanceFinder, + blockToDefs: Map>, + localToBlocks: Map> + ): Map> { + let blockToPhiStmts = new Map>(); + let blockToPhiLocals = new Map>(); + let localToPhiBlock = new Map>(); + + for (const [_, local] of body.getLocals()) { + localToPhiBlock.set(local, new Set()); + let phiBlocks = localToPhiBlock.get(local) as Set; + let blocks = Array.from(localToBlocks.get(local) as Set); + while (blocks.length !== 0) { + let block = blocks.splice(0, 1).at(0) as BasicBlock; + let dfs = dominanceFinder.getDominanceFrontiers(block); + for (const df of dfs) { + this.handleDf(blockToPhiStmts, blockToPhiLocals, phiBlocks, df, local, blockToDefs, blocks); + } + } + } + + return blockToPhiStmts; + } + + private handleDf( + blockToPhiStmts: Map>, + blockToPhiLocals: Map>, + phiBlocks: Set, + df: BasicBlock, + local: Local, + blockToDefs: Map>, + blocks: BasicBlock[] + ): void { + if (!phiBlocks.has(df)) { + phiBlocks.add(df); + + let phiStmt = this.createEmptyPhiStmt(local); + if (blockToPhiStmts.has(df)) { + blockToPhiStmts.get(df)?.add(phiStmt); + blockToPhiLocals.get(df)?.add(local); + } else { + let phiStmts = new Set(); + phiStmts.add(phiStmt); + blockToPhiStmts.set(df, phiStmts); + let phiLocals = new Set(); + phiLocals.add(local); + blockToPhiLocals.set(df, phiLocals); + } + blockToDefs.get(df)?.add(local); + + if (!blockToDefs.get(df)?.has(local)) { + blocks.push(df); + } + } + } + + private handleBlockWithSucc( + blockToPhiStmts: Map>, + succ: BasicBlock, + blockToDefs: Map>, + block: BasicBlock, + phiArgsNum: Map + ): void { + for (const phi of blockToPhiStmts.get(succ) as Set) { + let local = phi.getDef() as Local; + if (blockToDefs.get(block)?.has(local)) { + if (phiArgsNum.has(phi)) { + let num = phiArgsNum.get(phi) as number; + phiArgsNum.set(phi, num + 1); + } else { + phiArgsNum.set(phi, 1); + } + } + } + } + + private addPhiStmts(blockToPhiStmts: Map>, cfg: Cfg, blockToDefs: Map>): void { + let phiArgsNum = new Map(); + for (const block of cfg.getBlocks()) { + let succs = Array.from(block.getSuccessors()); + for (const succ of succs) { + if (blockToPhiStmts.has(succ)) { + this.handleBlockWithSucc(blockToPhiStmts, succ, blockToDefs, block, phiArgsNum); + } + } + } + + for (const block of blockToPhiStmts.keys()) { + let phis = blockToPhiStmts.get(block) as Set; + let phisTocheck = new Set(phis); + for (const phi of phisTocheck) { + if ((phiArgsNum.get(phi) as number) < 2) { + phis.delete(phi); + } + } + + for (const phi of phis) { + cfg.insertBefore(phi, block.getHead() as Stmt); + } + } + } + + private renameUseAndDef(stmt: Stmt, localToNameStack: Map, nextFreeIdx: number, newLocals: Set, newPhiStmts: Set): number { + let uses = stmt.getUses(); + if (uses.length > 0 && !this.constainsPhiExpr(stmt)) { + for (const use of uses) { + if (use instanceof Local) { + let nameStack = localToNameStack.get(use) as Local[]; + let newUse = nameStack[nameStack.length - 1]; + stmt.replaceUse(use, newUse); + } + } + } + + // rename def + let def = stmt.getDef(); + if (def != null && def instanceof Local) { + let newName = def.getName() + '#' + nextFreeIdx; + nextFreeIdx++; + let newDef = new Local(newName); + newDef.setOriginalValue(def); + newLocals.add(newDef); + localToNameStack.get(def)?.push(newDef); + (stmt).setLeftOp(newDef); + if (this.constainsPhiExpr(stmt)) { + newPhiStmts.add(stmt); + } + } + return nextFreeIdx; + } + + private renameLocals(body: ArkBody, dominanceTree: DominanceTree, blockToPhiStmts: Map>): void { + let newLocals = new Set(body.getLocals().values()); + let localToNameStack = new Map(); + for (const local of newLocals) { + localToNameStack.set(local, new Array()); + } + + let blockStack = new Array(); + let visited = new Set(); + let dfsBlocks = dominanceTree.getAllNodesDFS(); + let nextFreeIdx = 0; + for (const block of dfsBlocks) { + let newPhiStmts = new Set(); + for (const stmt of block.getStmts()) { + // rename uses and def + nextFreeIdx = this.renameUseAndDef(stmt, localToNameStack, nextFreeIdx, newLocals, newPhiStmts); + } + visited.add(block); + blockStack.push(block); + if (blockToPhiStmts.has(block)) { + blockToPhiStmts.set(block, newPhiStmts); + } + + // rename phiStmts' args + let succs = Array.from(block.getSuccessors()); + for (const succ of succs) { + if (!blockToPhiStmts.has(succ)) { + continue; + } + let phiStmts = blockToPhiStmts.get(succ) as Set; + for (const phiStmt of phiStmts) { + let def = phiStmt.getDef() as Local; + let oriDef = this.getOriginalLocal(def, new Set(localToNameStack.keys())) as Local; + let nameStack = localToNameStack.get(oriDef) as Local[]; + let arg = nameStack[nameStack.length - 1]; + this.addNewArgToPhi(phiStmt, arg, block); + } + } + + // if a block's children in dominance tree are visited, remove it + this.removeVisitedTree(blockStack, dominanceTree, visited, localToNameStack); + } + body.setLocals(newLocals); + } + + private removeVisitedTree(blockStack: BasicBlock[], dominanceTree: DominanceTree, visited: Set, localToNameStack: Map): void { + let top = blockStack[blockStack.length - 1]; + let children = dominanceTree.getChildren(top); + while (this.containsAllChildren(visited, children)) { + blockStack.pop(); + for (const stmt of top.getStmts()) { + let def = stmt.getDef(); + if (def != null && def instanceof Local) { + let oriDef = this.getOriginalLocal(def, new Set(localToNameStack.keys())) as Local; + localToNameStack.get(oriDef)?.pop(); + } + } + + // next block to check + if (blockStack.length > 0) { + top = blockStack[blockStack.length - 1]; + children = dominanceTree.getChildren(top); + } else { + break; + } + } + } + + private constainsPhiExpr(stmt: Stmt): boolean { + if (stmt instanceof ArkAssignStmt && stmt.getUses().length > 0) { + for (const use of stmt.getUses()) { + if (use instanceof ArkPhiExpr) { + return true; + } + } + } + return false; + } + + private getOriginalLocal(local: Local, locals: Set): Local | null { + if (locals.has(local)) { + return local; + } + let hashPos = local.getName().indexOf('#'); + let oriName = local.getName().substring(0, hashPos); + for (const oriLocal of locals) { + if (oriLocal.getName() === oriName) { + return oriLocal; + } + } + return null; + } + + private addNewArgToPhi(phiStmt: Stmt, arg: Local, block: BasicBlock): void { + for (let use of phiStmt.getUses()) { + if (use instanceof ArkPhiExpr) { + let phiExpr = use as ArkPhiExpr; + let args = phiExpr.getArgs(); + let argToBlock = phiExpr.getArgToBlock(); + args.push(arg); + argToBlock.set(arg, block); + phiExpr.setArgs(args); + phiExpr.setArgToBlock(argToBlock); + break; + } + } + } + + private containsAllChildren(blockSet: Set, children: BasicBlock[]): boolean { + for (const child of children) { + if (!blockSet.has(child)) { + return false; + } + } + return true; + } + + private createEmptyPhiStmt(local: Local): ArkAssignStmt { + let phiExpr = new ArkPhiExpr(); + return new ArkAssignStmt(local, phiExpr); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/transformer/Transformer.ts b/ets2panda/linter/arkanalyzer/src/transformer/Transformer.ts new file mode 100644 index 0000000000000000000000000000000000000000..790c9319b5b490c6a2314915f2a7ffda3f507f8e --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/transformer/Transformer.ts @@ -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. + */ + +/** + * + */ +class Transformer { + internalTransform(): void {} +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/AstTreeUtils.ts b/ets2panda/linter/arkanalyzer/src/utils/AstTreeUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..8266b8bafe2c8566d8f77c7c301686f0c5f599ae --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/AstTreeUtils.ts @@ -0,0 +1,69 @@ +/* + * 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. + */ + +import { ArkFile, ts } from '..'; +import { ETS_COMPILER_OPTIONS } from '../core/common/EtsConst'; +import * as crypto from 'crypto'; + +const sourceFileCache: Map = new Map(); + +export class AstTreeUtils { + /** + * get source file from code segment + * @param fileName source file name + * @param code source code + * @returns ts.SourceFile + */ + public static getASTNode(fileName: string, code: string): ts.SourceFile { + const key = this.getKeyFromCode(code); + let sourceFile = sourceFileCache.get(key); + if (sourceFile) { + return sourceFile; + } + sourceFile = this.createSourceFile(fileName, code); + sourceFileCache.set(key, sourceFile); + return sourceFile; + } + + /** + * get source file from ArkFile + * @param arkFile ArkFile + * @returns ts.SourceFile + */ + public static getSourceFileFromArkFile(arkFile: ArkFile): ts.SourceFile { + const signature = arkFile.getFileSignature().toString(); + const key = this.getKeyFromCode(signature); + let sourceFile = sourceFileCache.get(key); + if (sourceFile) { + return sourceFile; + } + sourceFile = this.createSourceFile(arkFile.getName(), arkFile.getCode()); + sourceFileCache.set(key, sourceFile); + return sourceFile; + } + + public static createSourceFile(fileName: string, code: string): ts.SourceFile { + return ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true, undefined, ETS_COMPILER_OPTIONS); + } + + /** + * convert source code to hash string + * @param code source code + * @returns string + */ + private static getKeyFromCode(code: string): string { + return crypto.createHash('sha256').update(code).digest('hex'); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/CfgStructualAnalysis.ts b/ets2panda/linter/arkanalyzer/src/utils/CfgStructualAnalysis.ts new file mode 100644 index 0000000000000000000000000000000000000000..01899770e6241b03dc565ea922340a942670e5ee --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/CfgStructualAnalysis.ts @@ -0,0 +1,1470 @@ +/* + * 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. + */ + +import { ArkIfStmt, ArkReturnStmt, ArkThrowStmt } from '../core/base/Stmt'; +import { Trap } from '../core/base/Trap'; +import { BasicBlock } from '../core/graph/BasicBlock'; +import { Cfg } from '../core/graph/Cfg'; + +export enum CodeBlockType { + NORMAL, + IF, + ELSE, + BREAK, + CONTINUE, + DO, + DO_WHILE, + WHILE, + FOR, + COMPOUND_END, + TRY, + CATCH, + FINALLY, +} + +export type TraversalCallback = (block: BasicBlock | undefined, type: CodeBlockType) => void; + +export class AbstractFlowGraph { + private nodes: AbstractNode[] = []; + private entry: AbstractNode; + private block2NodeMap: Map; + private structOf: Map = new Map(); + private structTypes: Map = new Map(); + private structBlocks: Map> = new Map(); + private loopMap: Map = new Map(); + + constructor(cfg: Cfg, traps?: Trap[]) { + this.block2NodeMap = new Map(); + for (const bb of cfg.getBlocks()) { + let an = new AbstractNode(); + an.setBlock(bb); + this.block2NodeMap.set(bb, an); + } + + for (const bb of cfg.getBlocks()) { + let an = this.block2NodeMap.get(bb)!; + for (const succ of bb.getSuccessors()) { + an.addSucc(this.block2NodeMap.get(succ)!); + } + for (const pred of bb.getPredecessors()) { + an.addPred(this.block2NodeMap.get(pred)!); + } + } + + let trapRegions = this.buildTrap(traps); + this.searchTrapFinallyNodes(trapRegions); + this.trapsStructuralAnalysis(trapRegions); + + this.entry = this.block2NodeMap.get(cfg.getStartingBlock()!)!; + this.entry = this.structuralAnalysis(this.entry); + } + + public getEntry(): AbstractNode { + return this.entry; + } + + public getForIncBlock(block: BasicBlock): BasicBlock { + let node = this.block2NodeMap.get(block)!; + let loop = this.loopMap.get(node)! as ForLoopRegion; + return loop.inc.getBlock()!; + } + + public preOrder(node: AbstractNode, callback: TraversalCallback, visitor: Set = new Set()): void { + visitor.add(node); + node.traversal(callback, CodeBlockType.NORMAL); + for (const succ of node.getSucc()) { + if (!visitor.has(succ)) { + this.preOrder(succ, callback, visitor); + } + } + } + + private structuralAnalysis(entry: AbstractNode, scope?: Set): AbstractNode { + let preds = entry.getPred(); + let entryBak = entry; + this.nodes = this.dfsPostOrder(entry, scope); + this.entry = entry; + this.buildCyclicStructural(); + + // acyclic structural + let postMax = this.nodes.length; + let change = true; + while (postMax > 1 && change) { + change = false; + for (let i = 0; i < postMax; i++) { + let node = this.nodes[i]; + let nset = new Set(); + let rtype = this.identifyRegionType(node, nset, scope); + if (!rtype) { + continue; + } + + let p = this.reduce(rtype, nset); + if (!p) { + continue; + } + + scope?.add(p); + if (nset.has(entry)) { + entry = p; + } + this.nodes = this.dfsPostOrder(entry, scope); + change = postMax !== this.nodes.length; + postMax = this.nodes.length; + } + } + + for (const pred of preds) { + pred.replaceSucc(entryBak, entry); + entry.addPred(pred); + } + + return entry; + } + + private dfsPostOrder( + node: AbstractNode, + scope?: Set, + visitor: Set = new Set(), + postOrder: AbstractNode[] = [] + ): AbstractNode[] { + visitor.add(node); + for (const succ of node.getSucc()) { + if (visitor.has(succ)) { + continue; + } + + if (scope && !scope.has(succ)) { + continue; + } + + this.dfsPostOrder(succ, scope, visitor, postOrder); + } + postOrder.push(node); + return postOrder; + } + + private buildCyclicStructural(): void { + for (const loop of this.prepareBuildLoops()) { + let nset = new Set(); + for (const n of loop) { + if (this.structOf.has(n)) { + nset.add(this.structOf.get(n)!); + } else { + nset.add(n); + } + } + let rtype = this.cyclicRegionType(nset); + let region = this.createRegion(rtype, nset)! as NaturalLoopRegion; + region.revise(); + this.structTypes.set(region, rtype); + let blocks = new Set(); + for (const s of nset) { + this.handleRegion(s, region, blocks); + } + this.structBlocks.set(region, blocks); + this.loopMap.set(region.header, region); + } + } + + private handleRegion(s: AbstractNode | Region, region: NaturalLoopRegion, blocks: Set): void { + if (!this.structOf.has(s)) { + this.structOf.set(s, region); + } + if (this.structBlocks.has(s as Region)) { + for (const b of this.structBlocks.get(s as Region)!) { + blocks.add(b); + } + } else { + blocks.add(s); + } + } + + private prepareBuildLoops(): Set[] { + let dom = this.buildDominator(); + let loops: Set[] = []; + for (const header of this.nodes) { + let innermost: Set | undefined; + let longest: number = 0; + + let backEdges = this.getBackEdges(dom, header); + if (backEdges.size === 0) { + continue; + } + + if (this.isSelfLoopNode(header)) { + loops.push(new Set([header])); + } + + for (const start of backEdges) { + let loop = this.naturalLoop(start, header); + if (!innermost || loop.size > longest) { + innermost = loop; + longest = loop.size; + } + } + loops.push(innermost!); + } + loops.sort((a, b) => a.size - b.size); + return loops; + } + + private buildDominator(): Map> { + let domin = new Map>(); + domin.set(this.entry, new Set([this.entry])); + for (const node of this.nodes) { + if (node !== this.entry) { + domin.set(node, new Set(this.nodes)); + } + } + + let change = true; + while (change) { + change = false; + for (const node of this.nodes) { + if (node === this.entry) { + continue; + } + let t = new Set(domin.get(node)!); + for (const p of node.getPred()) { + t = this.setIntersect(t, domin.get(p)!); + } + t.add(node); + if (!this.isSetEqual(t, domin.get(node)!)) { + change = true; + domin.set(node, t); + } + } + } + + return domin; + } + + private getBackEdges(dom: Map>, header: AbstractNode): Set { + let backEdges = new Set(); + for (const n of header.getPred()) { + // h dom n && n -> h + if (dom.get(n)?.has(header)) { + backEdges.add(n); + } + } + return backEdges; + } + + private naturalLoop(backEdgeStart: AbstractNode, backEdgeEnd: AbstractNode): Set { + let stack: AbstractNode[] = []; + let loop = new Set([backEdgeEnd, backEdgeStart]); + + stack.push(backEdgeStart); + + while (stack.length > 0) { + let m = stack.shift()!; + for (const pred of m.getPred()) { + if (loop.has(pred)) { + continue; + } + loop.add(pred); + stack.push(pred); + } + } + + return loop; + } + + private isSelfLoopNode(node: AbstractNode): boolean { + let inSucc = false; + let inPred = false; + + for (const pred of node.getPred()) { + if (pred === node) { + inPred = true; + } + } + + for (const succ of node.getSucc()) { + if (succ === node) { + inSucc = true; + } + } + + return inSucc && inPred; + } + + private isForLoopIncNode(node: AbstractNode): boolean { + for (const loop of this.loopMap.values()) { + if (loop.getType() === RegionType.FOR_LOOP_REGION) { + if (node === (loop as ForLoopRegion).inc) { + return true; + } + } + } + return false; + } + + private isValidInBlocks(node: AbstractNode, scope?: Set): boolean { + if (this.isForLoopIncNode(node) || node.hasIfStmt()) { + return false; + } + if (scope && !scope.has(node)) { + return false; + } + + return true; + } + + private isIfRegion(node: AbstractNode, nodeSet: Set): boolean { + nodeSet.clear(); + if (node.getSucc().length !== 2) { + return false; + } + let m = node.getSucc()[0]; + let n = node.getSucc()[1]; + if (m.getSucc().length === 1 && m.getSucc()[0] === n) { + nodeSet.add(node).add(m); + return true; + } + + return false; + } + + private isIfExitRegion(node: AbstractNode, nodeSet: Set): boolean { + nodeSet.clear(); + if (node.getSucc().length !== 2) { + return false; + } + let m = node.getSucc()[0]; + if (m.hasReturnStmt()) { + nodeSet.add(node).add(m); + return true; + } + + return false; + } + + private isIfElseRegion(node: AbstractNode, nodeSet: Set): boolean { + nodeSet.clear(); + if (node.getSucc().length !== 2) { + return false; + } + let m = node.getSucc()[0]; + let n = node.getSucc()[1]; + if ( + (m.getSucc().length === 1 && + n.getSucc().length === 1 && + m.getPred().length === 1 && + n.getPred().length === 1 && + m.getSucc()[0] === n.getSucc()[0]) || + (m.getSucc().length === 0 && n.getSucc().length === 0) + ) { + nodeSet.add(node).add(m).add(n); + return true; + } + + return false; + } + + private isBlockRegion(node: AbstractNode, nodeSet: Set, scope?: Set): boolean { + let n = node; + let p = true; + let s = n.getSucc().length === 1; + nodeSet.clear(); + + let blocks = []; + while (p && s && !nodeSet.has(n) && this.isValidInBlocks(n, scope)) { + nodeSet.add(n); + blocks.push(n); + n = n.getSucc()[0]; + p = n.getPred().length === 1; + s = n.getSucc().length === 1; + } + + if (p && this.isValidInBlocks(n, scope)) { + if (!nodeSet.has(n)) { + blocks.push(n); + } + nodeSet.add(n); + } + + n = node; + p = n.getPred().length === 1; + s = true; + while (p && s && this.isValidInBlocks(n, scope)) { + if (!nodeSet.has(n)) { + blocks.unshift(n); + } + nodeSet.add(n); + n = n.getPred()[0]; + if (nodeSet.has(n)) { + break; + } + p = n.getPred().length === 1; + s = n.getSucc().length === 1; + } + + if (s && this.isValidInBlocks(n, scope)) { + if (!nodeSet.has(n)) { + blocks.unshift(n); + } + nodeSet.add(n); + } + + nodeSet.clear(); + for (const n of blocks) { + nodeSet.add(n); + } + + if (nodeSet.size >= 2) { + return true; + } + return false; + } + + private isIfBreakRegion(node: AbstractNode, nodeSet: Set, loop: NaturalLoopRegion): boolean { + let m = node.getSucc()[0]; + nodeSet.clear(); + if (this.isExitLoop(m, this.structBlocks.get(loop)!)) { + nodeSet.add(node); + return true; + } + + if (m.getSucc().length === 1 && this.isExitLoop(m.getSucc()[0], this.structBlocks.get(loop)!)) { + nodeSet.add(node).add(m); + return true; + } + + return false; + } + + private isIfContinueRegion(node: AbstractNode, nodeSet: Set, loop: NaturalLoopRegion): boolean { + nodeSet.clear(); + let m = node.getSucc()[0]; + let n = node.getSucc()[1]; + if (loop.control.has(m)) { + nodeSet.add(node); + return true; + } + + if (m.getSucc().length === 1 && loop.control.has(m.getSucc()[0]) && !loop.control.has(n) && !this.isIfElseRegion(node, nodeSet)) { + nodeSet.add(node).add(m); + return true; + } + return false; + } + + private isWhileRegion(node: AbstractNode, nodeSet: Set, loop: NaturalLoopRegion): boolean { + nodeSet.clear(); + let m = node.getSucc()[0]; + if (loop.header === node && m.getSucc().length === 1 && m.getPred().length === 1 && m.getSucc()[0] === node) { + nodeSet.add(node).add(m); + return true; + } + return false; + } + + private isForRegion(node: AbstractNode, nodeSet: Set, loop: NaturalLoopRegion): boolean { + nodeSet.clear(); + if (loop.header === node && loop.getType() === RegionType.FOR_LOOP_REGION) { + let forLoop = loop as ForLoopRegion; + let blocks = node.getSucc()[0]; + if (forLoop.inc.getPred().length === 1 && forLoop.inc.getPred()[0] === blocks && blocks.getSucc().length === 1) { + nodeSet.add(node).add(forLoop.inc).add(blocks); + return true; + } + } + return false; + } + + private isDoWhileRegion(node: AbstractNode, nodeSet: Set, loop: NaturalLoopRegion): boolean { + nodeSet.clear(); + if (loop.back === node && loop.getType() === RegionType.DO_WHILE_LOOP_REGION) { + let blocks = node.getPred()[0]; + if (blocks.getSucc().length === 1 && blocks.getSucc()[0] === node && node.getSucc()[0] === blocks) { + nodeSet.add(blocks).add(node); + return true; + } + } + return false; + } + + private identifyRegionType(node: AbstractNode, nodeSet: Set, scope?: Set): RegionType | undefined { + if (this.isBlockRegion(node, nodeSet, scope)) { + return RegionType.BLOCK_REGION; + } + + let inLoop = false; + let region = this.structOf.get(node); + if (region && LOOP_TYPES.has(region?.getType())) { + inLoop = true; + } + + if (new Set(node.getPred()).has(node) && new Set(node.getSucc()).has(node)) { + nodeSet.add(node); + if (inLoop) { + return region?.getType(); + } + return RegionType.SELF_LOOP_REGION; + } + + if (node.getSucc().length !== 2) { + return undefined; + } + + if (inLoop) { + let loop = region as NaturalLoopRegion; + if (!loop.control.has(node)) { + if (this.isIfBreakRegion(node, nodeSet, loop)) { + return RegionType.IF_THEN_BREAK_REGION; + } + + if (this.isIfContinueRegion(node, nodeSet, loop)) { + return RegionType.IF_THEN_CONTINUE_REGION; + } + } + if (this.isWhileRegion(node, nodeSet, loop)) { + return RegionType.WHILE_LOOP_REGION; + } + + if (this.isForRegion(node, nodeSet, loop)) { + return RegionType.FOR_LOOP_REGION; + } + + if (this.isDoWhileRegion(node, nodeSet, loop)) { + return RegionType.DO_WHILE_LOOP_REGION; + } + } + + // check for if + if (this.isIfExitRegion(node, nodeSet)) { + return RegionType.IF_THEN_EXIT_REGION; + } + if (this.isIfRegion(node, nodeSet)) { + return RegionType.IF_REGION; + } + + // check for an if else + if (this.isIfElseRegion(node, nodeSet)) { + return RegionType.IF_ELSE_REGION; + } + + return undefined; + } + + private cyclicRegionType(nodeSet: Set): RegionType { + let nodes = Array.from(nodeSet); + let header = nodes[0]; + if (nodeSet.size === 1) { + let tail = nodes[0].getBlock()?.getTail(); + if (tail instanceof ArkIfStmt) { + return RegionType.DO_WHILE_LOOP_REGION; + } + return RegionType.WHILE_LOOP_REGION; + } + + let back = nodes[1]; + // exit loop from back + if (!this.hasExitLoopSucc(header, nodeSet) && this.hasExitLoopSucc(back, nodeSet)) { + return RegionType.DO_WHILE_LOOP_REGION; + } + + if (this.hasExitLoopSucc(header, nodeSet) && this.hasExitLoopSucc(back, nodeSet)) { + // header true exit loop --> exit is break + if (!nodeSet.has(header.getSucc()[0])) { + return RegionType.DO_WHILE_LOOP_REGION; + } + } + + // for + if (back.getSucc().length === 1 && back.getBlock()?.getStmts()?.length === 1) { + let isForLoop = true; + for (const pred of header.getPred()) { + if (nodeSet.has(pred) && pred !== back) { + isForLoop = false; + } + } + if (isForLoop) { + return RegionType.FOR_LOOP_REGION; + } + } + + return RegionType.WHILE_LOOP_REGION; + } + + private hasExitLoopSucc(node: AbstractNode, nodeSet: Set): boolean { + for (const succ of node.getSucc()) { + if (!nodeSet.has(succ)) { + return true; + } + } + + return false; + } + + private isExitLoop(node: AbstractNode | Region, nodeSet: Set): boolean { + if (this.structBlocks.has(node)) { + for (const n of this.structBlocks.get(node)!) { + if (!nodeSet.has(n)) { + return true; + } + } + } else { + if (!nodeSet.has(node)) { + return true; + } + } + + return false; + } + + private createRegion(rtype: RegionType, nodeSet: Set): Region | undefined { + let node: Region | undefined; + if (rtype === RegionType.BLOCK_REGION) { + node = new BlockRegion(nodeSet); + } else if (rtype === RegionType.IF_ELSE_REGION) { + node = new IfElseRegion(nodeSet); + } else if (rtype === RegionType.IF_REGION) { + node = new IfRegion(nodeSet); + } else if (rtype === RegionType.IF_THEN_EXIT_REGION) { + node = new IfExitRegion(nodeSet); + } else if (rtype === RegionType.IF_THEN_BREAK_REGION) { + node = new IfBreakRegion(nodeSet); + } else if (rtype === RegionType.IF_THEN_CONTINUE_REGION) { + node = new IfContinueRegion(nodeSet); + } else if (rtype === RegionType.SELF_LOOP_REGION) { + node = new SelfLoopRegion(nodeSet); + } else if (rtype === RegionType.WHILE_LOOP_REGION) { + let whileLoop = new WhileLoopRegion(nodeSet); + this.loopMap.set(whileLoop.header, whileLoop); + node = whileLoop; + } else if (rtype === RegionType.FOR_LOOP_REGION) { + let forLoop = new ForLoopRegion(nodeSet); + this.loopMap.set(forLoop.header, forLoop); + node = forLoop; + } else if (rtype === RegionType.DO_WHILE_LOOP_REGION) { + let doWhileLoop = new DoWhileLoopRegion(nodeSet); + this.loopMap.set(doWhileLoop.header, doWhileLoop); + node = doWhileLoop; + } else if (rtype === RegionType.TRY_CATCH_REGION || rtype === RegionType.TRY_FINALLY_REGION || rtype === RegionType.TRY_CATCH_FINALLY_REGION) { + node = new TrapRegion(nodeSet, rtype); + } + + return node; + } + + private reduce(rtype: RegionType, nodeSet: Set): Region | undefined { + let region = this.createRegion(rtype, nodeSet); + region?.replace(); + if (region === undefined) { + return undefined; + } + this.structTypes.set(region, rtype); + let blocks = new Set(); + for (const s of nodeSet) { + this.structOf.set(s, region); + if (this.structBlocks.has(s as Region)) { + for (const b of this.structBlocks.get(s as Region)!) { + blocks.add(b); + } + } else { + blocks.add(s); + } + } + this.structBlocks.set(region, blocks); + return region; + } + + private setIntersect(a: Set, b: Set): Set { + let r = new Set(); + if (!b) { + return r; + } + for (const n of b) { + if (a.has(n)) { + r.add(n); + } + } + + return r; + } + + private isSetEqual(a: Set, b: Set): boolean { + if (a.size !== b.size) { + return false; + } + + return this.setIntersect(a, b).size === a.size; + } + + private buildTrap(traps?: Trap[]): NaturalTrapRegion[] { + if (!traps) { + return []; + } + traps.sort((a, b) => a.getTryBlocks().length + a.getCatchBlocks().length - (b.getTryBlocks().length + b.getCatchBlocks().length)); + + let trapRegions: NaturalTrapRegion[] = []; + + for (const trap of traps) { + let region = new NaturalTrapRegion(trap, this.block2NodeMap); + let findTrapRegion = this.getNaturalTrapRegion(region); + + if (!findTrapRegion) { + for (const n of region.getNodes()) { + this.structOf.set(n, region); + } + trapRegions.push(region); + continue; + } + if (findTrapRegion.type === RegionType.TRY_FINALLY_REGION) { + findTrapRegion.trySet = region.trySet; + findTrapRegion.catchSet = region.catchSet; + region = findTrapRegion; + } else { + findTrapRegion.finallySet = region.finallySet; + region = findTrapRegion; + } + + for (const n of region.getNodes()) { + this.structOf.set(n, region); + } + region.type = RegionType.TRY_CATCH_FINALLY_REGION; + } + + this.structOf.clear(); + + return trapRegions; + } + + private searchTrapFinallyNodes(trapRegions: NaturalTrapRegion[]): void { + // search finally + for (const region of trapRegions) { + if (region.type === RegionType.TRY_CATCH_REGION) { + continue; + } + + this.bfs(region); + } + } + + private bfs(region: NaturalTrapRegion): void { + let finallyNodes = new Set(); + let count = (region as NaturalTrapRegion).finallySet!.size; + let queue = [region.getSucc()[0]]; + while (queue.length > 0 && finallyNodes.size < count) { + let node = queue[0]; + queue.splice(0, 1); + finallyNodes.add(node); + (region as NaturalTrapRegion).identifyFinallySet.add(node); + for (const succ of node.getSucc()) { + if (!finallyNodes.has(succ)) { + queue.push(succ); + } + } + } + } + + private getNaturalTrapRegion(trap: NaturalTrapRegion): NaturalTrapRegion | undefined { + let findTrap = this.findNaturalTrapRegion(trap.trySet); + if (findTrap) { + return findTrap; + } + if (trap.catchSet) { + findTrap = this.findNaturalTrapRegion(trap.catchSet); + } + + if (findTrap) { + return findTrap; + } + + if (trap.finallySet) { + findTrap = this.findNaturalTrapRegion(trap.finallySet); + } + + return findTrap; + } + + private findNaturalTrapRegion(nodes: Set): NaturalTrapRegion | undefined { + let findTrap: NaturalTrapRegion | undefined; + for (const node of nodes) { + if (!this.structOf.has(node)) { + return undefined; + } + if (!findTrap) { + findTrap = this.structOf.get(node)! as NaturalTrapRegion; + continue; + } + if (findTrap !== this.structOf.get(node)) { + return undefined; + } + } + return findTrap; + } + + private trapsStructuralAnalysis(trapRegions: NaturalTrapRegion[]): void { + trapRegions.sort((a, b) => a.size() - b.size()); + + for (const trap of trapRegions) { + let tryNode = this.trapsSubStructuralAnalysis(trap.trySet)!; + let catchNode: AbstractNode | undefined = this.trapsSubStructuralAnalysis(trap.catchSet); + let finnallyNode: AbstractNode | undefined = this.trapsSubStructuralAnalysis(trap.identifyFinallySet); + + if (catchNode === undefined) { + this.reduce(RegionType.TRY_FINALLY_REGION, new Set([tryNode, finnallyNode!])); + } else if (finnallyNode === undefined) { + this.reduce(RegionType.TRY_CATCH_REGION, new Set([tryNode, catchNode!])); + } else { + this.reduce(RegionType.TRY_CATCH_FINALLY_REGION, new Set([tryNode, catchNode!, finnallyNode!])); + } + } + } + + private trapsSubStructuralAnalysis(nodes?: Set): AbstractNode | undefined { + if (!nodes) { + return undefined; + } + let entry = Array.from(nodes)[0]; + if (nodes.size <= 1) { + return entry; + } + + for (const node of nodes) { + if (this.structOf.has(node)) { + nodes.add(this.structOf.get(node)!); + } + } + + return this.structuralAnalysis(entry, nodes); + } +} + +enum RegionType { + ABSTRACT_NODE, + TRY_NODE, + CATCH_NODE, + FINALLY_NODE, + /* Sequence of blocks. */ + BLOCK_REGION, + IF_REGION, + IF_ELSE_REGION, + IF_THEN_EXIT_REGION, + IF_THEN_BREAK_REGION, + IF_THEN_CONTINUE_REGION, + SELF_LOOP_REGION, + NATURAL_LOOP_REGION, + WHILE_LOOP_REGION, + DO_WHILE_LOOP_REGION, + FOR_LOOP_REGION, + CASE_REGION, + SWITCH_REGION, + TRY_CATCH_REGION, + TRY_FINALLY_REGION, + TRY_CATCH_FINALLY_REGION, +} + +const LOOP_TYPES = new Set([ + RegionType.SELF_LOOP_REGION, + RegionType.NATURAL_LOOP_REGION, + RegionType.WHILE_LOOP_REGION, + RegionType.FOR_LOOP_REGION, + RegionType.DO_WHILE_LOOP_REGION, +]); + +class AbstractNode { + type: RegionType; + private predNodes: AbstractNode[] = []; + private succNodes: AbstractNode[] = []; + private bb: BasicBlock | undefined; + + constructor() { + this.type = RegionType.ABSTRACT_NODE; + } + + public traversal(callback: TraversalCallback, type: CodeBlockType): void { + callback(this.bb, type); + } + + public getType(): RegionType { + return this.type; + } + + public getSucc(): AbstractNode[] { + return this.succNodes; + } + + public addSucc(node: AbstractNode): void { + this.succNodes.push(node); + } + + public replaceSucc(src: AbstractNode, dst: AbstractNode): void { + for (let i = 0; i < this.succNodes.length; i++) { + if (this.succNodes[i] === src) { + this.succNodes[i] = dst; + break; + } + } + } + + public removeSucc(src: AbstractNode): void { + for (let i = 0; i < this.predNodes.length; i++) { + if (this.succNodes[i] === src) { + this.succNodes.splice(i, 1); + break; + } + } + } + + public getPred(): AbstractNode[] { + return this.predNodes; + } + + public addPred(block: AbstractNode): void { + let set = new Set(this.predNodes); + if (set.has(block)) { + return; + } + this.predNodes.push(block); + } + + public replacePred(src: AbstractNode, dst: AbstractNode): void { + for (let i = 0; i < this.predNodes.length; i++) { + if (this.predNodes[i] === src) { + this.predNodes[i] = dst; + break; + } + } + } + + public removePred(src: AbstractNode): void { + for (let i = 0; i < this.predNodes.length; i++) { + if (this.predNodes[i] === src) { + this.predNodes.splice(i, 1); + break; + } + } + } + + public setBlock(bb: BasicBlock): void { + this.bb = bb; + } + + public getBlock(): BasicBlock | undefined { + return this.bb; + } + + public hasIfStmt(): boolean { + if (!this.bb) { + return false; + } + + for (let stmt of this.bb.getStmts()) { + if (stmt instanceof ArkIfStmt) { + return true; + } + } + return false; + } + + public hasReturnStmt(): boolean { + if (!this.bb) { + return false; + } + for (let stmt of this.bb.getStmts()) { + if (stmt instanceof ArkReturnStmt) { + return true; + } + } + return false; + } +} + +abstract class Region extends AbstractNode { + nset: Set; + constructor(nset: Set, type: RegionType) { + super(); + this.nset = nset; + this.type = type; + } + + public getBlock(): BasicBlock | undefined { + if (this.nset.size === 0) { + return undefined; + } + + return Array.from(this.nset)[0].getBlock(); + } + + public abstract replace(): void; +} + +class BlockRegion extends Region { + blocks: AbstractNode[]; + constructor(nset: Set) { + super(nset, RegionType.BLOCK_REGION); + this.blocks = Array.from(nset); + } + + public replace(): void { + for (let pred of this.blocks[0].getPred()) { + pred.replaceSucc(this.blocks[0], this); + this.addPred(pred); + } + + for (let succ of this.blocks[this.blocks.length - 1].getSucc()) { + succ.replacePred(this.blocks[this.blocks.length - 1], this); + this.addSucc(succ); + } + } + + public traversal(callback: TraversalCallback): void { + for (const node of this.blocks) { + node.traversal(callback, CodeBlockType.NORMAL); + } + } +} + +abstract class NaturalLoopRegion extends Region { + header: AbstractNode; + back: AbstractNode; + control: Set; + + constructor(nset: Set, type: RegionType = RegionType.NATURAL_LOOP_REGION) { + super(nset, type); + let nodes = Array.from(nset); + this.header = nodes[0]; + if (nset.size > 1) { + this.back = nodes[1]; + } else { + this.back = nodes[0]; + } + this.control = new Set([this.header]); + } + + public replace(): void { + for (let pred of this.header.getPred()) { + if (!this.nset.has(pred)) { + pred.replaceSucc(this.header, this); + this.addPred(pred); + } + } + + let succNodes = new Set(); + for (let node of this.nset) { + for (let succ of node.getSucc()) { + if (!this.nset.has(succ)) { + succNodes.add(succ); + } + } + } + + if (succNodes.size === 0) { + return; + } + + let pred = Array.from(succNodes)[0]; + let replaced = false; + for (let succ of pred.getPred()) { + if (this.nset.has(succ)) { + if (!replaced) { + pred.replacePred(succ, this); + this.addSucc(pred); + replaced = true; + } else { + pred.removePred(succ); + } + } + } + } + + public revise(): void { + // add node to loop sets + for (const node of this.nset) { + for (const succ of node.getSucc()) { + if (!this.nset.has(succ) && succ !== this.getExitNode() && succ.getSucc().length === 1 && succ.getSucc()[0] === this.getExitNode()) { + this.nset.add(succ); + } + } + } + } + + abstract getExitNode(): AbstractNode; +} + +class SelfLoopRegion extends NaturalLoopRegion { + constructor(nset: Set) { + super(nset, RegionType.SELF_LOOP_REGION); + this.back = this.header; + } + + public replace(): void { + for (let pred of this.header.getPred()) { + if (pred !== this.header) { + pred.replaceSucc(this.header, this); + this.addPred(pred); + } + } + + for (let succ of this.header.getSucc()) { + if (succ !== this.header) { + succ.replacePred(this.header, this); + this.addSucc(succ); + } + } + } + + getExitNode(): AbstractNode { + return this.header.getSucc()[1]; + } +} + +class WhileLoopRegion extends NaturalLoopRegion { + constructor(nset: Set) { + super(nset, RegionType.WHILE_LOOP_REGION); + } + + public traversal(callback: TraversalCallback): void { + this.header.traversal(callback, CodeBlockType.WHILE); + if (this.header !== this.back) { + this.back.traversal(callback, CodeBlockType.NORMAL); + } + callback(undefined, CodeBlockType.COMPOUND_END); + } + + getExitNode(): AbstractNode { + return this.header.getSucc()[1]; + } +} + +class DoWhileLoopRegion extends NaturalLoopRegion { + constructor(nset: Set) { + super(nset, RegionType.DO_WHILE_LOOP_REGION); + this.control.clear(); + this.control.add(this.back); + } + + public traversal(callback: TraversalCallback): void { + callback(undefined, CodeBlockType.DO); + if (this.header !== this.back) { + this.header.traversal(callback, CodeBlockType.NORMAL); + } + this.back.traversal(callback, CodeBlockType.DO_WHILE); + } + + getExitNode(): AbstractNode { + return this.back.getSucc()[1]; + } +} + +class ForLoopRegion extends NaturalLoopRegion { + inc: AbstractNode; + + constructor(nset: Set) { + super(nset, RegionType.FOR_LOOP_REGION); + this.inc = this.back; + this.control.add(this.inc); + } + + public traversal(callback: TraversalCallback): void { + this.header.traversal(callback, CodeBlockType.FOR); + for (const node of this.nset) { + if (node !== this.header && node !== this.inc) { + node.traversal(callback, CodeBlockType.NORMAL); + } + } + callback(undefined, CodeBlockType.COMPOUND_END); + } + + getExitNode(): AbstractNode { + return this.header.getSucc()[1]; + } +} + +class IfRegion extends Region { + contition: AbstractNode; + then: AbstractNode; + + constructor(nset: Set) { + super(nset, RegionType.IF_REGION); + let nodes = Array.from(nset); + this.contition = nodes[0]; + this.then = nodes[1]; + } + + public replace(): void { + this.replaceContitionPred(); + + for (let succ of this.then.getSucc()) { + if (succ !== this.then) { + succ.replacePred(this.then, this); + succ.removePred(this.contition); + this.addSucc(succ); + } + } + } + + public traversal(callback: TraversalCallback): void { + this.contition.traversal(callback, CodeBlockType.IF); + this.then.traversal(callback, CodeBlockType.NORMAL); + callback(undefined, CodeBlockType.COMPOUND_END); + } + + protected replaceContitionPred(): void { + for (let pred of this.contition.getPred()) { + if (pred !== this.contition) { + pred.replaceSucc(this.contition, this); + this.addPred(pred); + } + } + } +} + +class IfExitRegion extends IfRegion { + constructor(nset: Set) { + super(nset); + this.type = RegionType.IF_THEN_EXIT_REGION; + } + + public replace(): void { + this.replaceContitionPred(); + + let succ = this.contition.getSucc()[1]; + succ.replacePred(this.contition, this); + this.addSucc(succ); + } +} + +class IfBreakRegion extends IfRegion { + constructor(nset: Set) { + super(nset); + this.type = RegionType.IF_THEN_BREAK_REGION; + } + + public replace(): void { + this.replaceContitionPred(); + + let succ = this.contition.getSucc()[1]; + succ.replacePred(this.contition, this); + this.addSucc(succ); + + if (this.then) { + succ = this.then.getSucc()[0]; + succ.removePred(this.then); + } else { + succ = this.contition.getSucc()[0]; + succ.removePred(this.contition); + } + } + + public traversal(callback: TraversalCallback): void { + this.contition.traversal(callback, CodeBlockType.IF); + this.then?.traversal(callback, CodeBlockType.NORMAL); + callback(undefined, CodeBlockType.BREAK); + callback(undefined, CodeBlockType.COMPOUND_END); + } +} + +class IfContinueRegion extends IfBreakRegion { + constructor(nset: Set) { + super(nset); + this.type = RegionType.IF_THEN_CONTINUE_REGION; + } + + public traversal(callback: TraversalCallback): void { + this.contition.traversal(callback, CodeBlockType.IF); + this.then?.traversal(callback, CodeBlockType.NORMAL); + callback(undefined, CodeBlockType.CONTINUE); + callback(undefined, CodeBlockType.COMPOUND_END); + } +} + +class IfElseRegion extends Region { + contition: AbstractNode; + then: AbstractNode; + else: AbstractNode; + + constructor(nset: Set) { + super(nset, RegionType.IF_ELSE_REGION); + let nodes = Array.from(nset); + this.contition = nodes[0]; + this.then = nodes[1]; + this.else = nodes[2]; + } + + public replace(): void { + for (let pred of this.contition.getPred()) { + if (pred !== this.contition) { + pred.replaceSucc(this.contition, this); + this.addPred(pred); + } + } + + for (let succ of this.then.getSucc()) { + if (succ !== this.then) { + succ.replacePred(this.then, this); + succ.removePred(this.else); + this.addSucc(succ); + } + } + } + + public traversal(callback: TraversalCallback): void { + this.contition.traversal(callback, CodeBlockType.IF); + this.then.traversal(callback, CodeBlockType.NORMAL); + callback(undefined, CodeBlockType.ELSE); + this.else.traversal(callback, CodeBlockType.NORMAL); + callback(undefined, CodeBlockType.COMPOUND_END); + } +} + +class TrapRegion extends Region { + tryNode: AbstractNode; + catchNode?: AbstractNode; + finallyNode?: AbstractNode; + + constructor(nset: Set, type: RegionType) { + super(nset, type); + let nodes = Array.from(nset); + + this.tryNode = nodes[0]; + if (type === RegionType.TRY_CATCH_REGION) { + this.catchNode = nodes[1]; + } else if (type === RegionType.TRY_FINALLY_REGION) { + this.finallyNode = nodes[1]; + } else { + this.catchNode = nodes[1]; + this.finallyNode = nodes[2]; + } + } + + public replace(): void { + for (let pred of this.tryNode.getPred()) { + if (pred !== this.tryNode) { + pred.replaceSucc(this.tryNode, this); + this.addPred(pred); + } + } + + if (this.finallyNode) { + for (let succ of this.finallyNode.getSucc()) { + if (succ !== this.finallyNode) { + succ.replacePred(this.finallyNode, this); + this.addSucc(succ); + } + } + } else { + for (let succ of this.tryNode.getSucc()) { + if (succ !== this.tryNode) { + succ.replacePred(this.tryNode, this); + this.addSucc(succ); + } + } + } + } + + public traversal(callback: TraversalCallback): void { + callback(undefined, CodeBlockType.TRY); + this.tryNode.traversal(callback, CodeBlockType.NORMAL); + if (this.catchNode) { + callback(this.catchNode.getBlock(), CodeBlockType.CATCH); + this.catchNode?.traversal(callback, CodeBlockType.NORMAL); + } + if (this.finallyNode) { + callback(undefined, CodeBlockType.FINALLY); + this.finallyNode?.traversal(callback, CodeBlockType.NORMAL); + } + callback(undefined, CodeBlockType.COMPOUND_END); + } +} + +class NaturalTrapRegion extends Region { + trySet: Set; + catchSet?: Set; + finallySet?: Set; + identifyFinallySet: Set; + + constructor(trap: Trap, block2NodeMap: Map) { + super(new Set(), RegionType.TRY_CATCH_FINALLY_REGION); + this.trySet = new Set(); + this.catchSet = new Set(); + this.identifyFinallySet = new Set(); + + for (const block of trap.getTryBlocks()) { + this.trySet.add(block2NodeMap.get(block)!); + } + + for (const block of trap.getCatchBlocks()) { + this.catchSet.add(block2NodeMap.get(block)!); + } + + if (this.isFinallyNode(Array.from(this.catchSet!)[this.catchSet.size - 1])!) { + this.type = RegionType.TRY_FINALLY_REGION; + this.finallySet = this.catchSet; + this.catchSet = undefined; + } else { + this.type = RegionType.TRY_CATCH_REGION; + } + } + + private isFinallyNode(node: AbstractNode): boolean { + let block = node.getBlock(); + if (!block) { + return false; + } + + let stmtLen = block.getStmts().length; + if (stmtLen < 1) { + return false; + } + + let stmtLast = block.getStmts()[stmtLen - 1]; + return stmtLast instanceof ArkThrowStmt; + } + + public size(): number { + let size = this.trySet.size; + if (this.catchSet) { + size += this.catchSet.size; + } + if (this.finallySet) { + size += this.finallySet.size; + } + return size; + } + + public replace(): void {} + + public getNodes(): AbstractNode[] { + let nodes = Array.from(this.trySet); + + if (this.catchSet) { + nodes.push(...this.catchSet); + } + + if (this.finallySet) { + nodes.push(...this.finallySet); + } + return nodes; + } + + public getSucc(): AbstractNode[] { + let succ = new Set(); + + for (const node of this.trySet) { + for (const s of node.getSucc()) { + if (!this.trySet.has(s)) { + succ.add(s); + } + } + } + return Array.from(succ); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/FileUtils.ts b/ets2panda/linter/arkanalyzer/src/utils/FileUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..a4837006ed4512526243608ef0edfd6a714c0686 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/FileUtils.ts @@ -0,0 +1,134 @@ +/* + * 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. + */ + +import fs from 'fs'; +import path from 'path'; +import Logger, { LOG_MODULE_TYPE } from './logger'; +import { transfer2UnixPath } from './pathTransfer'; +import { OH_PACKAGE_JSON5 } from '../core/common/EtsConst'; +import { Language } from '../core/model/ArkFile'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'FileUtils'); + +export class FileUtils { + public static readonly FILE_FILTER = { + ignores: ['.git', '.preview', '.hvigor', '.idea', 'test', 'ohosTest'], + include: /(?): Map { + const moduleMap: Map = new Map(); + ohPkgContentMap.forEach((content, filePath) => { + const moduleName = content.name as string; + if (moduleName && moduleName.startsWith('@')) { + const modulePath = path.dirname(filePath); + moduleMap.set(moduleName, new ModulePath(modulePath, content.main ? path.resolve(modulePath, content.main as string) : '')); + } + }); + ohPkgContentMap.forEach((content, filePath) => { + if (!content.dependencies) { + return; + } + Object.entries(content.dependencies).forEach(([name, value]) => { + if (moduleMap.get(name)) { + return; + } + const modulePath = path.resolve(path.dirname(filePath), value.replace('file:', '')); + const key = path.resolve(modulePath, OH_PACKAGE_JSON5); + const target = ohPkgContentMap.get(key); + if (target) { + moduleMap.set(name, new ModulePath(modulePath, target.main ? path.resolve(modulePath, target.main as string) : '')); + } + }); + }); + return moduleMap; + } + + public static getFileLanguage(file: string, fileTags?: Map): Language { + if (fileTags && fileTags.has(file)) { + return fileTags.get(file) as Language; + } + const extension = path.extname(file).toLowerCase(); + switch (extension) { + case '.ts': + return Language.TYPESCRIPT; + case '.ets': + return Language.ARKTS1_1; + case '.js': + return Language.JAVASCRIPT; + default: + return Language.UNKNOWN; + } + } +} + +export class ModulePath { + path: string; + main: string; + + constructor(path: string, main: string) { + this.path = transfer2UnixPath(path); + this.main = transfer2UnixPath(main); + } +} + +export function getFileRecursively(srcDir: string, fileName: string, visited: Set = new Set()): string { + let res = ''; + if (!fs.existsSync(srcDir) || !fs.statSync(srcDir).isDirectory()) { + logger.warn(`Input directory ${srcDir} is not exist`); + return res; + } + + const filesUnderThisDir = fs.readdirSync(srcDir, { withFileTypes: true }); + const realSrc = fs.realpathSync(srcDir); + if (visited.has(realSrc)) { + return res; + } + visited.add(realSrc); + + filesUnderThisDir.forEach(file => { + if (res !== '') { + return res; + } + if (file.name === fileName) { + res = path.resolve(srcDir, file.name); + return res; + } + const tmpDir = path.resolve(srcDir, '../'); + res = getFileRecursively(tmpDir, fileName, visited); + return res; + }); + return res; +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/SparseBitVector.ts b/ets2panda/linter/arkanalyzer/src/utils/SparseBitVector.ts new file mode 100644 index 0000000000000000000000000000000000000000..fcb5c816ac5f5b5ef8e9b4f3ace185db43c041c4 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/SparseBitVector.ts @@ -0,0 +1,546 @@ +/* + * 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. + */ + +/** + * SparseBitVector is a LLVM-interfaces-like data structure designed to efficiently + * represent and manipulate large sets of integers where the majority of the elements + * are unset (i.e., sparse). It is particularly useful in scenarios where memory efficiency + * is critical, and the set of integers contains large gaps between set bits. + * + * The SparseBitVector is implemented as a collection of SparseBitVectorElement objects, + * where each element represents a fixed-size chunk of the bit vector. This allows the + * structure to only allocate memory for the portions of the bit vector that contain + * set bits, significantly reducing memory usage for sparse data. + * + * Key Features: + * - **Unordered**: We implement it as unordered rather than LLVM's for performance reason. + * - **Sparse Storage**: Only stores the indices of set bits, making it memory-efficient + * for sparse datasets. + * - **Efficient Operations**: Supports fast bitwise operations such as union and intersection + * - **Iterable**: Provides an iterator to traverse all set bits in stored order. + * - **Dynamic Resizing**: Automatically adjusts its internal structure as bits are set + * or reset. + * + * Perforceman VS Array + * - **Random Store** 2.5:1 + * - **Continuous Store** 1:1 + * - **Random Test** 1:6 + * - **Continuous Test** 1:1 + * - **Random Iterator** 4:1 + * - **Continuous Iterator** 2:1 + * + * The SparseBitVector is parameterized by `ElementSize`, which defines the size of each + * chunk (element) in the bit vector and MUST be times of 32. This allows for customization + * based on the expected sparsity and performance requirements. + * + */ + +export type Word = Uint16Array; +const BITWORD_SIZE = 16; // bits of a Word +const DEFAULT_SIZE = 64; +class SparseBitVectorElement { + private ELEMENT_SIZE; // bits of element. Default as 128 + private BITWORDS_NUM; // number of words + private bits: Word; + + constructor(elementSize: number = DEFAULT_SIZE) { + this.ELEMENT_SIZE = elementSize; + this.BITWORDS_NUM = Math.ceil(this.ELEMENT_SIZE / BITWORD_SIZE); + this.bits = new Uint16Array(this.BITWORDS_NUM); + } + + word(idx: number): number { + return this.bits[idx]; + } + + clone(): Word { + return new Uint16Array(this.bits); + } + + get elementSize(): number { + return this.ELEMENT_SIZE; + } + + get bitWordNum(): number { + return this.BITWORDS_NUM; + } + + // Check if the element is empty (all bits are zero) + isEmpty(): boolean { + return this.isZero(); + } + + // Set a bit at the given index + set(bitIdx: number): void { + const wordIndex = Math.floor(bitIdx / BITWORD_SIZE); + const bitOffset = bitIdx % BITWORD_SIZE; + this.bits[wordIndex] |= 1 << bitOffset; + } + + setWord(word: Word): void { + this.bits = word; + } + + // Reset a bit at the given index + reset(bitIdx: number): void { + const wordIndex = Math.floor(bitIdx / BITWORD_SIZE); + const bitOffset = bitIdx % BITWORD_SIZE; + this.bits[wordIndex] &= ~(1 << bitOffset); + } + + // Test if a bit is set + test(bitIdx: number): boolean { + const wordIndex = Math.floor(bitIdx / BITWORD_SIZE); + const bitOffset = bitIdx % BITWORD_SIZE; + return (this.bits[wordIndex] & (1 << bitOffset)) !== 0; + } + + // Set if not existing, else return + test_and_set(bitIdx: number): boolean { + let old = this.test(bitIdx); + if (!old) { + this.set(bitIdx); + return true; + } + return false; + } + + // Count the number of set bits in this element + count(): number { + let numBits = 0; + this.bits.forEach(word => { + numBits += this.countBits(word); + }); + return numBits; + } + + // Find the index of the first set bit in this element + findFirst(): number { + for (let i = 0; i < this.bits.length; i++) { + if (this.bits[i] !== 0) { + return i * BITWORD_SIZE + this.countTrailingZeros(this.bits[i]); + } + } + return -1; // No bits are set + } + + // Find the next set bit after the given index + findNext(bitIdx: number): number { + bitIdx++; + let wordIndex = Math.floor(bitIdx / BITWORD_SIZE); + let bitOffset = bitIdx % BITWORD_SIZE; + + // Check the current word + // Mask off previous bits + let word = this.bits[wordIndex] & (~0 << bitOffset); + if (word !== 0) { + return wordIndex * BITWORD_SIZE + this.countTrailingZeros(word); + } + + // Check subsequent words + for (let i = wordIndex + 1; i < this.bits.length; i++) { + if (this.bits[i] !== 0) { + return i * BITWORD_SIZE + this.countTrailingZeros(this.bits[i]); + } + } + + return -1; // No more bits are set + } + + // Comparison + equals(rhs: SparseBitVectorElement): boolean { + for (let i = 0; i < this.BITWORDS_NUM; i++) { + if (this.bits[i] !== rhs.word(i)) { + return false; + } + } + + return true; + } + + // Union this element with another element and return true if this one changed + unionWith(other: SparseBitVectorElement): boolean { + let changed = false; + for (let i = 0; i < this.bits.length; i++) { + const oldWord = changed ? 0 : this.bits[i]; + this.bits[i] |= other.bits[i]; + if (!changed && oldWord !== this.bits[i]) { + changed = true; + } + } + return changed; + } + + // Intersect this element with another element and return true if this one changed. + intersectWith(other: SparseBitVectorElement): boolean { + let changed = false; + for (let i = 0; i < this.bits.length; i++) { + const oldWord = changed ? 0 : this.bits[i]; + this.bits[i] &= other.bits[i]; + if (!changed && oldWord !== this.bits[i]) { + changed = true; + } + } + return changed; + } + + // Subtract another SparseBitVectorElement from this one. + subtractWith(rhs: SparseBitVectorElement): boolean { + let changed = false; + // Perform subtraction: this = this & ~rhs + for (let i = 0; i < this.bits.length; i++) { + const oldWord = this.bits[i]; + this.bits[i] &= ~rhs.bits[i]; + + // If any bit was changed, mark as changed + if (this.bits[i] !== oldWord) { + changed = true; + } + } + + return changed; + } + + // Count the number of set bits in a word + countBitsV2(word: number): number { + let count = 0; + while (word !== 0) { + word &= word - 1; + count++; + } + return count; + } + + // Count the number of set bits in a word + countBits(word: number): number { + // assume the value is treated as a unsigned integer + let v = word; + + // Step 1: Pairwise addition of bits + v = v - ((v >> 1) & 0x55555555); + // Step 2: Group bits into 4-bit chunks and add + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); + // Step 3: Group bits into 8-bit chunks and add + v = (v + (v >> 4)) & 0xf0f0f0f; + // Step 4: Multiply by a magic number to sum all 8-bit chunks into the highest byte + v = (v * 0x1010101) >> 24; + + return v; + } + + isZero(): boolean { + for (let i = 0; i < this.BITWORDS_NUM; i++) { + if (this.bits[i] !== 0) { + return false; + } + } + return true; + } + + // Count trailing zeros in a word + private countTrailingZeros(word: number): number { + if (word === 0) { + return BITWORD_SIZE; + } + + if ((word & 1) !== 0) { + return 0; + } + + let zeroBits = 0; + let shift = BITWORD_SIZE / 2; // Start with half the bit width + let mask = (1 << shift) - 1; // Mask for the lower half + + while (shift > 0) { + if ((word & mask) === 0) { + word >>= shift; + zeroBits |= Number(shift); + } + shift >>= 1; + mask >>= shift; + } + + return zeroBits; + } +} + +export class SparseBitVector { + private ELEMENT_SIZE: number; + // Unordered storage of elements. + // key is actually the element index (normally it is in element) + private elements: Map = new Map(); + + constructor(elementsSize: number = DEFAULT_SIZE) { + this.ELEMENT_SIZE = elementsSize; + } + + get elementSize(): number { + return this.ELEMENT_SIZE; + } + + get elems(): Map { + return this.elements; + } + + // Set a bit at the given index + set(bitIdx: number): void { + const elementIndex = Math.floor(bitIdx / this.ELEMENT_SIZE); + let element = this.elements.get(elementIndex); + if (!element) { + element = new SparseBitVectorElement(this.ELEMENT_SIZE); + this.elements.set(elementIndex, element); + } + element.set(bitIdx % this.ELEMENT_SIZE); + } + + // Test if a bit is set + test(bitIdx: number): boolean { + const elementIndex = Math.floor(bitIdx / this.ELEMENT_SIZE); + const element = this.elements.get(elementIndex); + return element ? element.test(bitIdx % this.ELEMENT_SIZE) : false; + } + + // Set a bit if not existing. Else return + testAndSet(bitIdx: number): boolean { + let old = this.test(bitIdx); + if (!old) { + this.set(bitIdx); + return true; + } + return false; + } + + // Reset a bit at the given index + reset(bitIdx: number): void { + const elementIndex = Math.floor(bitIdx / this.ELEMENT_SIZE); + let element = this.elements.get(elementIndex); + if (element) { + element.reset(bitIdx % this.ELEMENT_SIZE); + if (element.isEmpty()) { + this.elements.delete(elementIndex); + } + } + } + + // Clear all elements + clear(): void { + this.elements.clear(); + } + + // Clone, return a deep copied object + clone(): SparseBitVector { + const newVector = new SparseBitVector(this.elementSize); + for (const [idx, element] of this.elements) { + const newElement = new SparseBitVectorElement(this.elementSize); + newElement.setWord(element.clone()); + + newVector.elems.set(idx, newElement); + } + + return newVector; + } + + // Find the first set bit in the vector + findFirst(): number { + if (this.elements.size === 0) { + return -1; + } + const firstElement = this.elements.entries().next().value; + if (firstElement) { + const firstBit = firstElement[1].findFirst(); + return firstElement[0] * this.ELEMENT_SIZE + firstBit; + } else { + return -1; + } + } + + // Count the number of set bits in the vector + count(): number { + let count = 0; + this.elements.forEach((elem, _) => { + count += elem.count(); + }); + return count; + } + + // Check if the vector is empty + isEmpty(): boolean { + return this.elements.size === 0; + } + + [Symbol.iterator](): IterableIterator { + let iter = this.elements.entries(); + let next = iter.next(); + const elementSize = this.ELEMENT_SIZE; + let element = next.value; + if (!element) { + return { + next(): { value: undefined; done: true } { + return { value: undefined, done: true }; + }, + [Symbol.iterator](): IterableIterator { + return this; // Make the iterator itself iterable + }, + }; + } + let bitIndex = element[1].findFirst(); + return { + next(): IteratorResult { + if (element) { + let v = element[0] * elementSize + bitIndex; + bitIndex = element[1].findNext(bitIndex); + if (bitIndex === -1) { + next = iter.next(); + element = next.value; + if (element) { + bitIndex = element[1].findFirst(); + } + } + return { value: v, done: false }; + } + return { value: undefined, done: true }; + }, + [Symbol.iterator](): IterableIterator { + return this; // Make the iterator itself iterable + }, + }; + } + + /** + * Check if this SparseBitVector is equal to another SparseBitVector. + */ + equals(rhs: SparseBitVector): boolean { + if (this.ELEMENT_SIZE !== rhs.ELEMENT_SIZE || this.elems.size !== rhs.elems.size) { + return false; + } + + let rhsElems = rhs.elems; + for (let p of this.elements) { + let rhsElem = rhsElems.get(p[0]); + if (!rhsElem) { + return false; + } + if (!rhsElem.equals(p[1])) { + return false; + } + } + return true; + } + + /** + * Perform a union operation with another SparseBitVector. + * Returns True if this vector was changed, false otherwise. + */ + unionWith(rhs: SparseBitVector): boolean { + if (this.equals(rhs) || rhs.elems.size === 0) { + return false; + } + + let changed = false; + let newElems = new Map(); + for (let p of rhs.elems) { + let elem = this.elements.get(p[0]); + if (elem) { + changed = elem!.unionWith(p[1]) || changed; + } else { + newElems.set(p[0], p[1]); + } + } + + if (newElems.size > 0) { + newElems.forEach((v, k) => this.elements.set(k, v)); + changed = true; + } + + return changed; + } + + /** + * Perform an intersection operation with another SparseBitVector. + * Returns True if this vector was changed, false otherwise. + */ + intersectWith(rhs: SparseBitVector): boolean { + if (this.equals(rhs) || rhs.elems.size === 0) { + return false; + } + + let changed = false; + // If either vector is empty, the result is empty + if (this.elements.size === 0 || rhs.elems.size === 0) { + if (this.elements.size > 0) { + this.elements = new Map(); + changed = true; + } + return changed; + } + + let needDeleteIdx: Set = new Set(); + for (let p of this.elems) { + let elem = rhs.elems.get(p[0]); + if (elem) { + changed = p[1].intersectWith(elem) || changed; + if (changed && p[1].isZero()) { + needDeleteIdx.add(p[0]); + } + } else { + needDeleteIdx.add(p[0]); + } + } + + if (needDeleteIdx.size > 0) { + needDeleteIdx.forEach(idx => this.elements.delete(idx)); + changed = true; + } + + return changed; + } + + /** + * Subtract another SparseBitVector from this one. + * This operation modifies the current SparseBitVector in place. + * Return True if the current SparseBitVector was modified, false otherwise. + */ + subtractWith(rhs: SparseBitVector): boolean { + if (this.elementSize !== rhs.elementSize || this.isEmpty() || rhs.isEmpty()) { + return false; + } + + let needDeleteIdx: Set = new Set(); + let changed = false; + for (const [elementIndex, element] of this.elements) { + const rhsElement = rhs.elements.get(elementIndex); + + if (rhsElement) { + changed = element.subtractWith(rhsElement) || changed; + if (element.isEmpty()) { + needDeleteIdx.add(elementIndex); + } + } + } + + if (needDeleteIdx.size > 0) { + needDeleteIdx.forEach(idx => this.elements.delete(idx)); + changed = true; + } + + return changed; + } + + // Dump as string + toString(): string { + let ar = [...this]; + return ar.toString(); + } +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/callGraphUtils.ts b/ets2panda/linter/arkanalyzer/src/utils/callGraphUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..c15236a0b39262b735f78b2a3f81b647c536cce5 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/callGraphUtils.ts @@ -0,0 +1,210 @@ +/* + * 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. + */ + +import { Scene } from '../Scene'; +import { ArkClass } from '../core/model/ArkClass'; +import { ArkMethod } from '../core/model/ArkMethod'; +import { ClassSignature, MethodSignature } from '../core/model/ArkSignature'; +import Logger, { LOG_MODULE_TYPE } from './logger'; +import { ModelUtils } from '../core/common/ModelUtils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'callGraphUtils'); + +export class MethodSignatureManager { + private _workList: MethodSignature[] = []; + private _processedList: MethodSignature[] = []; + + get workList(): MethodSignature[] { + return this._workList; + } + + set workList(list: MethodSignature[]) { + this._workList = list; + } + + get processedList(): MethodSignature[] { + return this._processedList; + } + + set processedList(list: MethodSignature[]) { + this._processedList = list; + } + + public findInWorkList(signature: MethodSignature): MethodSignature | undefined { + return this.workList.find(item => item === signature); + } + + public findInProcessedList(signature: MethodSignature): boolean { + let result = this.processedList.find(item => item.toString() === signature.toString()); + return typeof result !== 'undefined'; + } + + public addToWorkList(signature: MethodSignature): void { + if (!isItemRegistered(signature, this.workList, (a, b) => a.toString() === b.toString())) { + this.workList.push(signature); + } + } + + public addToProcessedList(signature: MethodSignature): void { + if (!isItemRegistered(signature, this.processedList, (a, b) => a === b)) { + this.processedList.push(signature); + } + } + + public removeFromWorkList(signature: MethodSignature): void { + this.workList = this.workList.filter(item => item !== signature); + } + + public removeFromProcessedList(signature: MethodSignature): void { + this.processedList = this.processedList.filter(item => item.toString() !== signature.toString()); + } +} + +export class SceneManager { + private _scene!: Scene; + + get scene(): Scene { + return this._scene; + } + + set scene(value: Scene) { + this._scene = value; + } + + public getMethod(method: MethodSignature): ArkMethod | null { + let targetMethod = this._scene.getMethod(method); + if (targetMethod != null) { + return targetMethod; + } + // 支持SDK调用解析 + let file = this._scene.getFile(method.getDeclaringClassSignature().getDeclaringFileSignature()); + if (file) { + const methods = ModelUtils.getAllMethodsInFile(file); + for (let methodUnderFile of methods) { + if (method.toString() === methodUnderFile.getSignature().toString()) { + return methodUnderFile; + } + } + } + return targetMethod; + } + + public getClass(arkClass: ClassSignature): ArkClass | null { + if (typeof arkClass.getClassName() === 'undefined') { + return null; + } + let classInstance = this._scene.getClass(arkClass); + if (classInstance != null) { + return classInstance; + } + let sdkOrTargetProjectFile = this._scene.getFile(arkClass.getDeclaringFileSignature()); + // TODO: support get sdk class, targetProject class waiting to be supported + if (sdkOrTargetProjectFile != null) { + for (let classUnderFile of ModelUtils.getAllClassesInFile(sdkOrTargetProjectFile)) { + if (classUnderFile.getSignature().toString() === arkClass.toString()) { + return classUnderFile; + } + } + } + return classInstance; + } + + public getExtendedClasses(arkClass: ClassSignature): ArkClass[] { + let sourceClass = this.getClass(arkClass); + let classList = [sourceClass]; // 待处理类 + let extendedClasses: ArkClass[] = []; // 已经处理的类 + + while (classList.length > 0) { + let tempClass = classList.shift(); + if (tempClass == null) { + continue; + } + let firstLevelSubclasses: ArkClass[] = Array.from(tempClass.getExtendedClasses().values()); + + if (!firstLevelSubclasses) { + continue; + } + + for (let subclass of firstLevelSubclasses) { + if (!isItemRegistered(subclass, extendedClasses, (a, b) => a.getSignature().toString() === b.getSignature().toString())) { + // 子类未处理,加入到classList + classList.push(subclass); + } + } + + // 当前类处理完毕,标记为已处理 + if (!isItemRegistered(tempClass, extendedClasses, (a, b) => a.getSignature().toString() === b.getSignature().toString())) { + extendedClasses.push(tempClass); + } + } + return extendedClasses; + } +} + +export function isItemRegistered(item: T, array: T[], compareFunc: (a: T, b: T) => boolean): boolean { + for (let tempItem of array) { + if (compareFunc(tempItem, item)) { + return true; + } + } + return false; +} + +export function splitStringWithRegex(input: string): string[] { + // 正则表达式匹配 "a.b.c()" 并捕获 "a" "b" "c" + const regex = /^(\w+)\.(\w+)\.(\w+)\(\)$/; + const match = input.match(regex); + + if (match) { + // 返回捕获的部分,忽略整个匹配结果 + return match.slice(1); + } else { + // 如果输入不匹配,返回空数组 + return []; + } +} + +export function printCallGraphDetails(methods: Set, calls: Map, rootDir: string): void { + // 打印 Methods + logger.info('Call Graph:\n'); + logger.info('\tMethods:'); + methods.forEach(method => { + logger.info(`\t\t${method}`); + }); + + // 打印 Calls + logger.info('\tCalls:'); + const arrow = '->'; + calls.forEach((calledMethods, method) => { + // 对于每个调用源,只打印一次调用源和第一个目标方法 + const modifiedMethodName = `<${method}`; + logger.info(`\t\t${modifiedMethodName.padEnd(4)} ${arrow}`); + + for (let i = 0; i < calledMethods.length; i++) { + const modifiedCalledMethod = `\t\t<${calledMethods[i]}`; + logger.info(`\t\t${modifiedCalledMethod}`); + } + logger.info('\n'); + }); +} + +export function extractLastBracketContent(input: string): string { + // 正则表达式匹配最后一个尖括号内的内容,直到遇到左圆括号 + const match = input.match(/<([^<>]*)\(\)>$/); + if (match && match[1]) { + return match[1].trim(); + } + return ''; +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/crypto_utils.ts b/ets2panda/linter/arkanalyzer/src/utils/crypto_utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..9563d475b185cfd792bd3f5161f25bc4f5fb372f --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/crypto_utils.ts @@ -0,0 +1,34 @@ +/* + * 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. + */ + +import * as crypto from 'crypto'; + +export class CryptoUtils { + public static sha256(content: string): string { + return this.hash(content, 'sha256'); + } + + public static hash(content: string, algorithm: string): string { + return crypto.createHash(algorithm).update(content).digest('base64url'); + } + + public static hashcode(content: string): number { + let h = 0; + for (let i = 0; i < content.length; i++) { + h = (Math.imul(31, h) + content.charCodeAt(i)) | 0; + } + return h; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/entryMethodUtils.ts b/ets2panda/linter/arkanalyzer/src/utils/entryMethodUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..b908801378ae05590d4b2af3689d5573caebd8db --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/entryMethodUtils.ts @@ -0,0 +1,125 @@ +/* + * 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. + */ + +import { Scene } from '../Scene'; +import { ArkMethod } from '../core/model/ArkMethod'; +import { Stmt } from '../core/base/Stmt'; +import { FunctionType } from '../core/base/Type'; + +export const LIFECYCLE_METHOD_NAME: string[] = [ + 'onCreate', // 组件实例创建 + 'onDestroy', // 组件实例销毁 + 'onWindowStageCreate', // 窗口创建 + 'onWindowStageDestroy', // 窗口销毁 + 'onForeground', // 应用进入前台 + 'onBackground', // 应用进入后台 + 'onBackup', // 应用数据备份 + 'onRestore', // 应用数据恢复 + 'onContinue', + 'onNewWant', + 'onDump', + 'onSaveState', + 'onShare', + 'onPrepareToTerminate', + 'onBackPressed', + 'onSessionCreate', + 'onSessionDestory', + 'onAddForm', + 'onCastToNormalForm', + 'onUpdateForm', + 'onChangeFormVisibility', + 'onFormEvent', + 'onRemoveForm', + 'onConfigurationUpdate', + 'onAcquireFormState', + 'onWindowStageWillDestroy', +]; +export const CALLBACK_METHOD_NAME: string[] = [ + 'onClick', // 点击事件,当用户点击组件时触发 + 'onTouch', // 触摸事件,当手指在组件上按下、滑动、抬起时触发 + 'onAppear', // 组件挂载显示时触发 + 'onDisAppear', // 组件卸载消失时触发 + 'onDragStart', // 拖拽开始事件,当组件被长按后开始拖拽时触发 + 'onDragEnter', // 拖拽进入组件范围时触发 + 'onDragMove', // 拖拽在组件范围内移动时触发 + 'onDragLeave', // 拖拽离开组件范围内时触发 + 'onDrop', // 拖拽释放目标,当在本组件范围内停止拖拽行为时触发 + 'onKeyEvent', // 按键事件,当组件获焦后,按键动作触发 + 'onFocus', // 焦点事件,当组件获取焦点时触发 + 'onBlur', // 当组件失去焦点时触发的回调 + 'onHover', // 鼠标悬浮事件,鼠标进入或退出组件时触发 + 'onMouse', // 鼠标事件,当鼠标按键点击或在组件上移动时触发 + 'onAreaChange', // 组件区域变化事件,组件尺寸、位置变化时触发 + 'onVisibleAreaChange', // 组件可见区域变化事件,组件在屏幕中的显示区域面积变化时触发 +]; + +export const COMPONENT_LIFECYCLE_METHOD_NAME: string[] = [ + 'build', + 'aboutToAppear', + 'aboutToDisappear', + 'aboutToReuse', + 'aboutToRecycle', + 'onWillApplyTheme', + 'onLayout', + 'onPlaceChildren', + 'onMeasure', + 'onMeasureSize', + 'onPageShow', + 'onPageHide', + 'onFormRecycle', + 'onFormRecover', + 'onBackPress', + 'pageTransition', + 'onDidBuild', +]; + +export interface AbilityMessage { + srcEntry: string; + name: string; + srcEntrance: string; +} + +export function getCallbackMethodFromStmt(stmt: Stmt, scene: Scene): ArkMethod | null { + const invokeExpr = stmt.getInvokeExpr(); + if ( + invokeExpr === undefined || + invokeExpr.getMethodSignature().getDeclaringClassSignature().getClassName() !== '' || + !CALLBACK_METHOD_NAME.includes(invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName()) + ) { + return null; + } + + for (const arg of invokeExpr.getArgs()) { + const argType = arg.getType(); + if (argType instanceof FunctionType) { + const cbMethod = scene.getMethod(argType.getMethodSignature()); + if (cbMethod) { + return cbMethod; + } + } + } + return null; +} + +export function addCfg2Stmt(method: ArkMethod): void { + const cfg = method.getCfg(); + if (cfg) { + for (const block of cfg.getBlocks()) { + for (const stmt of block.getStmts()) { + stmt.setCfg(cfg); + } + } + } +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/getAllFiles.ts b/ets2panda/linter/arkanalyzer/src/utils/getAllFiles.ts new file mode 100644 index 0000000000000000000000000000000000000000..fe4af56c9ee242b52cea84b590a4107fc5f76554 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/getAllFiles.ts @@ -0,0 +1,71 @@ +/* + * 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. + */ + +import fs from 'fs'; +import path from 'path'; +import Logger, { LOG_MODULE_TYPE } from './logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'getAllFiles'); +/** + * 从指定目录中提取指定后缀名的所有文件 + * @param srcPath string 要提取文件的项目入口,相对或绝对路径都可 + * @param exts string[] 要提取的文件扩展名数组,每个扩展名需以点开头 + * @param filenameArr string[] 用来存放提取出的文件的原始路径的数组,可不传,默认为空数组 + * @param visited: Set 用来存放已经访问过的路径,避免递归栈溢出,可不传,默认为空数组 + * @return string[] 提取出的文件的原始路径数组 + */ +export function getAllFiles( + srcPath: string, + exts: string[], + ignore: string[] = [], + filenameArr: string[] = [], + visited: Set = new Set() +): string[] { + let ignoreFiles: Set = new Set(ignore); + // 如果源目录不存在,直接结束程序 + if (!fs.existsSync(srcPath)) { + logger.error(`Input directory ${srcPath} is not exist, please check!`); + return filenameArr; + } + + // 获取src的绝对路径 + const realSrc = fs.realpathSync(srcPath); + if (visited.has(realSrc)) { + return filenameArr; + } + visited.add(realSrc); + + // 遍历src,判断文件类型 + fs.readdirSync(realSrc).forEach(filename => { + if (ignoreFiles.has(filename)) { + return; + } + // 拼接文件的绝对路径 + const realFile = path.resolve(realSrc, filename); + + //TODO: 增加排除文件后缀和目录 + + // 如果是目录,递归提取 + if (fs.statSync(realFile).isDirectory()) { + getAllFiles(realFile, exts, ignore, filenameArr, visited); + } else { + // 如果是文件,则判断其扩展名是否在给定的扩展名数组中 + if (exts.includes(path.extname(filename))) { + filenameArr.push(realFile); + } + } + }); + return filenameArr; +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/json5parser.ts b/ets2panda/linter/arkanalyzer/src/utils/json5parser.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b581a7e42f4d192e03f6dfaf5345837bcb9b1ac --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/json5parser.ts @@ -0,0 +1,122 @@ +/* + * 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. + */ + +import * as ts from 'ohos-typescript'; +import * as fs from 'fs'; +import Logger, { LOG_MODULE_TYPE } from './logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'json5parser'); + +export function fetchDependenciesFromFile(filePath: string): { + [k: string]: unknown; +} { + if (!fs.existsSync(filePath)) { + return {}; + } + let configurationsText: string; + try { + configurationsText = fs.readFileSync(filePath, 'utf-8'); + } catch (error) { + logger.error(`Error reading file: ${error}`); + return {}; + } + const file = parseJsonText(configurationsText); + return file; +} + +export function parseJsonText(text: string): { [k: string]: unknown } { + let file; + try { + file = ts.parseJsonText('', text); + } catch (error) { + logger.error(`Error parsing file: ${error}`); + return {}; + } + const rootObjectLiteralExpression = getRootObjectLiteral(file); + if (!rootObjectLiteralExpression) { + logger.error('The JSON5 file format is incorrect, rootObjectLiteralExpression is null.'); + return {}; + } + return parseObjectLiteralExpression(rootObjectLiteralExpression, file); +} + +function getRootObjectLiteral(file: ts.JsonSourceFile): ts.ObjectLiteralExpression | undefined { + if (!file || !file.statements || !file.statements.length) { + logger.error('The JSON5 file format is incorrect, the root node statements is empty.'); + return undefined; + } + const expressionStatement = file.statements[0]; + if (expressionStatement.kind !== ts.SyntaxKind.ExpressionStatement) { + logger.error(`The JSON5 file format is incorrect, the first child node is not ExpressionStatement. kind: ${expressionStatement.kind}`); + return undefined; + } + const rootObjectLiteralExpression = (expressionStatement as ts.ExpressionStatement).expression; + if (!rootObjectLiteralExpression) { + logger.error('The JSON5 file format is incorrect, the first child node is empty.'); + return undefined; + } + + if (rootObjectLiteralExpression.kind === ts.SyntaxKind.ObjectLiteralExpression) { + return rootObjectLiteralExpression as ts.ObjectLiteralExpression; + } + + if (rootObjectLiteralExpression.kind === ts.SyntaxKind.ArrayLiteralExpression) { + const elements = (rootObjectLiteralExpression as ts.ArrayLiteralExpression).elements; + if (elements && elements.length && elements[0].kind === ts.SyntaxKind.ObjectLiteralExpression) { + return elements[0] as ts.ObjectLiteralExpression; + } + logger.error('The JSON5 file format is incorrect, the node ArrayLiteralExpression first element is not ObjectLiteralExpression.'); + } + logger.error('The JSON5 file format is incorrect.'); + return undefined; +} + +function parsePropertyInitializer(node: ts.Expression, file: ts.JsonSourceFile): unknown { + if (node.kind === ts.SyntaxKind.StringLiteral) { + return (node as ts.StringLiteral).text; + } else if (node.kind === ts.SyntaxKind.NumericLiteral) { + return (node as ts.NumericLiteral).text; + } else if (node.kind === ts.SyntaxKind.PrefixUnaryExpression) { + return (node as ts.PrefixUnaryExpression).getText(file); + } else if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) { + return parseArrayLiteral(node, file); + } else if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) { + return parseObjectLiteralExpression(node as ts.ObjectLiteralExpression, file); + } else if (node.kind === ts.SyntaxKind.TrueKeyword) { + return true; + } else if (node.kind === ts.SyntaxKind.FalseKeyword) { + return false; + } + return undefined; +} + +function parseArrayLiteral(node: ts.Expression, file: ts.JsonSourceFile): unknown[] { + const res: unknown[] = []; + (node as ts.ArrayLiteralExpression).elements.forEach(n => { + res.push(parsePropertyInitializer(n, file)); + }); + return res; +} + +function parseObjectLiteralExpression(ObjectLiteralExpression: ts.ObjectLiteralExpression, file: ts.JsonSourceFile): { [k: string]: unknown } { + const res: { [k: string]: unknown } = {}; + ObjectLiteralExpression.properties.forEach(node => { + const propNode = node as ts.PropertyAssignment; + const key = (propNode.name as ts.Identifier).text; + const value = parsePropertyInitializer(propNode.initializer, file); + res[key] = value; + }); + return res; +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/logger.ts b/ets2panda/linter/arkanalyzer/src/utils/logger.ts new file mode 100644 index 0000000000000000000000000000000000000000..0e42ac832c41117d9095f21b3de38e6a8dc5998d --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/logger.ts @@ -0,0 +1,101 @@ +/* + * 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. + */ + +import type { Logger } from 'log4js'; +import { configure, getLogger } from 'log4js'; + +export enum LOG_LEVEL { + ERROR = 'ERROR', + WARN = 'WARN', + INFO = 'INFO', + DEBUG = 'DEBUG', + TRACE = 'TRACE', +} + +export enum LOG_MODULE_TYPE { + DEFAULT = 'default', + ARKANALYZER = 'ArkAnalyzer', + HOMECHECK = 'HomeCheck', + TOOL = 'Tool', +} + +export default class ConsoleLogger { + public static configure( + logFilePath: string, + arkanalyzer_level: LOG_LEVEL = LOG_LEVEL.ERROR, + tool_level: LOG_LEVEL = LOG_LEVEL.INFO, + use_console: boolean = false + ): void { + let appendersTypes: string[] = []; + if (logFilePath) { + appendersTypes.push('file'); + } + if (!appendersTypes.length || use_console) { + appendersTypes.push('console'); + } + configure({ + appenders: { + file: { + type: 'fileSync', + filename: `${logFilePath}`, + maxLogSize: 5 * 1024 * 1024, + backups: 5, + compress: true, + encoding: 'utf-8', + layout: { + type: 'pattern', + pattern: '[%d] [%p] [%z] [%X{module}] - [%X{tag}] %m', + }, + }, + console: { + type: 'console', + layout: { + type: 'pattern', + pattern: '[%d] [%p] [%z] [%X{module}] - [%X{tag}] %m', + }, + }, + }, + categories: { + default: { + appenders: ['console'], + level: 'info', + enableCallStack: false, + }, + ArkAnalyzer: { + appenders: appendersTypes, + level: arkanalyzer_level, + enableCallStack: true, + }, + Tool: { + appenders: appendersTypes, + level: tool_level, + enableCallStack: true, + }, + }, + }); + } + + public static getLogger(log_type: LOG_MODULE_TYPE, tag: string = '-'): Logger { + let logger; + if (log_type === LOG_MODULE_TYPE.DEFAULT || log_type === LOG_MODULE_TYPE.ARKANALYZER) { + logger = getLogger(log_type); + } else { + logger = getLogger(LOG_MODULE_TYPE.TOOL); + } + logger.addContext('module', log_type); + logger.addContext('tag', tag); + return logger; + } +} diff --git a/ets2panda/linter/arkanalyzer/src/utils/pathTransfer.ts b/ets2panda/linter/arkanalyzer/src/utils/pathTransfer.ts new file mode 100644 index 0000000000000000000000000000000000000000..65858744c2935a12088c91cce4e6278ee24a3de3 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/src/utils/pathTransfer.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +import path from 'path'; + +export function transfer2UnixPath(path2Do: string): string { + return path.posix.join(...path2Do.split(/\\/)); +} diff --git a/ets2panda/linter/arkanalyzer/tsconfig.json b/ets2panda/linter/arkanalyzer/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..4f03c1a5677fe4f50721595e003a91a5bb30aa82 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.main.json", + "include": [ + "index.ts", + "src/**/*", + "tests/unit/**/*", + "tests/HeapDumpTest.ts" + ], + "compilerOptions": { + "outDir": "./out" + } +} \ No newline at end of file diff --git a/ets2panda/linter/arkanalyzer/tsconfig.main.json b/ets2panda/linter/arkanalyzer/tsconfig.main.json new file mode 100644 index 0000000000000000000000000000000000000000..c96613a134e43859103fed492cc78e75eab5a4e4 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/tsconfig.main.json @@ -0,0 +1,101 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + //"composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + //"outFile": "lib", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "strictPropertyInitialization": true, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} \ No newline at end of file diff --git a/ets2panda/linter/arkanalyzer/tsconfig.prod.json b/ets2panda/linter/arkanalyzer/tsconfig.prod.json new file mode 100644 index 0000000000000000000000000000000000000000..2be4cb427cbbbaa4ba733a1279ecd76348b5a0ec --- /dev/null +++ b/ets2panda/linter/arkanalyzer/tsconfig.prod.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.main.json", + "include": [ + "src/**/*" + ], + "compilerOptions": { + "outDir": "./lib" + } +} \ No newline at end of file diff --git a/ets2panda/linter/arkanalyzer/typedoc.json b/ets2panda/linter/arkanalyzer/typedoc.json new file mode 100644 index 0000000000000000000000000000000000000000..1b08d68d6925c2b388da76585a545eef75630cf4 --- /dev/null +++ b/ets2panda/linter/arkanalyzer/typedoc.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "name": "ArkAnalyzer", + "categoryOrder": [ + "core/base", + "core/base/expr", + "core/base/stmt", + "core/base/type", + "core/base/ref", + "core/model", + "core/graph", + "*" + ], + "entryPoints": [ + "./src/index.ts" + ], + "excludeInternal": true, + "useTsLinkResolution": true, + "out": "docs/api_docs", + "readme": "./README.en.md" +} \ No newline at end of file diff --git a/ets2panda/linter/arkanalyzer/vitest.config.ts b/ets2panda/linter/arkanalyzer/vitest.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..d098faa737cf71b7e2295be13220894ded5e938b --- /dev/null +++ b/ets2panda/linter/arkanalyzer/vitest.config.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['tests/unit/**/*.test.ts'], + coverage: { + include: ['src/**'], + }, + }, +}); diff --git a/ets2panda/linter/build_linter.py b/ets2panda/linter/build_linter.py index 24cf53c3f60f8a8b04019ef40a97fd575e8bb693..cfc970134ce210b74707b51b6b07175bf34cb7c9 100755 --- a/ets2panda/linter/build_linter.py +++ b/ets2panda/linter/build_linter.py @@ -19,6 +19,7 @@ import shutil import subprocess import sys import tarfile +import time def copy_files(source_path, dest_path, is_file=False): @@ -39,9 +40,38 @@ def run_cmd(cmd, execution_path=None): stdin=subprocess.PIPE, stderr=subprocess.PIPE, cwd=execution_path) - stdout, stderr = proc.communicate(timeout=300) + stdout, stderr = proc.communicate(timeout=600) if proc.returncode != 0: raise Exception(stderr.decode()) + return stdout + + +def run_cmd_with_retry(max_retries, wait_time, cmd, execution_path=None): + retry_count = 0 + while retry_count < max_retries: + try: + run_cmd(cmd, execution_path) + break + except Exception: + retry_count += 1 + time.sleep(wait_time) + if retry_count >= max_retries: + raise Exception("Failed to run cmd: " + cmd) + + +def is_npm_newer_than_6(options): + cmd = [options.npm, '-v'] + stdout = run_cmd(cmd, options.source_path) + version_str = stdout.decode('utf-8').strip() + # get npm major version(i.e. "6.14.15" -> 6) + major_version = int(version_str.split('.')[0]) + if major_version is not None: + if major_version <= 6: + return False + else: + return True + # default set to lower than v7 which can compatible with v7+ + return False def build(options): @@ -70,10 +100,145 @@ def copy_output(options): def install_typescript(options): - cmd = [options.npm, 'install', '--no-save', options.typescript] + new_npm = is_npm_newer_than_6(options) + tsc_file = 'file:' + options.typescript + if new_npm: + cmd = [options.npm, 'install', '--no-save', tsc_file, '--legacy-peer-deps', '--offline'] + else: + cmd = [options.npm, 'install', '--no-save', tsc_file] run_cmd(cmd, options.source_path) +def find_files_by_prefix_suffix(directory, prefix, suffix): + matched_files = [] + for filename in os.listdir(directory): + if filename.startswith(prefix) and filename.endswith(suffix): + matched_files.append(os.path.join(directory, filename)) + return sorted(matched_files, key=os.path.getctime, reverse=True) + + +def clean_old_packages(directory, prefix, suffix): + res = True + matched_files = find_files_by_prefix_suffix(directory, prefix, suffix) + if (matched_files): + for file in matched_files: + try: + os.remove(file) + except Exception: + res = False + return res + + +def backup_package_files(source_path): + package_name = 'package.json' + package_back_name = 'package.json.bak' + aa_path = os.path.join(source_path, 'arkanalyzer') + hc_path = os.path.join(source_path, 'homecheck') + linter_path = source_path + copy_files(os.path.join(aa_path, package_name), os.path.join(aa_path, package_back_name), True) + copy_files(os.path.join(hc_path, package_name), os.path.join(hc_path, package_back_name), True) + copy_files(os.path.join(linter_path, package_name), os.path.join(linter_path, package_back_name), True) + + +def clean_env(source_path): + package_name = 'package.json' + package_back_name = 'package.json.bak' + package_lock_name = 'package-lock.json' + aa_path = os.path.join(source_path, 'arkanalyzer') + hc_path = os.path.join(source_path, 'homecheck') + linter_path = source_path + try: + copy_files(os.path.join(aa_path, package_back_name), os.path.join(aa_path, package_name), True) + copy_files(os.path.join(hc_path, package_back_name), os.path.join(hc_path, package_name), True) + copy_files(os.path.join(linter_path, package_back_name), os.path.join(linter_path, package_name), True) + os.remove(os.path.join(hc_path, package_lock_name)) + os.remove(os.path.join(linter_path, package_lock_name)) + os.remove(os.path.join(aa_path, package_back_name)) + os.remove(os.path.join(hc_path, package_back_name)) + os.remove(os.path.join(linter_path, package_back_name)) + except Exception: + return False + return True + + +def aa_copy_lib_files(options): + aa_path = os.path.join(options.source_path, 'arkanalyzer') + source_file_1 = os.path.join(aa_path, 'node_modules', 'ohos-typescript', 'lib', 'lib.es5.d.ts') + dest_path = os.path.join(aa_path, 'builtIn', 'typescript', 'api', '@internal') + copy_files(source_file_1, dest_path, True) + source_file_2 = os.path.join(aa_path, 'node_modules', 'ohos-typescript', 'lib', 'lib.es2015.collection.d.ts') + copy_files(source_file_2, dest_path, True) + + +def hc_copy_lib_files(options): + hc_path = os.path.join(options.source_path, 'homecheck') + source_file = os.path.join(hc_path, 'node_modules', 'ohos-typescript', 'lib', 'lib.es5.d.ts') + dest_path = os.path.join(hc_path, 'resources', 'internalSdk', '@internal') + copy_files(source_file, dest_path, True) + + +def pack_arkanalyzer(options, new_npm): + aa_path = os.path.join(options.source_path, 'arkanalyzer') + tsc_file = 'file:' + options.typescript + pack_prefix = 'arkanalyzer-' + pack_suffix = '.tgz' + clean_old_packages(aa_path, pack_prefix, pack_suffix) + + if new_npm: + ts_install_cmd = [options.npm, 'install', '--no-save', tsc_file, '--legacy-peer-deps', '--offline'] + else: + ts_install_cmd = [options.npm, 'install', '--no-save', tsc_file] + compile_cmd = [options.npm, 'run', 'compile'] + pack_cmd = [options.npm, 'pack'] + run_cmd(ts_install_cmd, aa_path) + aa_copy_lib_files(options) + run_cmd(compile_cmd, aa_path) + run_cmd(pack_cmd, aa_path) + + +def install_homecheck(options, max_retries, wait_time): + new_npm = is_npm_newer_than_6(options) + pack_arkanalyzer(options, new_npm) + aa_path = os.path.join(options.source_path, 'arkanalyzer') + hc_path = os.path.join(options.source_path, 'homecheck') + aa_pack_prefix = 'arkanalyzer-' + hc_pack_prefix = 'homecheck-' + pack_suffix = '.tgz' + exist_aa_packs = find_files_by_prefix_suffix(aa_path, aa_pack_prefix, pack_suffix) + if (exist_aa_packs): + aa_file = 'file:' + exist_aa_packs[0] + if new_npm: + aa_install_cmd = [options.npm, 'install', aa_file, '--legacy-peer-deps', '--offline'] + else: + aa_install_cmd = [options.npm, 'install', aa_file] + run_cmd_with_retry(max_retries, wait_time, aa_install_cmd, hc_path) + else: + raise Exception('Failed to find arkanalyzer npm package') + + clean_old_packages(hc_path, hc_pack_prefix, pack_suffix) + tsc_file = 'file:' + options.typescript + if new_npm: + ts_install_cmd = [options.npm, 'install', '--no-save', tsc_file, '--legacy-peer-deps', '--offline'] + else: + ts_install_cmd = [options.npm, 'install', '--no-save', tsc_file] + pack_cmd = [options.npm, 'pack'] + compile_cmd = [options.npm, 'run', 'compile'] + run_cmd_with_retry(max_retries, wait_time, ts_install_cmd, hc_path) + hc_copy_lib_files(options) + run_cmd(compile_cmd, hc_path) + run_cmd(pack_cmd, hc_path) + exist_hc_packs = find_files_by_prefix_suffix(hc_path, hc_pack_prefix, pack_suffix) + if (exist_hc_packs): + hc_file = 'file:' + exist_hc_packs[0] + if new_npm: + hc_install_cmd = [options.npm, 'install', hc_file, '--legacy-peer-deps', '--offline'] + else: + hc_install_cmd = [options.npm, 'install', hc_file] + run_cmd_with_retry(max_retries, wait_time, hc_install_cmd, options.source_path) + else: + raise Exception('Failed to find homecheck npm package') + + def extract(package_path, dest_path, package_name): try: with tarfile.open(package_path, 'r:gz') as tar: @@ -100,14 +265,15 @@ def parse_args(): def main(): options = parse_args() + backup_package_files(options.source_path) + install_homecheck(options, 5, 3) install_typescript(options) node_modules_path = os.path.join(options.source_path, "node_modules") extract(options.typescript, node_modules_path, "typescript") build(options) copy_output(options) + clean_env(options.source_path) if __name__ == '__main__': sys.exit(main()) - - diff --git a/ets2panda/linter/eslint.config.mjs b/ets2panda/linter/eslint.config.mjs index c803d799b2fd6c591b605055e29a7af7a3759471..f5afd19191dc75d8699931ba67a7c70f8acd2ab1 100644 --- a/ets2panda/linter/eslint.config.mjs +++ b/ets2panda/linter/eslint.config.mjs @@ -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 @@ -34,7 +34,9 @@ export default tseslint.config( 'third_party/**/*', 'test/**/*', '**/**.json', - '**/**.js' + '**/**.js', + 'arkanalyzer/*', + 'homecheck/*' ] }, { @@ -98,7 +100,7 @@ export default tseslint.config( // imports 'import/no-absolute-path': 'error', - 'n/file-extension-in-import': ['error', 'never'], + 'n/file-extension-in-import': ['error', 'never', { '.json': 'always' }], // style '@stylistic/array-bracket-newline': ['error', 'consistent'], diff --git a/ets2panda/linter/homecheck/.prettierrc b/ets2panda/linter/homecheck/.prettierrc new file mode 100644 index 0000000000000000000000000000000000000000..727d5c6ae24fce2bbfa0ef12e33d29fb5fbc59f9 --- /dev/null +++ b/ets2panda/linter/homecheck/.prettierrc @@ -0,0 +1,10 @@ +{ + "trailingComma": "es5", + "tabWidth": 4, + "useTabs": false, + "semi": true, + "singleQuote": true, + "printWidth": 160, + "quoteProps": "as-needed", + "arrowParens": "avoid" +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/LICENSE b/ets2panda/linter/homecheck/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/ets2panda/linter/homecheck/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/ets2panda/linter/homecheck/OAT.xml b/ets2panda/linter/homecheck/OAT.xml new file mode 100644 index 0000000000000000000000000000000000000000..e377d607f471d35c4ce5b6144cb8e23232e2fd3f --- /dev/null +++ b/ets2panda/linter/homecheck/OAT.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/ets2panda/linter/homecheck/README.en.md b/ets2panda/linter/homecheck/README.en.md new file mode 100644 index 0000000000000000000000000000000000000000..656170858d3454e855b959947945fa16649be376 --- /dev/null +++ b/ets2panda/linter/homecheck/README.en.md @@ -0,0 +1,36 @@ +# arkcheck + +#### Description +ArkTS代码高性能反模式静态扫描工具 + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/ets2panda/linter/homecheck/README.md b/ets2panda/linter/homecheck/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b485697ce3c71d0af070fac7fcacaf33116f47d0 --- /dev/null +++ b/ets2panda/linter/homecheck/README.md @@ -0,0 +1,202 @@ +# homecheck + +## 项目简介 + +该项目(homecheck)专为提升代码质量而设计,能高效识别代码缺陷并提出方案;其核心功能是对应用工程项目执行静态代码分析,评估代码在安全性、性能等方面上的表现,精准定位问题及其在代码中的位置。 + +## 目录 + +``` +homecheck +├─config/ # 项目配置 +├─document/ # 项目文档 +├─resources/ # 依赖库 +├─src/ +│ ├─checker/ # 项目检测规则功能代码 +│ ├─codeFix/ # 修复 +│ ├─matcher/ # 匹配类型 +│ ├─model/ # 模块 +│ ├─utils/ # 公共接口 +│ └─run.ts # 项目入口 +└─test/ # 测试目录 +``` + +## 项目主体流程 + +1.读取配置文件projectConfig.json和ruleConfig.json + +2.使用**ArkAnalyzer**项目构建**sence** + +3.根据配置文件参数,获取需要检测的文件 + +4.前处理 + +5.进行检测 + +6.后处理 + +## QuickStart + +### 1.下载本项目 + +### 2.进入项目根目录,打开终端 + +``` +cmd +``` + +### 3.安装依赖库 + +``` +npm install +``` + +### 4.修改配置 + +**config\projectConfig.json**中修改项目配置 +示例: + +``` +{ + "projectName": "TestProject", + "projectPath": "/path/to/project", + "logPath": "./HomeCheck.log", + "ohosSdkPath": "/path/to/ohosSdk", + "hmsSdkPath": "/path/to/hmsSdk", + "checkPath": "", + "sdkVersion": 14, + "fix": "true", + "npmPath": "", + "sdksThirdParty": [ + { + "name": "thirdParty", + "path": "./resources/thirdPartyModules", + "moduleName": "" + } + ] +} +``` +字段说明: +``` +projectName:需要检测工程的名字 +projectPath:需要检测工程的路径 +logPath:日志输出路径 +ohosSdkPath:ohossdk路径,比如DevEco Studio安装目录下的sdk\default\openharmony\ets,请使用绝对路径 +hmsSdkPath:hmssdk路径,比如DevEco Studio安装目录下的sdk\default\hms\ets,请使用绝对路径 +checkPath:解析指定的文件 +sdkVersion:sdk版本 +fix:是否修复 +npmPath:自定义规则npm路径 +sdksThirdParty:sdk三方库,name:库名称,path:库路径,moduleName:模块名称 +``` + +**config\ruleConfig.json**中修改规则配置 +示例: + +``` +{ + "files": [ + "**/*.ets", + "**/*.ts" + ], + "ignore": [ + "**/ohosTest/**/*", + "**/node_modules/**/*", + "**/build/**/*", + "**/hvigorfile/**/*", + "**/oh_modules/**/*", + "**/.preview/**/*" + ], + "rules": { + "@performance/foreach-args-check":3 + }, + "ruleSet": [ + "plugin:@performance/all", + "plugin:@correctness/all" + ], + "overrides": [], + "extRuleSet": [] +} +``` + +字段说明: + +参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/ide-code-linter-V14#section1782903483817 +``` +files:待检测文件类型 +ignore:过滤文件 +rules:可以基于ruleSet配置的规则集,新增额外规则项 +ruleSet:规则集 +overrides:定制化检查的规则 +extRuleSet:自定义规则 +``` +extRuleSet:自定义规则,参考[自定义规则](#自定义规则) + +### 5.启动项目 + +注意修改projectConfig.json和ruleConfig.json文件路径 + +#### 5.1 命令行启动,示例: + +根目录下执行 +``` +node -r ts-node/register ./src/run.ts --projectConfigPath=./config/projectConfig.json --configPath=./config/ruleConfig.json +``` + +#### 5.2 vscode启动: + +根目录新建.vscode目录,并新建launch.json文件,内容参考.vscode_sample\launch.json + +点击左侧运行和调试按钮,点击启动程序,开始运行,运行结束查看HomeCheck.log +#### 5.3 webstorm启动: + +## 新增规则 + +### 自定义规则 +参考:[自定义规则开发指南](document/ExtRule自定义规则开发指南.md) + +### 检测规则 +参考:[新增检测规则开发指南](document/规则开发指南.md) + +## api +参考:[api说明](doc/globals.md) + +## 打包 + +根目录下执行命令: + +``` +npm pack +``` +产物,根目录下: + +homecheck-1.0.0.tgz + +## 安装与使用 + +参考:[homecheck安装与使用指南](document/homecheck安装与使用指南.md) + +## HomeCheck附带工具使用指南 + +参考:[HomeCheck附带工具使用指南](document/HomeCheck附带工具使用指南.md) + +### 日志 + +运行结果请查看根目录下的HomeCheck.log + +## 代码上库 +遵守openharmony-sig代码上库规范, 操作方法请参考:[创建pr指南](document/PR指南.md) + +## Issues +提交Issues请参考:[Issues指南](document/Issues指南.md)。 + +## 添加自验证测试用例 +自验证用例请参考:[单元测试用例开发指南](document/单元测试用例开发指南.md) + +## 相关仓 + +[ArkAnalyzer](https://gitcode.com/openharmony-sig/arkanalyzer) + +## 欢迎加入homecheck社区开发讨论 + +![homecheck社区开发讨论](document/img/homecheck社区开发讨论.JPG) \ No newline at end of file diff --git a/ets2panda/linter/homecheck/config/projectConfig.json b/ets2panda/linter/homecheck/config/projectConfig.json new file mode 100644 index 0000000000000000000000000000000000000000..2bfa7d765f0510e842207f436ed62ae85bbbcb88 --- /dev/null +++ b/ets2panda/linter/homecheck/config/projectConfig.json @@ -0,0 +1,25 @@ +{ + "projectName": "TestProject", + "projectPath": "D:\\arkProject", + "logPath": "./HomeCheck.log", + "ohosSdkPath": "D:\\DevEco Studio\\sdk\\default\\openharmony\\ets", + "hmsSdkPath": "D:\\DevEco Studio\\sdk\\default\\hms\\ets", + "checkPath": "", + "sdkVersion": 14, + "fix": "false", + "npmPath": "", + "npmInstallDir": "./", + "reportDir": "./report", + "arkCheckPath": "./", + "product": "default", + "sdksThirdParty": [ + { + "name": "thirdParty", + "path": "./resources/thirdPartyModules", + "moduleName": "" + } + ], + "fileOrFolderToCheck": [ "D:\\arkProject" ], + "logLevel": "INFO", + "arkAnalyzerLogLevel": "ERROR" +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/config/ruleConfig.json b/ets2panda/linter/homecheck/config/ruleConfig.json new file mode 100644 index 0000000000000000000000000000000000000000..3f724aeebf8f0d1f96f385fc032548c5099591f4 --- /dev/null +++ b/ets2panda/linter/homecheck/config/ruleConfig.json @@ -0,0 +1,22 @@ +{ + "files": [ + "**/*.ets", + "**/*.ts", + "**/*.js" + ], + "ignore": [ + "**/ohosTest/**/*", + "**/node_modules/**/*", + "**/build/**/*", + "**/hvigorfile/**/*", + "**/oh_modules/**/*", + "**/.preview/**/*" + ], + "rules": { + }, + "ruleSet": [ + "plugin:@migration/all" + ], + "overrides": [], + "extRuleSet": [] +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/package.json b/ets2panda/linter/homecheck/package.json new file mode 100644 index 0000000000000000000000000000000000000000..ae47a9e950e04f2fffdffb639519b65f7ac3138f --- /dev/null +++ b/ets2panda/linter/homecheck/package.json @@ -0,0 +1,28 @@ +{ + "scripts": { + "installArkAnalyzer": "bash ./scripts/install_arkanalyzer.sh", + "compile": "tsc -p ./tsconfig.prod.json", + "test": "vitest --no-color run", + "coverage": "vitest run --coverage", + "pack": "npm pack" + }, + "dependencies": { + "arkanalyzer": "file:../arkanalyzer", + "commander": "^9.4.0", + "fs-extra": "11.2.0", + "log4js": "^6.4.0", + "json5": "2.2.3" + }, + "name": "homecheck", + "version": "0.9.11-arkts1.2", + "description": "该项目(homecheck)专为提升代码质量而设计,能高效识别代码缺陷并提出方案;其核心功能是对应用工程项目执行静态代码分析,评估代码在安全性、性能等方面上的表现,精准定位问题及其在代码中的位置。", + "main": "lib/Index.js", + "files": [ + "docs", + "lib", + "resources", + "ruleSet.json" + ], + "author": "", + "license": "ISC" +} diff --git a/ets2panda/linter/homecheck/resources/sdkConfig.json b/ets2panda/linter/homecheck/resources/sdkConfig.json new file mode 100644 index 0000000000000000000000000000000000000000..51715b0b7868a93705707b779e0a5a22d3b7dd8f --- /dev/null +++ b/ets2panda/linter/homecheck/resources/sdkConfig.json @@ -0,0 +1,24 @@ +{ + "sdks": [ + { + "name": "internalSdk", + "path": "./resources/internalSdk", + "moduleName": "" + }, + { + "name": "ohosSdk", + "path": "", + "moduleName": "" + }, + { + "name": "hmsSdk", + "path": "", + "moduleName": "" + }, + { + "name": "thirdParty", + "path": "./resources/thirdPartyModules", + "moduleName": "" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/resources/thirdPartyModules/@hview/moment/index.d.ts b/ets2panda/linter/homecheck/resources/thirdPartyModules/@hview/moment/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..d5cac4b311493e55ebe8156a1898cac3bab18df5 --- /dev/null +++ b/ets2panda/linter/homecheck/resources/thirdPartyModules/@hview/moment/index.d.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 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. + */ +/** + * @param strict Strict parsing disables the deprecated fallback to the native Date constructor when + * parsing a string. + */ +export default function moment(): moment.Moment; +declare namespace moment { + interface Moment extends Object { + utcOffset(): number; + utcOffset(b: number | string, keepLocalTime?: boolean): Moment; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/gif-drawable/index.ets b/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/gif-drawable/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..f8d5dcb73dbaceb071bba6445c63522ed6938d9f --- /dev/null +++ b/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/gif-drawable/index.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 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 { default as GIFComponentV2 } from './src/main/ets/components/gif/display/GIFComponentV2'; +export { default as GIFComponent } from './src/main/ets/components/gif/display/GIFComponent'; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/gif-drawable/src/main/ets/components/gif/display/GIFComponent.ets b/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/gif-drawable/src/main/ets/components/gif/display/GIFComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..4cb318ca643fd8b162a9d45927ee247445cac824 --- /dev/null +++ b/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/gif-drawable/src/main/ets/components/gif/display/GIFComponent.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 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 GIFComponent { + export class ControllerOptions { + private openHardware: boolean = false; + setOpenHardware(open: boolean) { + this.openHardware = open; + return this; + } + } +} + +export default GIFComponent; diff --git a/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/gif-drawable/src/main/ets/components/gif/display/GIFComponentV2.ets b/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/gif-drawable/src/main/ets/components/gif/display/GIFComponentV2.ets new file mode 100644 index 0000000000000000000000000000000000000000..49f39c777a76d563af493c7c4fd6e09e08bffaed --- /dev/null +++ b/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/gif-drawable/src/main/ets/components/gif/display/GIFComponentV2.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 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 GIFComponentV2 { + export class ControllerOptions { + private openHardware: boolean = false; + setOpenHardware(open: boolean) { + this.openHardware = open; + return this; + } + } +} + +export default GIFComponentV2; diff --git a/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/lottie/index.d.ts b/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/lottie/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..41e2169ce8d8da78a4b5eeca5e5ae0fb09fb8211 --- /dev/null +++ b/ets2panda/linter/homecheck/resources/thirdPartyModules/@ohos/lottie/index.d.ts @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 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 class AnimationItem {destroy(name?: string): void;addEventListener(name: string, callback: LoadCallback): () => void; }; +export default class LottiePlayer {loadAnimation(params: Object): AnimationItem; destroy(name?: string): void;}; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/ruleSet.json b/ets2panda/linter/homecheck/ruleSet.json new file mode 100644 index 0000000000000000000000000000000000000000..adfc2898b56f1dc1b440bbe682d6abdf1d9c2fa0 --- /dev/null +++ b/ets2panda/linter/homecheck/ruleSet.json @@ -0,0 +1,213 @@ +{ + "plugin:@ArkTS-eslint/all": { + "@ArkTS-eslint/require-await-check": 2, + "@ArkTS-eslint/triple-slash-reference-check": 2, + "@ArkTS-eslint/restrict-template-expressions-check": 2, + "@ArkTS-eslint/restrict-plus-operands-check": 2, + "@ArkTS-eslint/switch-exhaustiveness-check": 2, + "@ArkTS-eslint/unified-signatures-check": 2, + "@ArkTS-eslint/no-regex-spaces-check": 2, + "@ArkTS-eslint/valid-typeof-check": 2, + "@ArkTS-eslint/array-type-check": 2, + "@ArkTS-eslint/no-useless-backreference-check": 2, + "@ArkTS-eslint/ban-tslint-comment-check": 2, + "@ArkTS-eslint/prefer-arrow-callback-check":2, + "@ArkTS-eslint/no-unnecessary-boolean-literal-compare-check":2, + "@ArkTS-eslint/ban-types-check": 2, + "@ArkTS-eslint/brace-style-check": 2, + "@ArkTS-eslint/no-unsafe-optional-chaining-check": 2, + "@ArkTS-eslint/no-useless-escape-check": 2, + "@ArkTS-eslint/no-useless-catch-check": 2, + "@ArkTS-eslint/no-this-alias-check": 2, + "@ArkTS-eslint/no-non-null-assertion-check": 2, + "@ArkTS-eslint/no-misused-new-check": 2, + "@ArkTS-eslint/no-require-imports-check": 2, + "@ArkTS-eslint/no-parameter-properties-check": 2, + "@ArkTS-eslint/no-redeclare-check": 2, + "@ArkTS-eslint/no-shadow-check": 2, + "@ArkTS-eslint/no-non-null-asserted-optional-chain-check": 2, + "@ArkTS-eslint/consistent-type-assertions-check": 2, + "@ArkTS-eslint/consistent-type-definitions-check": 2, + "@ArkTS-eslint/consistent-type-imports-check": 2, + "@ArkTS-eslint/consistent-indexed-object-style-check": 2, + "@ArkTS-eslint/no-new-wrappers-check": 2, + "@ArkTS-eslint/max-classes-per-file-check": 2, + "@ArkTS-eslint/max-nested-callbacks-check": 2, + "@ArkTS-eslint/no-async-promise-executor-check": 2, + "@ArkTS-eslint/no-array-constructor-check": 2, + "@ArkTS-eslint/max-depth-check": 2, + "@ArkTS-eslint/eqeqeq-check": 2, + "@ArkTS-eslint/no-array-constructor-ts-check": 2, + "@ArkTS-eslint/no-extra-semi-check": 2, + "@ArkTS-eslint/no-extra-boolean-cast-check":2, + "@ArkTS-eslint/no-confusing-void-expression-check":2, + "@ArkTS-eslint/prefer-const-check": 2, + "@ArkTS-eslint/await-thenable-check": 2, + "@ArkTS-eslint/init-declarations-check": 2, + "@ArkTS-eslint/default-param-last-check": 2, + "@ArkTS-eslint/explicit-function-return-type-check": 2, + "@ArkTS-eslint/explicit-module-boundary-types-check": 2, + "@ArkTS-eslint/no-dupe-class-members-check": 2, + "@ArkTS-eslint/ban-ts-comment-check": 2, + "@ArkTS-eslint/member-ordering-check": 2, + "@ArkTS-eslint/no-unnecessary-condition-check": 2, + "@ArkTS-eslint/no-unnecessary-qualifier-check": 2, + "@ArkTS-eslint/no-unnecessary-type-arguments-check": 2, + "@ArkTS-eslint/no-unnecessary-type-assertion-check": 2, + "@ArkTS-eslint/prefer-string-starts-ends-with-check": 2, + "@ArkTS-eslint/prefer-regexp-exec-check": 2, + "@ArkTS-eslint/max-lines-per-function-check": 2, + "@ArkTS-eslint/no-cond-assign-check": 2, + "@ArkTS-eslint/no-for-in-array-check": 2, + "@ArkTS-eslint/no-loss-of-precision-check": 2, + "@ArkTS-eslint/no-loop-func-check": 2, + "@ArkTS-eslint/no-extraneous-class-check": 2, + "@ArkTS-eslint/no-duplicate-imports-check": 2, + "@ArkTS-eslint/no-case-declarations-check": 2, + "@ArkTS-eslint/default-case-check": 2, + "@ArkTS-eslint/default-case-last-check": 2, + "@ArkTS-eslint/use-isnan-check": 2, + "@ArkTS-eslint/no-invalid-void-type-check": 2, + "@ArkTS-eslint/no-namespace-check": 2, + "@ArkTS-eslint/typedef-check": 2, + "@ArkTS-eslint/return-await-check":2, + "@ArkTS-eslint/prefer-reduce-type-parameter-check":2, + "@ArkTS-eslint/prefer-nullish-coalescing-check": 2, + "@ArkTS-eslint/max-lines-check": 2, + "@ArkTS-eslint/no-unnecessary-type-constraint-check": 2, + "@ArkTS-eslint/no-unsafe-argument-check": 2, + "@ArkTS-eslint/no-unsafe-call-check": 2, + "@ArkTS-eslint/no-control-regex-check": 2, + "@ArkTS-eslint/no-empty-character-class-check": 2, + "@ArkTS-eslint/no-ex-assign-check": 2, + "@ArkTS-eslint/no-invalid-regexp-check": 2, + "@ArkTS-eslint/no-octal-check": 2, + "@ArkTS-eslint/no-unexpected-multiline-check": 2, + "@ArkTS-eslint/no-unreachable-check": 2, + "@ArkTS-eslint/no-inferrable-types-check": 2, + "@ArkTS-eslint/space-before-function-paren-check": 2, + "@ArkTS-eslint/space-infix-ops-check": 2, + "@ArkTS-eslint/no-restricted-syntax-check": 2, + "@ArkTS-eslint/adjacent-overload-signatures-check": 2, + "@ArkTS-eslint/class-literal-property-style-check": 2, + "@ArkTS-eslint/no-confusing-non-null-assertion-check": 2, + "@ArkTS-eslint/no-empty-function-check": 2, + "@ArkTS-eslint/no-magic-numbers-check": 2, + "@ArkTS-eslint/prefer-enum-initializers-check": 2, + "@ArkTS-eslint/prefer-literal-enum-member-check": 2, + "@ArkTS-eslint/prefer-readonly-parameter-types-check": 2, + "@ArkTS-eslint/require-array-sort-compare-check": 2, + "@ArkTS-eslint/no-invalid-this-check": 2, + "@ArkTS-eslint/no-fallthrough-check": 2, + "@ArkTS-eslint/no-explicit-any-check": 2, + "@ArkTS-eslint/no-unused-expressions-check": 2, + "@ArkTS-eslint/no-throw-literal-check": 2, + "@ArkTS-eslint/comma-dangle-check": 2, + "@ArkTS-eslint/prefer-ts-expect-error-check": 2, + "@ArkTS-eslint/no-extra-parens-check": 2, + "@ArkTS-eslint/no-dynamic-delete-check": 2, + "@ArkTS-eslint/no-implicit-any-catch-check": 2, + "@ArkTS-eslint/no-empty-interface-check": 2, + "@ArkTS-eslint/no-unsafe-finally-check": 3, + "@ArkTS-eslint/prefer-function-type-check":3, + "@ArkTS-eslint/prefer-namespace-keyword-check": 3, + "@ArkTS-eslint/prefer-readonly-check": 2, + "@ArkTS-eslint/comma-spacing-check": 2, + "@ArkTS-eslint/naming-convention-check": 2, + "@ArkTS-eslint/no-extra-non-null-assertion-check": 2, + "@ArkTS-eslint/no-type-alias-check": 2, + "@ArkTS-eslint/type-annotation-spacing-check": 2, + "@ArkTS-eslint/func-call-spacing-check": 1, + "@ArkTS-eslint/unbound-method-check": 2, + "@ArkTS-eslint/method-signature-style-check": 2, + "@ArkTS-eslint/lines-between-class-members-check": 2, + "@ArkTS-eslint/member-delimiter-style-check": 2, + "@ArkTS-eslint/no-unsafe-return-check": 2, + "@ArkTS-eslint/no-use-before-define-check": 1, + "@ArkTS-eslint/quotes-check": 2, + "@ArkTS-eslint/prefer-as-const-check": 2, + "@ArkTS-eslint/prefer-optional-chain-check": 2, + "@ArkTS-eslint/no-trailing-spaces-check": 2, + "@ArkTS-eslint/no-unsafe-assignment-check": 2, + "@ArkTS-eslint/prefer-for-of-check": 2, + "@ArkTS-eslint/strict-boolean-expressions-check": 2, + "@ArkTS-eslint/no-implied-eval-check": 2, + "@ArkTS-eslint/semi-check": 2, + "@ArkTS-eslint/no-base-to-string-check": 2, + "@ArkTS-eslint/promise-function-async-check": 2, + "@ArkTS-eslint/prefer-includes-check": 2, + "@ArkTS-eslint/no-unsafe-member-access-check": 2, + "@ArkTS-eslint/no-unused-vars-check": 2, + "@ArkTS-eslint/no-useless-constructor-check": 2, + "@ArkTS-eslint/dot-notation-check": 2, + "@ArkTS-eslint/explicit-member-accessibility-check": 2, + "@ArkTS-eslint/keyword-spacing-check": 2, + "@ArkTS-eslint/no-floating-promises-check": 2, + "@ArkTS-eslint/no-misused-promises-check": 2 + }, + "plugin:@performance/all": { + "@performance/array-definition-check": 3, + "@performance/avoid-empty-callback-check": 3, + "@performance/avoid-update-auto-state-var-in-aboutToReuse-check": 3, + "@performance/constant-property-referencing-check-in-loops": 3, + "@performance/effectkit-blur-check": 3, + "@performance/foreach-args-check": 3, + "@performance/foreach-index-check": 1, + "@performance/image-sync-load-check": 3, + "@performance/list-in-scroll-check": 3, + "@performance/lottie-animation-destroy-check": 3, + "@performance/multiple-associations-state-var-check": 3, + "@performance/remove-redundant-state-var-check": 3, + "@performance/set-cached-count-for-lazyforeach-check": 3, + "@performance/start-window-icon-check": 3, + "@performance/timezone-interface-check": 3, + "@performance/typed-array-check": 3, + "@performance/use-object-link-to-replace-prop-check": 3, + "@performance/web-cache-mode-check": 3, + "@performance/number-init-check": 3, + "@performance/sparse-array-check": 3, + "@performance/high-frequency-log-check": 1, + "@performance/waterflow-data-preload-check": 3, + "@performance/union-type-array-check": 3, + "@performance/layout-properties-scale-check": 3, + "@performance/optional-parameters-check": 3, + "@performance/use-grid-layout-options-check": 3, + "@performance/remove-unchanged-state-var-check": 3, + "@performance/js-code-cache-by-precompile-check": 3, + "@performance/js-code-cache-by-interception-check": 3, + "@performance/web-on-active-check": 3, + "@performance/gif-hardware-decoding-check": 1 + }, + "plugin:@performance/recommended": { + "@performance/foreach-args-check": 1, + "@performance/start-window-icon-check": 3, + "@performance/waterflow-data-preload-check": 3, + "@performance/high-frequency-log-check": 1 + }, + "plugin:@security/all": { + "@security/specified-interface-call-chain-check": 3 + }, + "plugin:@correctness/all": { + "@correctness/audio-interrupt-check": 2, + "@correctness/audio-pause-or-mute-check": 1, + "@correctness/avsession-buttons-check": 1, + "@correctness/avsession-metadata-check": 1, + "@correctness/image-interpolation-check": 1, + "@correctness/image-pixel-format-check": 1 + }, + "plugin:@migration/all": { + "@migration/arkts-obj-literal-generate-class-instance": 1, + "@migration/arkts-instance-method-bind-this": 1, + "@migration/arkts-no-ts-like-as": 1, + "@migration/arkui-data-observation": 1, + "@migration/arkui-stateful-appstorage": 1, + "@migration/arkui-no-update-in-build": 1, + "@migration/arkui-custombuilder-passing": 1, + "@migration/no-method-overriding-field-check": 1, + "@migration/interop-backward-dfa": 1, + "@migration/interop-dynamic-object-literals": 1, + "@migration/interop-assign": 1, + "@migration/interop-boxed-type-check": 1, + "@migration/interop-js-modify-property": 1 + } +} diff --git a/ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh b/ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh new file mode 100644 index 0000000000000000000000000000000000000000..282d190c670e4295438767188c996c864deea436 --- /dev/null +++ b/ets2panda/linter/homecheck/scripts/install_arkanalyzer.sh @@ -0,0 +1,33 @@ +#!/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 -x + +# install and pack dependency arkanalyzer +cd ../arkanalyzer +npm install + +cp package.json package.json.bak + +sed -i '/postinstall/d' package.json +npm pack + +TAR_FILE=$(find . -maxdepth 1 -name "arkanalyzer-*.tgz" -print0) +cd ../homecheck +npm install ../arkanalyzer/$TAR_FILE + +# revert the project files +mv ../arkanalyzer/package.json.bak ../arkanalyzer/package.json +rm ../arkanalyzer/$TAR_FILE diff --git a/ets2panda/linter/homecheck/scripts/run_ci_ut.sh b/ets2panda/linter/homecheck/scripts/run_ci_ut.sh new file mode 100644 index 0000000000000000000000000000000000000000..56f455f87bfec03844eb6ea991bb9669ff4b7d15 --- /dev/null +++ b/ets2panda/linter/homecheck/scripts/run_ci_ut.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# Copyright (c) 2024 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 -x + +if [ -z "${ROOT_DIR+x}" ]; then + export ROOT_DIR=$(pwd) + echo "ROOT_DIR was not set. Initialized to $ROOT_DIR" +else + echo "ROOT_DIR is already set to $ROOT_DIR" +fi + +NODE_VERSION=v22.3.0 +NODE_HOME=$ROOT_DIR/pre_scripts/node-$NODE_VERSION-linux-x64 +NODE_URL=https://gitee.com/muya318/pre_scripts/raw/master/node-v22.3.0-linux-x64.tar.gz +NODE_BIN=node-v22.3.0-linux-x64.tar.gz + +prepare_nodejs() { + echo "### preparing nodejs" + if [ ! -d "$NODE_HOME" ]; then + cd $ROOT_DIR/pre_scripts + tar -xf $NODE_BIN + chmod 777 $NODE_HOME/bin/* + cd - + export PATH=$NODE_HOME/bin:$PATH + fi + npm config set registry=https://repo.huaweicloud.com/repository/npm/ + npm config set strict-ssl false + echo "###nodejs env ready" +} + +git clone https://gitee.com/muya318/pre_scripts.git + +prepare_nodejs + +pwd +cd $ROOT_DIR + +node -v +npm -v + +npm install +npm run test + +if [ $? -ne 0 ]; then + echo "************* Unit test failed *************" + exit 1 +fi + +echo "************* Unit test success *************" + +npm pack +if [ $? -ne 0 ]; then + echo "************* Npm pack failed *************" + exit 1 +fi +echo "************* Npm pack success *************" + +exit 0 \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/Index.ts b/ets2panda/linter/homecheck/src/Index.ts new file mode 100644 index 0000000000000000000000000000000000000000..6ad78b6bfe25006f6ab5f366effe38a2e7136803 --- /dev/null +++ b/ets2panda/linter/homecheck/src/Index.ts @@ -0,0 +1,45 @@ +/* + * 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. + */ + +// main +export { start, run } from './Main'; + +// checkers +export { BaseMetaData, BaseChecker } from './checker/BaseChecker'; + +// matchers +export * from './matcher/Matchers'; + +// models +export { CheckerStorage } from './utils/common/CheckerStorage'; +export { Rule } from './model/Rule'; +export { Defects, IssueReport, FileIssues, FileReports } from './model/Defects'; +export { RuleFix } from './model/Fix'; +export { Message, MessageType } from './model/Message'; +export { ProjectConfig } from './model/ProjectConfig'; +export { RuleConfig } from './model/RuleConfig'; +export * from './model/Scope'; + +// utils +export { CheckEntry } from './utils/common/CheckEntry'; +export { CheckerUtils } from './utils/checker/CheckerUtils'; +export { ConfigUtils } from './utils/common/ConfigUtils'; +export { FileUtils, WriteFileMode } from './utils/common/FileUtils'; +export { Json5parser } from './utils/common/Json5parser'; +export { Utils } from './utils/common/Utils'; + +// tools +export { runTool, Tools } from './tools/toolEntry'; +export { MigrationTool } from './tools/migrationTool/MigrationTool'; diff --git a/ets2panda/linter/homecheck/src/Main.ts b/ets2panda/linter/homecheck/src/Main.ts new file mode 100644 index 0000000000000000000000000000000000000000..0cd340554dc3bdb610cfda124c54b2c7e56e0572 --- /dev/null +++ b/ets2panda/linter/homecheck/src/Main.ts @@ -0,0 +1,61 @@ +/* + * 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. + */ +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { processAfterCheck } from './utils/common/AfterCheck'; +import { CheckEntry, checkEntryBuilder, getSelectFileList } from './utils/common/CheckEntry'; +import { ConfigUtils } from './utils/common/ConfigUtils'; +import { DefaultMessage } from './model/Message'; +import { Utils } from './utils/common/Utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Main'); + +export async function start(checkEntry: CheckEntry): Promise { + // 外部没有建立消息通道,使用默认通道 + if (!checkEntry.message) { + checkEntry.message = new DefaultMessage(); + } + + // 前处理 + if (!await checkEntryBuilder(checkEntry)) { + return false; + } + + // 开始检查 + await checkEntry.runAll(); + + // 后处理 + await processAfterCheck(checkEntry); + logger.info('Checking completed.'); + return true; +} + +export async function run(): Promise { + const startTime = new Date().getTime(); + const checkEntry = new CheckEntry(); + // 构建ruleConfig和projectConfig,保存至checkEntry中 + if (!ConfigUtils.parseConfig(Utils.parseCliOptions(process.argv), checkEntry)) { + return false; + } + + // 设置指定文件检查,不设置默认检查所有文件 + checkEntry.setCheckFileList(getSelectFileList(checkEntry.projectConfig.checkPath)); + + // 启动homecheck检查 + await start(checkEntry); + + const endTime = new Date().getTime(); + logger.info(`HomeCheck took: ${(endTime - startTime) / 1000} s.`); + return true; +}; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/checker/BaseChecker.ts b/ets2panda/linter/homecheck/src/checker/BaseChecker.ts new file mode 100644 index 0000000000000000000000000000000000000000..fb7d3375236a6c3b6aedda1611cbcd1ff2361eb3 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/BaseChecker.ts @@ -0,0 +1,37 @@ +/* + * 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. + */ + +import { ArkFile } from 'arkanalyzer'; +import { Rule } from '../model/Rule'; +import { MatcherCallback } from '../matcher/Matchers'; +import { IssueReport } from '../model/Defects'; + +export interface BaseMetaData { + severity: number, + ruleDocPath: string, + description: string, + [extendField: string]: any +} + +export interface BaseChecker { + metaData: object; + // 在CheckerFactory构建checker实例时,已对rule进行赋值 + rule: Rule; + registerMatchers(): MatcherCallback[]; + check(target: any): void; + codeFix?(arkFile: ArkFile, fixKey: string): boolean; + // 用于保存当前checker发现的告警信息与fix相关信息 + issues: IssueReport[]; +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..693f8914126a9a7d9a5da0d9e697963b77e5e460 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/AppStorageGetCheck.ts @@ -0,0 +1,155 @@ +/* + * 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 { + ArkInstanceInvokeExpr, + ArkMethod, + ArkStaticInvokeExpr, + CallGraph, + CallGraphBuilder, + Stmt, + Value, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, ClassMatcher, MethodMatcher, MatcherTypes, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { CALL_DEPTH_LIMIT, CALLBACK_METHOD_NAME, CallGraphHelper } from './Utils'; +import { WarnInfo } from '../../utils/common/Utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'AppStorageGetCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: + 'Get State of AppStorage in component build function, it will update UI interface when the state of AppStorage is changed', +}; + +const APP_STORAGE_STR = 'AppStorage'; +const API_SET: Set = new Set(['has', 'get', 'keys', 'size']); + +export class AppStorageGetCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private classMatcher: ClassMatcher = { + matcherType: MatcherTypes.CLASS, + hasViewTree: true, + }; + + private buildMatcher: MethodMatcher = { + matcherType: MatcherTypes.METHOD, + class: [this.classMatcher], + name: ['build'], + }; + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: this.buildMatcher, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (targetMtd: ArkMethod): void => { + const scene = targetMtd.getDeclaringArkFile().getScene(); + let callGraph = CallGraphHelper.getCGInstance(scene); + let callGraphBuilder = new CallGraphBuilder(callGraph, scene); + callGraphBuilder.buildClassHierarchyCallGraph([targetMtd.getSignature()]); + + this.checkMethod(targetMtd, callGraph); + }; + + private checkMethod(targetMtd: ArkMethod, cg: CallGraph, depth: number = 0): void { + if (depth > CALL_DEPTH_LIMIT) { + return; + } + const stmts = targetMtd.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + this.checkAppStorageGet(stmt); + const invokeExpr = stmt.getInvokeExpr(); + if (invokeExpr && invokeExpr instanceof ArkInstanceInvokeExpr) { + if ( + CALLBACK_METHOD_NAME.includes( + invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName() + ) + ) { + continue; + } + } + let callsite = cg.getCallSiteByStmt(stmt); + callsite.forEach(cs => { + let callee = cg.getArkMethodByFuncID(cs.calleeFuncID); + if (callee) { + this.checkMethod(callee, cg, depth + 1); + } + }); + } + } + + private checkAppStorageGet(stmt: Stmt): void { + let invokeExpr = stmt.getInvokeExpr(); + if (!(invokeExpr instanceof ArkStaticInvokeExpr)) { + return; + } + const methodSig = invokeExpr.getMethodSignature(); + if (methodSig.getDeclaringClassSignature().getClassName() !== APP_STORAGE_STR) { + return; + } + if (!API_SET.has(methodSig.getMethodSubSignature().getMethodName())) { + return; + } + this.addIssueReport(stmt, invokeExpr); + } + + private addIssueReport(stmt: Stmt, operand: Value): void { + const severity = this.rule.alert ?? this.metaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'AppStorageSpecChanged'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const originPosition = stmt.getOperandOriginalPosition(operand); + if (arkFile && originPosition) { + const originPath = arkFile.getFilePath(); + const line = originPosition.getFirstLine(); + const startCol = originPosition.getFirstCol(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + } + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..b8dcb06db7d2c47226110a65dfc9298937fdc42c --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/CustomBuilderCheck.ts @@ -0,0 +1,285 @@ +/* + * 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 { + ArkAssignStmt, + Scene, + Local, + Stmt, + Type, + ArkMethod, + AliasType, + AbstractInvokeExpr, + Value, + ArkFile, + AstTreeUtils, + ts, + FunctionType, + ArkClass, + ANONYMOUS_METHOD_PREFIX, + ArkInvokeStmt, +} from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MatcherCallback, MethodMatcher } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { FixInfo, RuleFix } from '../../model/Fix'; +import { FixPosition, FixUtils } from '../../utils/common/FixUtils'; +import { WarnInfo } from '../../utils/common/Utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CustomBuilderCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: 'The CustomBuilder type parameter only accepts functions annotated with @Builder', +}; + +export class CustomBuilderCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private buildMatcher: MethodMatcher = { + matcherType: MatcherTypes.METHOD, + }; + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: this.buildMatcher, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (target: ArkMethod): void => { + const scene = target.getDeclaringArkFile().getScene(); + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + let locals = new Set(); + for (const stmt of stmts) { + // 场景1:函数调用赋值给CustomBuilder类型的对象 + const local = this.isCallToBuilder(stmt, scene); + if (local) { + locals.add(local); + continue; + } + const usage = this.isPassToCustomBuilder(stmt, locals); + if (usage) { + this.addIssueReport(usage.getDeclaringStmt()!, usage); + } + + // 场景2:函数调用包在箭头函数中赋值给CustomBuilder类型的对象 + if (stmt instanceof ArkAssignStmt) { + const arrowMethod = this.findPotentialArrowFunction(stmt, target.getDeclaringArkClass()); + if (arrowMethod !== null && this.isCallToBuilderWrapWithArrow(arrowMethod)) { + this.addIssueReport(stmt, stmt.getRightOp()); + } + } + } + }; + + // 只有当赋值语句leftOp为CustomBuilder类型时,若rightOp是匿名箭头函数,则返回该箭头函数 + private findPotentialArrowFunction(stmt: Stmt, arkClass: ArkClass): ArkMethod | null { + if (!(stmt instanceof ArkAssignStmt) || !this.isCustomBuilderTy(stmt.getLeftOp().getType())) { + return null; + } + + const rightOpType = stmt.getRightOp().getType(); + if (!(rightOpType instanceof FunctionType)) { + return null; + } + + const methodName = rightOpType.getMethodSignature().getMethodSubSignature().getMethodName(); + const method = arkClass.getMethodWithName(methodName); + if (method === null || !method.isAnonymousMethod()) { + return null; + } + return method; + } + + private isCallToBuilderWrapWithArrow(arrowMethod: ArkMethod): boolean { + const scene = arrowMethod.getDeclaringArkFile().getScene(); + const stmts = arrowMethod.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkInvokeStmt)) { + continue; + } + const invokeExpr = stmt.getInvokeExpr(); + const method = scene.getMethod(invokeExpr.getMethodSignature()); + if (method && method.hasBuilderDecorator()) { + return true; + } + } + return false; + } + + private isCallToBuilder(stmt: Stmt, scene: Scene): Local | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof Local)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof AbstractInvokeExpr)) { + return undefined; + } + const method = scene.getMethod(rightOp.getMethodSignature()); + if (method && method.hasBuilderDecorator()) { + return leftOp; + } + return undefined; + } + + private isCustomBuilderTy(ty: Type): boolean { + return ty instanceof AliasType && ty.getName() === 'CustomBuilder'; + } + + private isPassToCustomBuilder(stmt: Stmt, locals: Set): Local | undefined { + if (stmt instanceof ArkAssignStmt) { + if (!this.isCustomBuilderTy(stmt.getLeftOp().getType())) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local && locals.has(rightOp)) { + return rightOp; + } + } + const invokeExpr = stmt.getInvokeExpr(); + if (invokeExpr) { + const paramTys = invokeExpr.getMethodSignature().getMethodSubSignature().getParameterTypes(); + const args = invokeExpr.getArgs(); + for (let i = 0; i < paramTys.length && i < args.length; ++i) { + if (!this.isCustomBuilderTy(paramTys[i])) { + continue; + } + const arg = args[i]; + if (arg instanceof Local && locals.has(arg)) { + return arg; + } + } + } + return undefined; + } + + private addIssueReport(stmt: Stmt, operand: Value): void { + const severity = this.rule.alert ?? this.metaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'CustomBuilderTypeChanged'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + true + ); + const fixPosition: FixPosition = { + startLine: warnInfo.line, + startCol: warnInfo.startCol, + endLine: -1, + endCol: -1, + }; + const ruleFix = this.generateRuleFix(fixPosition, stmt) ?? undefined; + this.issues.push(new IssueReport(defects, ruleFix)); + if (ruleFix === undefined) { + defects.fixable = false; + } + } + + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const originPosition = stmt.getOperandOriginalPosition(operand); + if (arkFile && originPosition) { + const originPath = arkFile.getFilePath(); + const line = originPosition.getFirstLine(); + const startCol = originPosition.getFirstCol(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + } + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; + } + + private generateRuleFix(fixPosition: FixPosition, stmt: Stmt): RuleFix | null { + let ruleFix: RuleFix = new RuleFix(); + const endPosition = this.getEndPositionOfStmt(stmt); + if (endPosition) { + fixPosition.endLine = endPosition.line; + fixPosition.endCol = endPosition.col; + } + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const sourceFile = AstTreeUtils.getASTNode(arkFile.getName(), arkFile.getCode()); + const range = FixUtils.getRangeWithAst(sourceFile, fixPosition); + ruleFix.range = range; + const originalText = FixUtils.getSourceWithRange(sourceFile, range); + if (originalText !== null) { + ruleFix.text = this.generateReplaceText(sourceFile, originalText, fixPosition); + } else { + return null; + } + return ruleFix; + } + + private getEndPositionOfStmt(stmt: Stmt): { line: number; col: number } | null { + const allPositions = stmt.getOperandOriginalPositions(); + if (allPositions === undefined) { + return null; + } + let res = { line: -1, col: -1 }; + allPositions.forEach(position => { + if (position.getLastLine() > res.line) { + res = { line: position.getLastLine(), col: position.getLastCol() }; + return; + } + if (position.getLastLine() === res.line && position.getLastCol() > res.col) { + res = { line: position.getLastLine(), col: position.getLastCol() }; + return; + } + }); + return res; + } + + private generateReplaceText(sourceFile: ts.SourceFile, originalText: string, fixPosition: FixPosition): string { + // 已经是箭头函数的场景,无需任何处理 + if (originalText.includes('=>')) { + return originalText; + } + + // 非箭头函数包裹的函数调用,需要使用箭头函数包裹 + const eol = FixUtils.getEolSymbol(sourceFile, fixPosition.startLine); + const startLineIndent = FixUtils.getIndentOfLine(sourceFile, fixPosition.startLine) ?? 0; + const increaseSpaces = FixUtils.getIndentWidth(sourceFile, fixPosition.startLine); + const space = ' '; + + let res = `() => {${eol}`; + const originalLineStrs = originalText.split(eol); + res += `${space.repeat(startLineIndent + increaseSpaces)}${originalLineStrs[0]}${eol}`; + for (let index = 1; index < originalLineStrs.length; index++) { + res += `${space.repeat(increaseSpaces)}${originalLineStrs[index]}${eol}`; + } + res += `${space.repeat(startLineIndent)}}`; + return res; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..d956fe529c7181a55527a35c870cabde40d9c4d8 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropAssignCheck.ts @@ -0,0 +1,273 @@ +/* + * 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, + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + FunctionType, + ClassType, + ArkNamespace, + PrimitiveType, + UnclearReferenceType, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { CALL_DEPTH_LIMIT, DVFGHelper, GlobalCallGraphHelper } from './Utils'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropAssignCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: 'Should not pass or assign a dynamic object to a variable of static type', +}; + +const RULE_ID = 'arkts-interop-s2d-dynamic-args-to-static'; +const BOXED_SET: Set = new Set(['String', 'Boolean', 'BigInt', 'Number']); +export class InteropAssignCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private cg: CallGraph; + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); + + for (let arkFile of scene.getFiles()) { + for (let clazz of arkFile.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, scene); + } + } + for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { + this.processNameSpace(namespace, scene); + } + } + }; + + public processNameSpace(namespace: ArkNamespace, scene: Scene): void { + for (let clazz of namespace.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, scene); + } + } + } + + public processArkMethod(target: ArkMethod, scene: Scene): void { + if (target.getLanguage() === Language.ARKTS1_2) { + this.checkPassToFunction(target, scene); + } else if (target.getLanguage() === Language.ARKTS1_1) { + this.checkAssignToField(target, scene); + } + } + + private checkPassToFunction(target: ArkMethod, scene: Scene) { + const callsites = this.cg.getInvokeStmtByMethod(target.getSignature()); + callsites.forEach(cs => { + let hasTargetArg = false; + const invoke = cs.getInvokeExpr()!; + const csMethod = cs.getCfg()?.getDeclaringMethod(); + invoke.getArgs().forEach(arg => { + const argTy = arg.getType(); + if (argTy instanceof PrimitiveType || this.isBoxedType(argTy)) { + return; + } + const argTyLang = this.getTypeDefinedLang(argTy, scene) ?? csMethod?.getLanguage() ?? Language.UNKNOWN; + if (argTyLang === Language.ARKTS1_1) { + hasTargetArg = true; + } + }); + if (!hasTargetArg) { + return; + } + let line = cs.getOriginPositionInfo().getLineNo(); + let column = cs.getOriginPositionInfo().getColNo(); + const problem = 'Interop'; + const desc = `${this.metaData.description} (${RULE_ID})`; + const severity = this.metaData.severity; + const ruleId = this.rule.ruleId; + const filePath = csMethod?.getDeclaringArkFile()?.getFilePath() ?? ''; + const defeats = new Defects(line, column, column, problem, desc, severity, ruleId, filePath, '', true, false, false); + this.issues.push(new IssueReport(defeats, undefined)); + }); + } + + private isBoxedType(checkType: Type): boolean { + const unclear = checkType instanceof UnclearReferenceType && BOXED_SET.has(checkType.getName()); + const cls = checkType instanceof ClassType && BOXED_SET.has(checkType.getClassSignature().getClassName()); + return unclear || cls; + } + + private checkAssignToField(target: ArkMethod, scene: Scene) { + const assigns: Stmt[] = this.collectAssignToObjectField(target, scene); + if (assigns.length > 0) { + DVFGHelper.buildSingleDVFG(target, scene); + } + assigns.forEach(assign => { + let result: Stmt[] = []; + let visited: Set = new Set(); + this.checkFromStmt(assign, scene, result, visited); + if (result.length === 0) { + // 这句 a.data = y 右侧的值没有从 1.1 传入的可能 + return; + } + let line = assign.getOriginPositionInfo().getLineNo(); + let column = assign.getOriginPositionInfo().getColNo(); + const problem = 'Interop'; + const desc = `${this.metaData.description} (${RULE_ID})`; + const severity = this.metaData.severity; + const ruleId = this.rule.ruleId; + const filePath = assign.getCfg()?.getDeclaringMethod().getDeclaringArkFile()?.getFilePath() ?? ''; + const defeats = new Defects(line, column, column, problem, desc, severity, ruleId, filePath, '', true, false, false); + this.issues.push(new IssueReport(defeats, undefined)); + }); + } + + private collectAssignToObjectField(method: ArkMethod, scene: Scene): Stmt[] { + const res: Stmt[] = []; + const stmts = method.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof ArkInstanceFieldRef)) { + continue; + } + if (!this.isObjectTy(leftOp.getType())) { + continue; + } + const baseTy = leftOp.getBase().getType(); + if (baseTy instanceof ClassType) { + const klass = scene.getClass(baseTy.getClassSignature()); + if (!klass) { + logger.warn(`check field of type 'Object' failed: cannot find arkclass by sig ${baseTy.getClassSignature().toString()}`); + } else if (klass.getLanguage() === Language.ARKTS1_2) { + res.push(stmt); + } + } else { + logger.warn(`check field of type 'Object' failed: unexpected base type ${baseTy.toString()}`); + } + } + return res; + } + + private checkFromStmt(stmt: Stmt, scene: Scene, res: Stmt[], visited: Set, depth: number = 0): void { + if (depth > CALL_DEPTH_LIMIT) { + return; + } + const node = DVFGHelper.getOrNewDVFGNode(stmt, scene); + let worklist: DVFGNode[] = [node]; + while (worklist.length > 0) { + const current = worklist.shift()!; + const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); + if (currentStmt instanceof ArkAssignStmt) { + const rightOpTy = currentStmt.getRightOp().getType(); + if (!this.isObjectTy(rightOpTy) && this.getTypeDefinedLang(rightOpTy, scene) === Language.ARKTS1_1) { + res.push(currentStmt); + continue; + } + } + const callsite = this.cg.getCallSiteByStmt(currentStmt); + callsite.forEach(cs => { + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + return; + } + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + declaringMtd.getReturnStmt().forEach(r => this.checkFromStmt(r, scene, res, visited, depth + 1)); + }); + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + const callsites = this.cg.getInvokeStmtByMethod(currentStmt.getCfg().getDeclaringMethod().getSignature()); + callsites.forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + }); + this.collectArgDefs(paramIdx, callsites, scene).forEach(d => this.checkFromStmt(d, scene, res, visited, depth + 1)); + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + } + } + + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private collectArgDefs(argIdx: number, callsites: Stmt[], scene: Scene): Stmt[] { + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + return callsites.flatMap(callsite => { + const target: Value | FieldSignature = getKey(callsite.getInvokeExpr()!.getArg(argIdx)); + return Array.from(DVFGHelper.getOrNewDVFGNode(callsite, scene).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && target === getKey(s.getLeftOp()); + }); + }); + } + + private isObjectTy(ty: Type): boolean { + return ty instanceof ClassType && ty.getClassSignature().getClassName() === 'Object'; + } + + private getTypeDefinedLang(type: Type, scene: Scene): Language | undefined { + let file = undefined; + if (type instanceof ClassType) { + file = scene.getFile(type.getClassSignature().getDeclaringFileSignature()); + } else if (type instanceof FunctionType) { + file = scene.getFile(type.getMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature()); + } + if (file) { + return file.getLanguage(); + } else { + logger.error(`fail to identify which file the type definition ${type.toString()} is in.`); + } + return undefined; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropBackwardDFACheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropBackwardDFACheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..9651894a32e058ab673a856c3b29f5581600baa6 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropBackwardDFACheck.ts @@ -0,0 +1,459 @@ +/* + * 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, + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + ArkInstanceInvokeExpr, + AnyType, + ClassType, + ArkStaticInvokeExpr, + AbstractInvokeExpr, + FunctionType, + UnknownType, + Local, + ArkClass, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { CALL_DEPTH_LIMIT, GlobalCallGraphHelper, DVFGHelper } from './Utils'; +import { findInteropRule } from './InteropRuleInfo'; +import { ArkFile, Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropBackwardDFACheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +const REFLECT_API: Map = new Map([ + ['apply', 0], + ['construct', 0], + ['defineProperty', 0], + ['deleteProperty', 0], + ['get', 0], + ['getOwnPropertyDescriptor', 0], + ['getPrototypeOf', 0], + ['has', 0], + ['isExtensible', 0], + ['ownKeys', 0], + ['preventExtensions', 0], + ['set', 0], + ['setPrototypeOf', 0], +]); + +const OBJECT_API: Map = new Map([ + ['getOwnPropertyDescriptor', 0], + ['getOwnPropertyDescriptors', 0], + ['getOwnPropertyNames', 0], + ['hasOwn', 0], + ['isExtensible', 0], + ['isFrozen', 0], + ['isSealed', 0], + ['keys', 0], + ['setPrototypeOf', 0], + ['values', 0], + ['assign', 1], + ['entries', 0], +]); + +class ObjDefInfo { + problemStmt: Stmt; + objLanguage: Language; +} + +export class InteropBackwardDFACheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private cg: CallGraph; + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); + + for (let arkFile of scene.getFiles()) { + const importVarMap: Map = new Map(); + this.collectImportedVar(importVarMap, arkFile, scene); + const topLevelVarMap: Map = new Map(); + this.collectTopLevelVar(topLevelVarMap, arkFile, scene); + + const handleClass = (cls: ArkClass): void => { + cls.getMethods().forEach(m => this.processArkMethod(m, scene, importVarMap, topLevelVarMap)); + }; + + arkFile.getClasses().forEach(cls => handleClass(cls)); + arkFile.getAllNamespacesUnderThisFile().forEach(n => n.getClasses().forEach(cls => handleClass(cls))); + } + }; + + private collectImportedVar(importVarMap: Map, file: ArkFile, scene: Scene) { + file.getImportInfos().forEach(importInfo => { + const exportInfo = importInfo.getLazyExportInfo(); + if (exportInfo === null) { + return; + } + const arkExport = exportInfo.getArkExport(); + if (!arkExport || !(arkExport instanceof Local)) { + return; + } + const declaringStmt = arkExport.getDeclaringStmt(); + if (!declaringStmt) { + return; + } + const definedLang = this.getTypeDefinedLang(arkExport.getType(), scene) ?? file.getLanguage(); + importVarMap.set(arkExport.getName(), definedLang); + }); + } + + private collectTopLevelVar(topLevelVarMap: Map, file: ArkFile, scene: Scene) { + const defaultMethod = file.getDefaultClass().getDefaultArkMethod(); + if (defaultMethod) { + DVFGHelper.buildSingleDVFG(defaultMethod, scene); + const stmts = defaultMethod.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof Local)) { + continue; + } + const name = leftOp.getName(); + if (name.startsWith('%') || name === 'this') { + continue; + } + topLevelVarMap.set(name, [...(topLevelVarMap.get(name) ?? []), stmt]); + } + } + } + + private processArkMethod( + target: ArkMethod, + scene: Scene, + importVarMap: Map, + topLevelVarMap: Map + ): void { + const currentLang = target.getLanguage(); + if (currentLang === Language.UNKNOWN) { + logger.warn(`cannot find the language for method: ${target.getSignature()}`); + return; + } + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + const invoke = stmt.getInvokeExpr(); + let isReflect = false; + let paramIdx = -1; + if (invoke && invoke instanceof ArkInstanceInvokeExpr) { + if (invoke.getBase().getName() === 'Reflect') { + isReflect = true; + paramIdx = + REFLECT_API.get(invoke.getMethodSignature().getMethodSubSignature().getMethodName()) ?? -1; + } + } + if (invoke && invoke instanceof ArkStaticInvokeExpr) { + const methodSig = invoke.getMethodSignature(); + const classSig = methodSig.getDeclaringClassSignature(); + if (classSig.getClassName() === 'ObjectConstructor' || classSig.getClassName() === 'Object') { + paramIdx = + OBJECT_API.get(invoke.getMethodSignature().getMethodSubSignature().getMethodName()) ?? -1; + } + } + if (paramIdx === -1) { + continue; + } + DVFGHelper.buildSingleDVFG(target, scene); + + const argDefs = this.findArgumentDef(stmt, paramIdx, currentLang, importVarMap, topLevelVarMap, scene); + if (this.isLanguage(argDefs)) { + this.reportIssue({ problemStmt: stmt, objLanguage: argDefs as Language }, currentLang, isReflect); + } else { + argDefs.forEach(def => { + let result: ObjDefInfo[] = []; + let visited: Set = new Set(); + this.checkFromStmt(def, currentLang, result, visited, importVarMap, topLevelVarMap, scene); + result.forEach(objDefInfo => { + this.reportIssue(objDefInfo, currentLang, isReflect); + }); + }); + } + } + } + + private reportIssue(objDefInfo: ObjDefInfo, apiLang: Language, isReflect: boolean) { + const problemStmt = objDefInfo.problemStmt; + const problemStmtMtd = problemStmt.getCfg()?.getDeclaringMethod(); + const problemStmtLang = problemStmtMtd?.getLanguage(); + const objLanguage = objDefInfo.objLanguage; + if (objLanguage === Language.UNKNOWN || problemStmtLang === Language.UNKNOWN) { + logger.warn(`cannot find the language for def: ${problemStmt.toString()}`); + return; + } + const interopRule = findInteropRule(apiLang, objLanguage, problemStmtLang, isReflect); + if (!interopRule) { + return; + } + const line = problemStmt.getOriginPositionInfo().getLineNo(); + const column = problemStmt.getOriginPositionInfo().getColNo(); + const problem = 'Interop'; + const desc = `${interopRule.description} (${interopRule.ruleId})`; + const severity = interopRule.severity; + const ruleId = this.rule.ruleId; + const filePath = problemStmtMtd?.getDeclaringArkFile()?.getFilePath() ?? ''; + const defeats = new Defects( + line, + column, + column, + problem, + desc, + severity, + ruleId, + filePath, + '', + true, + false, + false + ); + this.issues.push(new IssueReport(defeats, undefined)); + } + + private checkFromStmt( + stmt: Stmt, + apiLanguage: Language, + res: ObjDefInfo[], + visited: Set, + importVarMap: Map, + topLevelVarMap: Map, + scene: Scene, + depth: number = 0 + ): void { + if (depth > CALL_DEPTH_LIMIT) { + return; + } + const node = DVFGHelper.getOrNewDVFGNode(stmt, scene); + let worklist: DVFGNode[] = [node]; + while (worklist.length > 0) { + const current = worklist.shift()!; + const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); + if (currentStmt instanceof ArkAssignStmt) { + const rightOp = currentStmt.getRightOp(); + if (rightOp instanceof ArkInstanceFieldRef) { + // 处理 Reflect.apply(obj.getName, {a : 12}) + const base = rightOp.getBase(); + if (base instanceof Local && base.getDeclaringStmt()) { + worklist.push(DVFGHelper.getOrNewDVFGNode(base.getDeclaringStmt()!, scene)); + continue; + } + } + if (rightOp instanceof Local && !rightOp.getDeclaringStmt()) { + const name = rightOp.getName(); + if (importVarMap.has(name)) { + res.push({ problemStmt: currentStmt, objLanguage: importVarMap.get(name)! }); + continue; + } + } + const rightOpTy = rightOp.getType(); + if (!this.isIrrelevantType(rightOpTy)) { + const rightOpTyLang = this.getTypeDefinedLang(rightOpTy, scene); + if (rightOpTyLang && rightOpTyLang !== apiLanguage) { + res.push({ problemStmt: currentStmt, objLanguage: rightOpTyLang }); + continue; + } + } + } + const callsite = this.cg.getCallSiteByStmt(currentStmt); + if (callsite.length > 0) { + callsite.forEach(cs => { + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + return; + } + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + declaringMtd + .getReturnStmt() + .forEach(r => + this.checkFromStmt( + r, + apiLanguage, + res, + visited, + importVarMap, + topLevelVarMap, + scene, + depth + 1 + ) + ); + }); + continue; + } + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + this.cg.getInvokeStmtByMethod(currentStmt.getCfg().getDeclaringMethod().getSignature()).forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + const argDefs = this.findArgumentDef( + cs, + paramIdx, + apiLanguage, + importVarMap, + topLevelVarMap, + scene + ); + if (this.isLanguage(argDefs)) { + // imported var + res.push({ problemStmt: cs, objLanguage: argDefs as Language }); + } else { + argDefs.forEach(d => { + this.checkFromStmt( + d, + apiLanguage, + res, + visited, + importVarMap, + topLevelVarMap, + scene, + depth + 1 + ); + }); + } + }); + continue; + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + if (stmt instanceof ArkAssignStmt) { + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local && !rightOp.getDeclaringStmt()) { + (topLevelVarMap.get(rightOp.getName()) ?? []).forEach(def => { + worklist.push(DVFGHelper.getOrNewDVFGNode(def, scene)); + }); + } + } + } + } + + private isIrrelevantType(ty: Type): boolean { + const isObjectTy = (ty: Type): boolean => { + return ty instanceof ClassType && ty.getClassSignature().getClassName() === 'Object'; + }; + const isESObjectTy = (ty: Type): boolean => { + return ty.toString() === 'ESObject'; + }; + const isAnyTy = (ty: Type): ty is AnyType => { + return ty instanceof AnyType; + }; + const isUnkwonTy = (ty: Type): ty is UnknownType => { + return ty instanceof UnknownType; + }; + return isObjectTy(ty) || isESObjectTy(ty) || isAnyTy(ty) || isUnkwonTy(ty); + } + + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private isLanguage(value: Stmt[] | Language): value is Language { + return Object.values(Language).includes(value as Language); + } + + private findArgumentDef( + stmt: Stmt, + argIdx: number, + apiLanguage: Language, + importVarMap: Map, + topLevelVarMap: Map, + scene: Scene + ): Stmt[] | Language { + const invoke = stmt.getInvokeExpr(); + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + const arg: Value | FieldSignature = getKey((invoke as AbstractInvokeExpr).getArg(argIdx)); + if (!arg) { + logger.error(`arg${argIdx} of invoke ${stmt.toString()} is undefined`); + return []; + } + if (arg instanceof Local && arg.getDeclaringStmt() instanceof ArkAssignStmt) { + // 特殊处理,obj.getName 的类型有 bug + const rightOp = (arg.getDeclaringStmt() as ArkAssignStmt).getRightOp(); + if (rightOp instanceof ArkInstanceFieldRef) { + const base = rightOp.getBase(); + if (base instanceof Local && base.getDeclaringStmt()) { + return [base.getDeclaringStmt()!]; + } + } + } + const argTy = arg.getType(); + if (!this.isIrrelevantType(argTy)) { + const argTyLang = this.getTypeDefinedLang(argTy, scene); + if (argTyLang && argTyLang !== apiLanguage) { + return argTyLang; + } + } + if (arg instanceof Local && !arg.getDeclaringStmt()) { + const name = arg.getName(); + return topLevelVarMap.get(name) ?? importVarMap.get(name) ?? []; + } + return Array.from(DVFGHelper.getOrNewDVFGNode(stmt, scene).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && arg === getKey(s.getLeftOp()); + }); + } + + private getTypeDefinedLang(type: Type, scene: Scene): Language | undefined { + let file = undefined; + if (type instanceof ClassType) { + file = scene.getFile(type.getClassSignature().getDeclaringFileSignature()); + } else if (type instanceof FunctionType) { + file = scene.getFile(type.getMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature()); + } + if (file) { + return file.getLanguage(); + } + return undefined; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..42b4dc0973a789fe6d96f7a86e20bb8323dbbdf0 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropBoxedTypeCheck.ts @@ -0,0 +1,450 @@ +/* + * 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 { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule } from '../../model/Rule'; +import { Defects, IssueReport } from '../../model/Defects'; +import { FileMatcher, MatcherCallback, MatcherTypes } from '../../matcher/Matchers'; +import { + AbstractInvokeExpr, + ArkAssignStmt, + ArkClass, + ArkFile, + ArkMethod, + ArkNamespace, + ArkNewExpr, + ClassType, + FunctionType, + ImportInfo, + Local, + LOG_MODULE_TYPE, + Logger, + Scene, + Stmt, + Type, +} from 'arkanalyzer'; +import { ExportType } from 'arkanalyzer/lib/core/model/ArkExport'; +import { WarnInfo } from '../../utils/common/Utils'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { getLanguageStr } from './Utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ObservedDecoratorCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +const ruleId: string = '@migration/interop-boxed-type-check'; +const s2dRuleId: string = 'arkts-interop-s2d-boxed-type'; +const d2sRuleId: string = 'arkts-interop-d2s-boxed-type'; +const ts2sRuleId: string = 'arkts-interop-ts2s-boxed-type'; +const js2RuleId: string = 'arkts-interop-js2s-boxed-type'; + +const BOXED_SET: Set = new Set(['String', 'Boolean', 'Number']); + +type CheckedObj = { + namespaces: Map; + classes: Map; + methods: Map; +}; + +export class InteropBoxedTypeCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private fileMatcher: FileMatcher = { + matcherType: MatcherTypes.FILE, + }; + + public registerMatchers(): MatcherCallback[] { + const fileMatcher: MatcherCallback = { + matcher: this.fileMatcher, + callback: this.check, + }; + return [fileMatcher]; + } + + public check = (arkFile: ArkFile): void => { + let hasChecked: CheckedObj = { + namespaces: new Map(), + classes: new Map(), + methods: new Map(), + }; + const scene = arkFile.getScene(); + // Import对象对应的Export信息的推导在类型推导过程中是懒加载机制,调用getLazyExportInfo接口会自动进行推导 + arkFile.getImportInfos().forEach(importInfo => { + const exportInfo = importInfo.getLazyExportInfo(); + // TODO: import * from xxx是如何表示的? + if (exportInfo === null) { + // 导入内置库时为null + return; + } + const arkExport = exportInfo.getArkExport(); + if (arkExport === null || arkExport === undefined) { + // 按正常流程,上面的exportInfo不为null时,这里一定会将实际找到的export对象set为arkExport,所以这里应该走不到 + // import三方包时为null,未推导为undefined,推导后无结果为null + return; + } + + const exportType = arkExport.getExportType(); + // 如果import的是sdk,exportType可能是namespace等,但是找不到body体等详细赋值语句等内容,所以不影响如下的判断 + switch (exportType) { + case ExportType.NAME_SPACE: + this.findBoxedTypeInNamespace(importInfo, arkExport as ArkNamespace, scene, hasChecked); + return; + case ExportType.CLASS: + this.findBoxedTypeInClass(importInfo, arkExport as ArkClass, scene, hasChecked); + return; + case ExportType.METHOD: + this.findBoxedTypeWithMethodReturn(importInfo, arkExport as ArkMethod, scene, hasChecked); + return; + case ExportType.LOCAL: + this.findBoxedTypeWithLocal(importInfo, arkExport as Local, scene, hasChecked); + return; + default: + return; + } + }); + }; + + private findBoxedTypeInNamespace( + importInfo: ImportInfo, + arkNamespace: ArkNamespace, + scene: Scene, + hasChecked: CheckedObj + ): boolean | null { + // 判断namespace是否已查找过,避免陷入死循环 + const existing = hasChecked.namespaces.get(arkNamespace.getSignature().toString()); + if (existing !== undefined) { + return existing; + } + hasChecked.namespaces.set(arkNamespace.getSignature().toString(), null); + const exports = arkNamespace.getExportInfos(); + let found: boolean | null = null; + for (const exportInfo of exports) { + const arkExport = exportInfo.getArkExport(); + if (arkExport === undefined) { + continue; + } + + if (arkExport === null) { + // ArkAnalyzer此处有一个问题,无法区分export local是来自arkfile还是arknamespace,导致类型推导推出来是null + continue; + } + if (arkExport instanceof Local) { + found = this.findBoxedTypeWithLocal(importInfo, arkExport, scene, hasChecked); + } else if (arkExport instanceof ArkMethod) { + found = this.findBoxedTypeWithMethodReturn(importInfo, arkExport, scene, hasChecked); + } else if (arkExport instanceof ArkClass) { + found = this.findBoxedTypeInClass(importInfo, arkExport, scene, hasChecked); + } else if (arkExport instanceof ArkNamespace) { + found = this.findBoxedTypeInNamespace(importInfo, arkExport, scene, hasChecked); + } + if (found) { + hasChecked.namespaces.set(arkNamespace.getSignature().toString(), true); + return true; + } + } + hasChecked.namespaces.set(arkNamespace.getSignature().toString(), false); + return false; + } + + private isClassHasBoxedType(arkClass: ArkClass, scene: Scene, hasChecked: CheckedObj): boolean | null { + // step0: 判断class是否已查找过,避免陷入死循环 + const existing = hasChecked.classes.get(arkClass.getSignature().toString()); + if (existing !== undefined) { + return existing; + } + hasChecked.classes.set(arkClass.getSignature().toString(), null); + // step1: 查找class中的所有field,包含static和非static,判断initialized stmts中是否会用boxed类型对象给field赋值 + const allFields = arkClass.getFields(); + for (const field of allFields) { + // 此处不检查field signature中的Type,因为type直接写String时也表示成Class Type,无法区分是否为new String()生成的 + const initializer = field.getInitializer(); + if (initializer.length < 1) { + continue; + } + const lastStmt = initializer[initializer.length - 1]; + if (!(lastStmt instanceof ArkAssignStmt)) { + continue; + } + if (this.isValueAssignedByBoxed(lastStmt, initializer.slice(0, -1).reverse(), scene, hasChecked)) { + // 这里没有顺着field的定义语句中使用到的import对象去寻找原始的Boxed类型定义所在的文件的Language,而是直接使用field所在的语言 + // 应该也是ok的,因为上述import chain如何不合法,也会有告警在其import的地方给出 + hasChecked.classes.set(arkClass.getSignature().toString(), true); + return true; + } + } + + // step2: 查找class中的所有非generated method,判断所有的return操作符类型是否为boxed + const methods = arkClass.getMethods(); + for (const method of methods) { + const found = this.isMethodReturnHasBoxedType(method, scene, hasChecked); + if (found) { + hasChecked.classes.set(arkClass.getSignature().toString(), true); + return true; + } + } + hasChecked.classes.set(arkClass.getSignature().toString(), false); + return false; + } + + private isMethodReturnHasBoxedType(arkMethod: ArkMethod, scene: Scene, hasChecked: CheckedObj): boolean | null { + // 判断method是否已查找过,避免陷入死循环 + const existing = hasChecked.methods.get(arkMethod.getSignature().toString()); + if (existing !== undefined) { + return existing; + } + hasChecked.methods.set(arkMethod.getSignature().toString(), null); + const returnOps = arkMethod.getReturnValues(); + for (const op of returnOps) { + if (this.isBoxedType(op.getType())) { + hasChecked.methods.set(arkMethod.getSignature().toString(), true); + return true; + } + if (op instanceof Local && this.isLocalHasBoxedType(op, scene, hasChecked)) { + hasChecked.methods.set(arkMethod.getSignature().toString(), true); + return true; + } + } + hasChecked.methods.set(arkMethod.getSignature().toString(), false); + return false; + } + + // 此处不检查local的Type,因为type直接写String时也表示成Class Type,无法区分是否为new String()生成的 + private isLocalHasBoxedType(local: Local, scene: Scene, hasChecked: CheckedObj): boolean { + const method = local.getDeclaringStmt()?.getCfg().getDeclaringMethod(); + if (method === undefined) { + return false; + } + const stmts = method.getCfg()?.getStmts().reverse(); + if (stmts === undefined || stmts.length < 1) { + return false; + } + + const declaringStmt = local.getDeclaringStmt(); + if ( + declaringStmt !== null && + declaringStmt instanceof ArkAssignStmt && + this.isValueAssignedByBoxed(declaringStmt, stmts, scene, hasChecked) + ) { + return true; + } + for (const stmt of local.getUsedStmts()) { + if (stmt instanceof ArkAssignStmt) { + const leftOp = stmt.getLeftOp(); + if ( + leftOp instanceof Local && + leftOp.toString() === local.toString() && + this.isValueAssignedByBoxed(stmt, stmts, scene, hasChecked) + ) { + return true; + } + } + } + return false; + } + + private findBoxedTypeInClass( + importInfo: ImportInfo, + arkClass: ArkClass, + scene: Scene, + hasChecked: CheckedObj + ): boolean { + const importOpPosition = importInfo.getOriginTsPosition(); + const warnInfo: WarnInfo = { + line: importOpPosition.getLineNo(), + startCol: importOpPosition.getColNo(), + endCol: importOpPosition.getColNo(), + filePath: importInfo.getDeclaringArkFile().getFilePath(), + }; + const currLanguage = importInfo.getLanguage(); + const result = this.isClassHasBoxedType(arkClass, scene, hasChecked); + if (result) { + this.addIssueReport(warnInfo, currLanguage, arkClass.getLanguage()); + return true; + } + return false; + } + + private findBoxedTypeWithMethodReturn( + importInfo: ImportInfo, + arkMethod: ArkMethod, + scene: Scene, + hasChecked: CheckedObj + ): boolean { + const importOpPostion = importInfo.getOriginTsPosition(); + const warnInfo: WarnInfo = { + line: importOpPostion.getLineNo(), + startCol: importOpPostion.getColNo(), + endCol: importOpPostion.getColNo(), + filePath: importInfo.getDeclaringArkFile().getFilePath(), + }; + const currLanguage = importInfo.getLanguage(); + + // 此处不检查method signature中的return Type,因为return type直接写String时也表示成Class Type,无法区分是否为new String()生成的 + if (this.isMethodReturnHasBoxedType(arkMethod, scene, hasChecked)) { + this.addIssueReport(warnInfo, currLanguage, arkMethod.getLanguage()); + return true; + } + return false; + } + + private findBoxedTypeWithLocal( + importInfo: ImportInfo, + local: Local, + scene: Scene, + hasChecked: CheckedObj + ): boolean { + const importOpPosition = importInfo.getOriginTsPosition(); + const warnInfo: WarnInfo = { + line: importOpPosition.getLineNo(), + startCol: importOpPosition.getColNo(), + endCol: importOpPosition.getColNo(), + filePath: importInfo.getDeclaringArkFile().getFilePath(), + }; + const currLanguage = importInfo.getLanguage(); + const method = local.getDeclaringStmt()?.getCfg().getDeclaringMethod(); + if (method === undefined) { + return false; + } + if (this.isLocalHasBoxedType(local, scene, hasChecked)) { + this.addIssueReport(warnInfo, currLanguage, method.getLanguage()); + return true; + } + return false; + } + + private isBoxedType(checkType: Type): boolean { + // ArkAnalyzer表示new String()形式的类型为ClassType,Class Name为String、Boolean、Number + // TODO: 此处底座有一个bug,表示String()时推导为Unknown Type,正确的应该为string,但是不影响本规则的判断 + return checkType instanceof ClassType && BOXED_SET.has(checkType.getClassSignature().getClassName()); + } + + private addIssueReport(warnInfo: WarnInfo, currLanguage: Language, targetLanguage: Language): void { + const interopRule = this.getInteropRule(currLanguage, targetLanguage); + if (interopRule === null) { + return; + } + const severity = this.metaData.severity; + const currLanStr = getLanguageStr(currLanguage); + const targetLanStr = getLanguageStr(targetLanguage); + const problem = 'Interop'; + const describe = `Could not import object with boxed type from ${targetLanStr} to ${currLanStr} (${interopRule})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + describe, + severity, + ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getInteropRule(currLanguage: Language, targetLanguage: Language): string | null { + if (currLanguage === Language.ARKTS1_1) { + if (targetLanguage === Language.ARKTS1_2) { + return s2dRuleId; + } + } else if (currLanguage === Language.ARKTS1_2) { + if (targetLanguage === Language.TYPESCRIPT) { + return ts2sRuleId; + } + if (targetLanguage === Language.ARKTS1_1) { + return d2sRuleId; + } + if (targetLanguage === Language.JAVASCRIPT) { + return js2RuleId; + } + } + return null; + } + + // lastStmt为当前需要查找的对象的赋值语句,左值为查找对象,右值为往前继续查找的赋值起点 + // reverseStmtChain为以待查找对象为起点,所有一系列赋值语句的倒序排列 + private isValueAssignedByBoxed( + lastStmt: ArkAssignStmt, + previousReverseChain: Stmt[], + scene: Scene, + hasChecked: CheckedObj + ): boolean { + let locals: Set = new Set(); + const targetLocal = lastStmt.getRightOp(); + const targetLocalType = targetLocal.getType(); + if (this.isBoxedType(targetLocalType)) { + return true; + } + if (targetLocalType instanceof ClassType) { + const arkClass = scene.getClass(targetLocalType.getClassSignature()); + if (arkClass !== null && this.isClassHasBoxedType(arkClass, scene, hasChecked)) { + return true; + } + } + if (targetLocalType instanceof FunctionType) { + const arkMethod = scene.getMethod(targetLocalType.getMethodSignature()); + if (arkMethod !== null && this.isMethodReturnHasBoxedType(arkMethod, scene, hasChecked)) { + return true; + } + } + + if (!(targetLocal instanceof Local)) { + return false; + } + locals.add(targetLocal); + + const rightOp = lastStmt.getRightOp(); + if (!(rightOp instanceof Local)) { + return false; + } + locals.add(rightOp); + for (const stmt of previousReverseChain) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + const rightOp = stmt.getRightOp(); + if (!(leftOp instanceof Local) || !locals.has(leftOp)) { + continue; + } + if (rightOp instanceof Local) { + locals.add(rightOp); + continue; + } + if (rightOp instanceof ArkNewExpr) { + if (this.isBoxedType(rightOp.getClassType())) { + return true; + } + continue; + } + if (rightOp instanceof AbstractInvokeExpr) { + if (this.isBoxedType(rightOp.getType())) { + return true; + } + continue; + } + } + return false; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropDynamicObjectLiteralsCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropDynamicObjectLiteralsCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..3b59046d94a0f620aa22c6d27ffd8ef02c2addc3 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropDynamicObjectLiteralsCheck.ts @@ -0,0 +1,277 @@ +/* + * 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 { + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + DVFGBuilder, + ArkInstanceOfExpr, + ArkNewExpr, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + ClassType, + ArkNamespace, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFG, DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { CALL_DEPTH_LIMIT, getLanguageStr, getLineAndColumn, GlobalCallGraphHelper } from './Utils'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropObjectLiteralCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +const d2sRuleId: string = 'arkts-interop-d2s-object-literal'; +const ts2sRuleId: string = 'arkts-interop-ts2s-object-literal'; + +export class InteropObjectLiteralCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private cg: CallGraph; + private dvfg: DVFG; + private dvfgBuilder: DVFGBuilder; + private visited: Set = new Set(); + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); + + this.dvfg = new DVFG(this.cg); + this.dvfgBuilder = new DVFGBuilder(this.dvfg, scene); + + for (let arkFile of scene.getFiles()) { + if (arkFile.getLanguage() !== Language.ARKTS1_2) { + continue; + } + for (let clazz of arkFile.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, scene); + } + } + for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { + this.processNameSpace(namespace, scene); + } + } + }; + + public processNameSpace(namespace: ArkNamespace, scene: Scene): void { + for (let clazz of namespace.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, scene); + } + } + } + + public processArkMethod(target: ArkMethod, scene: Scene): void { + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceOfExpr)) { + continue; + } + if (!this.visited.has(target)) { + this.dvfgBuilder.buildForSingleMethod(target); + this.visited.add(target); + } + + let result: Stmt[] = []; + let checkAll = { value: true }; + let visited: Set = new Set(); + this.checkFromStmt(stmt, scene, result, checkAll, visited); + // 对于待检查的instanceof语句,其检查对象存在用字面量赋值的情况,需要判断对象声明时的类型注解的来源,满足interop场景时需在此处告警 + if (result.length > 0) { + const opType = rightOp.getOp().getType(); + if (!(opType instanceof ClassType)) { + continue; + } + const opTypeClass = scene.getClass(opType.getClassSignature()); + if (opTypeClass === null || opTypeClass.getCategory() === ClassCategory.OBJECT) { + continue; + } + if ( + opTypeClass.getLanguage() === Language.TYPESCRIPT || + opTypeClass.getLanguage() === Language.ARKTS1_1 + ) { + this.addIssueReport(stmt, rightOp, result, opTypeClass.getLanguage()); + } + } + } + } + + private checkFromStmt( + stmt: Stmt, + scene: Scene, + res: Stmt[], + checkAll: { value: boolean }, + visited: Set, + depth: number = 0 + ): void { + if (depth > CALL_DEPTH_LIMIT) { + checkAll.value = false; + return; + } + const node = this.dvfg.getOrNewDVFGNode(stmt); + let worklist: DVFGNode[] = [node]; + while (worklist.length > 0) { + const current = worklist.shift()!; + const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); + if (this.isObjectLiteral(currentStmt, scene)) { + res.push(currentStmt); + continue; + } + const callsite = this.cg.getCallSiteByStmt(currentStmt); + callsite.forEach(cs => { + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + return; + } + if (!this.visited.has(declaringMtd)) { + this.dvfgBuilder.buildForSingleMethod(declaringMtd); + this.visited.add(declaringMtd); + } + declaringMtd + .getReturnStmt() + .forEach(r => this.checkFromStmt(r, scene, res, checkAll, visited, depth + 1)); + }); + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + const callsites = this.cg.getInvokeStmtByMethod( + currentStmt.getCfg().getDeclaringMethod().getSignature() + ); + this.processCallsites(callsites); + this.collectArgDefs(paramIdx, callsites).forEach(d => + this.checkFromStmt(d, scene, res, checkAll, visited, depth + 1) + ); + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + } + } + + private processCallsites(callsites: Stmt[]): void { + callsites.forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + if (!this.visited.has(declaringMtd)) { + this.dvfgBuilder.buildForSingleMethod(declaringMtd); + this.visited.add(declaringMtd); + } + }); + } + + private isObjectLiteral(stmt: Stmt, scene: Scene): boolean { + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkNewExpr)) { + return false; + } + const classSig = rightOp.getClassType().getClassSignature(); + return scene.getClass(classSig)?.getCategory() === ClassCategory.OBJECT; + } + + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private collectArgDefs(argIdx: number, callsites: Stmt[]): Stmt[] { + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + return callsites.flatMap(callsite => { + const target: Value | FieldSignature = getKey(callsite.getInvokeExpr()!.getArg(argIdx)); + return Array.from(this.dvfg.getOrNewDVFGNode(callsite).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && target === getKey(s.getLeftOp()); + }); + }); + } + + private addIssueReport(stmt: Stmt, operand: Value, result: Stmt[], targetLanguage: Language): void { + const interopRuleId = this.getInteropRule(targetLanguage); + if (interopRuleId === null) { + return; + } + const severity = this.metaData.severity; + const warnInfo = getLineAndColumn(stmt, operand); + let targetLan = getLanguageStr(targetLanguage); + + const resPos: number[] = []; + result.forEach(stmt => resPos.push(stmt.getOriginPositionInfo().getLineNo())); + const problem = 'Interop'; + const desc = `instanceof including object literal with class type from ${targetLan} (${interopRuleId})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getInteropRule(targetLanguage: Language): string | null { + if (targetLanguage === Language.TYPESCRIPT) { + return ts2sRuleId; + } + if (targetLanguage === Language.ARKTS1_1) { + return d2sRuleId; + } + return null; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..3b912361f2bb7896b526e8a434388ddb7de83703 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropJSModifyPropertyCheck.ts @@ -0,0 +1,309 @@ +/* + * 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, + ArkMethod, + ArkAssignStmt, + Scene, + ArkInstanceFieldRef, + FunctionType, + ClassType, + MethodSignature, + ArkParameterRef, + Value, + Stmt, + ArkDeleteExpr, + FieldSignature, + ArkNamespace, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { ArkFile, Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { CALL_DEPTH_LIMIT, DVFGHelper } from './Utils'; +import { DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'InteropJSModifyPropertyCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: 'The layout of staic objects should not be modified', +}; + +const RULE_ID = 'arkts-interop-js2s-js-add-detele-static-prop'; + +class ParamInfo { + flag: boolean; + paramAssign: ArkAssignStmt; + callsites: Set; +} + +export class InteropJSModifyPropertyCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + const targetMethods: Map = new Map(); + this.collectTargetMethods(targetMethods, scene); + this.checkTargetMethods(targetMethods, scene); + }; + + private collectTargetMethods(targetMethods: Map, scene: Scene): void { + scene.getFiles().forEach(file => { + // 只处理 ArkTS1.2 import JS 函数的情况 + if (file.getLanguage() !== Language.ARKTS1_2) { + return; + } + file.getImportInfos().forEach(importInfo => { + const exportInfo = importInfo.getLazyExportInfo(); + if (exportInfo === null) { + return; + } + const arkExport = exportInfo.getArkExport(); + if (arkExport === null || arkExport === undefined) { + return; + } + if (!(arkExport instanceof ArkMethod && arkExport.getLanguage() === Language.JAVASCRIPT)) { + return; + } + // 创建初始化的参数标志位信息(标志位代表该参数是否被传入了 1.2 对象,默认为 false) + const paramInfo = this.createParamInfo(arkExport); + if (paramInfo.length > 0) { + targetMethods.set(arkExport.getSignature(), paramInfo); + } + }); + + // 寻找 JS 函数的被调用点,检查是否传入 ArkTS1.2 类型的对象并维护参数标志位信息 + for (let clazz of file.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.findCallsite(mtd, targetMethods, scene); + } + } + for (let namespace of file.getAllNamespacesUnderThisFile()) { + this.processNameSpace(namespace, targetMethods, scene); + } + }); + + // 跨函数检查 ArkTS1.2 类型对象是否被跨函数传到其他 JS 函数 + for (let i = 0; i < CALL_DEPTH_LIMIT; ++i) { + this.collectInterprocedualCallSites(targetMethods, scene); + } + } + + public processNameSpace( + namespace: ArkNamespace, + targetMethods: Map, + scene: Scene + ): void { + for (let clazz of namespace.getClasses()) { + for (let mtd of clazz.getMethods()) { + this.findCallsite(mtd, targetMethods, scene); + } + } + } + + private createParamInfo(method: ArkMethod): ParamInfo[] { + // 初始化参数标志数组 + const idxFlag = new Array(method.getParameters().length).fill(false); + // 寻找参数对应的 xxx = parameter 语句 + const paramAssigns = (method.getCfg()?.getStmts() ?? []) + .filter(s => s instanceof ArkAssignStmt && s.getRightOp() instanceof ArkParameterRef) + .map(s => s as ArkAssignStmt); + if (idxFlag.length !== paramAssigns.length) { + logger.error('param index num != param assign num'); + return []; + } + const result: ParamInfo[] = []; + for (let i = 0; i < idxFlag.length; i++) { + result.push({ flag: idxFlag[i], paramAssign: paramAssigns[i], callsites: new Set() }); + } + return result; + } + + private findCallsite(method: ArkMethod, targets: Map, scene: Scene): void { + const stmts = method.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + const invoke = stmt.getInvokeExpr(); + if (!invoke) { + continue; + } + const methodSig = invoke.getMethodSignature(); + if (!targets.has(methodSig)) { + continue; + } + invoke.getArgs().forEach((arg, idx): void => { + if (this.getTypeDefinedLang(arg.getType(), method.getDeclaringArkFile(), scene) !== Language.ARKTS1_2) { + return; + } + targets.get(methodSig)![idx].flag = true; + targets.get(methodSig)![idx].callsites.add(stmt); + }); + } + } + + private collectInterprocedualCallSites(targets: Map, scene: Scene): void { + new Map(targets).forEach((paramInfo, sig) => { + const method = scene.getMethod(sig)!; + DVFGHelper.buildSingleDVFG(method, scene); + paramInfo.forEach((paramInfo): void => { + if (paramInfo.flag) { + this.checkIfParamPassedToOtherMethod(paramInfo, targets, scene); + } + }); + }); + } + + private checkIfParamPassedToOtherMethod( + callerParamInfo: ParamInfo, + targets: Map, + scene: Scene + ): void { + const worklist: DVFGNode[] = [DVFGHelper.getOrNewDVFGNode(callerParamInfo.paramAssign, scene)]; + const visited: Set = new Set(); + while (worklist.length > 0) { + const current = worklist.shift()!; + const cunrrentStmt = current.getStmt(); + if (visited.has(cunrrentStmt)) { + continue; + } + visited.add(cunrrentStmt); + if (!(cunrrentStmt instanceof ArkAssignStmt)) { + continue; + } + current.getOutgoingEdges().forEach(edge => { + const dst = edge.getDstNode() as DVFGNode; + const dstStmt = dst.getStmt(); + // 假设有 JS 函数声明: function foo(obj),其中 obj 为受关注的参数 + // 只有类似 let obj2 = obj 或者 goo(obj) 这样的语句受到关注 + if (dstStmt instanceof ArkAssignStmt && dstStmt.getRightOp() === cunrrentStmt.getLeftOp()) { + worklist.push(dst); + return; + } + const invoke = dstStmt.getInvokeExpr(); + if (!invoke) { + return; + } + const calleeSig = invoke.getMethodSignature(); + const callee = scene.getMethod(calleeSig); + if (!callee || !callee.getCfg() || callee.getLanguage() !== Language.JAVASCRIPT) { + return; + } + if (!targets.has(calleeSig)) { + targets.set(calleeSig, this.createParamInfo(callee)); + } + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + invoke.getArgs().forEach((arg, idx) => { + if (getKey(arg) === getKey(cunrrentStmt.getLeftOp())) { + targets.get(calleeSig)![idx].flag = true; + callerParamInfo.callsites.forEach(cs => { + targets.get(calleeSig)![idx].callsites.add(cs); + }); + } + }); + }); + } + } + + private checkTargetMethods(targetMethods: Map, scene: Scene): void { + targetMethods.forEach((paramInfos, methodSig): void => { + const method = scene.getMethod(methodSig); + if (!method) { + logger.error(`cannot find ark method by method sig: ${methodSig.toString()}`); + return; + } + const targetParams = paramInfos + .filter(paramInfo => paramInfo.flag) + .map(paramInfo => paramInfo.paramAssign.getLeftOp()); + const stmts = method.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + let paramIdx = -1; + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkDeleteExpr) { + const fieldRef = rightOp.getField(); + if (fieldRef instanceof ArkInstanceFieldRef) { + paramIdx = targetParams.findIndex(p => p === fieldRef.getBase()); + } + } + const leftOp = stmt.getLeftOp(); + if (leftOp instanceof ArkInstanceFieldRef) { + paramIdx = targetParams.findIndex(p => p === leftOp.getBase()); + } + if (paramIdx !== -1) { + const callers = paramInfos[paramIdx]!; + callers.callsites.forEach(cs => this.reportIssue(cs)); + } + } + }); + } + + private getTypeDefinedLang(type: Type, defaultFile: ArkFile, scene: Scene): Language { + let file; + if (type instanceof ClassType) { + file = scene.getFile(type.getClassSignature().getDeclaringFileSignature()); + } else if (type instanceof FunctionType) { + file = scene.getFile(type.getMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature()); + } else { + file = defaultFile; + } + if (file) { + return file.getLanguage(); + } else { + logger.error(`fail to identify which file the type definition ${type.toString()} is in.`); + return Language.UNKNOWN; + } + } + + private reportIssue(problemStmt: Stmt) { + const line = problemStmt.getOriginPositionInfo().getLineNo(); + const column = problemStmt.getOriginPositionInfo().getColNo(); + const problem = 'Interop'; + const desc = `${this.metaData.description} (${RULE_ID})`; + const severity = this.metaData.severity; + const ruleId = this.rule.ruleId; + const filePath = problemStmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile()?.getFilePath() ?? ''; + const defeats = new Defects( + line, + column, + column, + problem, + desc, + severity, + ruleId, + filePath, + '', + true, + false, + false + ); + this.issues.push(new IssueReport(defeats, undefined)); + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts b/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..27be4df0a6edd2a1213a8c359eda4b1c4eab0d3c --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/InteropRuleInfo.ts @@ -0,0 +1,141 @@ +/* + * 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 { Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +export class InteropRuleInfo { + ruleId: string; + severity: number; + description: string; +} + +// 1.2 import 1.1 +// 1.1 Object => ArkTS 1.2 对象 +export const D2S_DYNAMIC_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-d2s-dynamic-object-on-static-instance', + severity: 1, + description: "ArkTS 1.1 Object's built-in methods work on ArkTS 1.2 objects", +}; + +// 1.2 import 1.1 +// 1.1 Reflect => ArkTS 1.2 对象 +export const D2S_DYNAMIC_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-d2s-dynamic-reflect-on-static-instance', + severity: 1, + description: "ArkTS 1.1 Reflect's built-in methods work on ArkTS 1.2 objects", +}; + +// 1.2 import 1.1 +// 1.2 Object => ArkTS 1.1 对象 +export const D2S_STATIC_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-d2s-static-object-on-dynamic-instance', + severity: 1, + description: "ArkTS 1.2 Object's built-in methods work on ArkTS 1.1 objects", +}; + +// 1.2 import 1.1 +// 1.2 Reflect => ArkTS 1.1 对象 +export const D2S_STATIC_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-d2s-static-reflect-on-dynamic-instance', + severity: 1, + description: "ArkTS 1.2 Reflect's built-in methods work on ArkTS 1.1 objects", +}; + +// 1.1 import 1.2 +// 1.1 Object => ArkTS 1.2 对象 +export const S2D_DYNAMIC_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-s2d-dynamic-object-on-static-instance', + severity: 1, + description: "ArkTS 1.1 Object's built-in methods work on ArkTS 1.2 objects", +}; + +// 1.1 import 1.2 +// 1.1 Reflect => ArkTS 1.2 对象 +export const S2D_DYNAMIC_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-s2d-dynamic-reflect-on-static-instance', + severity: 1, + description: "ArkTS 1.1 Reflect's built-in methods work on ArkTS 1.2 objects", +}; + +// 1.1 import 1.2 +// 1.2 Object => 1.1 对象 +export const S2D_STATIC_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-s2d-static-object-on-dynamic-instance', + severity: 1, + description: "ArkTS 1.2 Object's built-in methods work on ArkTS 1.1 objects", +}; + +// 1.1 import 1.2 +// 1.2 Reflect => 1.1 对象 +export const S2D_STATIC_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-s2d-static-reflect-on-dynamic-instance', + severity: 1, + description: "ArkTS 1.2 Reflect's built-in methods work on ArkTS 1.1 objects", +}; + +export const TS_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-ts2s-ts-object-on-static-instance', + severity: 1, + description: "TypeScript Object's built-in methods work on ArkTS objects", +}; + +export const TS_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-ts2s-ts-reflect-on-static-instance', + severity: 1, + description: "TypeScript Reflect's built-in methods work on ArkTS objects", +}; + +export const JS_OBJECT: InteropRuleInfo = { + ruleId: 'arkts-interop-js2s-js-object-on-static-instance', + severity: 1, + description: "JavaScript Object's built-in methods work on ArkTS objects", +}; + +export const JS_REFLECT: InteropRuleInfo = { + ruleId: 'arkts-interop-js2s-js-reflect-on-static-instance', + severity: 1, + description: "JavaScript Reflect's built-in methods work on ArkTS objects", +}; + +export function findInteropRule( + methodLang: Language, + typeDefLang: Language, + problemStmtLang: Language, + isReflect: boolean +): InteropRuleInfo | undefined { + if (methodLang === Language.ARKTS1_2 && typeDefLang === Language.ARKTS1_1) { + if (problemStmtLang === Language.ARKTS1_1) { + // 包含 object API 的 1.2 函数被导出到 1.1 文件使用 + return isReflect ? S2D_STATIC_REFLECT : S2D_STATIC_OBJECT; + } else { + return undefined; + } + } + if (methodLang === Language.ARKTS1_1 && typeDefLang === Language.ARKTS1_2) { + if (problemStmtLang === Language.ARKTS1_2) { + // 包含 object API 的 1.1 函数被导出到 1.2 文件使用 + return isReflect ? D2S_DYNAMIC_REFLECT : D2S_DYNAMIC_OBJECT; + } else { + return isReflect ? S2D_DYNAMIC_REFLECT: S2D_DYNAMIC_OBJECT ; + } + } + if (methodLang === Language.TYPESCRIPT && typeDefLang === Language.ARKTS1_2) { + return isReflect ? TS_REFLECT : TS_OBJECT; + } + if (methodLang === Language.JAVASCRIPT && typeDefLang === Language.ARKTS1_2) { + return isReflect ? JS_REFLECT : JS_OBJECT; + } + return undefined; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..c25cc59611ec6e7b8182054beace616da724ba7a --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/ModifyStateVarCheck.ts @@ -0,0 +1,187 @@ +/* + * 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 { + ArkAssignStmt, + ArkInstanceFieldRef, + ArkInstanceInvokeExpr, + CallGraph, + CallGraphBuilder, + Local, + Stmt, + Value, + FieldSignature, + ArkMethod, +} from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MatcherCallback, ClassMatcher, MethodMatcher } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { CALL_DEPTH_LIMIT, CALLBACK_METHOD_NAME, CallGraphHelper } from './Utils'; +import { WarnInfo } from '../../utils/common/Utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ModifyStateVarCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: 'It is not allowed to update state when the build function is running', +}; + +export class ModifyStateVarCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private classMatcher: ClassMatcher = { + matcherType: MatcherTypes.CLASS, + hasViewTree: true, + }; + + private buildMatcher: MethodMatcher = { + matcherType: MatcherTypes.METHOD, + class: [this.classMatcher], + name: ['build'], + }; + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: this.buildMatcher, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (target: ArkMethod): void => { + const scene = target.getDeclaringArkFile().getScene(); + let callGraph = CallGraphHelper.getCGInstance(scene); + let callGraphBuilder = new CallGraphBuilder(callGraph, scene); + callGraphBuilder.buildClassHierarchyCallGraph([target.getSignature()]); + + const arkClass = target.getDeclaringArkClass(); + const stateVars = new Set( + arkClass + .getFields() + .filter(f => f.hasDecorator('State')) + .map(f => f.getSignature()) + ); + if (stateVars.size > 0) { + this.checkMethod(target, callGraph, stateVars); + } + }; + + private checkMethod(target: ArkMethod, cg: CallGraph, stateVars: Set, depth: number = 0): void { + if (depth > CALL_DEPTH_LIMIT) { + return; + } + let aliases = new Set(); + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + const invokeExpr = stmt.getInvokeExpr(); + if (invokeExpr && invokeExpr instanceof ArkInstanceInvokeExpr) { + if ( + CALLBACK_METHOD_NAME.includes( + invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName() + ) + ) { + continue; + } + } + cg.getCallSiteByStmt(stmt).forEach(cs => { + const callee = cg.getArkMethodByFuncID(cs.calleeFuncID); + if (callee) { + this.checkMethod(callee, cg, stateVars, depth + 1); + } + }); + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + if (this.isAssignToStateVar(stmt, stateVars, aliases)) { + this.addIssueReport(stmt, stmt.getLeftOp()); + } else { + const alias = this.isAliasOfStateVar(stmt, stateVars, aliases); + if (alias) { + aliases.add(alias); + } + } + } + } + + private isAssignToStateVar(stmt: ArkAssignStmt, stateVars: Set, aliases: Set): boolean { + const leftOp = stmt.getLeftOp(); + if (leftOp instanceof ArkInstanceFieldRef) { + // this.n = 1 or this.obj.n = 1 + return stateVars.has(leftOp.getFieldSignature()) || aliases.has(leftOp.getBase()); + } else if (leftOp instanceof Local) { + return aliases.has(leftOp); + } + return false; + } + + private isAliasOfStateVar( + stmt: ArkAssignStmt, + stateVars: Set, + aliases: Set + ): Local | undefined { + const leftOp = stmt.getLeftOp(); + const rightOp = stmt.getRightOp(); + if (leftOp instanceof Local && rightOp instanceof ArkInstanceFieldRef) { + // %1 = this.n + // or + // %1 = this.obj; %2 = %1.n + if (stateVars.has(rightOp.getFieldSignature()) || aliases.has(rightOp.getBase())) { + return leftOp; + } + } + return undefined; + } + + private addIssueReport(stmt: Stmt, operand: Value): void { + const severity = this.rule.alert ?? this.metaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'NoStateUpdateDuringRender'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const originPosition = stmt.getOperandOriginalPosition(operand); + if (arkFile && originPosition) { + const originPath = arkFile.getFilePath(); + const line = originPosition.getFirstLine(); + const startCol = originPosition.getFirstCol(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + } + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/NoMethodOverridingFieldCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/NoMethodOverridingFieldCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..6c848ece77ea0fb2d598b1c0c00f3d71351c39d9 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/NoMethodOverridingFieldCheck.ts @@ -0,0 +1,78 @@ +/* + * 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 { + ArkAssignStmt, + ArkClass, + ArkFile, + ArkIfStmt, + ArkInstanceFieldRef, + ArkInstanceInvokeExpr, + ArkMethod, + ClassType, + FunctionType, + Local, + Stmt, + Value, +} from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MethodMatcher, MatcherCallback, ClassMatcher } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NoMethodOverridingFieldCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +export class NoMethodOverridingFieldCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private classMetcher: ClassMatcher = { + matcherType: MatcherTypes.CLASS, + ClassCategory: [ClassCategory.CLASS], + }; + + public registerMatchers(): MatcherCallback[] { + const methodCb: MatcherCallback = { + matcher: this.classMetcher, + callback: this.check, + }; + return [methodCb]; + } + + public check = (target: ArkClass): void => { + const interfaces = target.getAllHeritageClasses().filter(c => c.getCategory() === ClassCategory.INTERFACE); + for (const i of interfaces) { + const fields = i + .getFields() + .filter(f => f.getType() instanceof FunctionType) + .map(f => f.getName()); + fields.forEach(f => { + const method = target.getMethodWithName(f); + if (method) { + // record class + // console.log(`111`) + } + }); + } + }; +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/NoOptionalMethodCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/NoOptionalMethodCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..4be0d03726baa9979bed14e1cafdc3fa04a17c39 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/NoOptionalMethodCheck.ts @@ -0,0 +1,89 @@ +/* + * 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 { ArkClass, ArkMethod } from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MatcherCallback, ClassMatcher } from '../../Index'; +import { IssueReport } from '../../model/Defects'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NoOptionalMethodCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +export class NoOptionalMethodCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private classMetcher: ClassMatcher = { + matcherType: MatcherTypes.CLASS, + }; + + public registerMatchers(): MatcherCallback[] { + const classCb: MatcherCallback = { + matcher: this.classMetcher, + callback: this.check, + }; + return [classCb]; + } + + public check = (target: ArkClass): void => { + target + .getMethods() + .filter(m => m.getQuestionToken()) + .forEach(m => { + const posInfo = this.getMethodPos(m); + this.addIssueReport(posInfo); + }); + }; + + private addIssueReport(warnInfo: { line: number; startCol: number; endCol: number; filePath: string }): void { + const problem = ''; + const severity = this.rule.alert ?? this.metaData.severity; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + this.metaData.description, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getMethodPos(cls: ArkMethod): { line: number; startCol: number; endCol: number; filePath: string } { + const line = cls.getLineCol() ?? -1; + const startCol = cls.getColumn() ?? -1; + const endCol = startCol; + const arkFile = cls.getDeclaringArkFile(); + if (arkFile) { + return { line, startCol, endCol, filePath: arkFile.getFilePath() }; + } else { + logger.debug('ArkFile is null.'); + return { line, startCol, endCol, filePath: '' }; + } + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..f45c63723cfb7b492c0972d4079cd9d6ef5d6740 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/NoTSLikeAsCheck.ts @@ -0,0 +1,584 @@ +/* + * 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 path from 'path'; +import { + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + DVFGBuilder, + ArkInstanceOfExpr, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + ArkNamespace, + Local, + ArkCastExpr, + ClassType, + classSignatureCompare, + ArkField, + fileSignatureCompare, + Cfg, + BasicBlock, + ArkIfStmt, + ArkUnopExpr, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFG, DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { CALL_DEPTH_LIMIT, getGlobalsDefineInDefaultMethod, GlobalCallGraphHelper } from './Utils'; +import { WarnInfo } from '../../utils/common/Utils'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NoTSLikeAsCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +export class NoTSLikeAsCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private cg: CallGraph; + private dvfg: DVFG; + private dvfgBuilder: DVFGBuilder; + private visited: Set = new Set(); + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); + + this.dvfg = new DVFG(this.cg); + this.dvfgBuilder = new DVFGBuilder(this.dvfg, scene); + + for (let arkFile of scene.getFiles()) { + // 此规则仅对arkts1.1和arkts1.2进行检查,typescript在编译阶段会报错,javascript没有类型断言语法 + if (!(arkFile.getLanguage() === Language.ARKTS1_1 || arkFile.getLanguage() === Language.ARKTS1_2)) { + continue; + } + const defaultMethod = arkFile.getDefaultClass().getDefaultArkMethod(); + let globalVarMap: Map = new Map(); + if (defaultMethod) { + this.dvfgBuilder.buildForSingleMethod(defaultMethod); + globalVarMap = getGlobalsDefineInDefaultMethod(defaultMethod); + } + for (let clazz of arkFile.getClasses()) { + for (let field of clazz.getFields()) { + this.processClassField(field, globalVarMap, scene); + } + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, globalVarMap, scene); + } + } + for (let namespace of arkFile.getAllNamespacesUnderThisFile()) { + this.processNameSpace(namespace, globalVarMap, scene); + } + } + }; + + public processNameSpace(namespace: ArkNamespace, globalVarMap: Map, scene: Scene): void { + for (let ns of namespace.getNamespaces()) { + this.processNameSpace(ns, globalVarMap, scene); + } + for (let clazz of namespace.getClasses()) { + for (let field of clazz.getFields()) { + this.processClassField(field, globalVarMap, scene); + } + for (let mtd of clazz.getMethods()) { + this.processArkMethod(mtd, globalVarMap, scene); + } + } + } + + public processClassField(field: ArkField, globalVarMap: Map, scene: Scene): void { + const stmts = field.getInitializer(); + for (const stmt of stmts) { + const castExpr = this.getCastExpr(stmt); + if (castExpr === null) { + continue; + } + // 判断cast类型断言的类型是否是class,非class的场景不在本规则检查范围内 + if (!(castExpr.getType() instanceof ClassType)) { + continue; + } + let checkAll = { value: true }; + let visited: Set = new Set(); + const result = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited); + if (result !== null) { + this.addIssueReport(stmt, castExpr, result); + } else { + if (!checkAll.value) { + this.addIssueReport(stmt, castExpr); + } + } + } + } + + public processArkMethod(target: ArkMethod, globalVarMap: Map, scene: Scene): void { + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + // cast表达式所在语句为sink点,从该点开始进行逆向数据流分析 + const castExpr = this.getCastExpr(stmt); + if (castExpr === null) { + continue; + } + // 判断cast类型断言的类型是否是class,非class的场景不在本规则检查范围内 + if (!(castExpr.getType() instanceof ClassType)) { + continue; + } + if (this.hasCheckedWithInstanceof(stmt.getCfg(), stmt)) { + continue; + } + if (!this.visited.has(target)) { + this.dvfgBuilder.buildForSingleMethod(target); + this.visited.add(target); + } + + let checkAll = { value: true }; + let visited: Set = new Set(); + const result = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited); + if (result !== null) { + this.addIssueReport(stmt, castExpr, result); + } else { + if (!checkAll.value) { + this.addIssueReport(stmt, castExpr); + } + } + } + } + + private hasCheckedWithInstanceof(cfg: Cfg, stmt: Stmt): boolean { + const castExpr = this.getCastExpr(stmt); + if (castExpr === null) { + return false; + } + for (const block of cfg.getBlocks()) { + // 这里仅判断了cast op是否进行了instanceof判断,如果op是由op1赋值,op1进行了instanceof判断,此处不认为是做了有效检查 + // TODO: 还需进行复杂条件中包含类型守卫判断的情况,涉及&&,||等的复合 + const positiveCheck = this.isCastExprWithTypeAssurancePositive(block, castExpr); + const negativeCheck = this.isCastExprWithTypeAssuranceNegative(block, castExpr); + if (!(positiveCheck || negativeCheck)) { + continue; + } + let checkedBB: Set = new Set(); + let needCheckBB: number[] = []; + checkedBB.add(block.getId()); + const allSuccessors = block.getSuccessors(); + if (allSuccessors.length > 0 && positiveCheck) { + needCheckBB.push(allSuccessors[0].getId()); + } + if (allSuccessors.length > 1 && negativeCheck) { + needCheckBB.push(allSuccessors[1].getId()); + } + while (needCheckBB.length > 0) { + const bbId = needCheckBB.shift(); + if (bbId === undefined) { + break; + } + if (checkedBB.has(bbId)) { + continue; + } + checkedBB.add(bbId); + const bb = this.getBlockWithId(bbId, cfg); + if (bb === null) { + continue; + } + if (this.isStmtInBlock(stmt, bb)) { + return true; + } else { + bb.getSuccessors().forEach(b => needCheckBB.push(b.getId())); + } + } + } + return false; + } + + private isStmtInBlock(stmt: Stmt, block: BasicBlock): boolean { + for (const s of block.getStmts()) { + if (s === stmt) { + return true; + } + } + return false; + } + + private getBlockWithId(id: number, cfg: Cfg): BasicBlock | null { + const blocks = cfg.getBlocks(); + for (const bb of blocks) { + if (bb.getId() === id) { + return bb; + } + } + return null; + } + + private isCastExprWithTypeAssurancePositive(bb: BasicBlock, castExpr: ArkCastExpr): boolean { + for (const stmt of bb.getStmts()) { + if (!(stmt instanceof ArkIfStmt)) { + continue; + } + const conditionExpr = stmt.getConditionExpr(); + const op1 = conditionExpr.getOp1(); + const op2 = conditionExpr.getOp2(); + if (op1 instanceof Local) { + const declareStmt = op1.getDeclaringStmt(); + if (declareStmt !== null && this.isStmtWithTypeAssurancePositive(declareStmt, castExpr)) { + return true; + } + } + if (op2 instanceof Local) { + const declareStmt = op2.getDeclaringStmt(); + if (declareStmt !== null && this.isStmtWithTypeAssurancePositive(declareStmt, castExpr)) { + return true; + } + } + } + return false; + } + + private isCastExprWithTypeAssuranceNegative(bb: BasicBlock, castExpr: ArkCastExpr): boolean { + for (const stmt of bb.getStmts()) { + if (!(stmt instanceof ArkIfStmt)) { + continue; + } + const conditionExpr = stmt.getConditionExpr(); + const op1 = conditionExpr.getOp1(); + const op2 = conditionExpr.getOp2(); + if (op1 instanceof Local) { + const declareStmt = op1.getDeclaringStmt(); + if (declareStmt !== null && this.isStmtWithTypeAssuranceNegative(declareStmt, castExpr)) { + return true; + } + } + if (op2 instanceof Local) { + const declareStmt = op2.getDeclaringStmt(); + if (declareStmt !== null && this.isStmtWithTypeAssuranceNegative(declareStmt, castExpr)) { + return true; + } + } + } + return false; + } + + private isStmtWithTypeAssurancePositive(declareStmt: Stmt, castExpr: ArkCastExpr): boolean { + if (!(declareStmt instanceof ArkAssignStmt)) { + return false; + } + const rightOp = declareStmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceOfExpr)) { + return false; + } + const castOp = castExpr.getOp(); + const castType = castExpr.getType(); + const instanceofType = rightOp.getCheckType(); + if (castType.getTypeString() !== instanceofType.getTypeString()) { + return false; + } + const instanceofOp = rightOp.getOp(); + if (!(castOp instanceof Local && instanceofOp instanceof Local)) { + return false; + } + return castOp.getName() === instanceofOp.getName(); + } + + private isStmtWithTypeAssuranceNegative(declareStmt: Stmt, castExpr: ArkCastExpr): boolean { + if (!(declareStmt instanceof ArkAssignStmt)) { + return false; + } + const rightOp = declareStmt.getRightOp(); + if (!(rightOp instanceof ArkUnopExpr && rightOp.getOperator() === '!')) { + return false; + } + const unaryOp = rightOp.getOp(); + if (!(unaryOp instanceof Local)) { + return false; + } + const unaryOpDeclareStmt = unaryOp.getDeclaringStmt(); + if (unaryOpDeclareStmt === null || !(unaryOpDeclareStmt instanceof ArkAssignStmt)) { + return false; + } + const unaryOpRightOp = unaryOpDeclareStmt.getRightOp(); + if (!(unaryOpRightOp instanceof ArkInstanceOfExpr)) { + return false; + } + const castOp = castExpr.getOp(); + const castType = castExpr.getType(); + const instanceofType = unaryOpRightOp.getCheckType(); + if (castType.getTypeString() !== instanceofType.getTypeString()) { + return false; + } + const instanceofOp = unaryOpRightOp.getOp(); + if (!(castOp instanceof Local && instanceofOp instanceof Local)) { + return false; + } + return castOp.getName() === instanceofOp.getName(); + } + + private checkFromStmt( + stmt: Stmt, + scene: Scene, + globalVarMap: Map, + checkAll: { value: boolean }, + visited: Set, + depth: number = 0 + ): Stmt | null { + if (depth > CALL_DEPTH_LIMIT) { + checkAll.value = false; + return null; + } + const node = this.dvfg.getOrNewDVFGNode(stmt); + let worklist: DVFGNode[] = [node]; + while (worklist.length > 0) { + const current = worklist.shift()!; + const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); + if (this.isWithInterfaceAnnotation(currentStmt, scene)) { + return currentStmt; + } + const gv = this.checkIfCastOpIsGlobalVar(currentStmt); + if (gv) { + const globalDefs = globalVarMap.get(gv.getName()); + if (globalDefs === undefined) { + const importValue = this.checkIfCastOpIsFromImport(currentStmt); + if (importValue && importValue.getDeclaringStmt() !== null) { + worklist.push(this.dvfg.getOrNewDVFGNode(importValue.getDeclaringStmt()!)); + } + } else { + globalDefs.forEach(d => worklist.push(this.dvfg.getOrNewDVFGNode(d))); + } + continue; + } + + const callsite = this.cg.getCallSiteByStmt(currentStmt); + for (const cs of callsite) { + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + continue; + } + if (!this.visited.has(declaringMtd)) { + this.dvfgBuilder.buildForSingleMethod(declaringMtd); + this.visited.add(declaringMtd); + } + const returnStmts = declaringMtd.getReturnStmt(); + for (const stmt of returnStmts) { + const res = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited, depth + 1); + if (res !== null) { + return res; + } + } + } + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + const callsites = this.cg.getInvokeStmtByMethod( + currentStmt.getCfg().getDeclaringMethod().getSignature() + ); + this.processCallsites(callsites); + const argDefs = this.collectArgDefs(paramIdx, callsites); + for (const stmt of argDefs) { + const res = this.checkFromStmt(stmt, scene, globalVarMap, checkAll, visited, depth + 1); + if (res !== null) { + return res; + } + } + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + } + return null; + } + + private checkIfCastOpIsGlobalVar(stmt: Stmt): Local | undefined { + const obj = this.getCastOp(stmt); + if (obj instanceof Local && !obj.getDeclaringStmt()) { + return obj; + } + return undefined; + } + + private checkIfCastOpIsFromImport(stmt: Stmt): Local | undefined { + const obj = this.getCastOp(stmt); + if (obj === null || !(obj instanceof Local)) { + return undefined; + } + const importInfos = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile().getImportInfos(); + for (const importInfo of importInfos) { + if (importInfo.getImportClauseName() === obj.getName()) { + const exportInfo = importInfo.getLazyExportInfo(); + if (exportInfo === null) { + return undefined; + } + const arkExport = exportInfo.getArkExport(); + if (arkExport === null || arkExport === undefined) { + return undefined; + } + if (!(arkExport instanceof Local)) { + return undefined; + } + return arkExport; + } + } + return undefined; + } + + private processCallsites(callsites: Stmt[]): void { + callsites.forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + if (!this.visited.has(declaringMtd)) { + this.dvfgBuilder.buildForSingleMethod(declaringMtd); + this.visited.add(declaringMtd); + } + }); + } + + // 判断语句是否为赋值语句,且左值的类型注解为Interface,右值的类型与左值不一样 + private isWithInterfaceAnnotation(stmt: Stmt, scene: Scene): boolean { + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + const leftOpType = stmt.getLeftOp().getType(); + if (!(leftOpType instanceof ClassType)) { + return false; + } + const leftOpTypeclass = scene.getClass(leftOpType.getClassSignature()); + if (leftOpTypeclass === null) { + return false; + } + if (leftOpTypeclass.getCategory() !== ClassCategory.INTERFACE) { + return false; + } + const rightOpType = stmt.getRightOp().getType(); + if (!(rightOpType instanceof ClassType)) { + return true; + } + return !classSignatureCompare(leftOpType.getClassSignature(), rightOpType.getClassSignature()); + } + + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private getCastOp(stmt: Stmt): Value | null { + if (!(stmt instanceof ArkAssignStmt)) { + return null; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkCastExpr)) { + return null; + } + return rightOp.getOp(); + } + + private getCastExpr(stmt: Stmt): ArkCastExpr | null { + // method中使用as断言的地方可能是body体中,函数调用的实参,返回值,均会表示成ArkAssignStmt + if (!(stmt instanceof ArkAssignStmt)) { + return null; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkCastExpr)) { + return null; + } + return rightOp; + } + + private collectArgDefs(argIdx: number, callsites: Stmt[]): Stmt[] { + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + return callsites.flatMap(callsite => { + const target: Value | FieldSignature = getKey(callsite.getInvokeExpr()!.getArg(argIdx)); + return Array.from(this.dvfg.getOrNewDVFGNode(callsite).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && target === getKey(s.getLeftOp()); + }); + }); + } + + private addIssueReport(stmt: Stmt, operand: ArkCastExpr, relatedStmt?: Stmt): void { + const severity = this.rule.alert ?? this.metaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'As'; + const descPrefix = 'The value in type assertion is assigned by value with interface annotation'; + let desc = `(${this.rule.ruleId.replace('@migration/', '')})`; + + if (relatedStmt === undefined) { + desc = `Can not find all assignments of the value in type assertion, please check it manually ` + desc; + } else { + const sinkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); + const relatedFile = relatedStmt.getCfg().getDeclaringMethod().getDeclaringArkFile(); + if (fileSignatureCompare(sinkFile.getFileSignature(), relatedFile.getFileSignature())) { + desc = `${descPrefix} in Line ${relatedStmt.getOriginPositionInfo().getLineNo()} ` + desc; + } else { + desc = `${descPrefix} in file ${path.normalize(relatedFile.getName())}: ${relatedStmt.getOriginPositionInfo().getLineNo()} ` + desc; + } + } + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const originPosition = stmt.getOperandOriginalPosition(operand); + if (arkFile && originPosition) { + const originPath = arkFile.getFilePath(); + const line = originPosition.getFirstLine(); + const startCol = originPosition.getFirstCol(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + } + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..66a5c66380b92443cde465bcf577ad4e05791028 --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/ObjectLiteralCheck.ts @@ -0,0 +1,398 @@ +/* + * 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 { + ArkMethod, + ArkAssignStmt, + FieldSignature, + Stmt, + Scene, + Value, + ArkClass, + ArkFile, + ArkInstanceOfExpr, + ArkNewExpr, + CallGraph, + ArkParameterRef, + ArkInstanceFieldRef, + AbstractFieldRef, + Local, + ArkArrayRef, + ClassSignature, +} from 'arkanalyzer/lib'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { DVFGHelper, CALL_DEPTH_LIMIT, GlobalCallGraphHelper } from './Utils'; +import { WarnInfo } from '../../utils/common/Utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ObjectLiteralCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: 'Object literal shall generate instance of a specific class', +}; + +export class ObjectLiteralCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + private cg: CallGraph; + private visited: Set = new Set(); + + public registerMatchers(): MatcherCallback[] { + const matchBuildCb: MatcherCallback = { + matcher: undefined, + callback: this.check, + }; + return [matchBuildCb]; + } + + public check = (scene: Scene): void => { + this.cg = GlobalCallGraphHelper.getCGInstance(scene); + + for (let arkFile of scene.getFiles()) { + const topLevelVarMap: Map = new Map(); + this.collectImportedVar(topLevelVarMap, arkFile); + this.collectTopLevelVar(topLevelVarMap, arkFile, scene); + + const handleClass = (cls: ArkClass): void => { + cls.getMethods().forEach(m => this.processArkMethod(m, topLevelVarMap, scene)); + }; + + arkFile.getClasses().forEach(cls => handleClass(cls)); + arkFile.getAllNamespacesUnderThisFile().forEach(n => n.getClasses().forEach(cls => handleClass(cls))); + } + }; + + public processArkMethod(target: ArkMethod, topLevelVarMap: Map, scene: Scene): void { + const stmts = target.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceOfExpr)) { + continue; + } + if (!this.visited.has(target)) { + DVFGHelper.buildSingleDVFG(target, scene); + this.visited.add(target); + } + + let result: Stmt[] = []; + let checkAll = { value: true }; + let visited: Set = new Set(); + this.checkFromStmt(stmt, scene, result, topLevelVarMap, checkAll, visited); + result.forEach(s => this.addIssueReport(s, (s as ArkAssignStmt).getRightOp())); + if (!checkAll.value) { + this.addIssueReport(stmt, rightOp); + } + } + } + + private collectImportedVar(importVarMap: Map, file: ArkFile) { + file.getImportInfos().forEach(importInfo => { + const exportInfo = importInfo.getLazyExportInfo(); + if (exportInfo === null) { + return; + } + const arkExport = exportInfo.getArkExport(); + if (!arkExport || !(arkExport instanceof Local)) { + return; + } + const declaringStmt = arkExport.getDeclaringStmt(); + if (!declaringStmt) { + return; + } + importVarMap.set(arkExport.getName(), [declaringStmt]); + }); + } + + private collectTopLevelVar(topLevelVarMap: Map, file: ArkFile, scene: Scene) { + const defaultMethod = file.getDefaultClass().getDefaultArkMethod(); + if (!defaultMethod) { + return; + } + DVFGHelper.buildSingleDVFG(defaultMethod, scene); + const stmts = defaultMethod.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof Local)) { + continue; + } + const name = leftOp.getName(); + if (name.startsWith('%') || name === 'this') { + continue; + } + topLevelVarMap.set(name, [...(topLevelVarMap.get(name) ?? []), stmt]); + } + } + + private checkFromStmt( + stmt: Stmt, + scene: Scene, + res: Stmt[], + topLevelVarMap: Map, + checkAll: { value: boolean }, + visited: Set, + depth: number = 0 + ): void { + if (depth > CALL_DEPTH_LIMIT) { + checkAll.value = false; + return; + } + const node = DVFGHelper.getOrNewDVFGNode(stmt, scene); + let worklist: DVFGNode[] = [node]; + while (worklist.length > 0) { + const current = worklist.shift()!; + const currentStmt = current.getStmt(); + if (visited.has(currentStmt)) { + continue; + } + visited.add(currentStmt); + if (this.isObjectLiteral(currentStmt, scene)) { + res.push(currentStmt); + continue; + } + const isClsField = this.isClassField(currentStmt, scene); + if (isClsField) { + isClsField.forEach(d => worklist.push(DVFGHelper.getOrNewDVFGNode(d, scene))); + continue; + } + const isArrayField = this.isArrayField(currentStmt, topLevelVarMap); + if (isArrayField) { + isArrayField.forEach(d => worklist.push(DVFGHelper.getOrNewDVFGNode(d, scene))); + continue; + } + const gv = this.checkIfIsTopLevelVar(currentStmt); + if (gv) { + const globalDefs = topLevelVarMap.get(gv.getName()); + globalDefs?.forEach(d => { + worklist.push(DVFGHelper.getOrNewDVFGNode(d, scene)); + }); + continue; + } + const callsite = this.cg.getCallSiteByStmt(currentStmt); + callsite.forEach(cs => { + const declaringMtd = this.cg.getArkMethodByFuncID(cs.calleeFuncID); + if (!declaringMtd || !declaringMtd.getCfg()) { + return; + } + if (!this.visited.has(declaringMtd)) { + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + this.visited.add(declaringMtd); + } + declaringMtd + .getReturnStmt() + .forEach(r => this.checkFromStmt(r, scene, res, topLevelVarMap, checkAll, visited, depth + 1)); + }); + const paramRef = this.isFromParameter(currentStmt); + if (paramRef) { + const paramIdx = paramRef.getIndex(); + const callsites = this.cg.getInvokeStmtByMethod( + currentStmt.getCfg().getDeclaringMethod().getSignature() + ); + this.processCallsites(callsites, scene); + this.collectArgDefs(paramIdx, callsites, scene).forEach(d => + this.checkFromStmt(d, scene, res, topLevelVarMap, checkAll, visited, depth + 1) + ); + } + current.getIncomingEdge().forEach(e => worklist.push(e.getSrcNode() as DVFGNode)); + } + } + + private checkIfIsTopLevelVar(stmt: Stmt): Local | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof Local && !rightOp.getDeclaringStmt()) { + return rightOp; + } + if (!(rightOp instanceof ArkInstanceOfExpr)) { + return undefined; + } + const obj = rightOp.getOp(); + if (obj instanceof Local && !obj.getDeclaringStmt()) { + return obj; + } + return undefined; + } + + private processCallsites(callsites: Stmt[], scene: Scene): void { + callsites.forEach(cs => { + const declaringMtd = cs.getCfg().getDeclaringMethod(); + if (!this.visited.has(declaringMtd)) { + DVFGHelper.buildSingleDVFG(declaringMtd, scene); + this.visited.add(declaringMtd); + } + }); + } + + private isObjectLiteral(stmt: Stmt, scene: Scene): boolean { + if (!(stmt instanceof ArkAssignStmt)) { + return false; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkNewExpr)) { + return false; + } + const classSig = rightOp.getClassType().getClassSignature(); + if (scene.getClass(classSig)?.isAnonymousClass()) { + return true; + } + return false; + } + + private isClassField(stmt: Stmt, scene: Scene): Stmt[] | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const clsField = stmt.getRightOp(); + if (!(clsField instanceof AbstractFieldRef)) { + return undefined; + } + if (clsField instanceof ArkInstanceFieldRef && clsField.getBase().getName() !== 'this') { + return undefined; + } + const fieldSig = clsField.getFieldSignature(); + const clsSig = fieldSig.getDeclaringSignature(); + if (!(clsSig instanceof ClassSignature)) { + return undefined; + } + const cls = scene.getClass(clsSig); + if (!cls) { + logger.error(`cannot find class based on class sig: ${clsSig.toString()}`); + return undefined; + } + const field = cls.getField(fieldSig); + if (!field) { + logger.error(`cannot find field based on field sig: ${fieldSig.toString()}`); + return undefined; + } + if (!field.isStatic()) { + DVFGHelper.buildSingleDVFG(cls.getInstanceInitMethod(), scene); + } else { + DVFGHelper.buildSingleDVFG(cls.getStaticInitMethod(), scene); + } + return field.getInitializer().slice(-1); + } + + private isArrayField(stmt: Stmt, topLevelVarMap: Map): Stmt[] | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const arrField = stmt.getRightOp(); + if (!(arrField instanceof ArkArrayRef)) { + return undefined; + } + const arr = arrField.getBase(); + const index = arrField.getIndex(); + let arrDeclarations: Stmt[] = []; + if (arr.getDeclaringStmt()) { + arrDeclarations.push(arr.getDeclaringStmt()!); + } else if (topLevelVarMap.has(arr.getName())) { + arrDeclarations = topLevelVarMap.get(arr.getName())!; + } + const res: Stmt[] = arrDeclarations.flatMap(d => { + // arr = %0 + // %0[0] = ... + if (!(d instanceof ArkAssignStmt)) { + return []; + } + const arrVal = d.getRightOp(); + if (!(arrVal instanceof Local)) { + return []; + } + return arrVal.getUsedStmts().filter(u => { + if (!(u instanceof ArkAssignStmt)) { + return false; + } + const left = u.getLeftOp(); + return left instanceof ArkArrayRef && left.getBase() === arrVal && left.getIndex() === index; + }); + }); + return res; + } + + private isFromParameter(stmt: Stmt): ArkParameterRef | undefined { + if (!(stmt instanceof ArkAssignStmt)) { + return undefined; + } + const rightOp = stmt.getRightOp(); + if (rightOp instanceof ArkParameterRef) { + return rightOp; + } + return undefined; + } + + private collectArgDefs(argIdx: number, callsites: Stmt[], scene: Scene): Stmt[] { + const getKey = (v: Value): Value | FieldSignature => { + return v instanceof ArkInstanceFieldRef ? v.getFieldSignature() : v; + }; + return callsites.flatMap(callsite => { + const target: Value | FieldSignature = getKey(callsite.getInvokeExpr()!.getArg(argIdx)); + return Array.from(DVFGHelper.getOrNewDVFGNode(callsite, scene).getIncomingEdge()) + .map(e => (e.getSrcNode() as DVFGNode).getStmt()) + .filter(s => { + return s instanceof ArkAssignStmt && target === getKey(s.getLeftOp()); + }); + }); + } + + private addIssueReport(stmt: Stmt, operand: Value): void { + const severity = this.rule.alert ?? this.metaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'ObjectLiteral'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const originPosition = stmt.getOperandOriginalPosition(operand); + if (arkFile && originPosition) { + const originPath = arkFile.getFilePath(); + const line = originPosition.getFirstLine(); + const startCol = originPosition.getFirstCol(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + } + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..a6a56e9b4d2ef3d9d95783a0f6d5e03f4fd5004e --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/ObservedDecoratorCheck.ts @@ -0,0 +1,363 @@ +/* + * 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 path from 'path'; +import { + AbstractInvokeExpr, + ArkAssignStmt, + ArkClass, + ArkField, + ArkNewExpr, + ArkReturnStmt, + AstTreeUtils, + ClassType, + fileSignatureCompare, + Local, + Scene, + Type, +} from 'arkanalyzer'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, ClassMatcher, MatcherTypes, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { RuleFix } from '../../model/Fix'; +import { FixUtils } from '../../utils/common/FixUtils'; +import { WarnInfo } from '../../utils/common/Utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ObservedDecoratorCheck'); +const gMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: '', +}; + +const DECORATOR_SET: Set = new Set([ + 'State', + 'Prop', + 'Link', + 'Provide', + 'Consume', + 'LocalStorageProp', + 'LocalStorageLink', + 'StorageProp', + 'StorageLink', +]); + +// TODO: 需要考虑type alias、union type、intersection type中涉及class的场景 +export class ObservedDecoratorCheck implements BaseChecker { + readonly metaData: BaseMetaData = gMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private clsMatcher: ClassMatcher = { + matcherType: MatcherTypes.CLASS, + category: [ClassCategory.STRUCT], + }; + + public registerMatchers(): MatcherCallback[] { + const matchClsCb: MatcherCallback = { + matcher: this.clsMatcher, + callback: this.check, + }; + return [matchClsCb]; + } + + public check = (arkClass: ArkClass): void => { + const scene = arkClass.getDeclaringArkFile().getScene(); + for (const field of arkClass.getFields()) { + if (!field.getDecorators().some(d => DECORATOR_SET.has(d.getKind()))) { + continue; + } + // usedClasses用于记录field的初始化中涉及的所有class + let usedClasses: Set = new Set(); + // issueClasses用于记录usedClasses以及他们的所有父类 + let issueClasses: Set = new Set(); + // ArkAnalyzer此处有问题,若field的类型注解为unclear type,会用右边的替换左边的。 + const fieldType = field.getType(); + const initializers = field.getInitializer(); + let canFindAllTargets = true; + + let locals: Set = new Set(); + + // field的初始化语句的最后一句,一定是将右边的value赋值给field,此处仍然判断一次,排除其他场景或者初始化语句为空的场景 + const lastStmt = initializers[initializers.length - 1]; + if (!(lastStmt instanceof ArkAssignStmt)) { + continue; + } + const start = lastStmt.getRightOp(); + // 直接对属性进行常量赋值属于这种场景 + if (!(start instanceof Local)) { + continue; + } + locals.add(start); + for (const stmt of initializers.slice(0, -1).reverse()) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + + const leftOp = stmt.getLeftOp(); + const rightOp = stmt.getRightOp(); + if (!(leftOp instanceof Local)) { + continue; + } + if (!locals.has(leftOp)) { + continue; + } + if (rightOp instanceof Local) { + locals.add(rightOp); + } else if (rightOp instanceof ArkNewExpr) { + // 此处需要区分field = new cls()和field = {}两种场景,查找完毕需继续遍历stmts以解析条件表达式造成的多赋值场景 + canFindAllTargets = canFindAllTargets && this.handleNewExpr(scene, fieldType, rightOp, usedClasses); + } else if (rightOp instanceof AbstractInvokeExpr) { + canFindAllTargets = + canFindAllTargets && this.handleInvokeExpr(scene, fieldType, rightOp, usedClasses); + } else { + // 对应场景为使用条件表达式cond ? 123 : 456赋值时 + continue; + } + } + + for (const cls of usedClasses) { + issueClasses.add(cls); + this.getAllSuperClasses( + cls, + superCls => superCls.getCategory() === ClassCategory.CLASS && issueClasses.add(superCls) + ); + } + + for (const target of issueClasses) { + if (target.hasDecorator('Observed')) { + continue; + } + const pos = this.getClassPos(target); + const description = this.generateIssueDescription(field, target); + const ruleFix = this.generateRuleFix(pos, target) ?? undefined; + this.addIssueReport(pos, description, ruleFix); + } + + if (!canFindAllTargets) { + const pos = this.getFieldPos(field); + const description = this.generateIssueDescription(field, null, false); + this.addIssueReport(pos, description); + } + } + }; + + // 此处需要区分field = new cls()和field = {}两种场景 + // 对于field = new cls()场景,需要查找此右边class的所有父class + // 对于field = {}场景,需要查找左边field类型为class时的所有父class + private handleNewExpr(scene: Scene, fieldType: Type, rightOp: ArkNewExpr, targets: Set): boolean { + const target = scene.getClass(rightOp.getClassType().getClassSignature()); + if (target === null) { + return false; + } + + if (!target.isAnonymousClass()) { + // 理论上来说ArkNewExpr中的class一定ClassCategory.CLASS,此处仍然显式的检查一次 + if (target.getCategory() !== ClassCategory.CLASS) { + return true; + } + targets.add(target); + return true; + } + + // 处理匿名类场景,若右边为object literal时,需考虑左边是什么类型注解,将涉及的class找出 + if (target.getCategory() !== ClassCategory.OBJECT) { + return true; + } + if (!(fieldType instanceof ClassType)) { + return true; + } + const fieldClass = scene.getClass(fieldType.getClassSignature()); + if (fieldClass === null) { + return false; + } + if (fieldClass.getCategory() !== ClassCategory.CLASS) { + return true; + } + targets.add(fieldClass); + return true; + } + + // 遍历此处的调用方法的所有return stmts,查找class + // 此处需要区分返回值为class和object literal两种场景 + // 对于返回值为class的场景,需要查找此class的所有父class + // 对于存在返回值为object literal的场景,需要查找左边field类型为class时的所有父class + private handleInvokeExpr( + scene: Scene, + fieldType: Type, + invokeExpr: AbstractInvokeExpr, + targets: Set + ): boolean { + let canFindAllTargets = true; + const callMethod = scene.getMethod(invokeExpr.getMethodSignature()); + if (callMethod === null) { + return false; + } + const stmts = callMethod.getBody()?.getCfg().getStmts(); + if (stmts === undefined) { + return false; + } + for (const stmt of stmts) { + if (!(stmt instanceof ArkReturnStmt)) { + continue; + } + const opType = stmt.getOp().getType(); + if (!(opType instanceof ClassType)) { + continue; + } + const returnClass = scene.getClass(opType.getClassSignature()); + if (returnClass === null) { + canFindAllTargets = false; + continue; + } + if (returnClass.getCategory() === ClassCategory.CLASS) { + targets.add(returnClass); + } else if (returnClass.getCategory() === ClassCategory.OBJECT) { + if (!(fieldType instanceof ClassType)) { + continue; + } + const leftClass = scene.getClass(fieldType.getClassSignature()); + if (leftClass === null) { + canFindAllTargets = false; + continue; + } + if (leftClass.getCategory() === ClassCategory.CLASS) { + targets.add(leftClass); + } + } + } + return canFindAllTargets; + } + + // 采用广度优先遍历方式,逐层获取该class的所有父类,一直查找到基类 + // arkanalyzer getAllHeritageClasses有点问题,对于未能推出来的父类会忽略,不加入列表中返回。 + private getAllSuperClasses(arkClass: ArkClass, callback: (value: ArkClass) => void): void { + let superClasses: Set = new Set(); + const classes = arkClass.getAllHeritageClasses(); + while (classes.length > 0) { + const superCls = classes.shift()!; + const superSuperCls = superCls.getAllHeritageClasses(); + callback(superCls); + + if (superSuperCls.length > 0) { + classes.push(...superSuperCls); + } + } + } + + private generateIssueDescription( + field: ArkField, + issueClass: ArkClass | null, + canFindAllTargets: boolean = true + ): string { + if (issueClass === null || !canFindAllTargets) { + return `can not find all classes, please check this field manually`; + } + const fieldLine = field.getOriginPosition().getLineNo(); + const fieldColumn = field.getOriginPosition().getColNo(); + + const fieldFileSig = field.getDeclaringArkClass().getDeclaringArkFile().getFileSignature(); + const issueClassSig = issueClass.getDeclaringArkFile().getFileSignature(); + let res = `but it's not be annotated by @Observed (arkui-data-observation)`; + if (fileSignatureCompare(fieldFileSig, issueClassSig)) { + res = `The class is used by state property in [${fieldLine}, ${fieldColumn}], ` + res; + } else { + const filePath = path.normalize(fieldFileSig.getFileName()); + res = `The class is used by state property in file ${filePath} [${fieldLine}, ${fieldColumn}], ` + res; + } + return res; + } + + private getClassPos(cls: ArkClass): WarnInfo { + const arkFile = cls.getDeclaringArkFile(); + if (arkFile) { + const originPath = path.normalize(arkFile.getFilePath()); + const line = cls.getLine(); + const startCol = cls.getColumn(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; + } + } + + private getFieldPos(field: ArkField): WarnInfo { + const arkFile = field.getDeclaringArkClass().getDeclaringArkFile(); + const pos = field.getOriginPosition(); + if (arkFile && pos) { + const originPath = arkFile.getFilePath(); + const line = pos.getLineNo(); + const startCol = pos.getColNo(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; + } + } + + private addIssueReport(warnInfo: WarnInfo, description: string, ruleFix?: RuleFix): void { + const problem = 'DataObservationNeedObserved'; + const severity = this.rule.alert ?? this.metaData.severity; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + description, + severity, + this.rule.ruleId, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + true + ); + this.issues.push(new IssueReport(defects, ruleFix)); + if (ruleFix === undefined) { + defects.fixable = false; + } + } + + private generateRuleFix(warnInfo: WarnInfo, targetClass: ArkClass): RuleFix | null { + const arkFile = targetClass.getDeclaringArkFile(); + const sourceFile = AstTreeUtils.getASTNode(arkFile.getName(), arkFile.getCode()); + const startLineRange = FixUtils.getLineRange(sourceFile, warnInfo.line); + if (startLineRange === null) { + return null; + } + + const ruleFix = new RuleFix(); + ruleFix.range = startLineRange; + + const startLineStr = FixUtils.getSourceWithRange(sourceFile, startLineRange); + if (startLineStr === null) { + return null; + } + + const eol = FixUtils.getEolSymbol(sourceFile, warnInfo.line); + const startLineIndent = FixUtils.getIndentOfLine(sourceFile, warnInfo.line); + if (startLineIndent === null) { + return null; + } + const space = ' '; + ruleFix.text = `@Observed${eol}${space.repeat(startLineIndent)}${startLineStr}`; + return ruleFix; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts b/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..af8657687c1de1e597a6b4a0da9e3d2730f0479e --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/ThisBindCheck.ts @@ -0,0 +1,364 @@ +/* + * 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 { + ArkAssignStmt, + ArkIfStmt, + ArkInstanceFieldRef, + ArkInstanceInvokeExpr, + ArkMethod, + ClassType, + FunctionType, + Local, + Stmt, + Value, + Scene, + ArkNewArrayExpr, + ArkNewExpr, + ArkClass, + ClassSignature, +} from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { BaseChecker, BaseMetaData } from '../BaseChecker'; +import { Rule, Defects, MatcherTypes, MethodMatcher, MatcherCallback } from '../../Index'; +import { IssueReport } from '../../model/Defects'; +import { WarnInfo } from '../../utils/common/Utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ThisBindCheck'); + +const ARKTS_RULE_ID = '@migration/arkts-instance-method-bind-this'; +const arktsMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: "Instance method shall bind the 'this' by default", +}; + +const ARKUI_RULE_ID = '@migration/arkui-buildparam-passing'; +const arkuiMetaData: BaseMetaData = { + severity: 1, + ruleDocPath: '', + description: + 'The execution context of the function annotated with @Builder is determined at the time of declaration. Please check the code carefully to ensure the correct function context', +}; +const LOCAL_BUILDER_PREFIX = 'The @LocalBuilder decorator is not supported, it will be transformed to @Builder decorator. '; + +export class ThisBindCheck implements BaseChecker { + readonly metaData: BaseMetaData = arktsMetaData; + public rule: Rule; + public defects: Defects[] = []; + public issues: IssueReport[] = []; + + private methodMatcher: MethodMatcher = { + matcherType: MatcherTypes.METHOD, + }; + + public registerMatchers(): MatcherCallback[] { + const methodCb: MatcherCallback = { + matcher: this.methodMatcher, + callback: this.check, + }; + return [methodCb]; + } + + public check = (targetMtd: ArkMethod): void => { + const file = targetMtd.getDeclaringArkFile(); + if (file.getName().includes('.test.ets')) { + return; + } + const scene = file.getScene(); + const stmts = targetMtd.getBody()?.getCfg().getStmts() ?? []; + for (let i = 0; i < stmts.length; ++i) { + const stmt = stmts[i]; + // const method = a.foo + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceFieldRef)) { + continue; + } + const base = rightOp.getBase(); + const classTy = base.getType(); + if (!(classTy instanceof ClassType)) { + continue; + } + if (!(rightOp.getFieldSignature().getType() instanceof FunctionType)) { + continue; + } + const klass = scene.getClass(classTy.getClassSignature()); + const method = klass?.getMethodWithName(rightOp.getFieldName()); + if (!method || !method.getCfg() || !this.useThisInBody(method)) { + continue; + } + const isBuilder = method.hasBuilderDecorator(); + const isLocalBuilder = method.hasDecorator('LocalBuilder'); + const leftOp = stmt.getLeftOp(); + if (i + 1 >= stmts.length || !this.hasBindThis(leftOp, stmts[i + 1])) { + if (!this.isSafeUse(leftOp)) { + this.addIssueReport(stmt, isBuilder, isLocalBuilder, base, scene); + } + } + } + }; + + private useThisInBody(method: ArkMethod): boolean { + const thisInstance = (method.getThisInstance() as Local)!; + return thisInstance.getUsedStmts().length > 0; + } + + private isSafeUse(v: Value): boolean { + if (!(v instanceof Local)) { + return false; + } + + const users = v.getUsedStmts(); + if (users.length === 0) { + return false; + } + for (const user of users) { + if (user instanceof ArkIfStmt) { + const cond = user.getConditionExpr(); + if (v !== cond.getOp1() && v !== cond.getOp2()) { + return false; + } + } else { + return false; + } + } + return true; + } + + private hasBindThis(base: Value, next: Stmt): boolean { + if (!(next instanceof ArkAssignStmt)) { + return false; + } + const rightOp = next.getRightOp(); + if (rightOp instanceof ArkInstanceFieldRef && rightOp.getBase() === base) { + // const method = a.foo.name + return true; + } + if (!(rightOp instanceof ArkInstanceInvokeExpr)) { + return false; + } + if (rightOp.getBase() !== base) { + return false; + } + if (rightOp.getMethodSignature().getMethodSubSignature().getMethodName() !== 'bind') { + return false; + } + return true; + } + + private addIssueReport(stmt: ArkAssignStmt, isBuilder: boolean, isLocalBuilder: boolean, operand: Value, scene: Scene): void { + if ((isBuilder || isLocalBuilder) && this.isAssignToBuilderParam(stmt, scene)) { + this.reportArkUIIssue(stmt, operand, isLocalBuilder); + } else { + this.reportArkTSIssue(stmt, operand); + } + } + + private isAssignToBuilderParam(assign: ArkAssignStmt, scene: Scene): boolean { + /** + * class CA { + * @Builder builder() { ... } + * build() { + * Column() { CB({ content: this.builder }) } + * } + * } + * class CB { + * @BuilderParam content: () => void + * } + * + * ================================================== + * class %AC2$CA.build { + * constructor() { ... } + * %instInit() { + * %0 = this.builder + * this.content = %0 + * } + * } + * class CA { + * ... + * build() { + * ... + * %3 = new %AC2$CA.build + * %3.constructor() + * %4 = new CB + * %4.constructor(%3) + * ... + * } + * ... + * } + */ + const currentMethod = assign.getCfg().getDeclaringMethod(); + if (currentMethod.getName() !== '%instInit') { + return false; + } + const currentClass = currentMethod.getDeclaringArkClass(); + if (!currentClass.isAnonymousClass()) { + return false; + } + const currentClassSig = currentClass.getSignature(); + + const leftOp = assign.getLeftOp(); + if (!(leftOp instanceof Local)) { + return false; + } + const usedStmts = leftOp.getUsedStmts(); + if (usedStmts.length !== 1) { + return false; + } + const usedStmt = usedStmts[0]; + if (!(usedStmt instanceof ArkAssignStmt)) { + return false; + } + const target = usedStmt.getLeftOp(); + if (!(target instanceof ArkInstanceFieldRef)) { + return false; + } + const baseTy = target.getBase().getType(); + if (!(baseTy instanceof ClassType)) { + return false; + } + if ((baseTy as ClassType).getClassSignature() !== currentClassSig) { + return false; + } + const fieldName = target.getFieldName(); + + const declaringClassName = currentClassSig.getDeclaringClassName(); + if (declaringClassName === currentClass.getName()) { + return false; + } + const declaringClass = currentClass.getDeclaringArkFile().getClassWithName(declaringClassName); + if (!declaringClass) { + return false; + } + let targetClassSig = this.findDefinitionOfAnonymousClass(declaringClass, currentClassSig); + if (!targetClassSig) { + return false; + } + const targetClass = scene.getClass(targetClassSig); + if (!targetClass) { + return false; + } + const arkField = targetClass.getFieldWithName(fieldName); + if (!arkField) { + return false; + } + return arkField.hasBuilderParamDecorator(); + } + + private findDefinitionOfAnonymousClass(declaringClass: ArkClass, anonymousClassSig: ClassSignature): ClassSignature | undefined { + for (const m of declaringClass.getMethods()) { + const stmts = m.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const rightOp = stmt.getRightOp(); + if (!(rightOp instanceof ArkNewExpr)) { + continue; + } + if (rightOp.getClassType().getClassSignature() !== anonymousClassSig) { + continue; + } + const local = stmt.getLeftOp() as Local; + const classSignature = this.processUsedStmts(local, anonymousClassSig); + if (!classSignature) { + continue; + } + return classSignature; + } + } + return undefined; + } + + private processUsedStmts(local: Local, anonymousClassSig: ClassSignature): ClassSignature | null { + for (const usedStmt of local.getUsedStmts()) { + const invoke = usedStmt.getInvokeExpr(); + if (!invoke) { + continue; + } + const sig = invoke.getMethodSignature(); + if (sig.getMethodSubSignature().getMethodName() !== 'constructor') { + continue; + } + if (sig.getDeclaringClassSignature() === anonymousClassSig) { + continue; + } + return sig.getDeclaringClassSignature(); + } + return null; + } + + private reportArkTSIssue(stmt: ArkAssignStmt, operand: Value): void { + const severity = this.rule.alert ?? this.metaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'DefaultBindThis'; + const desc = `${this.metaData.description} (${this.rule.ruleId.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + ARKTS_RULE_ID, + warnInfo.filePath, + this.metaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private reportArkUIIssue(stmt: ArkAssignStmt, operand: Value, isLocalBuilder: boolean): void { + const severity = this.rule.alert ?? arkuiMetaData.severity; + const warnInfo = this.getLineAndColumn(stmt, operand); + const problem = 'BuilderParamContextChanged'; + const desc = `${isLocalBuilder ? LOCAL_BUILDER_PREFIX : ''}${arkuiMetaData.description} (${ARKUI_RULE_ID.replace('@migration/', '')})`; + let defects = new Defects( + warnInfo.line, + warnInfo.startCol, + warnInfo.endCol, + problem, + desc, + severity, + ARKUI_RULE_ID, + warnInfo.filePath, + arkuiMetaData.ruleDocPath, + true, + false, + false + ); + this.issues.push(new IssueReport(defects, undefined)); + } + + private getLineAndColumn(stmt: ArkAssignStmt, operand: Value): WarnInfo { + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const originPosition = stmt.getOperandOriginalPosition(operand); + if (arkFile && originPosition) { + const originPath = arkFile.getFilePath(); + const line = originPosition.getFirstLine(); + const startCol = originPosition.getFirstCol(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + } + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; + } +} diff --git a/ets2panda/linter/homecheck/src/checker/migration/Utils.ts b/ets2panda/linter/homecheck/src/checker/migration/Utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..0992bcbe88d2748a8d25a3b7b12b9c8b6492578c --- /dev/null +++ b/ets2panda/linter/homecheck/src/checker/migration/Utils.ts @@ -0,0 +1,152 @@ +/* + * 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 { ArkAssignStmt, ArkMethod, CallGraph, CallGraphBuilder, Local, LOG_MODULE_TYPE, Logger, Scene, Stmt, Value } from 'arkanalyzer/lib'; +import { WarnInfo } from '../../utils/common/Utils'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; +import { DVFG, DVFGNode } from 'arkanalyzer/lib/VFG/DVFG'; +import { DVFGBuilder } from 'arkanalyzer/lib/VFG/builder/DVFGBuilder'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Utils'); + +export const CALL_DEPTH_LIMIT = 2; +export class CallGraphHelper { + private static cgInstance: CallGraph | null = null; + + public static getCGInstance(scene: Scene): CallGraph { + if (!this.cgInstance) { + this.cgInstance = new CallGraph(scene); + } + return this.cgInstance; + } +} + +export class GlobalCallGraphHelper { + private static cgInstance: CallGraph | null = null; + + public static getCGInstance(scene: Scene): CallGraph { + if (!this.cgInstance) { + this.cgInstance = new CallGraph(scene); + let cgBuilder = new CallGraphBuilder(this.cgInstance, scene); + cgBuilder.buildCHA4WholeProject(true); + } + return this.cgInstance; + } +} + +export class DVFGHelper { + private static dvfgInstance: DVFG; + private static dvfgBuilder: DVFGBuilder; + private static built: Set = new Set(); + + private static createDVFGInstance(scene: Scene): void { + if (!this.dvfgInstance) { + this.dvfgInstance = new DVFG(GlobalCallGraphHelper.getCGInstance(scene)); + this.dvfgBuilder = new DVFGBuilder(this.dvfgInstance, scene); + } + } + + public static buildSingleDVFG(method: ArkMethod, scene: Scene): void { + if (!this.dvfgInstance) { + this.createDVFGInstance(scene); + } + if (!this.built.has(method)) { + this.dvfgBuilder.buildForSingleMethod(method); + this.built.add(method); + } + } + + public static getOrNewDVFGNode(stmt: Stmt, scene: Scene): DVFGNode { + if (!this.dvfgInstance) { + this.createDVFGInstance(scene); + } + return this.dvfgInstance!.getOrNewDVFGNode(stmt); + } +} + +export const CALLBACK_METHOD_NAME: string[] = [ + 'onClick', // 点击事件,当用户点击组件时触发 + 'onTouch', // 触摸事件,当手指在组件上按下、滑动、抬起时触发 + 'onAppear', // 组件挂载显示时触发 + 'onDisAppear', // 组件卸载消失时触发 + 'onDragStart', // 拖拽开始事件,当组件被长按后开始拖拽时触发 + 'onDragEnter', // 拖拽进入组件范围时触发 + 'onDragMove', // 拖拽在组件范围内移动时触发 + 'onDragLeave', // 拖拽离开组件范围内时触发 + 'onDrop', // 拖拽释放目标,当在本组件范围内停止拖拽行为时触发 + 'onKeyEvent', // 按键事件,当组件获焦后,按键动作触发 + 'onFocus', // 焦点事件,当组件获取焦点时触发 + 'onBlur', // 当组件失去焦点时触发的回调 + 'onHover', // 鼠标悬浮事件,鼠标进入或退出组件时触发 + 'onMouse', // 鼠标事件,当鼠标按键点击或在组件上移动时触发 + 'onAreaChange', // 组件区域变化事件,组件尺寸、位置变化时触发 + 'onVisibleAreaChange', // 组件可见区域变化事件,组件在屏幕中的显示区域面积变化时触发 +]; + +export function getLanguageStr(language: Language): string { + let targetLan: string = ''; + switch (language) { + case Language.JAVASCRIPT: + targetLan = 'javascript'; + break; + case Language.TYPESCRIPT: + targetLan = 'typescript'; + break; + case Language.ARKTS1_1: + targetLan = 'arkts1.1'; + break; + case Language.ARKTS1_2: + targetLan = 'arkts1.2'; + break; + default: + break; + } + return targetLan; +} + +export function getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo { + const arkFile = stmt.getCfg()?.getDeclaringMethod().getDeclaringArkFile(); + const originPosition = stmt.getOperandOriginalPosition(operand); + if (arkFile && originPosition) { + const originPath = arkFile.getFilePath(); + const line = originPosition.getFirstLine(); + const startCol = originPosition.getFirstCol(); + const endCol = startCol; + return { line, startCol, endCol, filePath: originPath }; + } else { + logger.debug('ArkFile is null.'); + } + return { line: -1, startCol: -1, endCol: -1, filePath: '' }; +} + +export function getGlobalsDefineInDefaultMethod(defaultMethod: ArkMethod): Map { + const globalVarMap: Map = new Map(); + const stmts = defaultMethod.getBody()?.getCfg().getStmts() ?? []; + for (const stmt of stmts) { + if (!(stmt instanceof ArkAssignStmt)) { + continue; + } + const leftOp = stmt.getLeftOp(); + if (!(leftOp instanceof Local)) { + continue; + } + const name = leftOp.getName(); + if (name.startsWith('%') || name === 'this') { + continue; + } + globalVarMap.set(name, [...(globalVarMap.get(name) ?? []), stmt]); + } + return globalVarMap; +} diff --git a/ets2panda/linter/homecheck/src/codeFix/FixEngine.ts b/ets2panda/linter/homecheck/src/codeFix/FixEngine.ts new file mode 100644 index 0000000000000000000000000000000000000000..483a60a3de20cbd0fcdb574c77998bd963aa6af2 --- /dev/null +++ b/ets2panda/linter/homecheck/src/codeFix/FixEngine.ts @@ -0,0 +1,33 @@ +/* + * 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 { Engine } from '../model/Engine'; +import { FixMode } from '../model/Fix'; +import { AIFixEngine } from './engines/AIFixEngine'; +import { EsLintFixEngine } from './engines/EsLintFixEngine'; +import { HomeCheckFixEngine } from './engines/HomeCheckFixEngine'; + +export class FixEngine { + public getEngine(mode: FixMode): Engine { + if (mode === FixMode.AST) { + return new EsLintFixEngine(); + } else if (mode === FixMode.ARKFILE) { + return new HomeCheckFixEngine(); + } else if (mode === FixMode.AI) { + return new AIFixEngine(); + } + throw TypeError(`${mode} does not support!`); + } +} diff --git a/ets2panda/linter/homecheck/src/codeFix/engines/AIFixEngine.ts b/ets2panda/linter/homecheck/src/codeFix/engines/AIFixEngine.ts new file mode 100644 index 0000000000000000000000000000000000000000..786d2863f3de728485f3f08426dd4168887c248b --- /dev/null +++ b/ets2panda/linter/homecheck/src/codeFix/engines/AIFixEngine.ts @@ -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. + */ + +import { ArkFile } from 'arkanalyzer'; +import { FileReports, IssueReport } from '../../model/Defects'; +import { Engine } from '../../model/Engine'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'EsLintFixEngine'); + +export class AIFixEngine implements Engine { + applyFix(arkFile: ArkFile, isses: IssueReport[]): FileReports { + logger.info('Todo implement.'); + throw TypeError('todo implement'); + } +} diff --git a/ets2panda/linter/homecheck/src/codeFix/engines/EsLintFixEngine.ts b/ets2panda/linter/homecheck/src/codeFix/engines/EsLintFixEngine.ts new file mode 100644 index 0000000000000000000000000000000000000000..a5f055289c04ba9e3b7529c111ba56b5a0713f5e --- /dev/null +++ b/ets2panda/linter/homecheck/src/codeFix/engines/EsLintFixEngine.ts @@ -0,0 +1,147 @@ +/* + * 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 { ArkFile } from 'arkanalyzer'; +import { FileReports, IssueReport } from '../../model/Defects'; +import { Engine } from '../../model/Engine'; +import { RuleFix } from '../../model/Fix'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { FixUtils } from '../../utils/common/FixUtils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'EsLintFixEngine'); +const BOM = '\uFEFF'; +let eof = '\r\n'; + + +export class EsLintFixEngine implements Engine { + applyFix(arkFile: ArkFile, fixIssues: IssueReport[], remainIssues: IssueReport[]): FileReports { + let sourceText = arkFile.getCode(); + const bom = sourceText.startsWith(BOM) ? BOM : ''; + let text = bom ? sourceText.slice(1) : sourceText; + let lastPos = Number.NEGATIVE_INFINITY; + let output = bom; + eof = FixUtils.getTextEof(text) || eof; + // issue非法数据检查及排序 + const ret = this.checkAndSortIssues(fixIssues, remainIssues); + fixIssues = ret.fixIssues, remainIssues = ret.remainIssues; + + if (fixIssues.length === 0) { + return { defects: remainIssues.map((issue => issue.defect)), output: '', filePath: arkFile.getFilePath() }; + } + // 深拷贝remainIssues,防止在遍历过程中修改remainIssues导致后续迭代出错 + const remainIssuesCopy = JSON.parse(JSON.stringify(remainIssues)); + for (const issue of fixIssues) { + let fix = issue.fix as RuleFix; + const start = fix.range[0]; + const end = fix.range[1]; + + output += text.slice(Math.max(0, lastPos), Math.max(0, start)); + output += fix.text; + lastPos = end; + fix.fixed = true; + this.updateRemainIssues(text, issue, remainIssues, remainIssuesCopy); + } + output += text.slice(Math.max(0, lastPos)); + return { defects: remainIssues.map((issue => issue.defect)), output: bom + output, filePath: arkFile.getFilePath() }; + } + + private checkAndSortIssues(fixIssues: IssueReport[], remainIssues: IssueReport[]): { + fixIssues: IssueReport[], remainIssues: IssueReport[] + } { + const fixIssuesValid: IssueReport[] = []; + fixIssues.forEach((issue) => { + const fix = issue.fix as RuleFix; + if (fix.range[0] <= fix.range[1] && fix.range[1] !== 0 && fix.range[0] >= 0) { + fixIssuesValid.push(issue); + } else { + remainIssues.push(issue); + } + }); + return { fixIssues: fixIssuesValid.sort(this.compareIssueByRange), remainIssues: remainIssues.sort(this.compareIssueByLocation) }; + } + + private compareIssueByRange(issue1: IssueReport, issue2: IssueReport): number { + let fix1 = issue1.fix; + let fix2 = issue2.fix; + if (FixUtils.isRuleFix(fix1) && FixUtils.isRuleFix(fix2)) { + return fix1.range[0] - fix2.range[0] || fix1.range[1] - fix2.range[1]; + } else { + return 0; + } + } + + private compareIssueByLocation(a: IssueReport, b: IssueReport): number { + return a.defect.reportLine - b.defect.reportLine || a.defect.reportColumn - b.defect.reportColumn; + } + + private updateRemainIssues(sourceText: string, issue: IssueReport, remainIssues: IssueReport[], remainIssuesOld: IssueReport[]): void { + if (remainIssues.length === 0) { + return; + } + let fix = issue.fix as RuleFix; + const start = fix.range[0]; + const end = fix.range[1]; + const fixEndCol = Number.parseInt(issue.defect.fixKey.split('%')[2]); + + const originLineNum = sourceText.slice(start, end).split(eof).length; + const fixTextLineNUM = fix.text.split(eof).length; + const subLine = fixTextLineNUM - originLineNum; + for (let i = 0; i < remainIssuesOld.length; i++) { + const defectOld = remainIssuesOld[i].defect; + const defectOldEndCol = Number.parseInt(defectOld.fixKey.split('%')[2]); + + // 1、当前告警区域完全在修复区域之前,不做处理。注意判断需使用旧的defect信息 + if (defectOld.reportLine < issue.defect.reportLine || + (defectOld.reportLine === issue.defect.reportLine && defectOldEndCol < issue.defect.reportColumn)) { + continue; + } + // 2、当前告警区域跟修复区域有重叠,不进行修复,直接删除该issue。TODO:该操作会导致重叠告警漏报,后续优化 + if (defectOld.reportLine === issue.defect.reportLine && + ((issue.defect.reportColumn < defectOld.reportColumn && defectOld.reportColumn < fixEndCol) || + (issue.defect.reportColumn < defectOldEndCol && defectOldEndCol < fixEndCol))) { + logger.warn(`The current defect area overlaps with the repair area, delete the defect, fixKey = ${defectOld.fixKey}`); + remainIssues.splice(i, 1); + remainIssuesOld.splice(i, 1); + i--; + continue; + } + // 注意行列号的累加需使用新的defect信息进行叠加 + const defectNew = remainIssues[i].defect; + // 更新行号 + defectNew.reportLine += subLine; + defectNew.fixKey = defectNew.fixKey.replace(/^[^%]*/, `${defectNew.reportLine}`); + defectNew.mergeKey = defectNew.mergeKey.replace(/%(.*?)%/, `%${defectNew.fixKey}%`); + // 更新列号, 当前告警跟修复issue在同一行,且在修复issue之后,需要进行列偏移 + if (defectOld.reportLine === issue.defect.reportLine) { + const splitText = fix.text.split(eof); + let endCol = 0; + if (splitText.length > 1) { + // 单行改多行,则偏移后的列号 = fixCode最后一行的长度 + 修复之前两个告警的间隔差值subCol + const subCol = defectNew.reportColumn - fixEndCol; + const colLen = Number.parseInt(defectNew.fixKey.split('%')[2]) - defectNew.reportColumn; + defectNew.reportColumn = splitText[splitText.length - 1].length + subCol; + endCol = defectNew.reportColumn + colLen; + } else { + // 单行改单行,则偏移后的列号 = 当前列号 + 修复后的列差(fixCode的长度 - 被替换的文本长度) + const subCol = fix.text.length - (end - start); + defectNew.reportColumn += subCol; + endCol = Number.parseInt(defectNew.fixKey.split('%')[2]) + subCol; + } + defectNew.fixKey = `${defectNew.reportLine}%${defectNew.reportColumn}%${endCol}%${defectNew.ruleId}`; + defectNew.mergeKey = defectNew.mergeKey.replace(/%(.*?)%/, `%${defectNew.fixKey}%`); + } + } + } +} diff --git a/ets2panda/linter/homecheck/src/codeFix/engines/HomeCheckFixEngine.ts b/ets2panda/linter/homecheck/src/codeFix/engines/HomeCheckFixEngine.ts new file mode 100644 index 0000000000000000000000000000000000000000..51268a1bc49038d967f3faf099be85168670ecb3 --- /dev/null +++ b/ets2panda/linter/homecheck/src/codeFix/engines/HomeCheckFixEngine.ts @@ -0,0 +1,81 @@ +/* + * 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 { ArkFile, SourceFilePrinter } from 'arkanalyzer'; +import { FileReports, IssueReport } from '../../model/Defects'; +import { Engine } from '../../model/Engine'; +import { FunctionFix } from '../../model/Fix'; +import path from 'path'; +// @ts-ignore +import { removeSync } from 'fs-extra'; +import { FileUtils, WriteFileMode } from '../../utils/common/FileUtils'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { FixUtils } from '../../utils/common/FixUtils'; + +const FIX_OUTPUT_DIR = './fixedCode'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'HomeCheckFixEngine'); + +export class HomeCheckFixEngine implements Engine { + + constructor() { + removeSync(FIX_OUTPUT_DIR); + } + + applyFix(arkFile: ArkFile, issues: IssueReport[]): FileReports { + let fixPath = ''; + const remainIssues: IssueReport[] = []; + for (let issue of issues) { + let fix = issue.fix; + if (fix === undefined) { + remainIssues.push(issue); + continue; + } + if (!FixUtils.isFunctionFix(fix)) { + remainIssues.push(issue); + continue; + } + let functionFix = fix as FunctionFix; + if (!issue.defect.fixable) { + remainIssues.push(issue); + continue; + } + if (!functionFix.fix(arkFile, issue.defect.fixKey)) { + remainIssues.push(issue); + continue; + } + fixPath = path.join(FIX_OUTPUT_DIR, arkFile.getName() + '.fix'); + if (this.arkFileToFile(arkFile, fixPath)) { + functionFix.fixed = true; + break; + } + } + return { defects: remainIssues.map((issue => issue.defect)), output: '', filePath: fixPath }; + } + + private arkFileToFile(arkFile: ArkFile, outputPath: string): boolean { + if (!arkFile) { + return false; + } + const printer = new SourceFilePrinter(arkFile); + try { + FileUtils.writeToFile(outputPath, printer.dump(), WriteFileMode.OVERWRITE); + return true; + } catch (e) { + logger.error(e); + return false; + } + } +} diff --git a/ets2panda/linter/homecheck/src/matcher/Matchers.ts b/ets2panda/linter/homecheck/src/matcher/Matchers.ts new file mode 100644 index 0000000000000000000000000000000000000000..2a651d2d1f5fa28306aeacf633399d1721943bcb --- /dev/null +++ b/ets2panda/linter/homecheck/src/matcher/Matchers.ts @@ -0,0 +1,227 @@ +/* + * 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. + */ + +import { ArkField, ArkFile, ArkMethod, ArkNamespace, Scene } from 'arkanalyzer'; +import { ArkClass, ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; + +export enum MethodCategory { + Accessor = 0, + ArrowFunction = 1, + FunctionExpression = 2, + Constructor = 3 +} + +export enum MatcherTypes { + FILE = 0, + NAMESPACE = 1, + CLASS = 2, + METHOD = 3, + FIELD = 4, + EXPR = 5 +} + +export interface BaseMatcher { + [matchFieldName: string]: any; +} + +//TODO: move to FileMatcher.ts +export interface FileMatcher extends BaseMatcher { + readonly matcherType: MatcherTypes.FILE; + name?: string; +} + +export interface NamespaceMatcher extends BaseMatcher { + readonly matcherType: MatcherTypes.NAMESPACE; + name?: string[]; + file?: (FileMatcher | ArkFile)[]; + namespace?: (NamespaceMatcher | ArkNamespace)[]; + isExport?: boolean; +} + +export interface ClassMatcher extends BaseMatcher { + readonly matcherType: MatcherTypes.CLASS; + name?: string[]; + file?: (FileMatcher | ArkFile)[]; + namespace?: (NamespaceMatcher | ArkNamespace)[]; + category?: ClassCategory[]; + isAbstract?: boolean; + isExport?: boolean; + extends?: (ClassMatcher | ArkClass)[]; + implements?: (ClassMatcher | ArkClass)[]; + hasViewTree?: boolean; +} + +export interface MethodMatcher extends BaseMatcher { + readonly matcherType: MatcherTypes.METHOD; + name?: string[]; + file?: (FileMatcher | ArkFile)[]; + namespace?: (NamespaceMatcher | ArkNamespace)[]; + class?: (ClassMatcher | ArkClass)[]; + category?: MethodCategory[]; + decorators?: string[]; + isStatic?: boolean; + isExport?: boolean; + isPublic?: boolean; + isPrivate?: boolean; + isProtected?: boolean; + isAbstract?: boolean; + hasViewTree?: boolean; + isAnonymous?: boolean; +} + +export interface FieldMatcher extends BaseMatcher { + readonly matcherType: MatcherTypes.FIELD; + name?: string[]; + file?: (FileMatcher | ArkFile)[]; + namespace?: (NamespaceMatcher | ArkNamespace)[]; + class?: (ClassMatcher | ArkClass)[]; + decorators?: string[]; + isStatic?: boolean; + isPublic?: boolean; + isPrivate?: boolean; + isProtected?: boolean; + isReadonly?: boolean; +} + +export interface MatcherCallback { + matcher: BaseMatcher | undefined, + callback: Function +} + +export function isMatchedFile(arkFile: ArkFile, matchers: (FileMatcher | ArkFile)[]): boolean { + for (const fileMatcher of matchers) { + if (fileMatcher instanceof ArkFile) { + if (arkFile === fileMatcher) { + return true; + } + } else { + if (fileMatcher.name && arkFile.getName() !== fileMatcher.name) { + continue; + } + return true; + } + } + return false; +} + +export function isMatchedNamespace(arkNs: ArkNamespace | null | undefined, matchers: (NamespaceMatcher | ArkNamespace)[]): boolean { + if (!arkNs) { + return false; + } + + for (const nsMatcher of matchers) { + if (nsMatcher instanceof ArkNamespace) { + if (arkNs === nsMatcher) { + return true; + } + } else { + if (nsMatcher.file && !isMatchedFile(arkNs.getDeclaringArkFile(), nsMatcher.file) || + nsMatcher.namespace && !isMatchedNamespace(arkNs.getDeclaringArkNamespace(), nsMatcher.namespace) || + nsMatcher.name && !nsMatcher.name.includes(arkNs.getName()) || + nsMatcher.isExported !== undefined && nsMatcher.isExported !== arkNs.isExport()) { + continue; + } + // todo: 未考虑嵌套ns场景 + return true; + } + } + return false; +} + +export function isMatchedClass(arkClass: ArkClass | null | undefined, matchers: (ClassMatcher | ArkClass)[]): boolean { + if (!arkClass) { + return false; + } + for (const classMatcher of matchers) { + if (classMatcher instanceof ArkClass) { + if (arkClass === classMatcher) { + return true; + } + } else { + if (classMatcher.file && !isMatchedFile(arkClass.getDeclaringArkFile(), classMatcher.file) || + classMatcher.namespace && !isMatchedNamespace(arkClass.getDeclaringArkNamespace(), classMatcher.namespace) || + classMatcher.name && !classMatcher.name.includes(arkClass.getName()) || + classMatcher.category && !classMatcher.category.includes(arkClass.getCategory()) || + classMatcher.isAbstract !== undefined && classMatcher.isAbstract !== arkClass.isAbstract() || + classMatcher.isExport !== undefined && classMatcher.isExport !== arkClass.isExport() || + classMatcher.hasViewTree !== undefined && classMatcher.hasViewTree !== arkClass.hasViewTree() || + // classMatcher.implements && !isMatchedClass(arkClass.getImplementedInterfaces(), classMatcher.implements) || + classMatcher.extends && !isMatchedClass(arkClass.getSuperClass(), classMatcher.extends)) { + continue; + } + return true; + } + } + return false; +} + +export function isMatchedMethod(arkMethod: ArkMethod | null | undefined, matchers: (MethodMatcher | ArkMethod)[]): boolean { + if (!arkMethod) { + return false; + } + for (const mtdMatcher of matchers) { + if (mtdMatcher instanceof ArkMethod) { + if (mtdMatcher === arkMethod) { + return true; + } + } else { + if (mtdMatcher.file && !isMatchedFile(arkMethod.getDeclaringArkFile(), mtdMatcher.file) || + mtdMatcher.namespace && !isMatchedNamespace(arkMethod.getDeclaringArkClass().getDeclaringArkNamespace(), mtdMatcher.namespace) || + mtdMatcher.class && !isMatchedClass(arkMethod.getDeclaringArkClass(), mtdMatcher.class) || + // mtdMatcher.category && !mtdMatcher.category.includes(arkMethod.getCategory()) || + mtdMatcher.isAnonymous && !arkMethod.isAnonymousMethod() || + mtdMatcher.name && !mtdMatcher.name.includes(arkMethod.getName()) || + mtdMatcher.decorators && !arkMethod.getDecorators().some(d => mtdMatcher.decorators!.includes(d.getKind())) || + mtdMatcher.isStatic !== undefined && mtdMatcher.isStatic !== arkMethod.isStatic() || + mtdMatcher.isExport !== undefined && mtdMatcher.isExport !== arkMethod.isExport() || + mtdMatcher.isPublic !== undefined && mtdMatcher.isPublic !== arkMethod.isPublic() || + mtdMatcher.isPrivate !== undefined && mtdMatcher.isPrivate !== arkMethod.isPrivate() || + mtdMatcher.isProtected !== undefined && mtdMatcher.isProtected !== arkMethod.isProtected() || + mtdMatcher.hasViewTree !== undefined && mtdMatcher.hasViewTree !== arkMethod.hasViewTree() || + mtdMatcher.isAbstract !== undefined && mtdMatcher.isAbstract !== arkMethod.isAbstract()) { + continue; + } + return true; + } + } + return false; +} + +export function isMatchedField(arkField: ArkField | null | undefined, matchers: (FieldMatcher | ArkField)[]): boolean { + if (!arkField) { + return false; + } + for (const fieldMatcher of matchers) { + if (fieldMatcher instanceof ArkField) { + if (fieldMatcher === arkField) { + return true; + } + } else { + if (fieldMatcher.file && !isMatchedFile(arkField.getDeclaringArkClass().getDeclaringArkFile(), fieldMatcher.file) || + fieldMatcher.namespace && !isMatchedNamespace(arkField.getDeclaringArkClass().getDeclaringArkNamespace(), fieldMatcher.namespace) || + fieldMatcher.class && !isMatchedClass(arkField.getDeclaringArkClass(), fieldMatcher.class) || + fieldMatcher.name && !fieldMatcher.name.includes(arkField.getName()) || + fieldMatcher.decorators && !arkField.getDecorators().some(d => fieldMatcher.decorators!.includes(d.getKind())) || + fieldMatcher.isStatic !== undefined && fieldMatcher.isStatic !== arkField.isStatic() || + fieldMatcher.isPublic !== undefined && fieldMatcher.isPublic !== arkField.isPublic() || + fieldMatcher.isPrivate !== undefined && fieldMatcher.isPrivate !== arkField.isPrivate() || + fieldMatcher.isProtected !== undefined && fieldMatcher.isProtected !== arkField.isProtected()) { + continue; + } + return true; + } + } + return false; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts new file mode 100644 index 0000000000000000000000000000000000000000..1e1565a7c11baa8e3724136b4dbf4440a6161f89 --- /dev/null +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchClass.ts @@ -0,0 +1,40 @@ +/* + * 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. + */ + +import { ArkClass, ArkFile } from 'arkanalyzer'; +import { ClassMatcher, isMatchedFile, isMatchedNamespace, isMatchedClass } from '../Matchers'; + +export function matchClass(arkFiles: ArkFile[], matcher: ClassMatcher, callback: Function): void { + for (let arkFile of arkFiles) { + if (matcher.file && !isMatchedFile(arkFile, matcher.file)) { + continue; + } + for (const ns of arkFile.getAllNamespacesUnderThisFile()) { + if (matcher.namespace && !isMatchedNamespace(ns, matcher.namespace)) { + continue; + } + matchClassProcess(matcher, ns.getClasses(), callback); + } + matchClassProcess(matcher, arkFile.getClasses(), callback); + } +} + +function matchClassProcess(matcher: ClassMatcher, classes: ArkClass[], callback: Function): void { + for (const arkClass of classes) { + if (isMatchedClass(arkClass, [matcher])) { + callback(arkClass); + } + } +} diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts new file mode 100644 index 0000000000000000000000000000000000000000..f42fd5d7031c4764bedf8cb9a7d68bfc4606cf79 --- /dev/null +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFields.ts @@ -0,0 +1,46 @@ +/* + * 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. + */ + +import { ArkClass, ArkFile } from 'arkanalyzer'; +import { isMatchedFile, isMatchedNamespace, isMatchedClass, FieldMatcher, isMatchedField } from '../Matchers'; + + +export function matchFields(arkFiles: ArkFile[], matcher: FieldMatcher, callback: Function): void { + for (let arkFile of arkFiles) { + if (matcher.file && !isMatchedFile(arkFile, matcher.file)) { + continue; + } + for (const ns of arkFile.getAllNamespacesUnderThisFile()) { + if (matcher.namespace && !isMatchedNamespace(ns, matcher.namespace)) { + continue; + } + matchFieldsInClasses(matcher, ns.getClasses(), callback); + } + matchFieldsInClasses(matcher, arkFile.getClasses(), callback); + } +} + +function matchFieldsInClasses(matcher: FieldMatcher, classes: ArkClass[], callback: Function): void { + for (const arkClass of classes) { + if (matcher.class && !isMatchedClass(arkClass, matcher.class)) { + continue; + } + for (const arkField of arkClass.getFields()) { + if (isMatchedField(arkField, [matcher])) { + callback(arkField); + } + } + } +} diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts new file mode 100644 index 0000000000000000000000000000000000000000..560fa54470b8a7becc532bc7b8d19410ad9aad55 --- /dev/null +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchFiles.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +import { ArkFile } from 'arkanalyzer'; +import { FileMatcher, isMatchedFile } from '../Matchers'; + +export function matchFiles(arkFiles: ArkFile[], matcher: FileMatcher, callback: Function): void { + for (let arkFile of arkFiles) { + if (isMatchedFile(arkFile, [matcher])) { + callback(arkFile); + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchMethods.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchMethods.ts new file mode 100644 index 0000000000000000000000000000000000000000..de9b782bf6365e0d42dfc6a1b67e9b18bb2df2e5 --- /dev/null +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchMethods.ts @@ -0,0 +1,46 @@ +/* + * 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. + */ + +import { ArkClass, ArkFile } from 'arkanalyzer'; +import { MethodMatcher, isMatchedFile, isMatchedNamespace, isMatchedClass, isMatchedMethod } from '../Matchers'; + + +export function matchMethods(arkFiles: ArkFile[], matcher: MethodMatcher, callback: Function): void { + for (let arkFile of arkFiles) { + if (matcher.file && !isMatchedFile(arkFile, matcher.file)) { + continue; + } + for (const ns of arkFile.getAllNamespacesUnderThisFile()) { + if (matcher.namespace && !isMatchedNamespace(ns, matcher.namespace)) { + continue; + } + matchMethodsInClasses(matcher, ns.getClasses(), callback); + } + matchMethodsInClasses(matcher, arkFile.getClasses(), callback); + } +} + +function matchMethodsInClasses(matcher: MethodMatcher, classes: ArkClass[], callback: Function): void { + for (const arkClass of classes) { + if (matcher.class && !isMatchedClass(arkClass, matcher.class)) { + continue; + } + for (const arkMethod of arkClass.getMethods(true)) { + if (isMatchedMethod(arkMethod, [matcher])) { + callback(arkMethod); + } + } + } +} diff --git a/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts new file mode 100644 index 0000000000000000000000000000000000000000..82b42d2ad657e52a7fed48627ea98a31605c8321 --- /dev/null +++ b/ets2panda/linter/homecheck/src/matcher/matcherAdapter/matchNameSpaces.ts @@ -0,0 +1,30 @@ +/* + * 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. + */ + +import { ArkFile } from 'arkanalyzer'; +import { NamespaceMatcher, isMatchedFile, isMatchedNamespace } from '../Matchers'; + +export function matchNameSpaces(arkFiles: ArkFile[], matcher: NamespaceMatcher, callback: Function): void { + for (let arkFile of arkFiles) { + if (matcher.file && !isMatchedFile(arkFile, matcher.file)) { + continue; + } + for (const ns of arkFile.getAllNamespacesUnderThisFile()) { + if (isMatchedNamespace(ns, [matcher])) { + callback(ns); + } + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/Defects.ts b/ets2panda/linter/homecheck/src/model/Defects.ts new file mode 100644 index 0000000000000000000000000000000000000000..cf38e10affcba61e4b4bc93e7b8e9d6ee4d606f9 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/Defects.ts @@ -0,0 +1,74 @@ +/* + * 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. + */ +import { AIFix, FunctionFix, RuleFix } from './Fix'; + +export const engine = { + engineName: '' +}; + +export class Defects { + reportLine: number; + reportColumn: number; + problem: string = ''; + description: string = ''; + severity: number = -1; // 0:info, 1:warning, 2:error + ruleId: string = '@perforce/'; + mergeKey: string = ''; // 文件路径%行号%开始列号%结束列号%规则%规则描述 + ruleDocPath: string = 'doc/.md'; + disabled: boolean = true; + checked: boolean = false; + fixable: boolean = false; // 是否可以修复 + fixKey: string = ''; // 行号%开始列号%结束列号%规则id + showIgnoreIcon: boolean = true; + engineName: string = engine.engineName; + + constructor(reportLine: number, reportColumn: number, endColumn: number, problem: string, description: string, severity: number, ruleId: string, + filePath: string, ruleDocPath: string, disabled: boolean, checked: boolean, fixable: boolean, showIgnoreIcon: boolean = true) { + this.reportLine = reportLine; + this.reportColumn = reportColumn; + this.problem = problem; + this.description = description; + this.severity = severity; + this.ruleId = ruleId; + this.fixKey = this.reportLine + '%' + this.reportColumn + '%' + endColumn + '%' + this.ruleId; + this.mergeKey = filePath + '%' + this.fixKey + '%' + this.description; + this.ruleDocPath = ruleDocPath; + this.disabled = disabled; + this.checked = checked; + this.fixable = fixable; + this.showIgnoreIcon = showIgnoreIcon; + } +} + +export class IssueReport { + defect: Defects; + fix: RuleFix | FunctionFix | AIFix | undefined; + + constructor(defect: Defects, fix: RuleFix | FunctionFix | AIFix | undefined) { + this.defect = defect; + this.fix = fix; + } +} + +export interface FileIssues { + filePath: string; + issues: IssueReport[]; +} + +export interface FileReports { + filePath: string; + defects: Defects[]; + output?: string; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/Engine.ts b/ets2panda/linter/homecheck/src/model/Engine.ts new file mode 100644 index 0000000000000000000000000000000000000000..7231f9faddc7e846b7534a4299e4bcb289c4adf8 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/Engine.ts @@ -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. + */ + +import { ArkFile } from 'arkanalyzer'; +import { FileReports, IssueReport } from './Defects'; + +export interface Engine { + /** + * 首次调用修复引擎时会调用,不同引擎的后续修复,可以内部单独实现 + * @param arkFile + * @param fixIssues 需要修复的issues列表 + * @param remainIssues 剩余issues列表 + * @returns FileReports + */ + applyFix(arkFile: ArkFile, fixIssues: IssueReport[], remainIssues: IssueReport[]): FileReports +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/File2Check.ts b/ets2panda/linter/homecheck/src/model/File2Check.ts new file mode 100644 index 0000000000000000000000000000000000000000..ecfc86270a7f9738fe6afd6ca45319a27f073504 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/File2Check.ts @@ -0,0 +1,118 @@ +/* + * 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. + */ +import { ArkFile } from 'arkanalyzer'; +import { BaseChecker } from '../checker/BaseChecker'; +import { MatcherTypes } from '../matcher/Matchers'; +import { matchFiles } from '../matcher/matcherAdapter/matchFiles'; +import { matchNameSpaces } from '../matcher/matcherAdapter/matchNameSpaces'; +import { matchClass } from '../matcher/matcherAdapter/matchClass'; +import { matchMethods } from '../matcher/matcherAdapter/matchMethods'; +import { matchFields } from '../matcher/matcherAdapter/matchFields'; +import { FileUtils } from '../utils/common/FileUtils'; +import { filterDisableIssue } from '../utils/common/Disable'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { IssueReport } from './Defects'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'File2Check'); + +export class File2Check { + public arkFile: ArkFile; + public enabledRuleCheckerMap: Map = new Map(); // TODO: key改为枚举 + public issues: IssueReport[] = []; + + private flMatcherMap = new Map(); + private nsMatcherMap = new Map(); + private clsMatcherMap = new Map(); + private mtdMatcherMap = new Map(); + private fieldMatcherMap = new Map(); + + constructor() {} + + public addChecker(ruleId: string, checker: BaseChecker): void { + this.enabledRuleCheckerMap.set(ruleId, checker); + } + + public collectMatcherCallbacks(): void { + this.enabledRuleCheckerMap.forEach(checker => { + const matcherCallbacks = checker.registerMatchers(); + matcherCallbacks.forEach(obj => { + const matcher = obj.matcher; + const callback = obj.callback; + switch (matcher?.matcherType) { + case MatcherTypes.FILE: + this.flMatcherMap.set(matcher, callback); + break; + case MatcherTypes.NAMESPACE: + this.nsMatcherMap.set(matcher, callback); + break; + case MatcherTypes.CLASS: + this.clsMatcherMap.set(matcher, callback); + break; + case MatcherTypes.METHOD: + this.mtdMatcherMap.set(matcher, callback); + break; + case MatcherTypes.FIELD: + this.fieldMatcherMap.set(matcher, callback); + break; + } + }); + }); + } + + public async emitCheck(): Promise { + this.flMatcherMap.forEach((callback, matcher) => { + matchFiles([this.arkFile], matcher, callback); + }); + this.nsMatcherMap.forEach((callback, matcher) => { + matchNameSpaces([this.arkFile], matcher, callback); + }); + this.clsMatcherMap.forEach((callback, matcher) => { + matchClass([this.arkFile], matcher, callback); + }); + this.mtdMatcherMap.forEach((callback, matcher) => { + matchMethods([this.arkFile], matcher, callback); + }); + this.fieldMatcherMap.forEach((callback, matcher) => { + matchFields([this.arkFile], matcher, callback); + }); + } + + public collectIssues(): void { + this.enabledRuleCheckerMap.forEach((v, k) => { + this.issues.push( + ...v.issues?.reduce((acc, cur) => { + if (acc.some(item => item.defect.mergeKey === cur.defect.mergeKey)) { + logger.debug('Skip the repeated issue, please check. issue.mergeKey = ' + cur.defect.mergeKey); + } else { + acc.push(cur); + } + return acc; + }, [] as IssueReport[]) + ); + }); + } + + public async checkDisable(): Promise { + const fileLineList = await FileUtils.readLinesFromFile(this.arkFile.getFilePath()); + this.issues = await filterDisableIssue(fileLineList, this.issues, this.arkFile.getFilePath()); + } + + public async run(): Promise { + this.collectMatcherCallbacks(); + await this.emitCheck(); + this.collectIssues(); + await this.checkDisable(); + } +} diff --git a/ets2panda/linter/homecheck/src/model/Fix.ts b/ets2panda/linter/homecheck/src/model/Fix.ts new file mode 100644 index 0000000000000000000000000000000000000000..459037c22055f12a6572afd2066b1a6f5cfcea91 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/Fix.ts @@ -0,0 +1,55 @@ +/* + * 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. + */ + +export type Range = [number, number]; + +export class FixInfo { + fixed?: boolean = false; +} + +// eslint修复信息 +export class RuleFix extends FixInfo { + /** + * 被修复字符串的起始位置 + */ + range: Range; + /** + * 要替换的文本 + */ + text: string; +} + +// homecheck的修复信息 +export class FunctionFix extends FixInfo { + /** + * 修复方法,入参为ArkFile和fixkey + */ + fix: Function; +} + +// AI修复的信息 +export class AIFix extends FixInfo { + /** + * 提供给大模型的修复语义 + */ + text: string[]; +} + +export enum FixMode { + AST, + ARKFILE, + AI, + UNKNOWN +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/Interfaces.ts b/ets2panda/linter/homecheck/src/model/Interfaces.ts new file mode 100644 index 0000000000000000000000000000000000000000..e357b58377cdcbf623ec90fd985655ab183cec03 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/Interfaces.ts @@ -0,0 +1,35 @@ +/* + * 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. + */ + +export interface ImageInfo { + width: number; + height: number; + type?: string; +} + +export type ImagesInfo = { + images?: ImageInfo[] +} & ImageInfo; + +export interface ImageData { + validate: (intput: Uint8Array) => boolean; + calculate: (input: Uint8Array, filepath?: string) => ImagesInfo; +} + +export interface IAttributes { + width: number | null; + height: number | null; + viewbox?: IAttributes | null; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/Message.ts b/ets2panda/linter/homecheck/src/model/Message.ts new file mode 100644 index 0000000000000000000000000000000000000000..b5591503548528c18b047f6454638fa84c9794ee --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/Message.ts @@ -0,0 +1,77 @@ +/* + * 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. + */ +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { FileReports } from './Defects'; +import { GeneratingJsonFile } from '../utils/common/GeneratingJsonFile'; +import path from 'path'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Message'); + +export interface Message { + sendResult(fileReports: FileReports[], reportDir?: string): void; + messageNotify(messageLevel: MessageType, msg: string): void; + progressNotify(progress: number, msg: string): void; +} + +export class DefaultMessage implements Message { + /** + * 发送消息 + * + * @param msg 要发送的消息内容 + */ + async sendResult(fileReports: FileReports[], reportDir?: string | undefined): Promise { + if (reportDir && reportDir.length !== 0) { + GeneratingJsonFile.generatingJsonFile(path.resolve(reportDir, 'issuesReport.json'), fileReports); + } else { + process.stdout.write(JSON.stringify(fileReports)); + } + } + + + /** + * 消息通知函数 + * + * @param messageLevel 消息类型,类型为MessageType枚举 + * @param msg 消息内容,类型为字符串 + */ + messageNotify(messageLevel: MessageType, msg: string): void { + logger.error(JSON.stringify(msg)); + return; + } + + + /** + * 通知进度更新 + * + * @param progress 进度值,取值范围为 0 到 1 之间 + * @param msg 与进度相关的消息 + */ + progressNotify(progress: number, msg: string): void { + const checkPercent = Math.floor(progress * 100); + if (checkPercent % 20 === 0) { + logger.info(`===== progress: ${checkPercent}% ======`); + } + } +} + +/** + * 告警消息类型 + */ +export enum MessageType { + BASE_ERROR = 0, + CHECK_ERROR = -1, + CHECK_WARN = -2, + CHECK_INFO = -3 +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/NumberValue.ts b/ets2panda/linter/homecheck/src/model/NumberValue.ts new file mode 100644 index 0000000000000000000000000000000000000000..bf791036459c8a031ea5cea9d6b698ce0ae7938a --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/NumberValue.ts @@ -0,0 +1,29 @@ +/* + * 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. + */ +export class NumberValue { + value: number; + type: ValueType; + + constructor(value: number, type: ValueType) { + this.value = value; + this.type = type; + } +} + +export enum ValueType { + INT, + DOUBLE, + UNKNOWN +} diff --git a/ets2panda/linter/homecheck/src/model/Project2Check.ts b/ets2panda/linter/homecheck/src/model/Project2Check.ts new file mode 100644 index 0000000000000000000000000000000000000000..3e9c1bf9ed811aeca8b3a79474ba520156a057d6 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/Project2Check.ts @@ -0,0 +1,185 @@ +/* + * 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. + */ + +import * as fs from 'fs'; +import { ArkFile } from 'arkanalyzer'; +import { BaseChecker } from '../checker/BaseChecker'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { MatcherTypes } from '../matcher/Matchers'; +import { matchFiles } from '../matcher/matcherAdapter/matchFiles'; +import { matchNameSpaces } from '../matcher/matcherAdapter/matchNameSpaces'; +import { matchClass } from '../matcher/matcherAdapter/matchClass'; +import { matchMethods } from '../matcher/matcherAdapter/matchMethods'; +import { matchFields } from '../matcher/matcherAdapter/matchFields'; +import { FileUtils } from '../utils/common/FileUtils'; +import { filterDisableIssue } from '../utils/common/Disable'; +import { IssueReport } from './Defects'; +import { Rule } from './Rule'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Project2Check'); + +export class Project2Check { + public arkFiles: ArkFile[]; + // TODO: key改为枚举 + public enabledRuleCheckerMap: Map = new Map(); + public issues: IssueReport[] = []; + public ruleMap: Map = new Map(); + + private sceneCallBacks: Function[] = []; + private flMatcherMap = new Map(); + private nsMatcherMap = new Map(); + private clsMatcherMap = new Map(); + private mtdMatcherMap = new Map(); + private fieldMatcherMap = new Map(); + + constructor() { + } + + public addChecker(ruleId: string, checker: BaseChecker): void { + this.enabledRuleCheckerMap.set(ruleId, checker); + } + + public collectMatcherCallbacks(): void { + this.enabledRuleCheckerMap.forEach(checker => { + const matcherCallbacks = checker.registerMatchers(); + matcherCallbacks.forEach(obj => { + const matcher = obj.matcher; + const callback = obj.callback; + if (!matcher) { + this.sceneCallBacks.push(callback); + return; + } + switch (matcher.matcherType) { + case MatcherTypes.FILE: + this.flMatcherMap.set(matcher, callback); + break; + case MatcherTypes.NAMESPACE: + this.nsMatcherMap.set(matcher, callback); + break; + case MatcherTypes.CLASS: + this.clsMatcherMap.set(matcher, callback); + break; + case MatcherTypes.METHOD: + this.mtdMatcherMap.set(matcher, callback); + break; + case MatcherTypes.FIELD: + this.fieldMatcherMap.set(matcher, callback); + break; + default: + break; + } + }); + }); + } + + public async emitCheck(): Promise { + await Promise.all(Array.from(this.enabledRuleCheckerMap.values()).map(checker => { + try { + this.processSceneCallbacks(); + this.flMatcherMap.forEach((callback, matcher) => { + matchFiles(this.arkFiles, matcher, callback); + }); + this.nsMatcherMap.forEach((callback, matcher) => { + matchNameSpaces(this.arkFiles, matcher, callback); + }); + this.clsMatcherMap.forEach((callback, matcher) => { + matchClass(this.arkFiles, matcher, callback); + }); + this.mtdMatcherMap.forEach((callback, matcher) => { + matchMethods(this.arkFiles, matcher, callback); + }); + this.fieldMatcherMap.forEach((callback, matcher) => { + matchFields(this.arkFiles, matcher, callback); + }); + } catch (error) { + logger.error(`Checker ${checker.rule.ruleId} error: `, error); + } + })); + } + + private processSceneCallbacks(): void { + try { + this.sceneCallBacks.forEach((callback) => { + if (this.arkFiles.length !== 0) { + callback(this.arkFiles[0].getScene()); + } + }); + } catch (error) { + logger.error(`Error in scene callbacks: `, error); + } + } + + public collectIssues(): void { + this.enabledRuleCheckerMap.forEach((v, k) => { + this.issues.push(...(v.issues?.reduce((acc, cur) => { + if (acc.some((item) => item.defect.mergeKey === cur.defect.mergeKey)) { + logger.debug('Skip the repeated issue, please check. issue.mergeKey = ' + cur.defect.mergeKey); + } else { + acc.push(cur); + } + return acc; + }, [] as IssueReport[]))); + }); + const issueMap: Map = new Map(); + this.issues.forEach(issue => { + issueMap.set(issue.defect.mergeKey, issue); + }); + const issueCopyMap = new Map(issueMap); + for (const [key, value] of issueCopyMap.entries()) { + const index = value.defect.mergeKey.indexOf('%' + value.defect.fixKey); + let filePath = ''; + if (index !== -1) { + filePath = value.defect.mergeKey.slice(0, index); + } + if (!this.ruleMap.has(filePath)) { + continue; + } + let rules = this.ruleMap.get(filePath); + if (!rules) { + continue; + } + let result = rules.find(rule => rule.ruleId === value.defect.ruleId); + if (!result) { + issueMap.delete(value.defect.mergeKey); + } else { + value.defect.severity = result.alert; + } + } + this.issues = Array.from(issueMap.values()); + } + + public async checkDisable(): Promise { + let filtedIssues: IssueReport[] = []; + for (const issue of this.issues) { + const filePath = issue.defect.mergeKey.split('%')[0]; + if (!fs.existsSync(filePath)) { + continue; + } + const fileLineList = await FileUtils.readLinesFromFile(filePath); + const filtedResult = await filterDisableIssue(fileLineList, [issue], filePath); + if (filtedResult.length > 0) { + filtedIssues = filtedIssues.concat(filtedResult[0]); + } + } + this.issues = filtedIssues; + } + + public async run(): Promise { + this.collectMatcherCallbacks(); + await this.emitCheck(); + this.collectIssues(); + await this.checkDisable(); + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/ProjectConfig.ts b/ets2panda/linter/homecheck/src/model/ProjectConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..7a5c7cbdfbd091e3c905e4c51099d5e2639f06c4 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/ProjectConfig.ts @@ -0,0 +1,78 @@ +/* + * 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. + */ + +import { LOG_LEVEL } from 'arkanalyzer'; +import { Language } from 'arkanalyzer/lib/core/model/ArkFile'; + +export class ProjectConfig { + projectName: string; + projectPath: string; + logPath: string; + ohosSdkPath: string; + hmsSdkPath: string; + checkPath: string; + apiVersion: number; + fix: string; + fixSelected: boolean; + npmPath: string; + npmInstallDir: string; + reportDir: string; + sdksThirdParty: string[]; + arkCheckPath: string; + product: string; + logLevel: LOG_LEVEL; + arkAnalyzerLogLevel: LOG_LEVEL; + + + // [filePath, languageTag] or [folderPath, languageTag] + languageTags: Map; + // [...filePaths, ...folderPaths] + fileOrFolderToCheck: string[]; + + constructor(config: any) { + this.projectName = config.projectName ?? ''; + this.projectPath = config.projectPath ?? ''; + this.logPath = config.logPath ?? ''; + this.ohosSdkPath = config.ohosSdkPath ?? ''; + this.hmsSdkPath = config.hmsSdkPath ?? ''; + this.checkPath = config.checkPath ?? ''; + this.apiVersion = config.sdkVersion ?? 14; + this.fix = config.fix ?? 'false'; + this.fixSelected = config.fixSelected ?? false; + this.npmPath = config.npmPath ? config.npmPath : 'npm'; + this.npmInstallDir = config.npmInstallDir ? config.npmInstallDir : './'; + this.reportDir = config.reportDir ? config.reportDir : './'; + this.sdksThirdParty = config.sdksThirdParty ?? []; + this.arkCheckPath = config.arkCheckPath ?? ''; + this.product = config.product ?? ''; + this.languageTags = config.languageTags ?? new Map(); + this.fileOrFolderToCheck = config.fileOrFolderToCheck ?? []; + this.logLevel = config.logLevel ?? LOG_LEVEL.INFO; + this.arkAnalyzerLogLevel = config.arkAnalyzerLogLevel ?? LOG_LEVEL.ERROR; + } +} + +export interface SelectedFileInfo { + filePath: string; + fixKey?: string[]; +} + +export class FileToCheck implements SelectedFileInfo { + public filePath: string; + + constructor(filePath: string) { + this.filePath = filePath; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/Rule.ts b/ets2panda/linter/homecheck/src/model/Rule.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0275c3c4f5aa0fa98b79efcbb5c1322d8e5fcb6 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/Rule.ts @@ -0,0 +1,42 @@ +/* + * 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. + */ + +export class Rule { + ruleId: string; + alert: ALERT_LEVEL; + allowExpressions: boolean; + ignoreRestArgs: boolean; + option: Object[] = []; + + constructor(ruleId: string, alert: ALERT_LEVEL = ALERT_LEVEL.SUGGESTION) { + this.ruleId = ruleId; + this.alert = alert; + this.allowExpressions = false; + this.ignoreRestArgs = false; + } +} + +export enum ALERT_LEVEL { + OFF = 0, + WARN = 1, + ERROR = 2, + SUGGESTION = 3, +} + +export interface ExtRuleSet { + ruleSetName: string; + packagePath: string; + extRules: object; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/RuleConfig.ts b/ets2panda/linter/homecheck/src/model/RuleConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..16d5f737aabb5d964ba070606d55113bd5cc95fc --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/RuleConfig.ts @@ -0,0 +1,56 @@ +/* + * 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. + */ + +import { GlobMatch } from '../utils/common/GlobMatch'; + +export class RuleConfig { + public files: GlobMatch; + public ignore: GlobMatch; + public rules: object; + public extRules: object; + public extRuleSet: object[]; + public ruleSet: string[]; + public overrides: RuleConfig[]; + + constructor(config: any) { + if (config.files && config.files.length > 0) { + this.files = new GlobMatch(config.files); + } else { + this.files = new GlobMatch(['**/*.ets']); + } + if (config.ignore) { + if (config.ignore.length > 0) { + this.ignore = new GlobMatch(config.ignore); + } + } else if (config.excluded && config.excluded.length > 0) { + this.ignore = new GlobMatch(config.excluded); + } + this.rules = config.rules ?? {}; + this.extRules = config.extRules ?? {}; + this.extRuleSet = config.extRuleSet ?? []; + this.ruleSet = config.ruleSet ?? []; + + if (config.overrides) { + let overrides: RuleConfig[] = []; + let overRuleConfigs = config.overrides; + overRuleConfigs.forEach((overRuleConfig: any) => { + overrides.push(new RuleConfig(overRuleConfig)); + }); + this.overrides = overrides; + } else { + this.overrides = []; + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/Scope.ts b/ets2panda/linter/homecheck/src/model/Scope.ts new file mode 100644 index 0000000000000000000000000000000000000000..3f4a98ca501dfcffe4505b3136a4bc7d4303b745 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/Scope.ts @@ -0,0 +1,61 @@ +/* + * 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. + */ +import { BasicBlock } from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { Variable } from './Variable'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Scope'); + +export enum TempLocation { + NOFOUND = 0, + LEFT, + RIGHT +} + +export enum ScopeType { + IF_TYPE = 0, + ELSE_TYPE, + FOR_CONDITION_TYPE, + FOR_IN_TYPE, + WHILE_TYPE, + CASE_TYPE, + UNKNOWN_TYPE = 10 +} + +export class Scope { + parentScope: Scope | null; + childScopeList: Array; + defList: Array; + blocks: Set; + scopeLevel: number; + scopeType: ScopeType; + + constructor(parent: Scope | null, defList: Array, level: number, type: ScopeType = ScopeType.UNKNOWN_TYPE) { + this.parentScope = parent; + this.childScopeList = new Array(); + this.defList = defList; + this.blocks = new Set(); + this.scopeLevel = level; + this.scopeType = type; + } + + public setChildScope(child: Scope): void { + this.childScopeList.push(child); + } + + public addVariable(variable: Variable): void { + this.defList.push(variable); + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/SparseArrayValue.ts b/ets2panda/linter/homecheck/src/model/SparseArrayValue.ts new file mode 100644 index 0000000000000000000000000000000000000000..16aa478599d5e30d70bc0f8a8a68124fdb7ab7d2 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/SparseArrayValue.ts @@ -0,0 +1,44 @@ +/* + * 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. + */ +export class SparseArrayValue { + + sparseArrayType: SparseArrayType; + baseStr: string; + valStr: string; + fulBaseStr: string; + fulStmtStr: string; + constructor(StmtType: SparseArrayType, baseStr: string, valStr: string) { + this.sparseArrayType = StmtType; + this.baseStr = baseStr; + this.valStr = valStr; + this.fulBaseStr = this.baseStr + this.valStr; + if (this.sparseArrayType === SparseArrayType.NEW_ARRAY) { + this.fulStmtStr = this.fulBaseStr + ')'; + } else if (this.sparseArrayType === SparseArrayType.ARRAY_RIGHT) { + this.fulStmtStr = this.fulBaseStr + ']'; + } else if (this.sparseArrayType === SparseArrayType.ARRAY_LEFT) { + this.fulStmtStr = this.fulBaseStr + ']'; + } else { + this.fulStmtStr = this.fulBaseStr; + } + } +} + +export enum SparseArrayType { + NEW_ARRAY, + ARRAY_RIGHT, + ARRAY_LEFT, + UNKNOWN +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/StmtExt.ts b/ets2panda/linter/homecheck/src/model/StmtExt.ts new file mode 100644 index 0000000000000000000000000000000000000000..4cc55501037629fd63a41598abdcc37125649c27 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/StmtExt.ts @@ -0,0 +1,23 @@ +/* + * 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. + */ +import { Stmt } from 'arkanalyzer'; +import { Scope } from './Scope'; + +export class StmtExt extends Stmt { + scope: Scope; + toString(): string { + return ''; + } +} diff --git a/ets2panda/linter/homecheck/src/model/VarInfo.ts b/ets2panda/linter/homecheck/src/model/VarInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..f0b4d33849310a857505d5c0182a2c9a1ffab711 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/VarInfo.ts @@ -0,0 +1,26 @@ +/* + * 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. + */ +import { Stmt } from 'arkanalyzer'; +import { Scope } from './Scope'; + +export class VarInfo { + stmt: Stmt; + scope: Scope; + + constructor(stmt: Stmt, scope: Scope) { + this.stmt = stmt; + this.scope = scope; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/model/Variable.ts b/ets2panda/linter/homecheck/src/model/Variable.ts new file mode 100644 index 0000000000000000000000000000000000000000..b9d4ea86e632918b0f7d07340036be436372a9b3 --- /dev/null +++ b/ets2panda/linter/homecheck/src/model/Variable.ts @@ -0,0 +1,32 @@ +/* + * 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. + */ +import { Local, Stmt } from 'arkanalyzer'; +import { VarInfo } from './VarInfo'; + +export class Variable { + defStmt: Stmt; + redefInfo: Set; + leftUsedInfo: Set; + + constructor(defStmt: Stmt) { + this.defStmt = defStmt; + this.redefInfo = new Set(); + this.leftUsedInfo = new Set(); + } + + public getName(): string { + return (this.defStmt.getDef() as Local).getName(); + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/run.ts b/ets2panda/linter/homecheck/src/run.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b468c10889e1cc3e97fb4438cfd4d9360d43208 --- /dev/null +++ b/ets2panda/linter/homecheck/src/run.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +import { run } from './Main'; + +run(); \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/runTool.ts b/ets2panda/linter/homecheck/src/runTool.ts new file mode 100644 index 0000000000000000000000000000000000000000..766a459f7cadb5ffa473cf4e64b1b84c97022c25 --- /dev/null +++ b/ets2panda/linter/homecheck/src/runTool.ts @@ -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. + */ + +import { ConfigUtils } from './utils/common/ConfigUtils'; +import { Utils } from './utils/common/Utils'; +import { MigrationTool } from './tools/migrationTool/MigrationTool'; + +async function run(): Promise { + const argvObj = Utils.parseCliOptions(process.argv); + const ruleConfig = ConfigUtils.getConfig(argvObj.configPath, argvObj.arkCheckPath); + const projectConfig = ConfigUtils.getConfig(argvObj.projectConfigPath); + if (!ruleConfig || !projectConfig) { + return false; + } + + const migrationTool = new MigrationTool(ruleConfig, projectConfig); + await migrationTool.buildCheckEntry(); + const result = await migrationTool.start(); + + return true; +}; + +run(); \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/tools/BuildModuleChains.ts b/ets2panda/linter/homecheck/src/tools/BuildModuleChains.ts new file mode 100644 index 0000000000000000000000000000000000000000..2d0d6ef9c4c1195c6d5bc428da92077487da6f5b --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/BuildModuleChains.ts @@ -0,0 +1,587 @@ +/* + * 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. + */ + +import { + AbstractFieldRef, ArkAssignStmt, ArkFile, ArkIfStmt, ArkInvokeStmt, ArkMethod, ArkNamespace, ArkNewExpr, + ArkNormalBinopExpr, ArkStaticInvokeExpr, ArkUnopExpr, ClassSignature, ClassType, DEFAULT_ARK_CLASS_NAME, + FunctionType, LocalSignature, MethodSignature, NamespaceSignature, Scene, Signature, TEMP_LOCAL_PREFIX, Value, + transfer2UnixPath +} from 'arkanalyzer'; +import { ArkClass, ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import { ExportSignature } from 'arkanalyzer/lib/core/model/ArkExport'; +import { Local } from 'arkanalyzer/lib/core/base/Local'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import path from 'path'; +import { FileUtils, WriteFileMode } from '../utils/common/FileUtils'; + +const OUTPUT_DIR_PATH = './ModuleChains'; +const FILE_NAME_CHAINS_JSON = 'ModuleChains.json'; +const FILE_NAME_FILE_ID_MAP = 'FileIdMap.json'; +const FILE_NAME_CHAINS_TXT = 'ModuleChains.txt'; +const logger = Logger.getLogger(LOG_MODULE_TYPE.TOOL, 'BuildModuleChains'); + +type ModuleSignature = ExportSignature | string; +const gFinishScanMap = new Map(); +const gNodeMap: Map = new Map(); +const gModuleIdMap: Map = new Map(); +const repeatFilePath: string[] = []; +let gOutPutDirPath: string = OUTPUT_DIR_PATH; +let gIsSkipSdk = true; + +let gOutStorage = ''; +let gOutNum = 0; + +interface NodeInfo { + filePath: string; + name: string; + type: number; + line: number; +} + +export function buildModuleChains(scene: Scene, arkFiles: ArkFile[], outputDirPath: string): boolean { + let fileNameFlag = ''; + if (outputDirPath.length !== 0) { + gOutPutDirPath = outputDirPath; + } + if (arkFiles.length === 0) { + fileNameFlag = 'allFiles'; + arkFiles = scene.getFiles(); + } else { + fileNameFlag = arkFiles[0].getName(); + } + let isOutput = false; + for (const arkFile of arkFiles) { + const busyArray = new Array(); + fileProcess(arkFile, busyArray); + } + logger.debug('Scan completed, start to write file...'); + isOutput = genResultForJson(scene, fileNameFlag); + clearGlobalMem(); + return isOutput; +} + +function clearGlobalMem(): void { + gFinishScanMap.clear(); + gNodeMap.clear(); + gModuleIdMap.clear(); + repeatFilePath.length = 0; + gOutStorage = ''; + gOutNum = 0; +} + +function genResultForJson(scene: Scene, fileName: string): boolean { + for (const [module] of gFinishScanMap) { + if (typeof module === 'string') { + const uniqueId = genUniqueId(); + genJsonNode(scene, module, uniqueId); + } + } + return outputNodeList(fileName.replace(/[\\/]/g, '_')); +} + +function genUniqueId(): string { + return Math.random().toString(36).substring(2); +} + +function genJsonNode(scene: Scene, module: ModuleSignature, uniqueId: string): void { + const nodeInfo = genNodeInfo(scene, module); + if (nodeInfo) { + gNodeMap.set(uniqueId, { nodeInfo: nodeInfo, nextNodes: [] }); + gModuleIdMap.set(module, uniqueId); + } else { + logger.warn(`create nodeInfo failed!`); + } + + let nextNodeList = gFinishScanMap.get(module); + if (!nextNodeList) { + return; + } + + for (const nextNode of nextNodeList) { + let nextUniqueId = gModuleIdMap.get(nextNode); + if (nextUniqueId) { + gNodeMap.get(uniqueId)?.nextNodes.push(nextUniqueId); + } else { + nextUniqueId = genUniqueId(); + gNodeMap.get(uniqueId)?.nextNodes.push(nextUniqueId); + genJsonNode(scene, nextNode, nextUniqueId); + } + } +} + +function classTypeToString(scene: Scene, classSign: ClassSignature): string { + const type = scene.getClass(classSign)?.getCategory(); + switch (type) { + case ClassCategory.CLASS: + return 'class'; + case ClassCategory.STRUCT: + return 'struct'; + case ClassCategory.INTERFACE: + return 'interface'; + case ClassCategory.ENUM: + return 'enum'; + case ClassCategory.TYPE_LITERAL: + return 'literal'; + case ClassCategory.OBJECT: + return 'object'; + default: + return ''; + } +} + +enum NodeType { + FILE = 0, + NAMESPACE, + CLASS, + STRUCT, + INTERFACE, + ENUM, + TYPE_LITERAL, + OBJECT, + FUNCTION, + VARIABLE +} + +function genNodeInfo(scene: Scene, module: ModuleSignature): NodeInfo | null { + let nodeInfo: NodeInfo | null = null; + if (module instanceof ClassSignature) { + const type = scene.getClass(module)?.getCategory(); + nodeInfo = { + filePath: module.getDeclaringFileSignature().getFileName(), + name: module.getClassName(), + // 底座ArkClass的枚举值差2 + type: (type !== undefined) ? type + 2 : -1, + line: -1 + }; + } else if (module instanceof MethodSignature) { + let className = module.getDeclaringClassSignature()?.getClassName(); + if (className === DEFAULT_ARK_CLASS_NAME) { + className = module.getDeclaringClassSignature().getDeclaringNamespaceSignature()?.getNamespaceName() ?? ''; + } + let methodName = module.getMethodSubSignature().getMethodName(); + const methodLine = scene.getMethod(module)?.getLine(); + let curLine: number = -1; + if (methodLine) { + curLine = methodLine; + } + methodName = className.length > 0 ? `${className}.${methodName}` : methodName; + nodeInfo = { + filePath: module.getDeclaringClassSignature()?.getDeclaringFileSignature().getFileName(), + name: methodName, + type: NodeType.FUNCTION, + line: curLine + }; + } else if (module instanceof NamespaceSignature) { + nodeInfo = { + filePath: module.getDeclaringFileSignature().getFileName(), + name: module.getNamespaceName(), + type: NodeType.NAMESPACE, + line: -1 + }; + } else if (module instanceof LocalSignature) { + const fileSign = module.getDeclaringMethodSignature().getDeclaringClassSignature().getDeclaringFileSignature(); + const methodLine = scene.getMethod(module.getDeclaringMethodSignature())?.getLine(); + let curLine: number = -1; + if (methodLine) { + curLine = methodLine; + } + nodeInfo = { + filePath: fileSign.getFileName() ?? '', + name: module.getName(), + type: NodeType.VARIABLE, + line: curLine + }; + } else if (typeof module === 'string') { + nodeInfo = { + filePath: module, + name: path.basename(module), + type: NodeType.FILE, + line: -1 + }; + } + return nodeInfo; +} + +function genResultForChains(arkFile: ArkFile): boolean { + for (const [module] of gFinishScanMap) { + if (typeof (module) === 'string' && module.includes(arkFile.getFileSignature().getFileName().replace(/\//g, '\\'))) { + genChain(module); + } + } + if (gOutStorage.length > 0 && outputStorage()) { + logger.info(gOutStorage.length + ' chains have been written to the file.'); + return true; + } + return false; +} + +function genChain(module: ModuleSignature, headChain: string = ''): void { + const nextNodes = gFinishScanMap.get(module); + if (nextNodes) { + for (const nextNode of nextNodes) { + genChain(nextNode, headChain + module.toString().replace(`/${DEFAULT_ARK_CLASS_NAME}./g`, '') + '\n>>'); + } + } else { + gOutStorage += headChain + module.toString().replace(`/${DEFAULT_ARK_CLASS_NAME}./g`, '') + '\n'; + gOutNum++; + if (gOutNum >= 1000 && outputStorage()) { + gOutStorage = ''; + gOutNum = 0; + } + } +} + +function fileProcess(arkFile: ArkFile, busyArray: Array): void { + const filePath = path.join('@' + arkFile.getProjectName(), transfer2UnixPath(arkFile.getName())); + if (!busyArray.includes(filePath) && !repeatFilePath.includes(filePath)) { + repeatFilePath.push(filePath); + busyArray.push(filePath); + const importList = arkFile.getImportInfos(); + for (const importModule of importList) { + const moduleSign = importModule.getLazyExportInfo()?.getArkExport()?.getSignature(); + if (!moduleSign) { + continue; + } + // 添加文件间依赖 + const importFile = importModule.getLazyExportInfo()?.getDeclaringArkFile(); + if (importFile) { + fileProcess(importFile, busyArray); + } + moduleDeeplyProcess(moduleSign, busyArray, arkFile.getScene()); + } + if (busyArray.length > 1 && typeof (busyArray[busyArray.length - 1]) === 'string') { + addLastNodeToMap(busyArray); + } + // 查找全局调用 + findGlobalDef(arkFile.getDefaultClass().getDefaultArkMethod(), busyArray); + busyArray.pop(); + } +} + +function findGlobalDef(dfltMethod: ArkMethod | null, busyArray: Array): void { + const stmts = dfltMethod?.getBody()?.getCfg().getStmts(); + for (const stmt of stmts ?? []) { + if (stmt instanceof ArkInvokeStmt) { + busyArray.push(stmt.getInvokeExpr().getMethodSignature()); + addLastNodeToMap(busyArray); + busyArray.pop(); + } + } +} + +function moduleDeeplyProcess(moduleSign: Signature, busyArray: Array, scene: Scene): void { + if (moduleSign instanceof ClassSignature) { + classProcess(scene.getClass(moduleSign), busyArray); + } else if (moduleSign instanceof MethodSignature) { + methodProcess(scene.getMethod(moduleSign), busyArray); + } else if (moduleSign instanceof NamespaceSignature) { + namespaceProcess(scene.getNamespace(moduleSign), busyArray); + } else if (moduleSign instanceof LocalSignature) { + busyArray.push(moduleSign); + addLastNodeToMap(busyArray); + busyArray.pop(); + } +} + +function namespaceProcess(ns: ArkNamespace | null, busyArray: Array): void { + if (!ns || busyArray.includes(ns.getSignature())) { + return; + } + const nsSign = ns.getSignature(); + busyArray.push(nsSign); + addLastNodeToMap(busyArray); + // 遍历过的节点不再遍历 + if (gFinishScanMap.has(nsSign)) { + busyArray.pop(); + return; + } + // 处理sdk跳过逻辑 + if (gIsSkipSdk && nsSign.getDeclaringFileSignature().getProjectName() !== ns.getDeclaringArkFile().getScene().getProjectName()) { + busyArray.pop(); + return; + } + // 处理当前层ns的类 + for (const arkClass of ns.getClasses()) { + classProcess(arkClass, busyArray); + } + // 递归处理嵌套ns的类 + for (const innerNs of ns.getNamespaces()) { + namespaceProcess(innerNs, busyArray); + } + busyArray.pop(); +} + +function classProcess(arkClass: ArkClass | null, busyArray: Array): void { + if (!arkClass || busyArray.includes(arkClass.getSignature())) { + return; + } + const arkClassSign = arkClass.getSignature(); + busyArray.push(arkClassSign); + if (!arkClass.isAnonymousClass()) { + addLastNodeToMap(busyArray); + } + + // 遍历过的节点不再遍历 + if (gFinishScanMap.has(arkClassSign)) { + busyArray.pop(); + return; + } + // 处理sdk跳过逻辑 + if (gIsSkipSdk && arkClassSign.getDeclaringFileSignature().getProjectName() !== arkClass.getDeclaringArkFile().getScene().getProjectName()) { + busyArray.pop(); + return; + } + // 1、继承类处理 + superClassProcess(arkClass, busyArray); + // 2、成员变量处理 + arkFieldProcess(arkClass, busyArray); + // 3、方法内处理 + for (const arkMethod of arkClass.getMethods()) { + methodProcess(arkMethod, busyArray); + } + busyArray.pop(); +} + +function methodProcess(arkMethod: ArkMethod | null | undefined, busyArray: Array): void { + if (!arkMethod || busyArray.includes(arkMethod.getSignature())) { + return; + } + const arkMethodSign = arkMethod.getSignature(); + busyArray.push(arkMethodSign); + if (!arkMethod.isAnonymousMethod()) { + addLastNodeToMap(busyArray); + } + // 遍历过的节点不再遍历 + if (gFinishScanMap.has(arkMethodSign)) { + busyArray.pop(); + return; + } + // 处理sdk跳过逻辑 + if (gIsSkipSdk && arkMethod.getDeclaringArkFile().getProjectName() !== arkMethod.getDeclaringArkFile().getScene().getProjectName()) { + busyArray.pop(); + return; + } + const stmts = arkMethod.getBody()?.getCfg()?.getStmts() ?? []; + const arkFile = arkMethod.getDeclaringArkFile(); + for (const stmt of stmts) { + if (stmt instanceof ArkInvokeStmt && stmt.getInvokeExpr() instanceof ArkStaticInvokeExpr) { + // 判断static调用是否为import, 仅考虑静态调用,示例调用场景在new stmt中处理 + staticExprProcess(stmt.getInvokeExpr() as ArkStaticInvokeExpr, arkFile, busyArray); + } else if (stmt instanceof ArkAssignStmt) { + // 判断右值中1、new class; 2、Local; 3、一元运算;4、二元运算;5、实例调用/实例字段 是否为import导入的模块 + rightOpProcess(stmt.getRightOp(), arkFile, busyArray); + } else if (stmt instanceof ArkIfStmt) { + // 判断ifStmt中变量或常量是否为import导入的模块 + ifStmtProcess(stmt, arkFile, busyArray); + } + } + busyArray.pop(); +} + +function staticExprProcess(invokeExpr: ArkStaticInvokeExpr, arkFile: ArkFile, busyArray: Array): void { + const methodSignature = invokeExpr.getMethodSignature(); + const classSignature = methodSignature.getDeclaringClassSignature(); + const methodName = methodSignature.getMethodSubSignature().getMethodName(); + let className = classSignature.getClassName(); + if (className === DEFAULT_ARK_CLASS_NAME) { + className = classSignature.getDeclaringNamespaceSignature()?.getNamespaceName() ?? ''; + } + const fileSign = classSignature.getDeclaringFileSignature(); + let invokeFilePath = arkFile.getScene().getFile(fileSign)?.getFilePath(); + if (invokeFilePath && invokeFilePath === arkFile.getFilePath()) { + // 本文件的模块,深搜 + methodProcess(arkFile.getScene().getMethod(methodSignature), busyArray); + return; + } + // 导入的模块 + for (const importInfo of arkFile.getImportInfos()) { + const importName = importInfo.getImportClauseName(); + const typeSign = importInfo.getLazyExportInfo()?.getArkExport()?.getSignature(); + if (typeSign && (methodName === importName || className === importName)) { + moduleDeeplyProcess(typeSign, busyArray, arkFile.getScene()); + } + } +} + +function ifStmtProcess(stmt: ArkIfStmt, curFile: ArkFile, busyArray: Array): void { + const op1 = stmt.getConditionExpr().getOp1(); + const op2 = stmt.getConditionExpr().getOp2(); + if (op1 instanceof Local) { + localProcess(op1, curFile, busyArray); + } + if (op2 instanceof Local) { + localProcess(op2, curFile, busyArray); + } +} + +function superClassProcess(arkClass: ArkClass, busyArray: Array): void { + const superName = arkClass.getSuperClass()?.getName(); + if (!superName || busyArray.includes(arkClass.getSuperClass()?.getSignature()!)) { + return; + } + for (const importInfo of arkClass.getDeclaringArkFile().getImportInfos()) { + const typeSign = importInfo.getLazyExportInfo()?.getArkExport()?.getSignature(); + if (importInfo.getImportClauseName() === superName && typeSign) { + moduleDeeplyProcess(typeSign, busyArray, arkClass.getDeclaringArkFile().getScene()); + } + } +} + +function arkFieldProcess(arkClass: ArkClass, busyArray: Array): void { + const arkFields = arkClass.getFields(); + for (const arkField of arkFields) { + const fieldStmts = arkField.getInitializer(); + for (const stmt of fieldStmts) { + if (stmt instanceof ArkAssignStmt) { + rightOpProcess(stmt.getRightOp(), arkClass.getDeclaringArkFile(), busyArray); + } + } + } +} + +function rightOpProcess(rightOp: Value, curFile: ArkFile, busyArray: Array): void { + if (rightOp instanceof ArkNewExpr) { + // 右值为new class场景 + const type = rightOp.getType(); + if (type instanceof ClassType) { + newExprProcess(type, curFile, busyArray); + } + } else if (rightOp instanceof Local) { + // 右值为Local场景 + localProcess(rightOp, curFile, busyArray); + } else if (rightOp instanceof ArkUnopExpr) { + // 右值为一元运算场景 + const ops = rightOp.getUses(); + for (const op of ops) { + if (op instanceof Local) { + localProcess(op, curFile, busyArray); + } + } + } else if (rightOp instanceof ArkNormalBinopExpr) { + // 右值为二元运算场景 + const op1 = rightOp.getOp1(); + const op2 = rightOp.getOp2(); + if (op1 instanceof Local) { + localProcess(op1, curFile, busyArray); + } + if (op2 instanceof Local) { + localProcess(op2, curFile, busyArray); + } + } else if (rightOp instanceof AbstractFieldRef) { + moduleDeeplyProcess(rightOp.getFieldSignature().getDeclaringSignature(), busyArray, curFile.getScene()); + } else if (rightOp instanceof ArkStaticInvokeExpr) { + staticExprProcess(rightOp, curFile, busyArray); + } +} + +function newExprProcess(type: ClassType, arkFile: ArkFile, busyArray: Array): void { + const classSign = type.getClassSignature(); + const className = classSign.getClassName(); + const curFilePath = arkFile.getFilePath(); + const classFilePath = arkFile.getScene().getFile(classSign.getDeclaringFileSignature())?.getFilePath(); + if (!curFilePath || !classFilePath) { + logger.debug('Get curFilePath or classFilePath failed.'); + return; + } + if (curFilePath === classFilePath) { + // 本文件类 + classProcess(arkFile.getClass(classSign), busyArray); + } else { + // 非本文件类 + for (const importInfo of arkFile.getImportInfos()) { + const typeSign = importInfo.getLazyExportInfo()?.getArkExport()?.getSignature(); + if (className === importInfo.getImportClauseName() && typeSign) { + moduleDeeplyProcess(typeSign, busyArray, arkFile.getScene()); + } + } + } +} + +function localProcess(rightOp: Local, curFile: ArkFile, busyArray: Array): void { + const type = rightOp.getType(); + // todo: Local变量为方法或者类地址,let a = class1,目前右值type为unknown,走else分支 + if (type instanceof ClassType) { + if (rightOp.getName().includes(TEMP_LOCAL_PREFIX)) { + return; + } + moduleDeeplyProcess(type.getClassSignature(), busyArray, curFile.getScene()); + } else if (type instanceof FunctionType) { + moduleDeeplyProcess(type.getMethodSignature(), busyArray, curFile.getScene()); + } else { + for (const importInfo of curFile.getImportInfos()) { + const typeSign = importInfo.getLazyExportInfo()?.getArkExport()?.getSignature(); + if (importInfo.getImportClauseName() === rightOp.getName() && typeSign) { + moduleDeeplyProcess(typeSign, busyArray, curFile.getScene()); + break; + } + } + } +} + +function isAnonymous(module: ModuleSignature): boolean { + return module.toString().includes('%A'); +} + +function addLastNodeToMap(busyArray: Array): void { + let index = busyArray.length - 2; + let lastModule = busyArray[index]; + while (isAnonymous(lastModule) && index > 0) { + index--; + lastModule = busyArray[index]; + } + let curModule = busyArray[busyArray.length - 1]; + const storage = gFinishScanMap.get(lastModule); + if (!storage) { + gFinishScanMap.set(lastModule, [curModule]); + } else if (!storage.includes(curModule)) { + storage.push(curModule); + } +} + +function outputNodeList(fileName: string): boolean { + // 文件和节点编号映射落盘 + + // import链落盘 + try { + FileUtils.writeToFile(path.join(gOutPutDirPath, fileName + '_' + FILE_NAME_CHAINS_JSON), JSON.stringify(mapToJson(gNodeMap)), WriteFileMode.OVERWRITE); + return true; + } catch (error) { + logger.error((error as Error).message); + return false; + } +} + +function outputStorage(): boolean { + try { + FileUtils.writeToFile(path.join(gOutPutDirPath, FILE_NAME_CHAINS_TXT), gOutStorage); + return true; + } catch (error) { + logger.error((error as Error).message); + return false; + } +} + +function mapToJson(map: Map): any { + const obj: { [key: string]: any } = Object.create(null); + for (const [key, value] of map) { + if (value instanceof Map) { + // 递归转换嵌套的Map + obj[key] = mapToJson(value); + } else { + obj[key] = value; + } + } + return obj; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/builder.ts b/ets2panda/linter/homecheck/src/tools/depGraph/builder.ts new file mode 100644 index 0000000000000000000000000000000000000000..b234cf945f9d9b1df4aea746006122b3b5f53bf4 --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/depGraph/builder.ts @@ -0,0 +1,82 @@ +/* + * 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. + */ + +import {ArkFile, BUILD_PROFILE_JSON5, parseJsonText, Scene} from 'arkanalyzer'; +import {File, FileDepsGraph} from './fileComponent'; +import {ArkFileDeps} from './fileDeps'; +import Logger, {LOG_MODULE_TYPE} from 'arkanalyzer/lib/utils/logger'; +import {Module, ModuleDepsGraph} from './moduleComponent'; +import {ModuleDeps} from './moduleDeps'; +import {getModuleKind} from './utils'; +import path from 'path'; +import fs from 'fs'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.TOOL, 'DepGraph'); + +export function buildFileDepGraph(arkFiles: ArkFile[]): FileDepsGraph { + let depGraph: FileDepsGraph = new FileDepsGraph(); + let arkFileDeps = ArkFileDeps.getInstance(); + arkFiles.forEach(arkFile => { + const nodeAttr: File = { + name: arkFile.getFilePath(), + kind: 0, + }; + let srcNode = depGraph.addDepsNode(arkFile.getFilePath(), nodeAttr); + arkFileDeps.addDeps(depGraph, srcNode, arkFile); + }); + return depGraph; +} + +export function buildModuleDepGraph(scene: Scene): ModuleDepsGraph { + let moduleGraph: ModuleDepsGraph = new ModuleDepsGraph(); + let moduleDeps: ModuleDeps = ModuleDeps.getInstance(); + const modules = getModules(scene.getRealProjectDir()); + modules.forEach((modulePath) => { + logger.info(`Project module: ${modulePath} found.`); + const nodeAttr: Module = { + name: modulePath, + kind: getModuleKind(modulePath), + }; + if (!moduleGraph.hasDepsNode(modulePath)) { + let srcNode = moduleGraph.addDepsNode(modulePath, nodeAttr); + moduleDeps.addDeps(moduleGraph, srcNode); + } + }); + return moduleGraph; +} + +function getModules(projectPath: string): string[] { + const buildProfile = path.join(projectPath, BUILD_PROFILE_JSON5); + let modulePaths: string[] = []; + if (fs.existsSync(buildProfile)) { + let configurationsText: string; + try { + configurationsText = fs.readFileSync(buildProfile, 'utf-8'); + } catch (error) { + logger.error(`Error reading file: ${error}`); + return modulePaths; + } + const buildProfileJson = parseJsonText(configurationsText); + const modules = buildProfileJson.modules; + if (modules instanceof Array) { + modules.forEach((module) => { + modulePaths.push(path.resolve(projectPath, module.srcPath as string)); + }); + } + } else { + logger.warn('There is no build-profile.json5 for this project.'); + } + return modulePaths; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/fileComponent.ts b/ets2panda/linter/homecheck/src/tools/depGraph/fileComponent.ts new file mode 100644 index 0000000000000000000000000000000000000000..efeed1febeb1db2d5697027c68e5947c5bab1c04 --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/depGraph/fileComponent.ts @@ -0,0 +1,95 @@ +/* + * 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. + */ + +import {DependsGraph, DependsNode} from 'arkanalyzer/lib/core/graph/DependsGraph'; +import {GraphPrinter} from 'arkanalyzer'; + +export enum FileCategory { + FILE = 0, + PKG = 1, + SO = 2, + UNKNOWN = -1, +} + +export interface FileCategoryType { + name: string; + id: number; +} + +export function getComponentCategories(): FileCategoryType[] { + return Object.entries(FileCategory) + .filter((e) => !isNaN(e[0] as any)) + .map((e) => ({name: e[1] as string, id: parseInt(e[0])})); +} + +export interface File { + id?: number; + name: string; + version?: number; + files?: Set; + kind: FileCategory; + tag?: string; +} + +export interface ImportInfo4Dep { + importClauseName: string; + importType: string; + importFrom?: string; + nameBeforeAs?: string; + isDefault?: boolean; +} + +export interface FileEdgeAttr { + kind: 0; + // import clause name + import type, import info + attr: Map; +} + +export class FileDepsGraph extends DependsGraph { + public constructor() { + super(); + } + + addImportInfo2Edge(edge: FileEdgeAttr, importInfo: ImportInfo4Dep): void { + const attrKey = `${importInfo.importClauseName} + ${importInfo.importType}`; + edge.attr.set(attrKey, importInfo); + } + + public toJson(): { nodes: File[]; edges: any[]; categories: {} } { + return { + categories: getComponentCategories(), + nodes: Array.from(this.getNodesIter()).map((value) => { + let pkg = (value as DependsNode).getNodeAttr() as File; + pkg.id = (value as DependsNode).getID(); + return pkg; + }), + edges: Array.from(this.edgesMap.values()).map((value) => { + return { + source: value.getSrcID(), + target: value.getDstID(), + attr: Array.from(value.getEdgeAttr().attr.values()) + }; + }), + }; + } + + public dump(): string { + return new GraphPrinter(this).dump(); + } + + getGraphName(): string { + return 'File Dependency Graph'; + } +} diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/fileDeps.ts b/ets2panda/linter/homecheck/src/tools/depGraph/fileDeps.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b6d7bb8424384125e3bd48c51366bfb4cb741f1 --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/depGraph/fileDeps.ts @@ -0,0 +1,87 @@ +/* + * 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. + */ + +import type {ArkFile, ImportInfo} from 'arkanalyzer'; +import type {DependsNode} from 'arkanalyzer/lib/core/graph/DependsGraph'; +import type {File, FileDepsGraph, ImportInfo4Dep} from './fileComponent'; + +export class ArkFileDeps { + private static instance: ArkFileDeps; + + private constructor() { + } + + public static getInstance(): ArkFileDeps { + if (!this.instance) { + this.instance = new ArkFileDeps(); + } + return this.instance; + } + + public addDeps(depsGraph: FileDepsGraph, node: DependsNode, arkFile: ArkFile): void { + let importInfos = arkFile.getImportInfos(); + if (importInfos && importInfos.length > 0) { + for (let importInfo of importInfos) { + this.processImportInfo(depsGraph, node, importInfo); + } + } + } + + private processImportInfo(depsGraph: FileDepsGraph, src: DependsNode, importInfo: ImportInfo): void { + const nodeAttr = this.genNodeByImportInfo(importInfo); + if (nodeAttr) { + const dst = depsGraph.addDepsNode(nodeAttr.name, nodeAttr); + const edge = depsGraph.addEdge(src, dst, {kind: 0, attr: new Map()}); + depsGraph.addImportInfo2Edge(edge.getEdgeAttr(), this.simplifyImportInfo(importInfo)); + } + } + + private genNodeByImportInfo(importInfo: ImportInfo): File | undefined { + const lazyExport = importInfo.getLazyExportInfo(); + if (lazyExport) { + const exportArkFile = lazyExport.getDeclaringArkFile(); + if (exportArkFile) { + return { + name: exportArkFile.getFilePath(), + kind: 0, + }; + } + } + const from = importInfo.getFrom(); + if (from?.endsWith('.so')) { + return { + name: importInfo.getFrom()!, + kind: 0, + }; + } + if (from) { + return { + name: importInfo.getFrom()!, + kind: 1, + }; + } + return undefined; + } + + private simplifyImportInfo(importInfo: ImportInfo): ImportInfo4Dep { + return { + importClauseName: importInfo.getImportClauseName(), + importType: importInfo.getImportType(), + importFrom: importInfo.getFrom(), + nameBeforeAs: importInfo.getNameBeforeAs(), + isDefault: importInfo.isDefault(), + }; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/moduleComponent.ts b/ets2panda/linter/homecheck/src/tools/depGraph/moduleComponent.ts new file mode 100644 index 0000000000000000000000000000000000000000..e44b256cc765d6d89f92618072c7e30b18b7f643 --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/depGraph/moduleComponent.ts @@ -0,0 +1,83 @@ +/* + * 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. + */ + +import {DependsGraph, DependsNode} from 'arkanalyzer/lib/core/graph/DependsGraph'; +import {GraphPrinter} from 'arkanalyzer'; + +export enum ModuleCategory { + ENTRY = 0, + FEATURE = 1, + HAR = 2, + HSP = 3, + THIRD_PARTY_PACKAGE = 4, + TAGGED_PACKAGE = 5, + UNKNOWN = -1, +} + +export interface ModuleCategoryType { + name: string; + id: number; +} + +export function getComponentCategories(): ModuleCategoryType[] { + return Object.entries(ModuleCategory) + .filter((e) => !isNaN(e[0] as any)) + .map((e) => ({name: e[1] as string, id: parseInt(e[0])})); +} + +export interface Module { + id?: number; + name: string; + version?: number; + files?: Set; + kind: ModuleCategory; + tag?: string; + originPath?: string;//for .har, .tgz, .hsp +} + +export interface ModuleEdgeAttr { + kind: 0; +} + +export class ModuleDepsGraph extends DependsGraph { + public constructor() { + super(); + } + + public toJson(): { nodes: Module[]; edges: any[]; categories: {} } { + return { + categories: getComponentCategories(), + nodes: Array.from(this.getNodesIter()).map((value) => { + let module = (value as DependsNode).getNodeAttr() as Module; + module.id = (value as DependsNode).getID(); + return module; + }), + edges: Array.from(this.edgesMap.values()).map((value) => { + return { + source: value.getSrcID(), + target: value.getDstID() + }; + }), + }; + } + + public dump(): string { + return new GraphPrinter(this).dump(); + } + + getGraphName(): string { + return 'Module Dependency Graph'; + } +} diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/moduleDeps.ts b/ets2panda/linter/homecheck/src/tools/depGraph/moduleDeps.ts new file mode 100644 index 0000000000000000000000000000000000000000..d603a7b8bd3672cecc8bbb288540075631356b76 --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/depGraph/moduleDeps.ts @@ -0,0 +1,106 @@ +/* + * 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. + */ + +import { fetchDependenciesFromFile, OH_PACKAGE_JSON5 } from 'arkanalyzer'; +import type { DependsNode } from 'arkanalyzer/lib/core/graph/DependsGraph'; +import { Module, ModuleCategory, ModuleDepsGraph } from './moduleComponent'; +import path from 'path'; +import fs from 'fs'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { getModuleKind, OH_MODULES_DIR } from './utils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.TOOL, 'moduleDeps'); + +export class ModuleDeps { + private static instance: ModuleDeps; + + private constructor() { + } + + public static getInstance(): ModuleDeps { + if (!this.instance) { + this.instance = new ModuleDeps(); + } + return this.instance; + } + + public addDeps(depsGraph: ModuleDepsGraph, src: DependsNode): void { + const moduleOhPkgPath = path.join(src.getNodeAttr().name, OH_PACKAGE_JSON5); + if (moduleOhPkgPath) { + const dstNodes: Module[] = this.getDstDeps(moduleOhPkgPath); + dstNodes.forEach((dstNode) => { + if (!depsGraph.hasDepsNode(dstNode.name)) { + const dst = depsGraph.addDepsNode(dstNode.name, dstNode); + const edge = depsGraph.addEdge(src, dst, { kind: 0 }); + this.addDeps(depsGraph, dst); + } + }); + } + } + + private getDstDeps(ohPkgPath: string): Module[] { + let dstDeps: Module[] = []; + const ohContent = fetchDependenciesFromFile(ohPkgPath); + let depMaps: Map = new Map(); + + if (ohContent && ohContent.dependencies) { + Object.entries(ohContent.dependencies).forEach(([name, value]) => { + dstDeps.push(this.genDstNode(name, value as string, ohPkgPath)); + }); + } + + return dstDeps; + } + + private genDstNode(key: string, value: string, ohPkgPath: string): Module { + if (value.startsWith('tag:')) { + return { + name: path.join(path.dirname(ohPkgPath), OH_MODULES_DIR, key), + kind: ModuleCategory.TAGGED_PACKAGE, + tag: value.replace(/^tag:/, ''), + }; + } else if (/^(file:|\.\/|\.\.\/)/.test(value)) { + return this.handleLocal(key, value.replace(/^file:/, ''), ohPkgPath); + } else if (/^[~^0-9]/.test(value)) { + return { + name: path.join(path.dirname(ohPkgPath), OH_MODULES_DIR, key), + kind: ModuleCategory.THIRD_PARTY_PACKAGE, + tag: value, + }; + } else { + return { + name: `Unknown: key is ${key}, value is ${value}, module path is ${path.dirname(ohPkgPath)}.`, + kind: ModuleCategory.UNKNOWN, + }; + } + } + + private handleLocal(moduleName: string, modulePath: string, ohPkgPath: string): Module { + const moduleInstalledPath = path.join(path.dirname(ohPkgPath), OH_MODULES_DIR, moduleName); + const originPkgPath = path.join(path.dirname(ohPkgPath), modulePath); + const isDir = fs.statSync(originPkgPath).isDirectory(); + let moduleKind = getModuleKind(moduleInstalledPath); + if (moduleKind === ModuleCategory.UNKNOWN && (modulePath.endsWith('.hsp') || modulePath.endsWith('.tgz'))) { + moduleKind = ModuleCategory.HSP; + } else if (moduleKind === ModuleCategory.UNKNOWN && (modulePath.endsWith('.har'))) { + moduleKind = ModuleCategory.HAR; + } + return { + name: isDir ? originPkgPath : moduleInstalledPath, + kind: moduleKind, + originPath: isDir ? undefined : originPkgPath, + }; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/tools/depGraph/utils.ts b/ets2panda/linter/homecheck/src/tools/depGraph/utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..a71dd517753ae93659dfff202aacfdf934db8ce3 --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/depGraph/utils.ts @@ -0,0 +1,54 @@ +/* + * 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. + */ + +import fs from 'fs'; +import {fetchDependenciesFromFile, OH_PACKAGE_JSON5} from 'arkanalyzer'; +import Logger, {LOG_MODULE_TYPE} from 'arkanalyzer/lib/utils/logger'; +import path from 'path'; +import {ModuleCategory} from './moduleComponent'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.TOOL, 'depGraphUtils'); + +export const OH_MODULES_DIR = './oh_modules/'; + +export function getModuleKind(modulePath: string): ModuleCategory { + const moduleJson5Path = path.join(modulePath, './src/main/module.json5'); + const content = fetchDependenciesFromFile(moduleJson5Path); + if (!content.type) { + switch (content.type as string) { + case 'entry': + return ModuleCategory.ENTRY; + case 'feature': + return ModuleCategory.FEATURE; + case 'har': + return ModuleCategory.HAR; + case 'shared': + return ModuleCategory.HSP; + default: + break; + } + } + + const ohPkgPath = path.join(modulePath, OH_PACKAGE_JSON5); + if (!fs.existsSync(ohPkgPath)) { + return ModuleCategory.UNKNOWN; + } + const ohPkgContent = fetchDependenciesFromFile(ohPkgPath); + if (ohPkgContent.packageType) { + return ModuleCategory.HSP; + } else { + return ModuleCategory.HAR; + } +} diff --git a/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts b/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts new file mode 100644 index 0000000000000000000000000000000000000000..5c3f6478eda979502d63bbb9e1cd817ead03cd0e --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/migrationTool/MigrationTool.ts @@ -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 { CheckEntry, checkEntryBuilder } from '../../utils/common/CheckEntry'; +import { RuleConfig } from '../../model/RuleConfig'; +import { ProjectConfig } from '../../model/ProjectConfig'; +import { Utils } from '../../utils/common/Utils'; +import { CheckerStorage } from '../../utils/common/CheckerStorage'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { FileUtils } from '../../utils/common/FileUtils'; +import { DefaultMessage } from '../../model/Message'; +import { FileIssues } from "../../model/Defects"; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'MigrationTool'); + +export class MigrationTool { + private checkEntry: CheckEntry; + + constructor(ruleConfig: any, projectConfig: any) { + this.checkEntry = new CheckEntry(); + // 解析规则配置文件 + this.checkEntry.ruleConfig = new RuleConfig(ruleConfig); + // 解析项目配置文件 + this.checkEntry.projectConfig = new ProjectConfig(projectConfig); + } + + public async buildCheckEntry(): Promise { + // 日志配置 + const logPath = this.checkEntry.projectConfig.logPath; + Utils.setLogConfig(logPath.length === 0 ? './HomeCheck.log' : logPath, + this.checkEntry.projectConfig.arkAnalyzerLogLevel, + this.checkEntry.projectConfig.logLevel); + logger.info(`buildCheckEntry start`); + // api版本配置 + CheckerStorage.getInstance().setApiVersion(this.checkEntry.projectConfig.apiVersion); + // product配置 + CheckerStorage.getInstance().setProduct(this.checkEntry.projectConfig.product); + // 设置指定文件检查,不设置默认检查所有文件 + this.checkEntry.setCheckFileList(FileUtils.getFileInfoFromFileList(this.checkEntry.projectConfig.fileOrFolderToCheck)); + + // 外部没有建立消息通道,使用默认通道 + if (!this.checkEntry.message) { + this.checkEntry.message = new DefaultMessage(); + } + + // 前处理 + if (!await checkEntryBuilder(this.checkEntry)) { + return false; + } + logger.info(`buildCheckEntry end`); + return true; + } + + public async start(): Promise { + logger.info(`MigrationTool run start`); + await this.checkEntry.runAll(); + + let result = this.checkEntry.sortIssues(); + logger.info(`MigrationTool run end`); + return result; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/tools/toolEntry.ts b/ets2panda/linter/homecheck/src/tools/toolEntry.ts new file mode 100644 index 0000000000000000000000000000000000000000..797900cece80693463163dce0b78eefdc35e73d0 --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/toolEntry.ts @@ -0,0 +1,136 @@ +/* + * 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. + */ + +import {ArkFile, Scene, SceneConfig} from 'arkanalyzer'; +import Logger, {LOG_MODULE_TYPE} from 'arkanalyzer/lib/utils/logger'; +import {buildModuleChains} from './BuildModuleChains'; +import {ProjectConfig} from '../model/ProjectConfig'; +import {FileUtils, WriteFileMode} from '../utils/common/FileUtils'; +import {Utils} from '../utils/common/Utils'; +import {buildFileDepGraph, buildModuleDepGraph} from './depGraph/builder'; +import {OptionValues} from 'commander'; +import {ConfigUtils} from '../Index'; +import path from 'path'; +import fs from 'fs'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.TOOL, 'runTool'); + +export function runTool(tool: Tools, argvObj: OptionValues): void { + const startTime = new Date().getTime(); + const projectConfig = new ProjectConfig(ConfigUtils.getConfig(argvObj.projectConfigPath)); + let depGraphOutputDir = argvObj.depGraphOutputDir; + + try { + // 配置日志文件路径 + const logPath = projectConfig.logPath; + Utils.setLogPath(logPath.length ? logPath : './HomeCheckTools.log'); + logger.info('start to run tool...'); + const scene = buildScene(projectConfig); + if (!scene) { + return; + } + // 运行对应工具模块 + switch (tool) { + case Tools.ImportChains: + logger.info('start to buildModuleChains...'); + buildModuleChains(scene, [], projectConfig.reportDir); + logger.info('buildModuleChains completed.'); + break; + case Tools.DepGraph: + if (!depGraphOutputDir) { + logger.warn('The output directory of dependency graph is not set, by default it will be set to current directory.'); + depGraphOutputDir = './'; + } + if (!fs.existsSync(depGraphOutputDir)) { + logger.error(`The given depGraphOutputDir: ${depGraphOutputDir} is not exist.`); + process.exit(-1); + } + genFileDepGraph(depGraphOutputDir, scene.getFiles()); + genModuleDepGraph(depGraphOutputDir, scene); + break; + default: + logger.error(`Unknown tool: ${tool}`); + break; + } + } catch (error) { + logger.error(`Error occurred: ${(error as Error).message}`); + return; + } + const endTime = new Date().getTime(); + logger.info(`HomeCheck tools took: ${(endTime - startTime) / 1000}s`); +} + +function buildScene(projectConfig: ProjectConfig): Scene | null { + try { + // 构建SceneConfig + const config: SceneConfig = new SceneConfig(); + const fileList = FileUtils.getAllFiles(projectConfig.projectPath, ['.ts', '.ets']); + config.buildFromProjectFiles(projectConfig.projectName, projectConfig.projectPath, fileList, FileUtils.genSdks(projectConfig)); + logger.info('Build sceneConfig completed.'); + // 构建Scene + const scene = new Scene(); + scene.buildSceneFromFiles(config); + logger.info('Build scene completed.'); + scene.inferTypes(); + logger.info('Infer types completed.'); + return scene; + } catch (error) { + logger.error(`Build scene or infer types error: ${(error as Error).message}`); + return null; + } +} + +function genFileDepGraph(outputPath: string, arkFiles: ArkFile[]): void { + const fileDepGraphJson = path.join(outputPath, './fileDepGraph.json'); + const fileDepGraphDot = path.join(outputPath, './fileDepGraph.dot'); + + logger.info('Started to build file dependency graph...'); + + const depGraph = buildFileDepGraph(arkFiles); + + const jsonRes = JSON.stringify(depGraph.toJson()); + FileUtils.writeToFile(fileDepGraphJson, jsonRes, WriteFileMode.OVERWRITE); + logger.info('Building dependency graph in json format has completed.'); + + const dotRes = depGraph.dump(); + FileUtils.writeToFile(fileDepGraphDot, dotRes, WriteFileMode.OVERWRITE); + logger.info('Building dependency graph in dot format has completed.'); + + logger.info('Building file dependency graph completed.'); +} + +function genModuleDepGraph(outputPath: string, scene: Scene): void { + const moduleDepGraphJson = path.join(outputPath, './moduleDepGraph.json'); + const moduleDepGraphDot = path.join(outputPath, './moduleDepGraph.dot'); + + logger.info('Started to build module dependency graph...'); + + const depGraph = buildModuleDepGraph(scene); + + const jsonRes = JSON.stringify(depGraph.toJson()); + FileUtils.writeToFile(moduleDepGraphJson, jsonRes, WriteFileMode.OVERWRITE); + logger.info('Building module graph in json format has completed.'); + + const dotRes = depGraph.dump(); + FileUtils.writeToFile(moduleDepGraphDot, dotRes, WriteFileMode.OVERWRITE); + logger.info('Building module graph in dot format has completed.'); + + logger.info('Building file module graph completed.'); +} + +export enum Tools { + ImportChains = 0, + DepGraph = 1, +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/tools/toolRun.ts b/ets2panda/linter/homecheck/src/tools/toolRun.ts new file mode 100644 index 0000000000000000000000000000000000000000..37d80e9a22201d21fadabd8fe58ccb64b1bbe25b --- /dev/null +++ b/ets2panda/linter/homecheck/src/tools/toolRun.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +import { Utils } from '../utils/common/Utils'; +import { runTool, Tools } from './toolEntry'; + +(function run(): void { + const argvObj = Utils.parseCliOptions(process.argv); + runTool(Tools.DepGraph, argvObj); +})(); \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/AbilityInterface.ts b/ets2panda/linter/homecheck/src/utils/checker/AbilityInterface.ts new file mode 100644 index 0000000000000000000000000000000000000000..8ec07bce61ea0639ce9662916ec9e24a4d34639e --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/AbilityInterface.ts @@ -0,0 +1,86 @@ +/* + * 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. + */ + +/** + * Record the module in the module.json5. + */ +export interface moduleJson5Module { + name: string; + type: string; + description: string; + mainElement: string; + deviceTypes: string[]; + deliveryWithInstall: boolean; + installationFree: boolean; + abilities: moduleAbility[]; + extensionAbilities: extensionAbility[]; +} + +/** + * Record the ability in the module. + */ +export interface moduleAbility { + name: string; + srcEntry: string; + description: string; + icon: string; + label: string; + startWindowIcon: string; + startWindowBackground: string; + exported: boolean; + skills: abilitySkill[]; +} + +/** + * Record the skill in the ability. + */ +interface abilitySkill { + entities: string[]; + actions: string[]; +} + +/** + * Record the extensionAbility in the module. + */ +export interface extensionAbility { + name: string; + srcEntry: string; + description: string; + icon: string; + label: string; + type: string; + metadata: extensionAbilityMetadata[]; +} + +/** + * Record the metadata in the extensionAbility. + */ +interface extensionAbilityMetadata { + name: string; + resource: string; +} + +/** + * Record the app in the app.json5. + */ +export interface appJson5App { + bundleName: string; + vendor: string; + versionCode: number; + versionName: string; + devicetypes: string[]; + icon: string; + label: string; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/BytesUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/BytesUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..3da521fffc187e79ce34c6f41b1be86fdacab248 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/BytesUtils.ts @@ -0,0 +1,104 @@ +/* + * 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 decoder = new TextDecoder(); +export const toUTF8String = ( + input: Uint8Array, + start = 0, + end = input.length +): string => decoder.decode(input.slice(start, end)); + +export const toHexString = ( + input: Uint8Array, + start = 0, + end = input.length +): string => input.slice(start, end).reduce((memo, i) => memo + `0${i.toString(16)}`.slice(-2), ''); + +const getView = ( + input: Uint8Array, + offset: number +): DataView => new DataView(input.buffer, input.byteOffset + offset); + +export const readInt16LE = (input: Uint8Array, offset = 0): number => + getView(input, offset).getInt16(0, true); + +export const readUInt16BE = (input: Uint8Array, offset = 0): number => + getView(input, offset).getUint16(0, false); + +export const readUInt16LE = (input: Uint8Array, offset = 0): number => + getView(input, offset).getUint16(0, true); + +export const readUInt24LE = (input: Uint8Array, offset = 0): number => { + const view = getView(input, offset); + return view.getUint16(0, true) + (view.getUint8(2) << 16); +}; + +export const readInt32LE = (input: Uint8Array, offset = 0): number => + getView(input, offset).getInt32(0, true); + +export const readUInt32BE = (input: Uint8Array, offset = 0): number => + getView(input, offset).getUint32(0, false); + +export const readUInt32LE = (input: Uint8Array, offset = 0): number => + getView(input, offset).getUint32(0, true); + +export const readUInt64 = ( + input: Uint8Array, + offset: number, + isBigEndian: boolean +): bigint => getView(input, offset).getBigUint64(0, !isBigEndian); + +const methods = { + readUInt16BE, + readUInt16LE, + readUInt32BE, + readUInt32LE +} as const; + +type MethodName = keyof typeof methods; + +export function readUInt( + input: Uint8Array, + bits: 16 | 32, + offset = 0, + isBigEndian = false +): number { + const endian = isBigEndian ? 'BE' : 'LE'; + const methodName = `readUInt${bits}${endian}` as MethodName; + return methods[methodName](input, offset); +} + +const INCH_CM = 2.54; + +const units: Record = { + in: 96, + cm: 96 / INCH_CM, + em: 16, + ex: 8, + m: (96 / INCH_CM) * 100, + mm: 96 / INCH_CM / 10, + pc: 96 / 72 / 12, + pt: 96 / 72, + px: 1, +}; +const unitsReg = new RegExp(`^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join('|')})?$`,); + +export function getLength(len: string): number | undefined { + const m = unitsReg.exec(len); + if (!m) { + return undefined; + } + return Math.round(Number(m[1]) * (units[m[2]] || 1)); +} diff --git a/ets2panda/linter/homecheck/src/utils/checker/CheckerUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/CheckerUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..58d2028b5fdc0911feae53c40dde01ef9a7cfdaa --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/CheckerUtils.ts @@ -0,0 +1,178 @@ +/* + * 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. + */ +import { ArkAssignStmt, ArkInvokeStmt, Stmt } from 'arkanalyzer/lib/core/base/Stmt'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { AbstractInvokeExpr, ArkAwaitExpr } from 'arkanalyzer/lib/core/base/Expr'; +import { Local } from 'arkanalyzer/lib/core/base/Local'; +import path from 'path'; +import { ArkClass, ArkFile, ArkInstanceFieldRef, FileSignature, Scene, Value } from 'arkanalyzer'; +import { ScopeType, TempLocation } from '../../model/Scope'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CheckUtils'); + +export class CheckerUtils { + /** + * 从给定的语句中获取调用表达式 + * @param stmt - 要处理的语句 + * @returns 如果找到调用表达式,则返回 AbstractInvokeExpr,否则返回 null + */ + public static getInvokeExprFromStmt(stmt: Stmt): AbstractInvokeExpr | null { + if (stmt instanceof ArkInvokeStmt) { + return stmt.getInvokeExpr(); + } else if (stmt instanceof ArkAssignStmt) { + const rightOp = stmt.getRightOp(); + if (rightOp instanceof AbstractInvokeExpr) { + return rightOp; + } + } + return null; + } + + /** + * 从给定的语句中获取调用表达式(Await) + * @param stmt - 要处理的语句 + * @returns 如果找到调用表达式,则返回 AbstractInvokeExpr,否则返回 null + */ + public static getInvokeExprFromAwaitStmt(stmt: Stmt): AbstractInvokeExpr | null { + if (stmt instanceof ArkInvokeStmt) { + return stmt.getInvokeExpr(); + } else if (stmt instanceof ArkAssignStmt) { + let rightOp = stmt.getRightOp(); + if (rightOp instanceof AbstractInvokeExpr) { + return rightOp; + } else if (rightOp instanceof ArkAwaitExpr) { + let promise = rightOp.getPromise(); + if (!(promise instanceof Local)) { + return null; + } + let declaringStmt = promise.getDeclaringStmt(); + if (!(declaringStmt instanceof ArkAssignStmt)) { + return null; + } + rightOp = declaringStmt.getRightOp(); + if (rightOp instanceof AbstractInvokeExpr) { + return rightOp; + } + } + } + return null; + } + + /** + * 获取语句的Scope类型 + * @param stmt 语句对象 + * @returns Scope类型 + */ + public static getScopeType(stmt: Stmt): ScopeType { + const text = stmt.getOriginalText() ?? ''; + if (!text) { + return ScopeType.UNKNOWN_TYPE; + } + if (text.startsWith('for (') || text.startsWith('for(')) { + return ScopeType.FOR_CONDITION_TYPE; + } else if (text.startsWith('while (') || text.startsWith('while(')) { + return ScopeType.WHILE_TYPE; + } else if (text.startsWith('if (') || text.startsWith('if(')) { + return ScopeType.IF_TYPE; + } + return ScopeType.UNKNOWN_TYPE; + } + + /** + * 判断给定的语句是否是声明语句 + * @param defName - 要检查的变量名 + * @param stmt - 要检查的语句 + * @returns 如果语句是声明语句,则返回true,否则返回false + */ + public static isDeclaringStmt(defName: string, stmt: Stmt): boolean { + const text = stmt.getOriginalText() ?? ''; + if (text) { + if (text.includes('let ' + defName) || text.includes('const ' + defName) || + text.includes('var ' + defName)) { + const c = text[text.indexOf(' ' + defName) + defName.length + 1]; + if (c === ' ' || c === ':' || c === '=') { + return true; + } + } + } + return false; + } + + /** + * 获取语句中临时变量的位置 + * @param stmt 语句 + * @returns 临时变量的位置 + */ + public static wherIsTemp(stmt: Stmt): TempLocation { + let def = stmt.getDef(); + if (def instanceof Local) { + if (def.getName().includes('%')) { + return TempLocation.LEFT; + } + } + if (stmt instanceof ArkAssignStmt) { + let right = stmt.getRightOp(); + if (right instanceof Local) { + if (right.getName().includes('%')) { + return TempLocation.RIGHT; + } + } + } + return TempLocation.NOFOUND; + } + + /** + * 根据文件路径获取ArkFile对象 + * @param scene Scene + * @param absolutePath 文件的绝对路径 + * @returns 返回对应的ArkFile对象,如果未找到则返回null + */ + public static getArkFileByFilePath(scene: Scene, absolutePath: string): ArkFile | null { + const relativePath = path.relative(scene.getRealProjectDir(), absolutePath); + const fileSign = new FileSignature(scene.getProjectName(), relativePath); + return scene.getFile(fileSign); + } + + /** + * 获取参数的右值 + * @param arg - 参数 + * @param arkClass - ArkClass对象 + * @returns Value | null - 返回参数的右值,如果不存在则返回null + */ + public static getArgRight(arg: Value, arkClass: ArkClass): Value | null { + if (!(arg instanceof Local)) { + return arg; + } + let decStmt = arg.getDeclaringStmt(); + if (!(decStmt instanceof ArkAssignStmt)) { + return null; + } + let rightOp = decStmt.getRightOp(); + if (!(rightOp instanceof ArkInstanceFieldRef)) { + return rightOp; + } + let field = arkClass.getField(rightOp.getFieldSignature()); + if (!field) { + return null; + } + for (let initializer of field.getInitializer()) { + if (!(initializer instanceof ArkAssignStmt)) { + continue; + } + return initializer.getRightOp(); + } + return null; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/ImageUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/ImageUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..f4d35c24646f0c3f4d5ce7b40ad30b5a65cf006e --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/ImageUtils.ts @@ -0,0 +1,99 @@ +/* + * 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. + */ + +import fs from 'fs'; +import { BMP } from './imageFormat/bmp'; +import { JPG } from './imageFormat/jpg'; +import { PNG } from './imageFormat/png'; +import { SVG } from './imageFormat/svg'; +import { WEBP } from './imageFormat/webp'; +import { ImageInfo } from '../../model/Interfaces'; + +const MaxInputSize = 512 * 1024; +const typeHandlers = { + bmp: BMP, + jpg: JPG, + png: PNG, + svg: SVG, + webp: WEBP, +}; + +export type imageType = keyof typeof typeHandlers; + +const firstBytes: Record = { + 0x42: 'bmp', + 0x52: 'webp', + 0x89: 'png', + 0xff: 'jpg', +}; +const keys = Object.keys(typeHandlers) as imageType[]; + +export function readImageInfo(filePath: string): ImageInfo | undefined { + const input = readFileSync(filePath); + if (!input) { return undefined; } + const type = detector(input); + if (typeof type === 'undefined') { + return undefined; + } + if (type in typeHandlers) { + const size = typeHandlers[type].calculate(input, filePath); + if (!size) { + return undefined; + } + let imageInfo = { width: size.width, height: size.height, type: '' }; + imageInfo.type = size.type ?? type; + if (size.images && size.images.length > 1) { + const largestImage = size.images.reduce((largest, current) => { + return current.width * current.height > largest.width * largest.height ? current : largest; + }, size.images[0]); + imageInfo.width = largestImage.width; + imageInfo.height = largestImage.height; + } + return imageInfo; + } + return undefined; +} + +function readFileSync(filepath: string): Uint8Array | undefined { + const descriptor = fs.openSync(filepath, 'r'); + try { + const { size } = fs.fstatSync(descriptor); + if (size <= 0) { + return undefined; + } + const inputSize = Math.min(size, MaxInputSize); + const input = new Uint8Array(inputSize); + fs.readSync(descriptor, input, 0, inputSize, 0); + return input; + } finally { + fs.closeSync(descriptor); + } +} + +function detector(input: Uint8Array): imageType | undefined { + try { + const byte = input[0]; + if (byte in firstBytes) { + const type = firstBytes[byte]; + if (type && typeHandlers[type].validate(input)) { + return type; + } + } + const finder = (key: imageType): boolean => typeHandlers[key].validate(input); + return keys.find(finder); + } catch (error) { + return undefined; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/NumberUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/NumberUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..4afca0d4f3b5027fcf7abf9c6c493b24e95818ad --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/NumberUtils.ts @@ -0,0 +1,343 @@ +/* + * 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. + */ + +import { AbstractExpr, ArkAssignStmt, ArkFile, ArkNormalBinopExpr, ArkStaticFieldRef, ArkUnopExpr, ClassSignature, Constant, ImportInfo, Local, NumberType, Stmt, Value } from 'arkanalyzer'; +import { VarInfo } from '../../model/VarInfo'; +import { CheckerStorage } from '../common/CheckerStorage'; +import { NumberValue, ValueType } from '../../model/NumberValue'; +import { StmtExt } from '../../model/StmtExt'; + +export class NumberUtils { + public static readonly mBinopList: string[] = ['+', '-', '*', '/', '%', '<<', '>>', '&', '|', '^', '>>>']; + + private static isSupportOperator(operator: string): boolean { + return this.mBinopList.includes(operator); + } + + public static isValueSupportCalculation(arkFile: ArkFile, valueStmtInfo: VarInfo, value: Value): boolean { + if (value instanceof Constant && value.getType() instanceof NumberType) { + return true; + } else if (value instanceof Local) { + let importInfo = NumberUtils.getValueImportInfo(arkFile, value); + if (importInfo) { + return NumberUtils.isImportValueSupportCalculate(arkFile, importInfo, value); + } else { + return NumberUtils.isMethodValueSupportCalculate(arkFile, valueStmtInfo, value); + } + } else if (value instanceof AbstractExpr && value.getType() instanceof NumberType) { + return NumberUtils.isExprSupportCalculate(arkFile, valueStmtInfo, value); + } else if (value instanceof ArkStaticFieldRef && value.getType() instanceof NumberType) { + return true; + } + return false; + } + + private static isExprSupportCalculate(arkFile: ArkFile, valueStmtInfo: VarInfo, value: AbstractExpr): boolean { + if (value instanceof ArkNormalBinopExpr && this.isSupportOperator(value.getOperator())) { + return NumberUtils.isValueSupportCalculation(arkFile, valueStmtInfo, value.getOp1()) && + NumberUtils.isValueSupportCalculation(arkFile, valueStmtInfo, value.getOp2()); + } else if (value instanceof ArkUnopExpr) { + let op = value.getUses()[0]; + return NumberUtils.isValueSupportCalculation(arkFile, valueStmtInfo, op); + } + return false; + } + + private static isMethodValueSupportCalculate(arkFile: ArkFile, valueStmtInfo: VarInfo, value: Local): boolean { + let scope = valueStmtInfo.scope; + let valueStmt: Stmt = valueStmtInfo.stmt; + if (!scope || !scope.defList) { + return false; + } + let hasFind = false; + let defList = scope.defList; + for (let defVar of defList) { + if (defVar.getName() !== value.getName()) { + continue; + } + hasFind = true; + let nearReDefStmtInfo = new VarInfo(defVar.defStmt, scope); + let reDefStmtInfos = defVar.redefInfo; + for (let reDefStmtInfo of reDefStmtInfos) { + let originalLine = valueStmt.getOriginPositionInfo().getLineNo(); + if (reDefStmtInfo.stmt.getOriginPositionInfo().getLineNo() >= originalLine) { + break; + } + nearReDefStmtInfo = reDefStmtInfo; + } + if (!nearReDefStmtInfo || !(nearReDefStmtInfo instanceof VarInfo)) { + continue; + } + let stmt = nearReDefStmtInfo.stmt; + if (stmt instanceof ArkAssignStmt) { + let rightOp = stmt.getRightOp(); + return NumberUtils.isValueSupportCalculation(arkFile, nearReDefStmtInfo, rightOp); + } + } + + if (!hasFind && scope.parentScope != null) { + let defStmtInfo = new VarInfo(valueStmt, scope.parentScope); + return NumberUtils.isValueSupportCalculation(arkFile, defStmtInfo, value); + } + return false; + } + + private static isImportValueSupportCalculate(arkFile: ArkFile, importInfo: ImportInfo, value: Local): boolean { + let exportInfo = importInfo.getLazyExportInfo(); + let importArkFile = exportInfo?.getDeclaringArkFile(); + if (!importArkFile) { + return false; + } + let scope = CheckerStorage.getInstance().getScope(importArkFile.getFilePath()); + if (!scope) { + return false; + } + for (let varDef of scope.defList) { + if (varDef.getName() !== value.getName()) { + continue; + } + let stmt = varDef.defStmt; + if (stmt instanceof ArkAssignStmt) { + let defStmtInfo = new VarInfo(stmt, scope); + let rightOp = stmt.getRightOp(); + return NumberUtils.isValueSupportCalculation(importArkFile, defStmtInfo, rightOp); + } + } + return false; + } + + private static getValueImportInfo(arkFile: ArkFile, value: Local): any { + let importInfos = arkFile.getImportInfos(); + for (let importInfo of importInfos) { + if (importInfo.getImportClauseName() === value.getName()) { + return importInfo; + } + } + return undefined; + } + + public static getNumberByScope(arkFile: ArkFile, valueStmtInfo: VarInfo, value: Value): NumberValue { + if (value instanceof Constant && value.getType() instanceof NumberType) { + let valueStr = value.getValue(); + let numberValue = Number(valueStr); + if (valueStr.includes('.')) { + return new NumberValue(numberValue, ValueType.DOUBLE); + } else { + return new NumberValue(numberValue, ValueType.INT); + } + } else if (value instanceof Local) { + let importInfo = this.getValueImportInfo(arkFile, value); + if (importInfo) { + return this.getImportNumberValue(arkFile, importInfo, value); + } else { + return this.getMethodNumberValue(arkFile, valueStmtInfo, value); + } + } else if (value instanceof AbstractExpr && value.getType() instanceof NumberType) { + return this.getExprNumberValue(arkFile, valueStmtInfo, value); + } else if (value instanceof ArkStaticFieldRef && value.getType() instanceof NumberType) { + return this.getStaticNumberValue(arkFile, valueStmtInfo, value); + } + return new NumberValue(0, ValueType.UNKNOWN); + } + + private static getImportNumberValue(arkFile: ArkFile, importInfo: ImportInfo, value: Local): NumberValue { + let exportInfo = importInfo.getLazyExportInfo(); + let importArkFile = exportInfo?.getDeclaringArkFile(); + if (!importArkFile) { + return new NumberValue(0, ValueType.UNKNOWN); + } + let scope = CheckerStorage.getInstance().getScope(importArkFile.getFilePath()); + if (!scope) { + return new NumberValue(0, ValueType.UNKNOWN); + } + for (let varDef of scope.defList) { + if (varDef.getName() !== value.getName()) { + continue; + } + let stmt = varDef.defStmt; + if (stmt instanceof ArkAssignStmt) { + let defStmtInfo = new VarInfo(stmt, scope); + let rightOp = stmt.getRightOp(); + return this.getNumberByScope(importArkFile, defStmtInfo, rightOp); + } + } + return new NumberValue(0, ValueType.UNKNOWN); + } + + private static getMethodNumberValue(arkFile: ArkFile, valueStmtInfo: VarInfo, value: Local): NumberValue { + let scope = valueStmtInfo.scope; + let valueStmt = valueStmtInfo.stmt; + if (!scope || !scope.defList) { + return new NumberValue(0, ValueType.UNKNOWN); + } + let hasFind = false; + let defList = scope.defList; + for (let defVar of defList) { + if (defVar.getName() !== value.getName()) { + continue; + } + hasFind = true; + + let nearReDefStmtInfo = new VarInfo(defVar.defStmt, scope); + let reDefStmtInfos = defVar.redefInfo; + + for (let reDefStmtInfo of reDefStmtInfos) { + let originalLine = valueStmt.getOriginPositionInfo().getLineNo(); + let redefLine = reDefStmtInfo.stmt.getOriginPositionInfo().getLineNo(); + if (redefLine >= originalLine) { + break; + } + nearReDefStmtInfo = reDefStmtInfo; + } + let stmt = nearReDefStmtInfo.stmt; + if (stmt instanceof ArkAssignStmt) { + let rightOp = stmt.getRightOp(); + return this.getNumberByScope(arkFile, nearReDefStmtInfo, rightOp); + } + } + + if (!hasFind && scope.parentScope != null) { + let defStmtInfo = new VarInfo(valueStmt, scope.parentScope); + return this.getNumberByScope(arkFile, defStmtInfo, value); + } + return new NumberValue(0, ValueType.UNKNOWN); + } + + private static getExprNumberValue(arkFile: ArkFile, stmeInfo: VarInfo, value: AbstractExpr): NumberValue { + if (value instanceof ArkNormalBinopExpr) { + if (this.isSupportOperator(value.getOperator())) { + let valueOfOp1 = this.getNumberByScope(arkFile, stmeInfo, value.getOp1()); + let valueOfOp2 = this.getNumberByScope(arkFile, stmeInfo, value.getOp2()); + switch (value.getOperator()) { + case '+': + return new NumberValue(valueOfOp1.value + valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '-': + return new NumberValue(valueOfOp1.value - valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '*': + return new NumberValue(valueOfOp1.value * valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '/': + return new NumberValue(valueOfOp1.value / valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '%': + return new NumberValue(valueOfOp1.value % valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '&': + return new NumberValue(valueOfOp1.value & valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '|': + return new NumberValue(valueOfOp1.value | valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '^': + return new NumberValue(valueOfOp1.value ^ valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '>>': + return new NumberValue(valueOfOp1.value >> valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '<<': + return new NumberValue(valueOfOp1.value << valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + case '>>>': + return new NumberValue(valueOfOp1.value >>> valueOfOp2.value, valueOfOp1.type | valueOfOp2.type); + } + } + } else if (value instanceof ArkUnopExpr) { + let op = value.getUses()[0]; + let valueOfOp = this.getNumberByScope(arkFile, stmeInfo, op); + switch (value.getOperator()) { + case '-': + return new NumberValue(-valueOfOp.value, valueOfOp.type); + case '~': + return new NumberValue(~valueOfOp.value, valueOfOp.type); + } + } + return new NumberValue(0, ValueType.UNKNOWN); + } + + private static getStaticNumberValue(arkFile: ArkFile, valueStmtInfo: VarInfo, value: ArkStaticFieldRef): NumberValue { + let classSignature = value.getFieldSignature().getDeclaringSignature(); + if (!(classSignature instanceof ClassSignature)) { + return new NumberValue(0, ValueType.UNKNOWN); + } + + let fileSignature = classSignature.getDeclaringFileSignature(); + let staticClassArkFile = arkFile.getScene().getFile(fileSignature); + + if (staticClassArkFile) { + let staticClass = staticClassArkFile.getClass(classSignature); + if (!staticClass) { + return new NumberValue(0, ValueType.UNKNOWN); + } + + let staticField = staticClass.getStaticFieldWithName(value.getFieldName()); + if (!staticField) { + return new NumberValue(0, ValueType.UNKNOWN); + } + + let stmts = staticField.getInitializer(); + if (stmts.length === 0) { + return new NumberValue(0, ValueType.UNKNOWN); + } + + let stmt = stmts[0]; + new VarInfo(stmt, (stmt as StmtExt).scope); + if (!(stmt instanceof ArkAssignStmt)) { + return new NumberValue(0, ValueType.UNKNOWN); + } + + let initValue = stmt.getRightOp(); + return this.getNumberByScope(arkFile, valueStmtInfo, initValue); + } + return new NumberValue(0, ValueType.UNKNOWN); + } + + public static getOriginalValueText(stmt: Stmt, value: Value): string { + let valStr = ''; + if (value instanceof Constant) { + valStr = value.toString(); + } else if (value instanceof Local) { + if (!value.toString().includes('%')) { + valStr = value.toString(); + } else { + let declaringStmt = value.getDeclaringStmt(); + if (declaringStmt instanceof ArkAssignStmt) { + return this.getOriginalValueText(stmt, declaringStmt.getRightOp()); + } + } + } else if (value instanceof ArkNormalBinopExpr) { + if (!value.toString().includes('%')) { + valStr = value.toString(); + } else { + let originalPosition = stmt.getOperandOriginalPosition(value); + if (!originalPosition) { + return this.getOriginalValueText(stmt, value.getOp1()) + ' ' + value.getOperator() + ' ' + + this.getOriginalValueText(stmt, value.getOp2()); + } + const text = stmt.getOriginalText(); + if (!text || text.length === 0) { + return this.getOriginalValueText(stmt, value.getOp1()) + ' ' + value.getOperator() + ' ' + + this.getOriginalValueText(stmt, value.getOp2()); + } + let startColum = stmt.getOriginPositionInfo().getColNo(); + return text.substring(originalPosition.getFirstCol() - startColum, originalPosition.getLastCol() - startColum); + } + } else if (value instanceof ArkUnopExpr) { + if (!value.toString().includes('%')) { + valStr = value.toString(); + } else { + valStr = value.getOperator() + this.getOriginalValueText(stmt, value.getUses()[0]); + } + } else if (value instanceof ArkStaticFieldRef) { + let fieldSignature = value.getFieldSignature(); + let declaringSignature = fieldSignature.getDeclaringSignature(); + if (declaringSignature instanceof ClassSignature) { + valStr = declaringSignature.getClassName() + '.' + fieldSignature.getFieldName(); + } + } + return valStr; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/StringUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/StringUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..f6ddea74b0f2935e8dd38c13ca54f0409d4617f8 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/StringUtils.ts @@ -0,0 +1,178 @@ +/* + * 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. + */ + +import { AbstractExpr, ArkAssignStmt, ArkFile, ArkNormalBinopExpr, ArkStaticFieldRef, ClassSignature, ClassType, Constant, ImportInfo, Local, Stmt, StringType, Value } from 'arkanalyzer'; +import { ClassCategory } from 'arkanalyzer/lib/core/model/ArkClass'; +import { VarInfo } from '../../model/VarInfo'; +import { StmtExt } from '../../model/StmtExt'; +import { CheckerStorage } from '../common/CheckerStorage'; +import { Scope } from '../../model/Scope'; + +export class StringUtils { + public static getStringByScope(arkFile: ArkFile, valueStmtInfo: VarInfo, value: Value): string { + if (value instanceof Constant) { + return value.getValue(); + } else if (value instanceof Local) { + if (!value.toString().includes('%')) { + let importInfo = this.getValueImportInfo(arkFile, value); + if (importInfo) { + return this.getImportStringValue(importInfo, value); + } else { + return this.getMethodStringValue(arkFile, valueStmtInfo, value); + } + } else { + let declaringStmt = value.getDeclaringStmt(); + if (!declaringStmt) { + return ''; + } + let tmpStmt = declaringStmt; + if (!(declaringStmt instanceof ArkAssignStmt)) { + return ''; + } + let rightOp = declaringStmt.getRightOp(); + valueStmtInfo.stmt = declaringStmt; + valueStmtInfo.scope = (tmpStmt as StmtExt).scope; + return this.getStringByScope(arkFile, valueStmtInfo, rightOp); + } + } else if (value instanceof AbstractExpr && value.getType() instanceof StringType) { + return this.getExprStringValue(arkFile, valueStmtInfo, value); + } else if (value instanceof ArkStaticFieldRef && value.getType() instanceof StringType) { + return this.getStaticStringValue(arkFile, value); + } else if (value instanceof ArkStaticFieldRef && value.getType() instanceof ClassType) { + return this.getStaticStringValue(arkFile, value); + } + return ''; + } + + private static getValueImportInfo(arkFile: ArkFile, value: Local): ImportInfo | undefined { + let importInfos = arkFile.getImportInfos(); + for (let importInfo of importInfos) { + if (importInfo.getImportClauseName() === value.getName()) { + return importInfo; + } + } + return undefined; + } + + private static getImportStringValue(importInfo: ImportInfo, value: Local): string { + let exportInfo = importInfo.getLazyExportInfo(); + let importArkFile = exportInfo?.getDeclaringArkFile(); + if (!importArkFile) { + return ''; + } + let scope = CheckerStorage.getInstance().getScope(importArkFile.getFilePath()); + if (!scope) { + return ''; + } + for (let varDef of scope.defList) { + if (varDef.getName() === value.getName()) { + continue; + } + let stmt = varDef.defStmt; + const text = stmt.getOriginalText(); + if (!text || text.length === 0 || !text.includes('const')) { + continue; + } + if (stmt instanceof ArkAssignStmt) { + let defStmtInfo = new VarInfo(stmt, scope); + let rightOp = stmt.getRightOp(); + return this.getStringByScope(importArkFile, defStmtInfo, rightOp); + } + } + return ''; + } + + private static getMethodStringValue(arkFile: ArkFile, valueStmtInfo: VarInfo, value: Local): string { + let scope: Scope = valueStmtInfo.scope; + let valueStmt: Stmt = valueStmtInfo.stmt; + let hasFind = false; + if (!scope || !scope.defList) { + return ''; + } + let defLists = scope.defList; + for (let defVar of defLists) { + if (defVar.getName() !== value.getName()) { + continue; + } + hasFind = true; + let nearReDefStmtInfo = new VarInfo(defVar.defStmt, scope); + let reDefStmtInfos = defVar.redefInfo; + for (let reDefStmtInfo of reDefStmtInfos) { + let originalLine = valueStmt.getOriginPositionInfo().getLineNo(); + let redefLine = reDefStmtInfo.stmt.getOriginPositionInfo().getLineNo(); + if (redefLine >= originalLine) { + break; + } + nearReDefStmtInfo = reDefStmtInfo; + } + let stmt = nearReDefStmtInfo.stmt; + if (stmt instanceof ArkAssignStmt) { + let rightOp = stmt.getRightOp(); + return this.getStringByScope(arkFile, nearReDefStmtInfo, rightOp); + } + } + if (!hasFind && scope.parentScope !== null) { + let defStmtInfo = new VarInfo(valueStmt, scope.parentScope); + return this.getStringByScope(arkFile, defStmtInfo, value); + } + return ''; + } + + private static getExprStringValue(arkFile: ArkFile, stmtInfo: VarInfo, value: AbstractExpr): string { + if (value instanceof ArkNormalBinopExpr) { + let stringOfOp1 = this.getStringByScope(arkFile, stmtInfo, value.getOp1()); + let stringOfOp2 = this.getStringByScope(arkFile, stmtInfo, value.getOp2()); + switch (value.getOperator()) { + case '+': + return stringOfOp1 + stringOfOp2; + } + } + return ''; + } + + private static getStaticStringValue(arkFile: ArkFile, value: ArkStaticFieldRef): string { + let classSignature = value.getFieldSignature().getDeclaringSignature(); + if (!(classSignature instanceof ClassSignature)) { + return ''; + } + let fieldSignature = classSignature.getDeclaringFileSignature(); + let staticClassArkFile = arkFile.getScene().getFile(fieldSignature); + if (!staticClassArkFile) { + return ''; + } + let staticClass = staticClassArkFile.getClass(classSignature); + if (!staticClass) { + return ''; + } + let staticField = staticClass.getStaticFieldWithName(value.getFieldName()); + if (!staticField) { + return ''; + } + if (staticClass.getCategory() === ClassCategory.CLASS && !staticField.isReadonly()) { + return ''; + } + let stmts = staticField.getInitializer(); + if (stmts.length === 0) { + return ''; + } + let stmt = stmts[0]; + let varInfo = new VarInfo(stmt, (stmt as StmtExt).scope); + if (!(stmt instanceof ArkAssignStmt)) { + return ''; + } + let initValue = stmt.getRightOp(); + return this.getStringByScope(staticClassArkFile, varInfo, initValue); + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/TypeUtils.ts b/ets2panda/linter/homecheck/src/utils/checker/TypeUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..d592f86fc190bf570e63918c71fd55182d82a6e8 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/TypeUtils.ts @@ -0,0 +1,193 @@ +/* + * 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 { AliasType, ArrayType, ClassType, FunctionType, GenericType, TupleType, Type, UnclearReferenceType, UnionType } from 'arkanalyzer'; + +/** + * 检查类型是否为指定类型 + * + * @param appointType 指定类型 + * @param type 被检查类型 + * @returns + */ +export function isAppointType(appointType: Type, type: Type): boolean { + + if (appointType.getTypeString() === type.getTypeString()) { + return true; + } + + if (type instanceof ArrayType) { + return isAppointType(appointType, type.getBaseType()); + } + + if (type instanceof UnclearReferenceType) { + return generic(appointType, type.getGenericTypes()); + } + + if (type instanceof UnionType) { + return generic(appointType, type.getTypes()); + } + + if (type instanceof FunctionType) { + return generic(appointType, type.getRealGenericTypes()); + } + + if (type instanceof ClassType) { + return generic(appointType, type.getRealGenericTypes()); + } + + if (type instanceof TupleType) { + return generic(appointType, type.getTypes()); + } + + if (type instanceof AliasType) { + return isAppointType(appointType, type.getOriginalType()); + } + + if (type instanceof GenericType) { + let defType = type.getDefaultType(); + let constraintType = type.getConstraint(); + return (defType ? isAppointType(appointType, defType) : false) || + (constraintType ? isAppointType(appointType, constraintType) : false); + } + return false; +} + +function generic(appointType: Type, type: Type[] | undefined): boolean { + if (!type) { + return false; + } + for (const t of type) { + if (isAppointType(appointType, t)) { + return true; + } + } + return false; +} + +/** + * 递归替换类型中的指定类型 + * + * @param appointType 指定类型 + * @param type 需要被替换的类型 + * @param newType 新的类型 + * @returns + */ +export function fixAppointType(appointType: Type, type: Type, newType: Type): Type { + if (appointType.getTypeString() === type.getTypeString()) { + return newType; + } + + if (type instanceof ArrayType) { + type.setBaseType(fixAppointType(appointType, type.getBaseType(), newType)); + return type; + } + + if (type instanceof UnclearReferenceType) { + return handleUnclearReferenceType(appointType, type, newType); + } + + if (type instanceof UnionType) { + return handleUnionType(appointType, type, newType); + } + + if (type instanceof FunctionType) { + return handleFunctionType(appointType, type, newType); + } + + if (type instanceof ClassType) { + return handleClassType(appointType, type, newType); + } + + if (type instanceof TupleType) { + return handleTupleType(appointType, type, newType); + } + + if (type instanceof AliasType) { + type.setOriginalType(fixAppointType(appointType, type.getOriginalType(), newType)); + return type; + } + + if (type instanceof GenericType) { + return handleGenericType(appointType, type, newType); + } + return type; +} + +// 处理 UnclearReferenceType 的逻辑 +function handleUnclearReferenceType(appointType: Type, type: UnclearReferenceType, newType: Type): Type { + const genericTypes = type.getGenericTypes() || []; + for (let i = 0; i < genericTypes.length; i++) { + genericTypes[i] = fixAppointType(appointType, genericTypes[i], newType); + } + return new UnclearReferenceType(type.getName(), genericTypes); +} + +// 处理 UnionType 的逻辑 +function handleUnionType(appointType: Type, type: UnionType, newType: Type): Type { + const unionTypes = type.getTypes() || []; + for (let i = 0; i < unionTypes.length; i++) { + unionTypes[i] = fixAppointType(appointType, unionTypes[i], newType); + } + return new UnionType(unionTypes); +} + +// 处理 FunctionType 的逻辑 +function handleFunctionType(appointType: Type, type: FunctionType, newType: Type): Type { + const realGenericTypes = type.getRealGenericTypes() || []; + for (let i = 0; i < realGenericTypes.length; i++) { + realGenericTypes[i] = fixAppointType(appointType, realGenericTypes[i], newType); + } + return new FunctionType(type.getMethodSignature(), realGenericTypes); +} + +// 处理 ClassType 的逻辑 +function handleClassType(appointType: Type, type: ClassType, newType: Type): Type { + const realGenericTypes = type.getRealGenericTypes() || []; + for (let i = 0; i < realGenericTypes.length; i++) { + realGenericTypes[i] = fixAppointType(appointType, realGenericTypes[i], newType); + } + type.setRealGenericTypes(realGenericTypes); + return type; +} + +// 处理 TupleType 的逻辑 +function handleTupleType(appointType: Type, type: TupleType, newType: Type): Type { + const tupleTypes = type.getTypes() || []; + for (let i = 0; i < tupleTypes.length; i++) { + tupleTypes[i] = fixAppointType(appointType, tupleTypes[i], newType); + } + return new TupleType(tupleTypes); +} + +// 处理 GenericType 的逻辑 +function handleGenericType(appointType: Type, type: GenericType, newType: Type): Type { + let defType = type.getDefaultType(); + let constraintType = type.getConstraint(); + if (defType) { + defType = fixAppointType(appointType, defType, newType); + } + if (constraintType) { + constraintType = fixAppointType(appointType, constraintType, newType); + } + if (defType) { + type.setDefaultType(defType); + } + + if (constraintType) { + type.setConstraint(constraintType); + } + return type; +} diff --git a/ets2panda/linter/homecheck/src/utils/checker/ViewTreeTool.ts b/ets2panda/linter/homecheck/src/utils/checker/ViewTreeTool.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0efc7e602205375faa7644acd9ba6927adda6d0 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/ViewTreeTool.ts @@ -0,0 +1,40 @@ +/* + * 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. + */ +import { ViewTreeNode } from 'arkanalyzer'; +import { ArkClass } from 'arkanalyzer'; + +export class ViewTreeTool { + private recordMap: Map; + + constructor() { + this.recordMap = new Map(); + } + + hasTraverse(item: ArkClass | ViewTreeNode): boolean { + let classSig = ''; + if (item instanceof ArkClass) { + classSig = item.getSignature().toString(); + } else { + if (item.signature) { + classSig = item.signature.toString(); + } else { + return false; + } + } + let result = this.recordMap.get(classSig); + this.recordMap.set(classSig, true); + return result === true; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/bmp.ts b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/bmp.ts new file mode 100644 index 0000000000000000000000000000000000000000..58a20fcc462a727f2edcd55b791b55d4ab3ecf9e --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/bmp.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +import type { ImageData } from '../../../model/Interfaces'; +import { readInt32LE, readUInt32LE, toUTF8String } from '../BytesUtils'; + +export const BMP: ImageData = { + validate: (input) => toUTF8String(input, 0, 2) === 'BM', + calculate: (input) => ({ + height: Math.abs(readInt32LE(input, 22)), + width: readUInt32LE(input, 18), + }), +}; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/jpg.ts b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/jpg.ts new file mode 100644 index 0000000000000000000000000000000000000000..04950560341cde2b4f4b70e4e1b572360e839257 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/jpg.ts @@ -0,0 +1,117 @@ +/* + * 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. + */ + +import type { ImageInfo, ImageData } from '../../../model/Interfaces'; +import { readUInt, readUInt16BE, toHexString } from '../BytesUtils'; + +const EXIF_MARKER = '45786966'; +const APP1_DATA_SIZE_BYTES = 2; +const EXIF_HEADER_BYTES = 6; +const TIFF_BYTE_ALIGN_BYTES = 2; +const BIG_ENDIAN_BYTE_ALIGN = '4d4d'; +const LITTLE_ENDIAN_BYTE_ALIGN = '4949'; +const IDF_ENTRY_BYTES = 12; +const NUM_DIRECTORY_ENTRIES_BYTES = 2; + +function isEXIF(input: Uint8Array): boolean { + return toHexString(input, 2, 6) === EXIF_MARKER; +} + +function extractSize(input: Uint8Array, index: number): ImageInfo { + return { + height: readUInt16BE(input, index), + width: readUInt16BE(input, index + 2), + }; +} + + +function extractOrientation(exifBlock: Uint8Array, isBigEndian: boolean): number | undefined { + const idfOffset = 8; + const offset = EXIF_HEADER_BYTES + idfOffset; + const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian); + for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) { + const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES; + const end = start + IDF_ENTRY_BYTES; + if (start > exifBlock.length) { + return undefined; + } + const block = exifBlock.slice(start, end); + const tagNumber = readUInt(block, 16, 0, isBigEndian); + if (tagNumber === 274) { + const dataFormat = readUInt(block, 16, 2, isBigEndian); + if (dataFormat !== 3) { + return undefined; + } + const numberOfComponents = readUInt(block, 32, 4, isBigEndian); + if (numberOfComponents !== 1) { + return undefined; + } + return readUInt(block, 16, 8, isBigEndian); + } + } + return undefined; +} + +function validateExifBlock(input: Uint8Array, index: number): number | undefined { + const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index); + const byteAlign = toHexString(exifBlock, EXIF_HEADER_BYTES, EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES); + const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN; + const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN; + if (isBigEndian || isLittleEndian) { + return extractOrientation(exifBlock, isBigEndian); + } + return undefined; +} + +function validateInput(input: Uint8Array, index: number): void { + if (index > input.length) { + throw new TypeError('Corrupt JPG, exceeded buffer limits'); + } +} + +export const JPG: ImageData = { + validate: (input) => toHexString(input, 0, 2) === 'ffd8', + + calculate(_input) { + let input = _input.slice(4); + let orientation: number | undefined; + let next: number; + while (input.length) { + const i = readUInt16BE(input, 0); + if (input[i] !== 0xff) { + input = input.slice(1); + continue; + } + if (isEXIF(input)) { + orientation = validateExifBlock(input, i); + } + validateInput(input, i); + next = input[i + 1]; + if (next === 0xc0 || next === 0xc1 || next === 0xc2) { + const size = extractSize(input, i + 5); + if (!orientation) { + return size; + } + return { + height: size.height, + orientation, + width: size.width, + }; + } + input = input.slice(i + 2); + } + throw new TypeError('Invalid JPG, no size found'); + }, +}; \ No newline at end of file diff --git a/ets2panda/ast_verifier/checkInfiniteLoop.h b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/png.ts similarity index 30% rename from ets2panda/ast_verifier/checkInfiniteLoop.h rename to ets2panda/linter/homecheck/src/utils/checker/imageFormat/png.ts index ddf98a21def464e750327ee3465a3f9da16c6bfc..81b12981e46e62e45e12dadb866b7ff0dae22901 100644 --- a/ets2panda/ast_verifier/checkInfiniteLoop.h +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/png.ts @@ -1,10 +1,10 @@ /* - * 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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -13,24 +13,38 @@ * limitations under the License. */ -#ifndef ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKINFINITELOOP_H -#define ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKINFINITELOOP_H +import type { ImageData } from '../../../model/Interfaces'; +import { readUInt32BE, toUTF8String } from '../BytesUtils'; -#include "checkContext.h" +const pngSignature = 'PNG\r\n\x1a\n'; +const pngImageHeaderChunkName = 'IHDR'; +const pngFriedChunkName = 'CgBI'; -namespace ark::es2panda::compiler::ast_verifier { +export const PNG: ImageData = { + validate(input) { + if (pngSignature === toUTF8String(input, 1, 8)) { + let chunkName = toUTF8String(input, 12, 16); + if (chunkName === pngFriedChunkName) { + chunkName = toUTF8String(input, 28, 32); + } + if (chunkName !== pngImageHeaderChunkName) { + throw new TypeError('Invalid PNG'); + } + return true; + } + return false; + }, -class CheckInfiniteLoop : public RecursiveInvariant { - template - friend class InvariantBase; - [[nodiscard]] CheckResult operator()(const ir::AstNode *ast); - bool ConditionIsAlwaysTrue(const ir::Expression *const test) const; - bool HasBreakOrReturnStatement(const ir::Statement *const body) const; - [[nodiscard]] CheckResult HandleWhileStatement(const ir::WhileStatement *const stmt); - [[nodiscard]] CheckResult HandleDoWhileStatement(const ir::DoWhileStatement *const stmt); - [[nodiscard]] CheckResult HandleForUpdateStatement(const ir::ForUpdateStatement *const stmt); -}; - -} // namespace ark::es2panda::compiler::ast_verifier - -#endif // ES2PANDA_COMPILER_CORE_AST_VERIFIER_CHECKINFINITELOOP_H + calculate(input) { + if (toUTF8String(input, 12, 16) === pngFriedChunkName) { + return { + height: readUInt32BE(input, 36), + width: readUInt32BE(input, 32), + }; + } + return { + height: readUInt32BE(input, 20), + width: readUInt32BE(input, 16), + }; + }, +}; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/svg.ts b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/svg.ts new file mode 100644 index 0000000000000000000000000000000000000000..7c681289422140334459d7da3e93a24ba39377d5 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/svg.ts @@ -0,0 +1,100 @@ +/* + * 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. + */ + +import type { ImageInfo, ImageData, IAttributes } from '../../../model/Interfaces'; +import { toUTF8String, getLength } from '../BytesUtils'; + +const svgReg = /"']|"[^"]*"|'[^']*')*>/; +const extractorRegExps = { + root: svgReg, + height: /\sheight=(['"])([^%]+?)\1/, + width: /\swidth=(['"])([^%]+?)\1/, + viewbox: /\sviewbox=(['"])(.+?)\1/i, +}; + +function parseViewbox(viewbox: string): IAttributes | undefined { + const bounds = viewbox.split(' '); + let tmpWeight = getLength(bounds[3]); + let tmpWidth = getLength(bounds[2]); + if (tmpWidth && tmpWeight) { + return { height: tmpWeight, width: tmpWidth }; + } + return undefined; +} + +function getAttirbutes(root: string): IAttributes | undefined { + const widths = root.match(extractorRegExps.width); + const heights = root.match(extractorRegExps.height); + const viewbox = root.match(extractorRegExps.viewbox); + if (widths && heights && viewbox) { + let tempHeight = getLength(heights[2]); + let tmpWidth = getLength(widths[2]); + if (tmpWidth && tempHeight) { + return { + height: heights && tempHeight, + viewbox: viewbox && parseViewbox(viewbox[2]), + width: widths && tmpWidth, + }; + } + } + return undefined; +} + +function calculateByDimensions(attrs: IAttributes): ImageInfo { + return { + height: attrs.height as number, + width: attrs.width as number, + }; +} + +function calculateByViewbox(attrs: IAttributes, viewbox: IAttributes): ImageInfo { + const ratio = (viewbox.width as number) / (viewbox.height as number); + if (attrs.height) { + return { + height: attrs.height, + width: Math.floor(attrs.height * ratio) + }; + } else if (attrs.width) { + return { + height: Math.floor(attrs.width * ratio), + width: attrs.width, + }; + } else { + return { + height: viewbox.height as number, + width: viewbox.width as number, + }; + } +} + +export const SVG: ImageData = { + validate: (input) => svgReg.test(toUTF8String(input, 0, 1000)), + + calculate(input) { + const root = toUTF8String(input).match(extractorRegExps.root); + if (root) { + const attrs = getAttirbutes(root[0]); + if (attrs) { + if (attrs.width && attrs.height) { + return calculateByDimensions(attrs); + } + if (attrs.viewbox) { + return calculateByViewbox(attrs, attrs.viewbox); + } + } + } + throw new TypeError('Invalid SVG'); + }, +}; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/checker/imageFormat/webp.ts b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/webp.ts new file mode 100644 index 0000000000000000000000000000000000000000..554281816ff323234b677830fa7a3bac33c49178 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/checker/imageFormat/webp.ts @@ -0,0 +1,68 @@ +/* + * 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. + */ + +import type { ImageInfo, ImageData } from '../../../model/Interfaces'; +import { readInt16LE, readUInt24LE, toHexString, toUTF8String } from '../BytesUtils'; + +function calculateExtended(input: Uint8Array): ImageInfo { + return { + height: 1 + readUInt24LE(input, 7), + width: 1 + readUInt24LE(input, 4), + }; +} + +function calculateLossLess(input: Uint8Array): ImageInfo { + return { + height: 1 + (((input[4] & 0xf) << 10) | (input[3] << 2) | ((input[2] & 0xc0) >> 6)), + width: 1 + (((input[2] & 0x3f) << 8) | input[1]), + }; +} + +function calculateLossy(input: Uint8Array): ImageInfo { + return { + height: readInt16LE(input, 8) & 0x3fff, + width: readInt16LE(input, 6) & 0x3fff, + }; +} + +export const WEBP: ImageData = { + validate(input) { + const riffHeader = 'RIFF' === toUTF8String(input, 0, 4); + const webpHeader = 'WEBP' === toUTF8String(input, 8, 12); + const vp8Header = 'VP8' === toUTF8String(input, 12, 15); + return riffHeader && webpHeader && vp8Header; + }, + calculate(_input) { + const chunkHeader = toUTF8String(_input, 12, 16); + const input = _input.slice(20, 30); + if (chunkHeader === 'VP8X') { + const extendedHeader = input[0]; + const validStart = (extendedHeader & 0xc0) === 0; + const validEnd = (extendedHeader & 0x01) === 0; + if (validStart && validEnd) { + return calculateExtended(input); + } + throw new TypeError('Invalid WebP'); + } + if (chunkHeader === 'VP8' && input[0] !== 0x2f) { + return calculateLossy(input); + } + const signature = toHexString(input, 3, 6); + if (chunkHeader === 'VP8L' && signature !== '9d012a') { + return calculateLossLess(input); + } + throw new TypeError('Invalid WebP'); + }, +}; \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/AfterCheck.ts b/ets2panda/linter/homecheck/src/utils/common/AfterCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..762f51232073302fc22b4ccdc80da666537288c8 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/AfterCheck.ts @@ -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. + */ + +import { FileReports } from '../../Index'; +import { CheckEntry } from './CheckEntry'; + +export async function processAfterCheck(checkEntry: CheckEntry): Promise { + // 按规则维度统计告警信息,按文件维度汇总告警信息 + const fileIssues = checkEntry.sortIssues(); + let fileReports: FileReports[] = []; + if (checkEntry.projectConfig.fix === 'true') { + // 代码修复 + fileReports = checkEntry.codeFix(fileIssues); + } else { + // 转换输出格式,去掉fix相关信息 + fileIssues.forEach((fileIssue) => { + fileReports.push({ filePath: fileIssue.filePath, defects: fileIssue.issues.map(issue => issue.defect) }); + }); + } + // 发送消息 + await checkEntry.message?.sendResult(fileReports, checkEntry.projectConfig.reportDir); +} diff --git a/ets2panda/linter/homecheck/src/utils/common/CheckBuilder.ts b/ets2panda/linter/homecheck/src/utils/common/CheckBuilder.ts new file mode 100644 index 0000000000000000000000000000000000000000..1fa55aca999d6b2d851c879497439d33d1e1a10c --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/CheckBuilder.ts @@ -0,0 +1,51 @@ +/* + * 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. + */ +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { ArkFile } from 'arkanalyzer'; +import { Rule, BaseChecker } from '../../Index'; +import { File2Check } from '../../model/File2Check'; +import { Project2Check } from '../../model/Project2Check'; +import { CheckerFactory } from './CheckerFactory'; + + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CheckBuilder'); + +export function fileCheckBuilder(arkFile: ArkFile, enabledRules: Rule[]): File2Check { + let checkIns = new File2Check(); + checkIns.arkFile = arkFile; + enabledRules.forEach(rule => { + const checkerInstance = CheckerFactory.getChecker(rule); + if (checkerInstance) { + checkIns.addChecker(rule.ruleId, checkerInstance as BaseChecker); + } else { + logger.error(`Cannot find checker according rule id: ${rule.ruleId}`); + } + }); + return checkIns; +} + +export function projectCheckBuilder(arkFiles: ArkFile[], enabledRules: Rule[]): Project2Check { + let checkIns = new Project2Check(); + checkIns.arkFiles = arkFiles; + enabledRules.forEach(rule => { + const checkerInstance = CheckerFactory.getChecker(rule); + if (checkerInstance) { + checkIns.addChecker(rule.ruleId, checkerInstance as BaseChecker); + } else { + logger.log(`Cannot find checker according rule id: ${rule.ruleId}`); + } + }); + return checkIns; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts b/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts new file mode 100644 index 0000000000000000000000000000000000000000..e08dbb90f7327a8e624256650a80fbfc70c3d4fb --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/CheckEntry.ts @@ -0,0 +1,281 @@ +/* + * 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. + */ + +import { Scene } from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { SceneConfig } from 'arkanalyzer'; +import { fileRuleMapping } from './FileRuleMapping'; +import { RuleConfig } from '../../model/RuleConfig'; +import { ProjectConfig, SelectedFileInfo } from '../../model/ProjectConfig'; +import { Project2Check } from '../../model/Project2Check'; +import { File2Check } from '../../model/File2Check'; +import { DisableText } from './Disable'; +import { Message } from '../../model/Message'; +import { FileUtils } from './FileUtils'; +import { ScopeHelper } from './ScopeHelper'; +import { RuleListUtil } from './DefectsList'; +import { FixMode } from '../../model/Fix'; +import { FileIssues, FileReports, IssueReport, engine } from '../../model/Defects'; +import { FixUtils } from './FixUtils'; +import { FixEngine } from '../../codeFix/FixEngine'; +import { CheckerUtils } from '../checker/CheckerUtils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CheckEntry'); + +export class CheckEntry { + public ruleConfig: RuleConfig; + public projectConfig: ProjectConfig; + public projectCheck: Project2Check; + public fileChecks: File2Check[] = []; + public scene: Scene; + public message: Message; + public selectFileList: SelectedFileInfo[] = []; + + constructor() { + } + + public addFileCheck(fileCheck: File2Check): void { + this.fileChecks.push(fileCheck); + } + + public addProjectCheck(projectCheck: Project2Check): void { + this.projectCheck = projectCheck; + } + + public setDisableText(fileDisableText: string, nextLineDisableText: string): void { + DisableText.FILE_DISABLE_TEXT = fileDisableText; + DisableText.NEXT_LINE_DISABLE_TEXT = nextLineDisableText; + } + + public setEngineName(engineName: string): void { + engine.engineName = engineName; + } + + public setCheckFileList(selectFileList: SelectedFileInfo[]): void { + this.selectFileList = selectFileList; + } + + public setMessage(message: Message): void { + this.message = message; + } + + public async runAll(): Promise { + // TODO: worker_threads改造 + let checkedIndex = 1; + for (const fileCheck of this.fileChecks) { + try { + await fileCheck.run(); + // 进度条通知 + this.message?.progressNotify(checkedIndex / (this.fileChecks.length + 1), fileCheck.arkFile.getFilePath()); + checkedIndex++; + } catch (error) { + logger.error(`Error running file check for ${fileCheck.arkFile.getFilePath()}: ${(error as Error).message}`); + continue; + } + } + + if (this.projectCheck) { + try { + await this.projectCheck.run(); + this.message?.progressNotify(checkedIndex / (this.fileChecks.length + 1), 'Project Check'); + } catch (error) { + logger.error(`Error running project check: ${(error as Error).message}`); + } + } + } + + /** + * 按规则维度统计并输出告警信息,按文件维度汇总并返回告警信息。 + * + * @returns FileReport[] 文件报告数组,每个元素包含文件名、缺陷列表和输出信息 + */ + public sortIssues(): FileIssues[] { + const issuesMapByChecker: Map = new Map(); + const issuesMapByFile: Map = new Map(); + RuleListUtil.printDefects(); + for (const fileCheck of this.fileChecks) { + if (!fileCheck.issues || fileCheck.issues.length === 0) { + continue; + } + issuesMapByFile.set(fileCheck.arkFile.getFilePath(), fileCheck.issues); + for (const issue of fileCheck.issues) { + logger.debug(issue.defect.mergeKey); + const checkerStorage = issuesMapByChecker.get(issue.defect.ruleId); + if (checkerStorage) { + checkerStorage.push(issue); + } else { + issuesMapByChecker.set(issue.defect.ruleId, [issue]); + } + } + } + + for (const issue of this.projectCheck?.issues ?? []) { + logger.debug(issue.defect.mergeKey); + const checkerStorage = issuesMapByChecker.get(issue.defect.ruleId); + if (checkerStorage) { + checkerStorage.push(issue); + } else { + issuesMapByChecker.set(issue.defect.ruleId, [issue]); + } + + const filePath = issue.defect.mergeKey.split('%')[0]; + const fileStorage = issuesMapByFile.get(filePath); + if (fileStorage) { + fileStorage.push(issue); + } else { + issuesMapByFile.set(filePath, [issue]); + } + } + issuesMapByChecker.forEach((issues, checker) => { + logger.info(issues.length + ' issues from checker - ' + checker); + }); + const fileReports: FileIssues[] = []; + issuesMapByFile.forEach((issues, filePath) => { + fileReports.push({ filePath, issues }); + }); + return fileReports; + } + + public buildScope(): void { + new ScopeHelper().buildScope(this.scene); + } + + /** + * 修复代码问题 + * + * @param fileIssues 以文件为维度的issues信息 + * @returns 修复后的文件报告数组,去掉已修复issues,且需更新未修复issues行列号等信息 + */ + public codeFix(fileIssues: FileIssues[]): FileReports[] { + const fileReports: FileReports[] = []; + for (const fileIssue of fileIssues) { + const arkFile = CheckerUtils.getArkFileByFilePath(this.scene, fileIssue.filePath); + if (!arkFile) { + fileReports.push({ filePath: fileIssue.filePath, defects: fileIssue.issues.map(issue => issue.defect) }); + continue; + } + let keys: string[] = []; + let isFixAll = false; + // 寻找该文件的fixKey,即需要修复的issue + for (const fileInfo of this.selectFileList) { + if (fileInfo.fixKey && fileInfo.filePath === fileIssue.filePath) { + keys = fileInfo.fixKey; + break; + } + } + // 没有指定key,则修复所有issue + if (keys.length === 0) { + isFixAll = true; + } + + const remainIssues: IssueReport[] = []; + const astFixIssues: IssueReport[] = []; + this.classifyIssues(fileIssue.issues, isFixAll, keys, astFixIssues, remainIssues); + const astFixReport = new FixEngine().getEngine(FixMode.AST).applyFix(arkFile, astFixIssues, remainIssues); + fileReports.push(astFixReport); + } + return fileReports; + } + + private classifyIssues(allIssues: IssueReport[], fixAll: boolean, keys: string[], astFixIssues: IssueReport[], + remainIssues: IssueReport[]): void { + for (const issue of allIssues) { + if (fixAll || keys.includes(issue.defect.fixKey)) { + if (issue.fix && issue.defect.fixable && FixUtils.isRuleFix(issue.fix)) { + astFixIssues.push(issue); + } else { + remainIssues.push(issue); + logger.debug('Fix type is unsupported.'); + } + } else { + remainIssues.push(issue); + } + } + } +} + +export async function checkEntryBuilder(checkEntry: CheckEntry): Promise { + // 1、 无指定文件则检查项目下所有文件 + let checkFileList = checkEntry.selectFileList.map(file => file.filePath); + if (checkFileList.length === 0) { + checkFileList = FileUtils.getAllFiles(checkEntry.projectConfig.projectPath, ['.ts', '.ets', '.js', '.json5']); + } + + // 2、文件过滤和文件级屏蔽处理 + checkFileList = await FileUtils.getFiltedFiles(checkFileList, checkEntry.ruleConfig); + logger.info('File count: ' + checkFileList.length); + if (checkFileList.length === 0) { + checkEntry.message?.progressNotify(1, 'No file to check.'); + return false; + } + + // 3、scene按需构建、scope构建 + if (!buildScene(checkFileList, checkEntry)) { + return false; + } + + // 4、规则和文件映射构建 + if (!(await fileRuleMapping(checkFileList, checkEntry))) { + return false; + } + return true; +} + +/** + * 获取指定检查的文件列表 + * + * @param checkFilePath - 指定的检查文件路径的配置文件路径,该文件内容示例{'checkPath': [{'filePath': 'xxx', 'fixKey': ['%line%sCol%eCol%ruleId']}]} + * filePath为需要检查的文件路径,fixKey为需要修复的缺陷key,空数组则不修复。 + * @returns SelectFileInfo[] - 需要检查的文件列表 + */ +export function getSelectFileList(checkFilePath: string): SelectedFileInfo[] { + if (checkFilePath.length > 0) { + // 解析指定的文件 + return FileUtils.getSeletctedFileInfos(checkFilePath, ['.ts', '.ets', '.json5']); + } + return []; +} + +/** + * 构建Scene + * @param fileList - 文件列表 + * @param checkEntry - 检查条目 + * @returns {boolean} - 构建是否成功 + */ +function buildScene(fileList: string[], checkEntry: CheckEntry): boolean { + try { + // 构建SceneConfig信息 + const sceneConfig = new SceneConfig(); + const projectName = checkEntry.projectConfig.projectName; + const projectPath = checkEntry.projectConfig.projectPath; + const languageTags = checkEntry.projectConfig.languageTags; + const sdkList = FileUtils.genSdks(checkEntry.projectConfig); + sceneConfig.buildFromProjectFiles(projectName, projectPath, fileList, sdkList, languageTags); + logger.info('Build sceneConfig completed.'); + // 构建Scene信息 + checkEntry.scene = new Scene(); + checkEntry.scene.buildSceneFromFiles(sceneConfig); + logger.info('Build scene completed.'); + checkEntry.scene.inferTypes(); + logger.info('Infer types completed.'); + } catch (error) { + logger.error('Build scene or infer types error: ', error); + return false; + } + // 构建Scope信息 + checkEntry.buildScope(); + logger.info('Build scope completed.'); + return true; +} diff --git a/ets2panda/linter/homecheck/src/utils/common/CheckerFactory.ts b/ets2panda/linter/homecheck/src/utils/common/CheckerFactory.ts new file mode 100644 index 0000000000000000000000000000000000000000..09611792395d0788dc46c1cbb48577188115b68f --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/CheckerFactory.ts @@ -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. + */ +import { BaseChecker } from '../../checker/BaseChecker'; +import { Rule } from '../../model/Rule'; +import { ProxyChecker } from './CheckerIndex'; + +export class CheckerFactory { + static getChecker(rule: Rule): BaseChecker | null { + const checkerInstance = ProxyChecker.getClass(rule.ruleId); + if (!checkerInstance) { + return null; + } + checkerInstance.rule = rule; + return checkerInstance; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/CheckerIndex.ts b/ets2panda/linter/homecheck/src/utils/common/CheckerIndex.ts new file mode 100644 index 0000000000000000000000000000000000000000..b022e5bd1227339a2646678c688f74b18f39cb1e --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/CheckerIndex.ts @@ -0,0 +1,66 @@ +/* + * 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. + */ + +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { ObservedDecoratorCheck } from '../../checker/migration/ObservedDecoratorCheck'; +import { ThisBindCheck } from '../../checker/migration/ThisBindCheck'; +import { ObjectLiteralCheck } from '../../checker/migration/ObjectLiteralCheck'; +import { AppStorageGetCheck } from '../../checker/migration/AppStorageGetCheck'; +import { ModifyStateVarCheck } from '../../checker/migration/ModifyStateVarCheck'; +import { NoMethodOverridingFieldCheck } from '../../checker/migration/NoMethodOverridingFieldCheck'; +import { CustomBuilderCheck } from '../../checker/migration/CustomBuilderCheck'; +import { InteropBackwardDFACheck } from '../../checker/migration/InteropBackwardDFACheck'; +import { InteropBoxedTypeCheck } from '../../checker/migration/InteropBoxedTypeCheck'; +import { InteropObjectLiteralCheck } from '../../checker/migration/InteropDynamicObjectLiteralsCheck'; +import { InteropAssignCheck } from '../../checker/migration/InteropAssignCheck'; +import { InteropJSModifyPropertyCheck } from '../../checker/migration/InteropJSModifyPropertyCheck'; +import { NoTSLikeAsCheck } from '../../checker/migration/NoTSLikeAsCheck'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CheckerIndex'); + +export const fileRules = { + '@migration/arkts-instance-method-bind-this': ThisBindCheck, + '@migration/arkui-data-observation': ObservedDecoratorCheck, + '@migration/arkui-stateful-appstorage': AppStorageGetCheck, + '@migration/arkui-no-update-in-build': ModifyStateVarCheck, + '@migration/arkui-custombuilder-passing': CustomBuilderCheck, + '@migration/no-method-overriding-field-check': NoMethodOverridingFieldCheck, + '@migration/interop-boxed-type-check': InteropBoxedTypeCheck, +}; + +export const projectRules = { + '@migration/arkts-obj-literal-generate-class-instance': ObjectLiteralCheck, + '@migration/interop-backward-dfa': InteropBackwardDFACheck, + '@migration/interop-assign': InteropAssignCheck, + '@migration/interop-js-modify-property': InteropJSModifyPropertyCheck, + '@migration/interop-dynamic-object-literals': InteropObjectLiteralCheck, + '@migration/arkts-no-ts-like-as': NoTSLikeAsCheck, +}; + +// 新增文件级的checker,需要在此处注册 +export const file2CheckRuleMap: Map = new Map(Object.entries(fileRules)); +// 新增项目级checker,需要在此处注册 +export const project2CheckRuleMap: Map = new Map(Object.entries(projectRules)); + +export class ProxyChecker { + static getClass(ruleId: string): any { + const checker = file2CheckRuleMap.get(ruleId) ?? project2CheckRuleMap.get(ruleId); + if (!checker) { + logger.error(`${ruleId} is not matched to any checker`); + return null; + } + return new checker(); + } +} diff --git a/ets2panda/linter/homecheck/src/utils/common/CheckerStorage.ts b/ets2panda/linter/homecheck/src/utils/common/CheckerStorage.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3bedd5017d59910d6579916b5fb00d2a2f1a9c3 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/CheckerStorage.ts @@ -0,0 +1,83 @@ +/* + * 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. + */ + +import { Scope } from '../../model/Scope'; + +export class CheckerStorage { + private static instance: CheckerStorage; + private scopeMap: Map = new Map(); + private apiVersion: number = 16; + private product: string = ''; + + /** + * 获取 CheckerStorage 的单例实例 + * @returns {CheckerStorage} CheckerStorage 的单例实例 + */ + public static getInstance(): CheckerStorage { + if (!CheckerStorage.instance) { + CheckerStorage.instance = new CheckerStorage(); + } + return CheckerStorage.instance; + } + + /** + * 根据文件路径获取Scope + * @param filePath - 文件路径 + * @returns Scope | undefined - 返回Scope对象或undefined + */ + public getScope(filePath: string): Scope | undefined { + return this.scopeMap.get(filePath); + } + + /** + * 设置Scope映射 + * @param scopeMap - Scope映射,类型为 Map + */ + public setScopeMap(scopeMap: Map): void { + this.scopeMap = scopeMap; + } + + /** + * 设置API版本 + * @param api API版本号 + */ + public setApiVersion(api: number): void { + this.apiVersion = api; + } + + /** + * 获取API版本号 + * @returns {number} 返回API版本号 + */ + public getApiVersion(): number { + return this.apiVersion; + } + + /** + * 设置product + * @param product + */ + public setProduct(pro: string): void { + this.product = pro; + } + + /** + * 获取product + * @returns {string} 返回product + */ + public getProduct(): string { + return this.product; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/ConfigUtils.ts b/ets2panda/linter/homecheck/src/utils/common/ConfigUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..79d18b719741c68ef60459e3160cb7b46f1386ee --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/ConfigUtils.ts @@ -0,0 +1,275 @@ +/* + * 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. + */ +import { ALERT_LEVEL, ExtRuleSet, Rule } from '../../model/Rule'; +import { FileUtils } from './FileUtils'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { Utils } from './Utils'; +import { execSync } from 'child_process'; +import { Json5parser } from './Json5parser'; +import { OptionValues } from 'commander'; +import { CheckerStorage } from './CheckerStorage'; +import path from 'path'; +import { CheckEntry } from './CheckEntry'; +import { RuleConfig } from '../../model/RuleConfig'; +import { ProjectConfig } from '../../model/ProjectConfig'; +import { file2CheckRuleMap, project2CheckRuleMap } from './CheckerIndex'; +import fs from 'fs'; +import { Message, MessageType } from '../../model/Message'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ConfigUtils'); + +export class ConfigUtils { + /** + * 获取配置文件 + * @param configPath 配置文件路径 + * @param rootDir 根目录,可选参数 + * @returns 返回解析后的配置对象,如果解析失败则返回null + */ + public static getConfig(configPath: string, rootDir?: string): any | null { + if (!fs.existsSync(configPath) && rootDir) { + // 规则配置文件不存在,使用默认配置文件 + configPath = path.join(rootDir, 'config', 'ruleConfg.json'); + } + + try { + return Json5parser.parseJsonText(FileUtils.readFile(configPath)); + } catch (e) { + logger.error(e); + return null; + } + } + + /** + * 解析配置文件并设置检查入口 + * @param argvObj 命令行参数对象 + * @param checkEntry 检查入口对象 + * @returns 是否成功解析配置文件 + */ + public static parseConfig(argvObj: OptionValues, checkEntry: CheckEntry): boolean { + const ruleConfig = ConfigUtils.getConfig(argvObj.configPath, argvObj.arkCheckPath); + const projectConfig = ConfigUtils.getConfig(argvObj.projectConfigPath); + if (!ruleConfig || !projectConfig) { + return false; + } + + // 解析规则配置文件 + checkEntry.ruleConfig = new RuleConfig(ruleConfig); + // 解析项目配置文件 + checkEntry.projectConfig = new ProjectConfig(projectConfig); + // 日志配置 + const logPath = checkEntry.projectConfig.logPath; + Utils.setLogPath(logPath.length === 0 ? './HomeCheck.log' : logPath); + logger.info('Checking started.'); + // api版本配置 + CheckerStorage.getInstance().setApiVersion(checkEntry.projectConfig.apiVersion); + // product配置 + CheckerStorage.getInstance().setProduct(checkEntry.projectConfig.product); + return true; + } + + /** + * 从配置文件中获取规则 + * @param ruleConfig 规则配置 + * @param projectConfig 项目配置 + * @param message 消息通知实例 + * @returns Map, ruleId -- Rule + */ + public static getRuleMap(ruleConfig: RuleConfig, projectConfig: ProjectConfig, message: Message): Map { + let ruleMap: Map = new Map(); + const allRules = ConfigUtils.getRuleSetMap(projectConfig.arkCheckPath); + for (const ruleSetStr of ruleConfig.ruleSet ?? []) { + const ruleSet = allRules.get(ruleSetStr); + if (!ruleSet) { + logger.error('Invalid ruleSet name: ' + ruleSetStr); + continue; + } + for (const [ruleId, level] of Object.entries(ruleSet)) { + const alert = Utils.getEnumValues(level, ALERT_LEVEL); + const rule = new Rule(ruleId, alert); + ruleMap.set(rule.ruleId, rule); + } + } + + for (const ruleInfo of Object.entries(ruleConfig.rules ?? {})) { + if (!this.isOnlineRule(ruleInfo[0], allRules)) { + logger.error('Invalid rule name: ' + ruleInfo[0]); + continue; + } + const rule = this.genRuleByOneRuleCfg(ruleInfo); + if (!rule) { + continue; + } + ruleMap.set(rule.ruleId, rule); + } + + // override 独有配置 + Object.entries(ruleConfig.extRules ?? {}).forEach(ruleInfo => { + const rule = this.genRuleByOneRuleCfg(ruleInfo); + if (!rule) { + return; + } + ruleMap.set(rule.ruleId, rule); + }); + + // 解析自定义规则集配置 + this.parseExtRuleConfig(ruleConfig, projectConfig, message, allRules, ruleMap); + return ruleMap; + } + + /** + * 解析自定义规则配置 + * @param ruleConfig 规则配置 + * @param projectConfig 项目配置 + * @param message 消息对象 + * @param allRules 所有规则集合 + * @param ruleMap 规则映射 + */ + private static parseExtRuleConfig(ruleConfig: RuleConfig, projectConfig: ProjectConfig, message: Message, + allRules: Map, ruleMap: Map): void { + logger.info('The npmPath:' + projectConfig.npmPath); + logger.info('The npmInstallDir:' + projectConfig.npmInstallDir); + const extRuleSetSet = new Set(); + (ruleConfig.extRuleSet as ExtRuleSet[]).forEach((ruleSet) => { + if (!this.checkExtRuleSetConfig(ruleSet, allRules, extRuleSetSet, message)) { + return; + } + try { + const cmd = `${projectConfig.npmPath} install --no-save --prefix "${projectConfig.npmInstallDir}" "${ruleSet.packagePath}"`; + logger.info('Start to execute cmd: ' + cmd); + const execLog = execSync(cmd); + logger.info('Exec log: ' + execLog.toString()); + } catch (e) { + logger.error((e as Error).message); + return; + } + logger.info('npm install completed.'); + + let extPkg: any = null; + try { + extPkg = require(path.resolve(projectConfig.npmInstallDir, 'node_modules', ruleSet.ruleSetName)); + } catch (e) { + logger.error((e as Error).message); + message?.messageNotify(MessageType.CHECK_WARN, `Failed to get ${ruleSet.ruleSetName}, please check the ruleSetName.`); + return; + } + extRuleSetSet.add(ruleSet.ruleSetName); + + this.processExternalRules(ruleSet, allRules, extPkg, message, ruleMap); + }); + } + + private static processExternalRules(ruleSet: ExtRuleSet, allRules: Map, extPkg: any, message: Message, ruleMap: Map): void { + Object.entries(ruleSet.extRules ?? {}).forEach(ruleInfo => { + if (this.isOnlineRule(ruleInfo[0], allRules)) { + message?.messageNotify(MessageType.CHECK_WARN, `The extRuleName can't be the same as the internal rules name, name = ${ruleInfo[0]}.`); + return; + } + const rule = this.genRuleByOneRuleCfg(ruleInfo); + if (!rule) { + return; + } + let module = extPkg?.file2CheckRuleMap?.get(rule.ruleId); + if (module) { + file2CheckRuleMap.set(rule.ruleId, module); + } else { + module = extPkg?.project2CheckRuleMap?.get(rule.ruleId); + if (module) { + project2CheckRuleMap.set(rule.ruleId, module); + } else { + message?.messageNotify(MessageType.CHECK_WARN, `Failed to get '${rule.ruleId}' in '${ruleSet.ruleSetName}', please check the extRules.`); + return; + } + } + ruleMap.set(rule.ruleId, rule); + }); + } + + /** + * 通过单个规则配置生成Rule对象,eg: '@ruleSet/ruleName': 'error' | ['error', []...] + * @param ruleCfg - 规则配置,格式为 [string, any] + * @returns Rule | null - 生成的规则对象或 null + */ + private static genRuleByOneRuleCfg(ruleCfg: [string, any]): Rule | null { + let alert = ALERT_LEVEL.SUGGESTION; + let option: any[] = []; + if (ruleCfg[1] instanceof Array) { + alert = Utils.getEnumValues(ruleCfg[1][0], ALERT_LEVEL); + for (let i = 1; i < ruleCfg[1].length; i++) { + option.push(ruleCfg[1][i]); + } + } else { + alert = Utils.getEnumValues(ruleCfg[1], ALERT_LEVEL); + } + const rule = new Rule(ruleCfg[0], alert); + rule.option = option; + return rule; + } + + /** + * 读取RuleSet.json中配置的规则集 + */ + static getRuleSetMap(rootDir: string): Map { + const ruleSetMap: Map = new Map(); + try { + const fileStr = FileUtils.readFile(path.join(rootDir, 'ruleSet.json')); + const config: Record = JSON.parse(fileStr); + for (const [key, value] of Object.entries(config)) { + ruleSetMap.set(key, value); + } + } catch (error) { + logger.error((error as Error).message); + } + return ruleSetMap; + } + + /** + * 检查指定的规则是否存在 + * @param ruleId - 要检查的规则ID + * @param allRules - 包含所有规则的Map对象 + * @returns 如果规则存在则返回true,否则返回false + */ + static isOnlineRule(ruleId: string, allRules: Map): boolean { + for (const [ruleSet, rules] of allRules) { + if (Object.keys(rules).includes(ruleId)) { + return true; + } + } + return false; + } + + /** + * 检查自定义规则集配置的有效性 + * @param ruleSet - 自定义规则集 + * @param allRules - 所有规则集合 + * @param extRuleSetSet - 自定义规则集集合 + * @param message - 消息对象 + * @returns {boolean} - 是否通过检查 + */ + static checkExtRuleSetConfig(ruleSet: ExtRuleSet, allRules: Map, extRuleSetSet: Set, message: Message): boolean { + if (allRules.get(`${ruleSet.ruleSetName}`)) { + message?.messageNotify(MessageType.CHECK_WARN, `The extRuleSetName can't be the same as the name of internal rule set name, name = ${ruleSet.ruleSetName}.`); + return false; + } + if (!ruleSet.packagePath || ruleSet.packagePath.length === 0 || FileUtils.isExistsSync(ruleSet.packagePath) === false) { + message?.messageNotify(MessageType.CHECK_WARN, `'${ruleSet.packagePath}' is invalid or not exist, please check the packagePath.`); + return false; + } + if (extRuleSetSet.has(ruleSet.ruleSetName)) { + message?.messageNotify(MessageType.CHECK_WARN, `'${ruleSet.ruleSetName}' is conflict, please check the ruleSetName.`); + return false; + } + return true; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/DefectsList.ts b/ets2panda/linter/homecheck/src/utils/common/DefectsList.ts new file mode 100644 index 0000000000000000000000000000000000000000..e21b56f6dea429a4b12c58f22292b70304ef00ff --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/DefectsList.ts @@ -0,0 +1,54 @@ +/* + * 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. + */ +import { Defects } from '../../model/Defects'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'CheckEntry'); + +namespace DefectsList { + let defects: Defects[] = []; + + export function add(defect: Defects): void { + defects.push(defect); + } + + export function updateDefectByIndex(index: number, defect: Defects): void { + defects[index] = defect; + } + + export function getDefects(): Defects[] { + return defects; + } + + export function clear(): void { + defects = []; + } +} + + +export class RuleListUtil { + static push(defect: Defects): void { + } + + static updateDefect(defect: Defects): void { + } + + static printDefects(): void { + } + + static isFilter(ruleId: string): boolean { + return ruleId.startsWith('@ArkTS-eslint'); + } +} diff --git a/ets2panda/linter/homecheck/src/utils/common/Disable.ts b/ets2panda/linter/homecheck/src/utils/common/Disable.ts new file mode 100644 index 0000000000000000000000000000000000000000..e8f86a26181832606afabbf6b5748401fd0220e1 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/Disable.ts @@ -0,0 +1,58 @@ +/* + * 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 * as fs from 'fs'; +import path from 'path'; +import { IssueReport } from '../../model/Defects'; +import { FileUtils } from '../../Index'; + +export const DisableText = { + FILE_DISABLE_TEXT: '\/* homecheck-disable *\/', + NEXT_LINE_DISABLE_TEXT: '\/\/ homecheck-disable-next-line ', +}; + +export async function filterDisableIssue(lineList: string[], issues: IssueReport[], filePath: string): Promise { + let filtedIssues: IssueReport[] = []; + for (const issue of issues) { + // @migration/arkui-data-observation规则的自动修复是在定义处,存在跨文件场景 + const actualFilePath = path.normalize(issue.defect.mergeKey.split('%')[0]); + if (path.normalize(actualFilePath) !== path.normalize(filePath)) { + if (!fs.existsSync(actualFilePath)) { + continue; + } + lineList = await FileUtils.readLinesFromFile(actualFilePath); + } + // 有些特殊规则允许返回行列号为0 + if (issue.defect.reportLine < 0 || issue.defect.reportLine - 1 > lineList.length) { + continue; + } + const text = lineList[issue.defect.reportLine - 2]; + if (!isDisableIssue(text, issue.defect.ruleId)) { + filtedIssues.push(issue); + } + } + return filtedIssues; +} + +function isDisableIssue(lineText: string, ruleId: string): boolean { + if (!lineText || lineText.length === 0) { + return false; + } + + if (lineText.includes(DisableText.NEXT_LINE_DISABLE_TEXT) && lineText.includes(ruleId)) { + return true; + } + return false; +} diff --git a/ets2panda/linter/homecheck/src/utils/common/FileRuleMapping.ts b/ets2panda/linter/homecheck/src/utils/common/FileRuleMapping.ts new file mode 100644 index 0000000000000000000000000000000000000000..b78400ff292dbaaab5766115337c445051df003b --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/FileRuleMapping.ts @@ -0,0 +1,153 @@ +/* + * 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. + */ + +import { ArkFile } from 'arkanalyzer'; +import { CheckEntry } from './CheckEntry'; +import { ConfigUtils } from './ConfigUtils'; +import { CheckerUtils } from '../checker/CheckerUtils'; +import { file2CheckRuleMap, project2CheckRuleMap } from './CheckerIndex'; +import { Rule } from '../../model/Rule'; +import { RuleConfig } from '../../model/RuleConfig'; +import { fileCheckBuilder, projectCheckBuilder } from './CheckBuilder'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { FileUtils } from './FileUtils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'fileRuleMapping'); + +export async function fileRuleMapping(checkFileList: string[], checkEntry: CheckEntry): Promise { + // 获取规则配置文件的规则,除了override + const allRulesMap = ConfigUtils.getRuleMap(checkEntry.ruleConfig, checkEntry.projectConfig, checkEntry.message); + if (allRulesMap.size === 0) { + checkEntry.message?.progressNotify(1, 'No rule to check'); + return false; + } + + let arkFiles: ArkFile[] = []; + const fiRulesMap: Map = new Map(); + const fileRulesMap = await createFileRulesMap(checkFileList, allRulesMap, checkEntry, file2CheckRuleMap, fiRulesMap); + for (const filePath of checkFileList) { + try { + const arkFile = CheckerUtils.getArkFileByFilePath(checkEntry.scene, filePath); + if (!arkFile) { + continue; + } + + arkFiles.push(arkFile); + const enabledRules = fileRulesMap.get(filePath); + if (enabledRules) { + checkEntry.addFileCheck(fileCheckBuilder(arkFile, enabledRules)); + } + } catch (error) { + logger.error(`Error processing file ${filePath}: ${(error as Error).message}`); + } + } + + const proRulesMap: Map = new Map(); + const projectRulesMap = await createFileRulesMap(checkFileList, allRulesMap, checkEntry, project2CheckRuleMap, proRulesMap); + const projectRules = Array.from(proRulesMap.values()); + try { + checkEntry.addProjectCheck(projectCheckBuilder(arkFiles, projectRules)); + checkEntry.projectCheck.ruleMap = projectRulesMap; + } catch (error) { + logger.error(`Error adding project check: ${(error as Error).message}`); + } + return true; +} + +function filterRule(allRulesMap: Map, filterMap?: Map): Rule[] { + const rules: Rule[] = []; + for (const [key, value] of allRulesMap) { + if (filterMap && !filterMap.has(key)) { + continue; + } + rules.push(value); + } + return rules; +} + +async function createFileRulesMap(allFiles: string[], allRulesMap: Map, checkEntry: CheckEntry, + checksRuleMap: Map, proRulesMap: Map): Promise> { + // 获取配置的规则列表 + let fileRulesMap: Map = new Map(); + const ruleMap = filterRule(allRulesMap, checksRuleMap); + + const defaultRules = Array.from(ruleMap.values()); + allFiles.forEach(filePath => fileRulesMap.set(filePath, defaultRules)); + ruleMap.forEach(rule => { + proRulesMap.set(rule.ruleId, rule); + }); + // 检查额外规则覆盖 + for (const override of checkEntry.ruleConfig.overrides ?? []) { + try { + const overrideFileRulesMap = await createFileRulesMapWithOverride(checkEntry, override, checksRuleMap, proRulesMap); + fileRulesMap = mergeFileRulesMap(fileRulesMap, overrideFileRulesMap); + } catch (error) { + logger.error(`Error check extra rule overrides: ${(error as Error).message}`); + } + } + return fileRulesMap; +} + +async function createFileRulesMapWithOverride(checkEntry: CheckEntry, override: RuleConfig, + checksRuleMap: Map, proRulesMap: Map): Promise> { + let checkFileList = checkEntry.selectFileList.map(file => file.filePath); + if (checkFileList.length === 0) { + checkFileList = FileUtils.getAllFiles(checkEntry.projectConfig.projectPath, ['.ts', '.ets', '.json5']); + } + checkFileList = await FileUtils.getFiltedFiles(checkFileList, override); + const allRuleMap = ConfigUtils.getRuleMap(override, checkEntry.projectConfig, checkEntry.message); + const ruleMap = filterRule(allRuleMap, checksRuleMap); + ruleMap.forEach(rule => { + if (!proRulesMap.has(rule.ruleId)) { + proRulesMap.set(rule.ruleId, rule); + } + }); + const fileRulesMap: Map = new Map(); + const defaultRules = Array.from(ruleMap.values()); + checkFileList.forEach(filePath => fileRulesMap.set(filePath, defaultRules)); + return fileRulesMap; +} + +function mergeFileRulesMap(fileRulesMap: Map, + overrideFileRulesMap: Map): Map { + // 取fileRule和overrideRule交集 + for (const [key, vals] of overrideFileRulesMap) { + if (!fileRulesMap.has(key) || vals.length === 0) { + continue; + } + let fileRules = fileRulesMap.get(key); + if (!fileRules || fileRules.length === 0) { + fileRulesMap.set(key, vals); + continue; + } + let newRules = [...fileRules]; + vals.forEach(val => { + let existIndex = fileRules?.findIndex(fileRule => fileRule.ruleId === val.ruleId); + if (existIndex === undefined || existIndex === -1) { + newRules.push(val); + } else { + newRules[existIndex] = val; + } + }); + fileRulesMap.set(key, newRules); + } + // 筛除关闭的rule + const filteredRulesMap = new Map(); + for (const [key, rules] of fileRulesMap) { + const filteredRules = rules.filter(rule => rule.alert !== 0); + filteredRulesMap.set(key, filteredRules); + } + return filteredRulesMap; +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts b/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..48b06a414dc94e9e5474890f8a89dd32be5116fd --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/FileUtils.ts @@ -0,0 +1,313 @@ +/* + * 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. + */ +import * as fs from 'fs'; +import * as path from 'path'; +import { createInterface, Interface } from 'readline'; +import { DisableText } from './Disable'; +import { Sdk } from 'arkanalyzer/lib/Config'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { FileToCheck, ProjectConfig, SelectedFileInfo } from '../../model/ProjectConfig'; +import { RuleConfig } from '../../model/RuleConfig'; +import { GlobMatch } from './GlobMatch'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'FileUtils'); +export class FileUtils { + /** + * 读取指定文件并返回其内容 + * @param {string} fileName - 要读取的文件名 + * @returns {string} - 文件内容 + */ + public static readFile(fileName: string): string { + return fs.readFileSync(fileName, 'utf8').replace(/^\ufeff/u, ''); + } + + /** + * 根据给定的文件列表和规则配置,过滤出符合规则的文件列表。 + * @param fileList 文件列表。 + * @param ruleConfig 规则配置,包含匹配和忽略文件的规则,以及可能的重写规则。 + * @returns 返回符合规则的文件列表,异常情况下返回空数组。 + */ + public static async getFiltedFiles(fileList: string[], ruleConfig: RuleConfig): Promise { + try { + let result = await this.matchFiles(fileList, ruleConfig.files, ruleConfig.ignore); + const overrides = ruleConfig.overrides; + if (overrides.length > 0) { + for (const override of overrides) { + result = result.concat(await this.getFiltedFiles(fileList, override)); + result = [...new Set(result)]; + } + } + return result; + } catch (error) { + logger.error(`Error occurred while reading files: ${error}`); + return []; + } + } + + /** + * 匹配文件列表中的文件,返回符合条件的文件路径列表 + * @param fileList 文件路径列表 + * @param fileTypes 文件类型列表,使用glob模式匹配 + * @param ignoreDirs 要忽略的目录列表,使用glob模式匹配,默认为空数组 + * @returns 符合条件的文件路径列表 + */ + public static async matchFiles(fileList: string[], fileGlob: GlobMatch, ignoreGlob: GlobMatch): Promise { + let result: string[] = []; + for (const filePath of fileList) { + if (!ignoreGlob?.matchGlob(filePath) && fileGlob.matchGlob(filePath)) { + // 读取file文件内容首行,若为屏蔽行则跳过 + const firstLineText = await this.readLinesFromFile(filePath, 1); + if (firstLineText.includes(DisableText.FILE_DISABLE_TEXT)) { + continue; + } + result.push(filePath); + } + } + return result; + } + + + /** + * 从文件中读取指定行或全部行 + * @param filePath 文件路径 + * @param lineNo 要读取的行号,不传或者0值则读取全部行 + * @returns 读取到的行组成的字符串数组 + * @throws 如果读取文件时发生错误,将抛出异常 + */ + public static async readLinesFromFile(filePath: string, lineNo?: number): Promise { + return new Promise((resolve, reject) => { + let lines: string[] = []; + let readLineNo = 1; + + const readStream = fs.createReadStream(filePath); + const rl = createInterface({ + input: readStream, + crlfDelay: Infinity + }); + + const handleLine = (line: string): void => { + if (lineNo) { + if (readLineNo === lineNo) { + lines.push(line); + rl.close(); + } + } else { + lines.push(line); + } + readLineNo++; + }; + + rl.on('line', handleLine); + + rl.on('close', () => { + readStream.destroy(); + resolve(lines); + }); + + rl.on('error', (err) => { + readStream.destroy(); + reject(err); + }); + + readStream.on('error', (err) => { + rl.close(); + reject(err); + }); + }); + } + + private processHandleLine(lineNo: number | undefined, readLineNo: number, lines: string[], rl: Interface): void { + const handleLine = (line: string): void => { + if (lineNo) { + if (readLineNo === lineNo) { + lines.push(line); + rl.close(); + } + } else { + lines.push(line); + } + readLineNo++; + }; + + rl.on('line', handleLine); + } + + /** + * 检查文件是否存在 + * @param filePath 文件路径 + * @returns 如果文件存在则返回true,否则返回false + */ + public static isExistsSync(filePath: string): boolean { + return fs.existsSync(filePath); + } + + /** + * 从指定路径的JSON文件中获取符合条件的文件信息列表 + * @param jsonPath JSON文件路径 + * @param exts 文件扩展名数组 + * @returns 符合条件的文件信息数组 + */ + public static getSeletctedFileInfos(jsonPath: string, exts: string[]): SelectedFileInfo[] { + const fileInfoList: SelectedFileInfo[] = []; + try { + const jsonData = JSON.parse(fs.readFileSync(jsonPath, 'utf8')); + jsonData.checkPath?.forEach((fileInfo: SelectedFileInfo) => { + if (exts.includes(path.extname(fileInfo.filePath))) { + fileInfoList.push(fileInfo); + } + }); + } catch (error) { + logger.error(`Error occurred while reading file list from ${jsonPath}: ${error}`); + } + return fileInfoList; + } + + public static getFileInfoFromFileList(fileOrFolderList: string[]): SelectedFileInfo[] { + const fileInfoList: SelectedFileInfo[] = []; + fileOrFolderList.forEach((fileOrFolderPath) => { + if (fs.statSync(fileOrFolderPath).isFile()) { + fileInfoList.push(new FileToCheck(fileOrFolderPath)); + } else { + const filesInFolder = FileUtils.getAllFiles(fileOrFolderPath, []); + filesInFolder.forEach((filePath) => { + fileInfoList.push(new FileToCheck(filePath)); + }); + } + }); + return fileInfoList; + } + + /** + * 获取指定目录下所有符合条件的文件 + * @param dirPath - 目录路径 + * @param exts - 文件扩展名数组,如果为空则获取所有文件,['.ts', '.ets', '.json5'] + * @param filenameArr - 存储符合条件的文件路径的数组,默认为空数组 + * @param visited - 已访问的目录集合,默认为空集合 + * @returns 符合条件的文件路径数组 + */ + public static getAllFiles(dirPath: string, exts: string[], filenameArr: string[] = [], visited: Set = new Set()): string[] { + // 检查目录是否存在 + if (!fs.existsSync(dirPath)) { + logger.error(`'${dirPath}' is not exist, please check!`); + return filenameArr; + } + // 获取目录的绝对路径 + const realSrc = fs.realpathSync(dirPath); + // 避免重复访问 + if (visited.has(realSrc)) { + return filenameArr; + } + visited.add(realSrc); + // 读取目录下的文件和文件夹 + fs.readdirSync(realSrc).forEach(fileName => { + if (this.shouldSkipFile(fileName)) { + return; + } + const realFile = path.resolve(realSrc, fileName); + // 如果是文件夹,则递归调用 + if (fs.statSync(realFile).isDirectory()) { + this.getAllFiles(realFile, exts, filenameArr, visited); + } else { + // 如果扩展名为空,则添加所有文件 + if (exts.length === 0) { + filenameArr.push(realFile); + } else if (this.shouldAddFile(realFile, exts)) { + filenameArr.push(realFile); + } + } + }); + return filenameArr; + } + + private static shouldSkipFile(fileName: string): boolean { + return ['oh_modules', 'node_modules', 'hvigorfile.ts', 'ohosTest'].includes(fileName); + } + + private static shouldAddFile(filePath: string, exts: string[]): boolean { + if (exts.length === 0) { + return true; + } + const ext = path.extname(filePath).toLowerCase(); + return exts.includes(ext); + } + + /** + * 生成SDK数组 + * @param projectConfig - 项目配置 + * @returns Sdk[] - SDK数组 + */ + public static genSdks(projectConfig: ProjectConfig): Sdk[] { + let sdks: Sdk[] = []; + const sdkConfigPath = path.join(projectConfig.arkCheckPath, 'resources', 'sdkConfig.json'); + if (fs.existsSync(sdkConfigPath)) { + const configurations = JSON.parse(fs.readFileSync(sdkConfigPath, 'utf-8')); + sdks = configurations.sdks ?? []; + } + if (!projectConfig.ohosSdkPath && !projectConfig.hmsSdkPath) { + return sdks; + } + sdks.forEach(sdk => { + if (sdk.name === 'ohosSdk') { + sdk.path = projectConfig.ohosSdkPath; + } else if (sdk.name === 'hmsSdk') { + sdk.path = projectConfig.hmsSdkPath; + } else { + sdk.path = path.join(projectConfig.arkCheckPath, sdk.path); + } + }); + projectConfig.sdksThirdParty?.forEach(sdkThirdParty => { + let sdkJson = JSON.parse(JSON.stringify(sdkThirdParty)); + let sdkFd = sdks.find(sdk => sdk.name === sdkJson.name); + if (!sdkFd) { + let sdk3rd: Sdk = { + name: sdkJson.name, + path: path.resolve(sdkJson.path), + moduleName: sdkJson.moduleName, + }; + sdks.push(sdk3rd); + } else { + sdkFd.path = path.resolve(sdkJson.path); + sdkFd.moduleName = sdkJson.moduleName; + } + }); + return sdks; + } + + + /** + * 写入文件,同步接口 + * @param filePath 文件路径 + * @param content 写入的内容 + * @param mode 写入模式,不传默认为追加模式 + **/ + public static writeToFile(filePath: string, content: string, mode: WriteFileMode = WriteFileMode.APPEND): void { + const dirName = path.dirname(filePath); + if (!fs.existsSync(dirName)) { + fs.mkdirSync(dirName, { recursive: true }); + } + if (mode === WriteFileMode.OVERWRITE) { + fs.writeFileSync(filePath, content, { encoding: 'utf8' }); + } else if (mode === WriteFileMode.APPEND) { + fs.appendFileSync(filePath, content, { encoding: 'utf8' }); + } else { + logger.error(`Invalid write mode: ${mode}`); + } + } +} + +export enum WriteFileMode { + OVERWRITE, + APPEND +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts b/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..3dc2fc66733fdae58cb1bfce65f1c6f142202226 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/FixUtils.ts @@ -0,0 +1,210 @@ +/* + * 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 { ArkClass, ArkFile, ArkMethod, AstTreeUtils, ExportInfo, ImportInfo, Stmt, ts } from 'arkanalyzer'; +import { AIFix, FunctionFix, Range, RuleFix } from '../../model/Fix'; + +export type FixPosition = { + startLine: number, + startCol: number, + endLine: number, + endCol: number +}; + +export class FixUtils { + + public static getRangeStart(arkFile: ArkFile, codeNode: Stmt | ArkMethod | ArkClass | ExportInfo | ImportInfo): number { + let lineNum = 0; + let startColumn = 0; + if (codeNode instanceof Stmt) { + let originalPosition = codeNode.getOriginPositionInfo(); + lineNum = originalPosition.getLineNo(); + startColumn = originalPosition.getColNo(); + } else if (codeNode instanceof ArkMethod) { + lineNum = codeNode.getLine() ?? 0; + startColumn = codeNode.getColumn() ?? 0; + } else if (codeNode instanceof ArkClass) { + lineNum = codeNode.getLine() ?? 0; + startColumn = codeNode.getColumn() ?? 0; + } else if (codeNode instanceof ExportInfo) { + let originalPosition = codeNode.getOriginTsPosition(); + lineNum = originalPosition.getLineNo(); + startColumn = originalPosition.getColNo(); + } else if (codeNode instanceof ImportInfo) { + let originalPosition = codeNode.getOriginTsPosition(); + lineNum = originalPosition.getLineNo(); + startColumn = originalPosition.getColNo(); + } + // 原文代码 + let code = arkFile.getCode(); + // 找到当前分割符所在行 + let lineBreak = this.getTextEof(code); + let cnt = 0; + if (lineBreak.length > 0) { + for (let index = 1; index !== lineNum; index++) { + cnt = code.indexOf(lineBreak, cnt + 1); + } + } + let start = (cnt === 0 && startColumn === 1) ? 0 : (cnt + startColumn + 1);//对第一行第一列特殊处理,后续代码都是以0,所以需要+1 + return start; + } + + // 根据输入的代码片段的起始、结束行列号信息,计算此代码片段在该文件中的起始偏移量、结束偏移量数据 + public static getRangeWithAst(sourceFile: ts.SourceFile, fixPosition: FixPosition): Range { + const startNumber = ts.getPositionOfLineAndCharacter(sourceFile, fixPosition.startLine - 1, fixPosition.startCol - 1); + const endNumber = ts.getPositionOfLineAndCharacter(sourceFile, fixPosition.endLine - 1, fixPosition.endCol - 1); + return [startNumber, endNumber]; + } + + // 根据输入的起始行号信息,计算该行的起始偏移量、结束偏移量数据 + public static getLineRange(sourceFile: ts.SourceFile, lineNumber: number): Range | null { + const lineStarts = sourceFile.getLineStarts(); + + // 验证行号范围 + if (lineNumber < 1 || lineNumber > lineStarts.length) { + return null; + } + + const startPos = lineStarts[lineNumber - 1]; + let endPos: number; + + // 处理文件最后一行 + if (lineNumber === lineStarts.length) { + endPos = sourceFile.text.length; + } else { + endPos = lineStarts[lineNumber] - 1; + } + return [startPos, endPos]; + } + + // 根据给定的起始、结束偏移量数据,获取此段代码片段的源码字符串,位置信息不合法则返回null + public static getSourceWithRange(sourceFile: ts.SourceFile, range: Range): string | null { + const start = range[0]; + const end = range[1]; + if (start < 0 || end > sourceFile.text.length || start > end) { + return null; + } + return sourceFile.text.substring(start, end); + } + + // 根据给定的行号,获取该行的源码字符串,行号不合法则返回null + public static getLineText(sourceFile: ts.SourceFile, lineNumber: number): string | null { + const range = this.getLineRange(sourceFile, lineNumber); + if (range === null) { + return null; + } + + return sourceFile.text.substring(range[0], range[1]); + } + + // 根据给定的行号,获取该行的换行符,获取失败则使用默认的'\n'换行符 + public static getEolSymbol(sourceFile: ts.SourceFile, lineNumber: number): string { + let res = '\n'; + const lineStr = this.getLineText(sourceFile, lineNumber); + if (lineStr === null) { + return res; + } + + const lfIndex = lineStr.indexOf('\n'); + if (lfIndex > 0 && lineStr[lfIndex - 1] === '\r') { + res = '\r\n'; + } + return res; + } + + // 根据给定的行号,获取该行的缩进数量,采用空格缩进时为空格数量,采用tab缩进时为tab数量,行号不合法则返回null + public static getIndentOfLine(sourceFile: ts.SourceFile, lineNumber: number): number | null { + const lineStr = this.getLineText(sourceFile, lineNumber); + if (lineStr === null) { + return null; + } + + const space = ' '; + let res = 0; + for (const char of lineStr) { + if (char === space) { + res++; + } else { + break; + } + } + return res; + } + + // 根据给定的行号,获取该行附近的缩进宽度,采用空格缩进时为空格数量,采用tab缩进时为tab数量,无法找到则返回2 + public static getIndentWidth(sourceFile: ts.SourceFile, lineNumber: number): number { + const lineIndent = FixUtils.getIndentOfLine(sourceFile, lineNumber); + let indentWidth = 0; + + // 从当前行向上寻找最近的缩进量 + let currLineIndent = lineIndent; + let previousLine = lineNumber - 1; + while (indentWidth <= 0 && previousLine > 0 && currLineIndent !== null) { + const previousLineIndent = FixUtils.getIndentOfLine(sourceFile, previousLine); + if (previousLineIndent !== null) { + indentWidth = Math.abs(currLineIndent - previousLineIndent); + } + currLineIndent = previousLineIndent; + previousLine--; + } + if (indentWidth > 0) { + return indentWidth; + } + + // 从当前行向下寻找最近的缩进量 + currLineIndent = lineIndent; + let nextLine = lineNumber + 1; + while (indentWidth <= 0 && nextLine < sourceFile.getLineStarts().length && currLineIndent !== null) { + const nextLineIndent = FixUtils.getIndentOfLine(sourceFile, nextLine); + if (nextLineIndent !== null) { + indentWidth = Math.abs(nextLineIndent - currLineIndent); + } + currLineIndent = nextLineIndent; + nextLine++; + } + if (indentWidth > 0) { + return indentWidth; + } + return 2; + } + + public static getTextEof(text: string): string { + if (text.includes('\r\n')) { + return '\r\n'; + } else if (text.includes('\n')) { + return '\n'; + } else if (text.includes('\r')) { + return '\r'; + } else { + return ''; + } + } + + public static isRuleFix(object: any): object is RuleFix { + return typeof object === 'object' && 'range' in object && 'text' in object; + } + + public static isFunctionFix(object: any): object is FunctionFix { + return typeof object === 'object' && 'fix' in object; + } + + public static isAIFix(object: any): object is AIFix { + return typeof object === 'object' && 'text' in object; + } + + public static hasOwnPropertyOwn(object: any, key: string): boolean { + return typeof object === 'object' && key in object; + } +} diff --git a/ets2panda/linter/homecheck/src/utils/common/GeneratingJsonFile.ts b/ets2panda/linter/homecheck/src/utils/common/GeneratingJsonFile.ts new file mode 100644 index 0000000000000000000000000000000000000000..7df577806fb8c15739047e1125ef398d4f3e1cc8 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/GeneratingJsonFile.ts @@ -0,0 +1,151 @@ +/* + * 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 * as path from 'path'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { FileReports } from '../../model/Defects'; +import { FileUtils, WriteFileMode } from './FileUtils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'GeneratingJsonFile'); +const severitys: string[] = ['OFF', 'WARN', 'ERROR', 'SUGGESTION']; +const FILE_NAMING_RULE = '@hw-stylistic/file-naming-convention'; + +export class GeneratingJsonFile { + public static generatingJsonFile(filePath: string, fileReports: FileReports[]): void { + const fileDefectInfos = this.format(fileReports); + let results: Map = new Map(); + for (let fileDefectInfo of fileDefectInfos) { + this.addResult(fileDefectInfo, results); + } + const jsonString = this.format2(results); + try { + FileUtils.writeToFile(filePath, jsonString, WriteFileMode.OVERWRITE); + } catch (error) { + logger.error(`write file ${filePath} failed, error: ${error}`); + } + } + + /** + * 过滤掉部分不需要的defect属性 + * + * @param fileReports 原始文件缺陷信息数组 + * @returns 过滤后的文件缺陷信息数组 + */ + private static format(fileReports: FileReports[]): FileDefectInfo[] { + const fileDefectInfos: FileDefectInfo[] = []; + for (const fileReport of fileReports) { + const fileDefectInfo: FileDefectInfo = { + filePath: fileReport.filePath, + defects: [] + }; + for (const defect of fileReport.defects) { + const defectInfo: DefectInfo = { + reportLine: defect.reportLine, + reportColumn: defect.reportColumn, + ruleId: defect.ruleId, + severity: severitys[defect.severity], + mergeKey: defect.mergeKey, + description: defect.description, + ruleDocPath: defect.ruleDocPath + }; + fileDefectInfo.defects.push(defectInfo); + } + fileDefectInfos.push(fileDefectInfo); + } + return fileDefectInfos; + } + + private static addResult(defect: FileDefectInfo, results: Map): void { + const normalizedPath = path.normalize(defect.filePath).toLocaleLowerCase(); + if (!results.has(normalizedPath)) { + results.set(normalizedPath, defect); + } else { + results.get(normalizedPath)?.defects.push(...defect.defects); + } + const defectInfo = results.get(normalizedPath); + defectInfo?.defects.sort((defectA, defectB) => { + if (defectA.ruleId === FILE_NAMING_RULE) { + return -1; + } + if (defectB.ruleId === FILE_NAMING_RULE) { + return 1; + } + if (defectA.reportLine === defectB.reportLine) { + if (defectA.reportColumn === defectB.reportColumn) { + return defectA.mergeKey.localeCompare(defectB.mergeKey); + } + return defectA.reportColumn - defectB.reportColumn; + } + return defectA.reportLine - defectB.reportLine; + }); + } + + private static format2(results: Map): string { + const jsonResults: JsonResult[] = []; + for (let result of results) { + const oneResult: JsonResult = { + filePath: '', + messages: [] + }; + oneResult.filePath = result[1].filePath; + let defects = result[1].defects; + for (let defect of defects) { + const oneDefect: SimpleDefect = { + line: 0, + column: 0, + severity: '', + message: '', + rule: '', + }; + oneDefect.line = defect.reportLine; + oneDefect.column = defect.reportColumn; + oneDefect.severity = defect.severity; + oneDefect.message = defect.description; + oneDefect.rule = defect.ruleId; + oneResult.messages.push(oneDefect); + } + jsonResults.push(oneResult); + } + return JSON.stringify(jsonResults, null, 2); + } +} + +interface JsonResult { + filePath: string; + messages: SimpleDefect[]; +} + +interface SimpleDefect { + line: number; + column: number; + severity: string; + message: string; + rule: string | null; +} + +interface FileDefectInfo { + filePath: string; + defects: DefectInfo[]; +} + +interface DefectInfo { + severity: string; + description: string; + mergeKey: string; + reportLine: number; + reportColumn: number; + ruleId: string | null; + ruleDocPath: string | null; +} diff --git a/ets2panda/linter/homecheck/src/utils/common/GlobMatch.ts b/ets2panda/linter/homecheck/src/utils/common/GlobMatch.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b45e07d3a533ed5af91b97f6c759428d7a5fe9f --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/GlobMatch.ts @@ -0,0 +1,56 @@ +/* + * 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. + */ + +export class GlobMatch { + private regexps: string[] = []; + + constructor(globPattern: string[]) { + this.regexps = globPattern.map(pattern => this.globToRegexp(pattern)); + } + + matchGlob(path: string): boolean { + path = path.replace(/\\/g, '/'); + return this.regexps.some(regexp => new RegExp(regexp).test(path)); + } + + private globToRegexp(glob: string): string { + glob = glob.replace(/\\/g, '/').replace(/\/+/g, '/'); + const specialChars = new Set(['.', '+', '*', '?', '[', '^', ']', '(', ')', '{', '}', '|']); + let regexp = ''; + let isStar = false; + for (let i = 0; i < glob.length; i++) { + const char = glob[i]; + if (char === '*') { + if (!isStar) { + regexp += '.*'; // 匹配任意字符序列,包括空字符串。 + } + isStar = true; + continue; + } else if (char === '?') { + regexp += '.'; // 匹配任意单个字符。 + } else if (specialChars.has(char)) { + regexp += `\\${char}`; // 转义特殊字符。 + } else { + regexp += char; + } + isStar = false; + } + // 防止配置的是'.c', 匹配到了'.cpp' + if (regexp.match('.*\\.[a-zA-Z]+$')) { + regexp = `${regexp}$`; + } + return regexp; + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/Json5parser.ts b/ets2panda/linter/homecheck/src/utils/common/Json5parser.ts new file mode 100644 index 0000000000000000000000000000000000000000..712ee7728bed50972d384a777e24413185063451 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/Json5parser.ts @@ -0,0 +1,130 @@ +/* + * 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. + */ + +import { ts } from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Json5parser'); + +export class Json5parser { + /** + * 获取JSON5文件的根对象字面量表达式 + * @param file - JSON5文件的源文件对象 + * @returns 如果找到根对象字面量表达式,则返回该表达式;否则返回undefined + */ + public static getRootObjectLiteral(file: ts.JsonSourceFile): ts.ObjectLiteralExpression | undefined { + // 检查文件语句是否为空 + if (!file.statements || !file.statements.length) { + logger.error('The JSON5 file format is incorrect, the root node statements is empty.'); + return undefined; + } + const expressionStatement = file.statements[0]; + if (expressionStatement.kind !== ts.SyntaxKind.ExpressionStatement) { + logger.error(`The JSON5 file format is incorrect, the first child node is not ExpressionStatement. kind: ${expressionStatement.kind}`); + return undefined; + } + // JSON5顶层对象仅识别一个 + const rootObjectLiteralExpression = (expressionStatement as ts.ExpressionStatement).expression; + if (!rootObjectLiteralExpression) { + logger.error('The JSON5 file format is incorrect, the first child node expression is empty.'); + return undefined; + } + // 检查表达式是否为对象字面量表达式 + if (rootObjectLiteralExpression.kind === ts.SyntaxKind.ObjectLiteralExpression) { + return rootObjectLiteralExpression as ts.ObjectLiteralExpression; + } + // 检查表达式是否为数组字面量表达式 + if (rootObjectLiteralExpression.kind === ts.SyntaxKind.ArrayLiteralExpression) { + const elements = (rootObjectLiteralExpression as ts.ArrayLiteralExpression).elements; + // 检查数组是否为空或第一个元素是否为对象字面量表达式 + if (elements && elements.length && elements[0].kind === ts.SyntaxKind.ObjectLiteralExpression) { + return elements[0] as ts.ObjectLiteralExpression; + } + logger.error('The JSON5 file format is incorrect, the node ArrayLiteralExpression first element is not ObjectLiteralExpression.'); + } + logger.error('The JSON5 file format is incorrect.'); + return undefined; + } + + /** + * 解析对象字面量表达式 + * @param objectLiteralExpression - 对象字面量表达式 + * @param file - JSON源文件 + * @returns 解析后的对象字面量表达式 + */ + private static parseObjectLiteralExpression(objectLiteralExpression: ts.ObjectLiteralExpression, file: ts.JsonSourceFile): { [k: string]: unknown } { + const res: { [k: string]: unknown } = {}; + objectLiteralExpression.properties.forEach(node => { + const propNode = node as ts.PropertyAssignment; + const key = (propNode.name as ts.Identifier).text; + const value = this.parsePropertyInitializer(propNode.initializer, file); + res[key] = value; + }); + return res; + } + + /** + * 解析语法树中的表达式节点 + * @param node - 表达式节点 + * @param file - JSON源文件 + * @returns 解析后的值 + */ + private static parsePropertyInitializer(node: ts.Expression, file: ts.JsonSourceFile): unknown { + if (node.kind === ts.SyntaxKind.StringLiteral) { + return (node as ts.StringLiteral).text; + } else if (node.kind === ts.SyntaxKind.NumericLiteral) { + return parseInt((node as ts.NumericLiteral).text); + } else if (node.kind === ts.SyntaxKind.PrefixUnaryExpression) { + return Number((node as ts.PrefixUnaryExpression).getText(file)); + } else if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) { + return this.parseArrayLiteral(node, file); + } else if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) { + return this.parseObjectLiteralExpression(node as ts.ObjectLiteralExpression, file); + } else if (node.kind === ts.SyntaxKind.TrueKeyword) { + return true; + } else if (node.kind === ts.SyntaxKind.FalseKeyword) { + return false; + } + return undefined; + } + + /** + * 解析数组字面量表达式 + * @param node - 要解析的表达式节点 + * @param file - 所属的 JSON 源文件 + * @returns 解析后的数组 + */ + private static parseArrayLiteral(node: ts.Expression, file: ts.JsonSourceFile): unknown[] { + const res: unknown[] = []; + (node as ts.ArrayLiteralExpression).elements.forEach(n => { + res.push(this.parsePropertyInitializer(n, file)); + }); + return res; + } + + /** + * 解析JSON文本 + * @param text - 要解析的JSON文本 + * @returns 解析后的对象 + */ + public static parseJsonText(text: string): { [k: string]: unknown } { + const file = ts.parseJsonText('', text); + const rootObjectLiteralExpression = this.getRootObjectLiteral(file); + if (!rootObjectLiteralExpression) { + return {}; + } + return this.parseObjectLiteralExpression(rootObjectLiteralExpression, file); + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts b/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts new file mode 100644 index 0000000000000000000000000000000000000000..4c481600dd009dad67fafa8ca5b435c070501d5d --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/ScopeHelper.ts @@ -0,0 +1,273 @@ +/* + * 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. + */ +import { ArkArrayRef, ArkAssignStmt, ArkClass, ArkIfStmt, ArkThisRef, BasicBlock, DEFAULT_ARK_METHOD_NAME, Local, Scene, Stmt } from 'arkanalyzer'; +import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { CheckerStorage, CheckerUtils, Scope, ScopeType, TempLocation } from '../../Index'; +import { Variable } from '../../model/Variable'; +import { VarInfo } from '../../model/VarInfo'; +import { FixUtils } from './FixUtils'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'ScopeHelper'); + +export class ScopeHelper { + private gFilePath: string = ''; + private firstBlock: BasicBlock | undefined; + private finishBlockSet: Set; + private isSwitchLastCase = false; + private gFinishIfStmtLines: number[] = []; + private gTernaryConditionLines: Set = new Set(); + + public buildScope(scene: Scene): void { + let scopeMap = new Map(); + for (const file of scene.getFiles()) { + this.gFilePath = file.getFilePath(); + const firstScope = new Scope(null, new Array(), 0); + scopeMap.set(this.gFilePath, firstScope); + for (const clazz of file.getClasses()) { + this.createScopeInClass(clazz, firstScope); + } + } + CheckerStorage.getInstance().setScopeMap(scopeMap); + } + + private createScopeInClass(clazz: ArkClass, firstScope: Scope): void { + for (let method of clazz.getMethods()) { + this.gFinishIfStmtLines = []; + this.gTernaryConditionLines.clear(); + this.finishBlockSet = new Set(); + this.firstBlock = method.getBody()?.getCfg()?.getStartingBlock(); + if (!this.firstBlock) { + logger.trace(`${clazz.getName()}::${method.getName()} has no body.`); + continue; + } + let curScope = firstScope; + if (method.getName() !== DEFAULT_ARK_METHOD_NAME) { + curScope = new Scope(firstScope, new Array(), 1); + firstScope.setChildScope(curScope); + } + this.blockProcess(this.firstBlock, curScope); + } + } + + private blockProcess(block: BasicBlock, parentScope: Scope): void { + let curScope = parentScope; + let stmts = block.getStmts(); + if (stmts.length === 0) { + return; + } + if (this.isFirstThisBlock(block)) { + const succBlocks = block.getSuccessors(); + if (succBlocks.length > 0) { + this.blockProcess(block.getSuccessors()[0], curScope); + return; + } + } + let isSwitchBlock = false; + let nextScopeType = CheckerUtils.getScopeType(stmts[stmts.length - 1]); + curScope.blocks.add(block); + this.finishBlockSet.add(block); + for (let i = 0; i < stmts.length; i++) { + const stmt = stmts[i]; + if ((i === stmts.length - 1) && (this.isForStmtDefinedPart(stmts[stmts.length - 1], nextScopeType))) { + curScope = this.genChildScope(curScope, ScopeType.FOR_CONDITION_TYPE); + nextScopeType = ScopeType.UNKNOWN_TYPE; + } + if (!FixUtils.hasOwnPropertyOwn(stmt, 'scope')) { + Object.defineProperty(stmt, 'scope', { value: curScope }); + } + if (stmt instanceof ArkAssignStmt && !this.assignStmtProcess(stmt, curScope)) { + continue; + } else if (stmt instanceof ArkIfStmt) { + this.gFinishIfStmtLines.push(stmt.getOriginPositionInfo().getLineNo()); + if (/^.*\?.*:.*$/.test(stmt.getOriginalText() ?? '')) { + this.gTernaryConditionLines.add(stmt.getOriginPositionInfo().getLineNo()); + } + } + } + if (isSwitchBlock) { + this.switchBlockPreProcess(block, curScope); + } else { + this.nextBlockPreProcess(block, curScope, nextScopeType); + } + } + + private isFirstThisBlock(block: BasicBlock): boolean { + if (block.getPredecessors().length === 0) { + const stmts = block.getStmts(); + if (stmts.length === 1) { + if (stmts[0] instanceof ArkAssignStmt && + stmts[0].getRightOp() instanceof ArkThisRef) { + return true; + } + } + } + return false; + } + + private isForStmtDefinedPart(stmt: Stmt, nextScopeType: ScopeType): boolean { + if (stmt instanceof ArkAssignStmt && nextScopeType === ScopeType.FOR_CONDITION_TYPE && + !this.gFinishIfStmtLines.includes(stmt.getOriginPositionInfo().getLineNo())) { + return true; + } + return false; + } + + private genChildScope(curScope: Scope, scopeType: ScopeType): Scope { + let newScope = new Scope(curScope, new Array(), curScope.scopeLevel + 1, scopeType); + curScope.setChildScope(newScope); + return newScope; + } + + private assignStmtProcess(stmt: Stmt, curScope: Scope): boolean { + let def = stmt.getDef(); + if (def instanceof Local) { + if (def.getName() === 'this') { + return false; + } + const isForStmtThirdPart = (CheckerUtils.getScopeType(stmt) === ScopeType.FOR_CONDITION_TYPE && + this.gFinishIfStmtLines.includes(stmt.getOriginPositionInfo().getLineNo())); + if (CheckerUtils.wherIsTemp(stmt) === TempLocation.LEFT || + (!isForStmtThirdPart && CheckerUtils.isDeclaringStmt(def.getName(), stmt))) { + curScope.addVariable(new Variable(stmt)); + } else { + this.getDefAndSetRedef(def.getName(), curScope, curScope, stmt, SetDefMode.REDEF); + } + } else if (def instanceof ArkArrayRef) { + let base = def.getBase(); + if (base instanceof Local && !base.getName().includes('%')) { + this.getDefAndSetRedef(base.getName(), curScope, curScope, stmt, SetDefMode.LEFTUSED); + } + } + return true; + } + + private getDefAndSetRedef(name: string, searchScope: Scope, varScope: Scope, stmt: Stmt, mode: SetDefMode): boolean { + let defList = searchScope.defList; + for (let variable of defList) { + if (variable.getName() === name) { + if (mode === SetDefMode.REDEF) { + variable.redefInfo.add(new VarInfo(stmt, varScope)); + } else if (mode === SetDefMode.LEFTUSED) { + variable.leftUsedInfo.add(new VarInfo(stmt, varScope)); + } + } + } + if (searchScope.parentScope !== null) { + return this.getDefAndSetRedef(name, searchScope.parentScope, varScope, stmt, mode); + } + return false; + } + + private switchBlockPreProcess(block: BasicBlock, curScope: Scope): void { + const caseBlocks = block.getSuccessors(); + for (let caseBlock of caseBlocks) { + this.finishBlockSet.add(caseBlock); + } + for (let i = 0; i < caseBlocks.length; i++) { + if (i === caseBlocks.length - 1) { + this.isSwitchLastCase = true; + } + this.blockProcess(caseBlocks[i], this.genChildScope(curScope, ScopeType.CASE_TYPE)); + } + this.isSwitchLastCase = false; + } + + private nextBlockPreProcess(block: BasicBlock, curScope: Scope, nextScopeType: ScopeType): void { + const succBlocks = block.getSuccessors(); + const proedBlocks = block.getPredecessors(); + for (let i = 0; i < succBlocks.length; i++) { + if (this.finishBlockSet.has(succBlocks[i])) { + continue; + } + if (this.isTernaryCondition(succBlocks[i], proedBlocks)) { + this.blockProcess(succBlocks[i], curScope); + continue; + } + this.handleSuccessorBlock(succBlocks[i], curScope, nextScopeType, i); + } + } + + private handleSuccessorBlock(succBlock: BasicBlock, curScope: Scope, nextScopeType: ScopeType, index: number): void { + if (index === 0) { + if (this.isNeedCreateScope(nextScopeType)) { + const type = (nextScopeType === ScopeType.FOR_CONDITION_TYPE) ? ScopeType.FOR_IN_TYPE : nextScopeType; + this.blockProcess(succBlock, this.genChildScope(curScope, type)); + } else { + if (this.isSwitchLastCase) { + this.isSwitchLastCase = false; + curScope = curScope.parentScope ?? curScope; + } + this.blockProcess(succBlock, this.getReturnScope(succBlock, curScope)); + } + } else { + if (nextScopeType === ScopeType.FOR_CONDITION_TYPE) { + this.blockProcess(succBlock, this.getReturnScope(succBlock, curScope.parentScope ?? curScope)); + } else if (nextScopeType === ScopeType.WHILE_TYPE) { + this.blockProcess(succBlock, this.getReturnScope(succBlock, curScope)); + } else { + this.blockProcess(succBlock, this.genChildScope(curScope, ScopeType.ELSE_TYPE)); + } + } + } + + private isTernaryCondition(succBlock: BasicBlock, predBlocks: BasicBlock[]): boolean { + const succStmts = succBlock.getStmts(); + if (succStmts.length > 0 && this.gTernaryConditionLines.has(succStmts[0].getOriginPositionInfo().getLineNo())) { + return true; + } else if (predBlocks.length === 1 && this.gTernaryConditionLines.has(predBlocks?.[0].getStmts()?.at(-1)?.getOriginPositionInfo().getLineNo() ?? 0)) { + return true; + } else { + return false; + } + } + + private isNeedCreateScope(nextScopeType: ScopeType): boolean { + if (nextScopeType === ScopeType.IF_TYPE || + nextScopeType === ScopeType.FOR_CONDITION_TYPE || + nextScopeType === ScopeType.WHILE_TYPE) { + return true; + } + return false; + } + + private getReturnScope(succBlock: BasicBlock, curScope: Scope): Scope { + const stmts = succBlock.getStmts(); + if (stmts.length !== 0) { + const type = CheckerUtils.getScopeType(stmts[0]); + if ([ScopeType.WHILE_TYPE, ScopeType.FOR_CONDITION_TYPE].includes(type)) { + return curScope; + } + } else { + return curScope; + } + let returnScopeLevel = curScope.scopeLevel - (succBlock.getPredecessors().length - 1); + let exitNum = curScope.scopeLevel - returnScopeLevel; + while (exitNum) { + if (curScope.parentScope !== null) { + curScope = curScope.parentScope; + exitNum--; + } else { + logger.debug('CountExitScopeNum error!'); + break; + } + } + return curScope; + } +} + +enum SetDefMode { + REDEF = 0, + LEFTUSED +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/src/utils/common/Utils.ts b/ets2panda/linter/homecheck/src/utils/common/Utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..3dcd8e695dd64f97ac29613b27d93040d7bcabc1 --- /dev/null +++ b/ets2panda/linter/homecheck/src/utils/common/Utils.ts @@ -0,0 +1,94 @@ +/* + * 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. + */ +import Logger, { LOG_LEVEL, LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger'; +import { Command, OptionValues } from 'commander'; + +const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Utils'); + +export class Utils { + /** + * 解析命令行选项 + * @param args 命令行参数数组 + * @returns 解析后的选项值 + */ + static parseCliOptions(args: string[]): OptionValues { + logger.info('Parse cli options.'); + const program = new Command(); + return this.getCliOptions(program, args); + } + + /** + * 获取命令行选项 + * @param program Command 对象 + * @param args 命令行参数数组 + * @returns 选项值对象 + */ + static getCliOptions(program: Command, args: string[]): OptionValues { + program + .option('--configPath ', 'rule config path') + .option('--projectConfigPath ', 'project config path') + .option('--depGraphOutputDir ', 'output directory of dependency graph') + .parse(args); + return program.opts(); + } + + /** + * 设置日志路径 + * @param logPath 日志路径 + */ + static setLogPath(logPath: string): void { + Logger.configure(logPath, LOG_LEVEL.INFO, LOG_LEVEL.INFO); + } + + /** + * 设置日志信息,包含路径、arkanalyzer日志级别、homecheck日志级别 + */ + static setLogConfig(logPath: string, aaLevel: LOG_LEVEL, hcLevel: LOG_LEVEL): void { + Logger.configure(logPath, aaLevel, hcLevel); + } + + /** + * 获取枚举类型的值 + * @param value - 枚举值,可以是字符串或数字 + * @param enumType - 枚举类型 + * @returns 枚举值对应的枚举类型值 + */ + static getEnumValues(value: string | number, enumType: any): any { + const key = Object.keys(enumType).find(k => k.toLowerCase() === value || enumType[k as string] === value); + return enumType[key as string]; + } + + /** + * 按行号和列号对键值对进行排序 + * @param keyA 格式为 "行号%列号%规则ID" 的字符串 + * @param keyB 格式为 "行号%列号%规则ID" 的字符串 + * @returns 排序比较结果 + */ + public static sortByLineAndColumn(keyA: string, keyB: string): number { + const [lineA, colA] = keyA.split('%', 2).map(Number); + const [lineB, colB] = keyB.split('%', 2).map(Number); + if (lineA !== lineB) { + return lineA - lineB; + } + return colA - colB; + } +} + +export type WarnInfo = { + line: number, + startCol: number, + endCol: number, + filePath: string +}; diff --git a/ets2panda/linter/homecheck/tsconfig.json b/ets2panda/linter/homecheck/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..29c940a8750e4239571c001575115895f8737e06 --- /dev/null +++ b/ets2panda/linter/homecheck/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.main.json", + "include": [ + "Index.ts", + "src/**/*" + ], + "compilerOptions": { + "outDir": "./out" + } +} diff --git a/ets2panda/linter/homecheck/tsconfig.main.json b/ets2panda/linter/homecheck/tsconfig.main.json new file mode 100644 index 0000000000000000000000000000000000000000..8aa61bd2c1a28e499f36125643a439cc853df848 --- /dev/null +++ b/ets2panda/linter/homecheck/tsconfig.main.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + "declaration": true, + "declarationMap": false, + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + "strictPropertyInitialization": false, + "outDir": "dist", + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "skipLibCheck": true, /* Skip type checking all .d.ts files. */ + } +} diff --git a/ets2panda/linter/homecheck/tsconfig.prod.json b/ets2panda/linter/homecheck/tsconfig.prod.json new file mode 100644 index 0000000000000000000000000000000000000000..4aa413773d41f2812d7a5bcbcc4d384e41127e72 --- /dev/null +++ b/ets2panda/linter/homecheck/tsconfig.prod.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.main.json", + "include": [ + "src/**/*", + ], + "compilerOptions": { + "outDir": "./lib" + } +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/typedoc.json b/ets2panda/linter/homecheck/typedoc.json new file mode 100644 index 0000000000000000000000000000000000000000..23abcc61a90082af862f83c9e9b6de6a14c379b5 --- /dev/null +++ b/ets2panda/linter/homecheck/typedoc.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "name": "homecheck", + "entryPoints": [ + "./src/Index.ts" + ], + "out": "doc", + "readme": "./README.md" +} \ No newline at end of file diff --git a/ets2panda/linter/homecheck/vitest.config.ts b/ets2panda/linter/homecheck/vitest.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..211d2a840e8089701e0c9af0b6dce42addf44a8a --- /dev/null +++ b/ets2panda/linter/homecheck/vitest.config.ts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 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 tsconfigPaths from 'vite-tsconfig-paths'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['test/**/**.test.ts'], + }, + plugins: [ + tsconfigPaths() + ] +}); \ No newline at end of file diff --git a/ets2panda/linter/package.json b/ets2panda/linter/package.json index 6b88208578d35d1c518d3e88e255a4b918337bf5..9c02abca4546da39b55045be4245ee1f063e3d13 100644 --- a/ets2panda/linter/package.json +++ b/ets2panda/linter/package.json @@ -16,14 +16,16 @@ "compile": "npm run tsc", "postcompile": "node scripts/testRunner/post-compile.mjs", "build": "npm run clean && npm run compile && npm run webpack && npm run pack:linter", - "install-ohos-typescript": "node scripts/install-ohos-typescript.mjs", + "install-ohos-typescript": "node scripts/install-ohos-typescript-and-homecheck.mjs", "pack:linter": "rimraf bundle && mkdir bundle && npm pack --pack-destination bundle", "pretest": " npm run fix", "test": "npm run test_all && npm run test_ts_import_ets", - "test_all": "npm run testrunner -- -d test/main,test/rules,test/regression,test/extended_features,test/ohmurl,test/interop", + "test_all": "npm run testrunner -- -d test/main,test/rules,test/regression,test/extended_features,test/migration,test/ohmurl,test/interop,test/sdkwhite,test/concurrent,test/builtin", "test_main": "npm run testrunner -- -d test/main", "test_ohmurl": "npm run testrunner -- -d test/ohmurl", "test_interop": "npm run testrunner -- -d test/interop", + "test_sdk": "npm run testrunner -- -d test/sdkwhite", + "test_concurrent": "npm run testrunner -- -d test/concurrent", "test_rules": "npm run testrunner -- -d test/rules", "test_regression": "npm run testrunner -- -d test/regression", "test_extended_features": "npm run testrunner -- -d test/extended_features", @@ -32,9 +34,9 @@ "test_regression_sdk": "npm run testrunner -- -d test/regression --sdk", "test_rules_sdk": "npm run testrunner -- -d test/rules --sdk", "test_ts_import_ets": "npm run testrunner -- -d test/ts_import_ets/ts --sdk --interop-mode", - "test_migration": "npm run testrunner -- -d test/migrate", + "test_migration": "npm run testrunner -- -d test/migration", "testrunner": "npm run compile && node build/testRunner/TestRunner.js", - "update-tests": "node scripts/update-test-results.mjs test/main test/rules test/regression test/extended_features test/ts_import_ets/ts", + "update-tests": "node scripts/update-test-results.mjs test/main test/rules test/regression test/extended_features test/ts_import_ets/ts test/migration test/ohmurl test/interop test/sdkwhite test/concurrent test/builtin", "eslint-check": "npx eslint .", "eslint-fix": "npm run eslint-check -- --fix", "prettier-fix": "npx prettier --write .", @@ -42,8 +44,11 @@ }, "dependencies": { "commander": "^9.4.0", + "homecheck": "file:./homecheck", "log4js": "^6.4.0", - "yup": "^1.4.0" + "yup": "^1.4.0", + "fs-extra": "11.2.0", + "json5": "2.2.3" }, "devDependencies": { "@eslint/compat": "latest", @@ -66,6 +71,7 @@ }, "bundleDependencies": [ "log4js", - "commander" + "commander", + "homecheck" ] } diff --git a/ets2panda/linter/scripts/install-ohos-typescript.mjs b/ets2panda/linter/scripts/install-ohos-typescript-and-homecheck.mjs similarity index 54% rename from ets2panda/linter/scripts/install-ohos-typescript.mjs rename to ets2panda/linter/scripts/install-ohos-typescript-and-homecheck.mjs index 74b60af5571b211394879bc5fdd672e5c127c888..5fc2c55baa1b709e4f9ad0ecaa6c50ee2c265aea 100644 --- a/ets2panda/linter/scripts/install-ohos-typescript.mjs +++ b/ets2panda/linter/scripts/install-ohos-typescript-and-homecheck.mjs @@ -19,6 +19,7 @@ import { exit } from 'node:process' import { dirname } from 'path' import shell from 'shelljs' import { fileURLToPath } from 'url' +import path from 'node:path' // waitTime in ms function sleep(waitTime) { @@ -33,38 +34,70 @@ function sleep(waitTime) { function detectOS() { let windowsPlatforms = ['win32', 'win64', 'windows', 'wince'] let linuxPlatforms = ['linux'] + let macosPlatforms = ['darwin'] + let detectedOS = null - const opetaringSystemName = os.platform().toLowerCase() + const operatingSystemName = os.platform().toLowerCase() - if (windowsPlatforms.indexOf(opetaringSystemName) !== -1) { + if (windowsPlatforms.indexOf(operatingSystemName) !== -1) { detectedOS = 'Windows' - } else if (linuxPlatforms.indexOf(opetaringSystemName) !== -1) { + } else if (linuxPlatforms.indexOf(operatingSystemName) !== -1) { detectedOS = 'Linux' + } else if (macosPlatforms.indexOf(operatingSystemName) !== -1) { + detectedOS = 'macOS' } return detectedOS } +function backupPackageJson(dirPath) { + const pkgPath = path.join(dirPath, 'package.json') + const backupName = `package.json.bak-${Date.now()}` + + if (!fs.existsSync(pkgPath)) { + console.error(`[ERROR] package.json not found in ${dirPath}`) + process.exit(1) + } + + fs.copyFileSync(pkgPath, path.join(dirPath, backupName)) + return backupName +} + +function restorePackageJson(dirPath, backupFile) { + const currentPkg = path.join(dirPath, 'package.json') + const backupPath = path.join(dirPath, backupFile) + + if (!fs.existsSync(backupPath)) { + console.error(`[ERROR] Backup file not found: ${backupPath}`) + process.exit(1) + } + + fs.rmSync(currentPkg, { force: true }) + fs.renameSync(backupPath, currentPkg) +} + function getTypescript(detectedOS) { const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); - + const linter = __dirname + '/..' const third_party = __dirname + '/../third_party' const typescript_dir = third_party + '/third_party_typescript' - + const arkanalyzer = __dirname + '/../arkanalyzer' + const homecheck = __dirname + '/../homecheck' + if (!fs.existsSync(third_party)) { fs.mkdirSync(third_party); } - let branch = process.env.TYPESCRIPT_BRANCH ?? 'master' + let branch = process.env.TYPESCRIPT_BRANCH ?? 'OpenHarmony_feature_20250328' - if (detectedOS === 'Linux') { + if (detectedOS === 'Linux' || detectedOS === 'macOS') { let timeToWait = 5000 const iterations = 4 if (!fs.existsSync(typescript_dir)) { for (let i = 0; i <= iterations; i++) { - shell.exec(`git clone --depth=1 https://gitee.com/openharmony/third_party_typescript.git ${typescript_dir}`, { stdio: 'ignore', fatal: true } ) + shell.exec(`git clone --depth=1 https://gitee.com/openharmony/third_party_typescript.git -b ${branch} ${typescript_dir}`, { stdio: 'ignore', fatal: true } ) if (fs.existsSync(typescript_dir) || i === iterations) { break; } @@ -102,16 +135,41 @@ function getTypescript(detectedOS) { console.log('OS was detected, but was not expected') exit(1) } - - const npm_package = shell.exec('npm pack').stdout.trim() + + const npm_typescript_package = shell.exec('npm pack').stdout.trim() + + shell.cd(arkanalyzer) + const arkanalyzerBackFile = backupPackageJson(arkanalyzer) + shell.exec(`npm install ${typescript_dir}/${npm_typescript_package}`) + shell.exec('npm run compile') + const npm_arkanalyzer_package = shell.exec('npm pack').stdout.trim() + restorePackageJson(arkanalyzer, arkanalyzerBackFile) + shell.rm('-rf', 'lib') + + shell.cd(homecheck) + const homecheckBackFile = backupPackageJson(homecheck) + + shell.exec(`npm install ${arkanalyzer}/${npm_arkanalyzer_package}`) + shell.exec(`npm install --no-save ${typescript_dir}/${npm_typescript_package}`) + shell.exec('npm run compile') + const npm_homecheck_package = shell.exec('npm pack').stdout.trim() + restorePackageJson(homecheck, homecheckBackFile) + shell.rm('-rf', 'lib') + shell.cd(linter) - shell.exec(`npm install --no-save ${typescript_dir}/${npm_package}`) - + shell.exec(`npm install --no-save ${typescript_dir}/${npm_typescript_package} ${homecheck}/${npm_homecheck_package}`) + const node_modules = linter + '/node_modules' - + fs.rmSync(node_modules + '/typescript', {recursive: true, force: true}) - shell.exec(`tar -xzf "${typescript_dir}/${npm_package}" -C node_modules --strip-components 1 --one-top-level=typescript`); - shell.rm(`${typescript_dir}/${npm_package}`) + + const targetDir = path.join('node_modules', 'typescript') + fs.mkdirSync(targetDir, { recursive: true }) + + shell.exec(`tar -xzf "${typescript_dir}/${npm_typescript_package}" -C "${targetDir}" --strip-components 1`) + shell.rm(`${typescript_dir}/${npm_typescript_package}`) + shell.rm(`${arkanalyzer}/${npm_arkanalyzer_package}`) + shell.rm(`${homecheck}/${npm_homecheck_package}`) } const detectedOS = detectOS() diff --git a/ets2panda/linter/scripts/update-test-results.mjs b/ets2panda/linter/scripts/update-test-results.mjs index a76bc1b09da43ac06ab122f1c3f41a3e904cfcb7..19cbb231f3a4dfa463d2b016e6e4c92e21c1e661 100644 --- a/ets2panda/linter/scripts/update-test-results.mjs +++ b/ets2panda/linter/scripts/update-test-results.mjs @@ -17,24 +17,26 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; const TS_EXT = ".ts"; -const ETS_EXT = ".ets"; -const TSX_EXT = ".tsx"; -const ETSX_EXT = ".etsx"; const D_TS_EXT = '.d.ts'; +const TSX_EXT = ".tsx"; +const ETS_EXT = ".ets"; class Mode { - static DEFAULT = 1; - static AUTOFIX = 2; - static ARKTS2 = 3; + static DEFAULT = 1; + static AUTOFIX = 2; + static ARKTS2 = 3; + static MIGRATE = 4; } -const RESULT_EXT = []; -RESULT_EXT[Mode.DEFAULT] = '.json'; -RESULT_EXT[Mode.AUTOFIX] = '.autofix.json'; -RESULT_EXT[Mode.ARKTS2] = '.arkts2.json'; +const LINT_RESULT_EXT = []; +LINT_RESULT_EXT[Mode.DEFAULT] = '.json'; +LINT_RESULT_EXT[Mode.AUTOFIX] = '.autofix.json'; +LINT_RESULT_EXT[Mode.ARKTS2] = '.arkts2.json'; +LINT_RESULT_EXT[Mode.MIGRATE] = '.migrate.json'; const DIFF_EXT = '.diff'; const RESULTS_DIR = 'results'; const TEST_ARGS_EXT = '.args.json'; +const MIGRATE_RESULT_SUFFIX = '.migrate'; let testDirs = []; @@ -42,96 +44,138 @@ let testDirs = []; let force_update = false; for (let arg of process.argv.slice(2)) { - if (arg === '--force') - force_update = true; - else - testDirs.push(arg); + if (arg === '--force') + force_update = true; + else + testDirs.push(arg); } -const DEFAULT_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." +const DEFAULT_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." ]; function readJsonFile(filePath) { - try { - let resultFile = fs.readFileSync(filePath).toString(); - return JSON.parse(resultFile); - } catch (error) { - return undefined; - } + try { + let resultFile = fs.readFileSync(filePath).toString(); + return JSON.parse(resultFile); + } catch (error) { + return undefined; + } } function updateTestFile(testDir, testFile) { - let testModes = [Mode.DEFAULT]; - - const testArgsFile = path.join(testDir, testFile + TEST_ARGS_EXT); - if (fs.existsSync(testArgsFile)) { - const testArgs = readJsonFile(testArgsFile); - if (testArgs?.mode?.autofix !== undefined) testModes.push(Mode.AUTOFIX); - if (testArgs?.mode?.arkts2 !== undefined) testModes.push(Mode.ARKTS2); - } - - for (const mode of testModes) { - updateTest(testDir, testFile, mode); - } + let testModes = [Mode.DEFAULT]; + + const testArgsFile = path.join(testDir, testFile + TEST_ARGS_EXT); + if (fs.existsSync(testArgsFile)) { + const testArgs = readJsonFile(testArgsFile); + if (testArgs?.mode?.autofix !== undefined) testModes.push(Mode.AUTOFIX); + if (testArgs?.mode?.arkts2 !== undefined) testModes.push(Mode.ARKTS2); + if (testArgs?.mode?.migrate !== undefined) testModes.push(Mode.MIGRATE); + } + + for (const mode of testModes) { + updateTest(testDir, testFile, mode); + } } function updateTest(testDir, testFile, mode) { - let resultExt = RESULT_EXT[mode]; - let resultFileWithExt = testFile + resultExt; - let resultFilePath = path.join(testDir, resultFileWithExt); - - // Update test result when: - // - '.diff' exists - // - expected '.json' for specified test mode doesn't exist - // - 'force' option is enabled - if (fs.existsSync(resultFilePath) && !fs.existsSync(path.join(testDir, RESULTS_DIR, resultFileWithExt + DIFF_EXT)) && !force_update) { - return; - } - - let expectedResult = readJsonFile(resultFilePath); - - const copyright = expectedResult?.copyright ?? DEFAULT_COPYRIGHT; - - let actualResult = readJsonFile(path.join(testDir, RESULTS_DIR, resultFileWithExt)); - if (!actualResult || !actualResult.result) { - console.log(`Failed to update ${resultFileWithExt}: couldn't process ACTUAL result file.`); - return; - } - - // Write file with actual test results. - let newResultJSON = JSON.stringify({ copyright, result: actualResult.result }, null, 4); + updateLintResult(testDir, testFile, mode); + if (mode === Mode.MIGRATE) { + updateMigrateResult(testDir, testFile); + } +} + +function updateLintResult(testDir, testFile, mode) { + let resultExt = LINT_RESULT_EXT[mode]; + let resultFileWithExt = testFile + resultExt; + let resultFilePath = path.join(testDir, resultFileWithExt); + + // Update test result when: + // - '.diff' exists + // - expected '.json' for specified test mode doesn't exist + // - 'force' option is enabled + if (fs.existsSync(resultFilePath) && !fs.existsSync(path.join(testDir, RESULTS_DIR, resultFileWithExt + DIFF_EXT)) && !force_update) { + return; + } + + let expectedResult = readJsonFile(resultFilePath); + + const copyright = expectedResult?.copyright ?? DEFAULT_COPYRIGHT; + + let actualResult = readJsonFile(path.join(testDir, RESULTS_DIR, resultFileWithExt)); + if (!actualResult || !actualResult.result) { + console.log(`Failed to update ${resultFileWithExt}: couldn't process ACTUAL result file.`); + return; + } + + // Write file with actual test results. + try { + const newResultJSON = JSON.stringify({ copyright, result: actualResult.result }, null, 4); fs.writeFileSync(resultFilePath, newResultJSON); + } + catch (e) { + console.log(`Failed to update ${resultFileWithExt}: ${e.message || e}`); + return; + } + + + console.log(`Updated ${resultFileWithExt}`); +} - console.log(`Updated ${resultFileWithExt}`); +function updateMigrateResult(testDir, testFile) { + let resultExt = MIGRATE_RESULT_SUFFIX + path.extname(testFile); + let resultFileWithExt = testFile + resultExt; + let resultFilePath = path.join(testDir, resultFileWithExt); + + // Update test result when: + // - '.diff' exists + // - expected result file doesn't exist + // - 'force' option is enabled + if (fs.existsSync(resultFilePath) && !fs.existsSync(path.join(testDir, RESULTS_DIR, resultFileWithExt + DIFF_EXT)) && !force_update) { + return; + } + + try { + const actualResultFilePath = path.join(testDir, RESULTS_DIR, resultFileWithExt); + fs.copyFileSync(actualResultFilePath, resultFilePath); + } + catch (e) { + console.log(`Failed to update ${resultFileWithExt}: ${e.message || e}`); + return; + } + + console.log(`Updated ${resultFileWithExt}`); } for (let testDir of testDirs) { - if (!fs.existsSync(path.join(testDir, RESULTS_DIR))) continue; - - // Get tests from test directory. - let testFiles = fs.readdirSync(testDir).filter(x => - (x.trimEnd().endsWith(TS_EXT) && !x.trimEnd().endsWith(D_TS_EXT)) || - x.trimEnd().endsWith(TSX_EXT) || - x.trimEnd().endsWith(ETS_EXT) || - x.trimEnd().endsWith(ETSX_EXT) - ); - - if (!testFiles) continue; - - // Update result for each test: - for (let testFile of testFiles) { - updateTestFile(testDir, testFile); - } + if (!fs.existsSync(path.join(testDir, RESULTS_DIR))) continue; + + // Get tests from test directory. + let testFiles = fs.readdirSync(testDir).filter(x => { + const file = x.trimEnd(); + return ( + (file.endsWith(TS_EXT) && !file.endsWith(D_TS_EXT)) || + file.endsWith(TSX_EXT) || + file.endsWith(ETS_EXT) + ) && !file.endsWith(MIGRATE_RESULT_SUFFIX + path.extname(file)) + }); + + if (!testFiles) continue; + + // Update result for each test: + for (let testFile of testFiles) { + updateTestFile(testDir, testFile); + } } \ No newline at end of file diff --git a/ets2panda/linter/src/cli/CommandLineParser.ts b/ets2panda/linter/src/cli/CommandLineParser.ts index ae1471a6be2af2a6c9ff3f01eaee835acdc90308..d20a18c218867a72fc21cb608ce62aa073e5fd2a 100644 --- a/ets2panda/linter/src/cli/CommandLineParser.ts +++ b/ets2panda/linter/src/cli/CommandLineParser.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -16,6 +16,7 @@ import { Logger } from '../lib/Logger'; import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import { ARKTS_IGNORE_DIRS_OH_MODULES } from '../lib/utils/consts/ArktsIgnorePaths'; import type { OptionValues } from 'commander'; import { Command, Option } from 'commander'; import * as ts from 'typescript'; @@ -25,6 +26,7 @@ import * as path from 'node:path'; const TS_EXT = '.ts'; const TSX_EXT = '.tsx'; const ETS_EXT = '.ets'; +const JS_EXT = '.js'; interface CommanderParseOptions { exitOnFail?: boolean; @@ -43,6 +45,9 @@ interface ParsedCommand { const getFiles = (dir: string): string[] => { const resultFiles: string[] = []; + if (dir.includes(ARKTS_IGNORE_DIRS_OH_MODULES)) { + return []; + } const files = fs.readdirSync(dir); for (let i = 0; i < files.length; ++i) { @@ -51,7 +56,7 @@ const getFiles = (dir: string): string[] => { resultFiles.push(...getFiles(name)); } else { const extension = path.extname(name); - if (extension === TS_EXT || extension === TSX_EXT || extension === ETS_EXT) { + if (extension === TS_EXT || extension === TSX_EXT || extension === ETS_EXT || extension === JS_EXT) { resultFiles.push(name); } } @@ -87,18 +92,66 @@ function parseCommand(program: Command, cmdArgs: string[]): ParsedCommand { }; } -function formOptionPaths(cmdlOptions: CommandLineOptions, options: OptionValues): CommandLineOptions { - const opts = cmdlOptions; - if (options.sdkExternalApiPath) { - opts.sdkExternalApiPath = options.sdkExternalApiPath; +function formSdkOptions(cmdOptions: CommandLineOptions, commanderOpts: OptionValues): void { + if (commanderOpts.sdkExternalApiPath) { + cmdOptions.sdkExternalApiPath = commanderOpts.sdkExternalApiPath; } - if (options.sdkDefaultApiPath) { - opts.sdkDefaultApiPath = options.sdkDefaultApiPath; + if (commanderOpts.sdkDefaultApiPath) { + cmdOptions.sdkDefaultApiPath = commanderOpts.sdkDefaultApiPath; } - if (options.arktsWholeProjectPath) { - opts.arktsWholeProjectPath = options.arktsWholeProjectPath; + if (commanderOpts.arktsWholeProjectPath) { + cmdOptions.arktsWholeProjectPath = commanderOpts.arktsWholeProjectPath; + } +} + +function formMigrateOptions(cmdOptions: CommandLineOptions, commanderOpts: OptionValues): void { + if (commanderOpts.migrate) { + cmdOptions.linterOptions.migratorMode = true; + cmdOptions.linterOptions.enableAutofix = true; + } + if (commanderOpts.migrationBackupFile === false) { + cmdOptions.linterOptions.noMigrationBackupFile = true; + } + if (commanderOpts.migrationMaxPass) { + const num = Number(commanderOpts.migrationMaxPass); + cmdOptions.linterOptions.migrationMaxPass = isNaN(num) ? 0 : num; + } + if (commanderOpts.migrationReport) { + cmdOptions.linterOptions.migrationReport = true; + } + if (commanderOpts.arktsWholeProjectPath) { + cmdOptions.linterOptions.wholeProjectPath = commanderOpts.arktsWholeProjectPath; + } +} + +function formIdeInteractive(cmdOptions: CommandLineOptions, commanderOpts: OptionValues): void { + if (commanderOpts.ideInteractive) { + cmdOptions.linterOptions.ideInteractive = true; + } + if (commanderOpts.checkTsAndJs) { + cmdOptions.linterOptions.checkTsAndJs = true; + } + if (commanderOpts.onlyArkts2SyntaxRules) { + cmdOptions.onlySyntax = true; + } +} + +function formArkts2Options(cmdOptions: CommandLineOptions, commanderOpts: OptionValues): void { + if (commanderOpts.arkts2) { + cmdOptions.linterOptions.arkts2 = true; + } + if (commanderOpts.skipLinter) { + cmdOptions.skipLinter = true; + } + if (commanderOpts.homecheck) { + cmdOptions.homecheck = true; + } + if (commanderOpts.outputFilePath) { + cmdOptions.outputFilePath = path.normalize(commanderOpts.outputFilePath); + } + if (commanderOpts.verbose) { + cmdOptions.verbose = true; } - return opts; } function formCommandLineOptions(parsedCmd: ParsedCommand): CommandLineOptions { @@ -114,7 +167,7 @@ function formCommandLineOptions(parsedCmd: ParsedCommand): CommandLineOptions { opts.logTscErrors = true; } if (options.devecoPluginMode) { - opts.linterOptions.ideMode = true; + opts.devecoPluginModeDeprecated = true; } if (options.checkTsAsSource !== undefined) { opts.linterOptions.checkTsAsSource = options.checkTsAsSource; @@ -128,23 +181,17 @@ function formCommandLineOptions(parsedCmd: ParsedCommand): CommandLineOptions { if (options.autofix) { opts.linterOptions.enableAutofix = true; } - if (options.arkts2) { - opts.linterOptions.arkts2 = true; - } if (options.warningsAsErrors) { opts.linterOptions.warningsAsErrors = true; } if (options.useRtLogic !== undefined) { opts.linterOptions.useRtLogic = options.useRtLogic; } - if (options.ideInteractive) { - opts.linterOptions.ideInteractive = true; - } - if (options.migrate !== undefined) { - opts.linterOptions.migratorMode = options.migrate; - opts.linterOptions.enableAutofix = true; - } - return formOptionPaths(opts, options); + formIdeInteractive(opts, options); + formSdkOptions(opts, options); + formMigrateOptions(opts, options); + formArkts2Options(opts, options); + return opts; } function createCommand(): Command { @@ -158,7 +205,6 @@ function createCommand(): Command { program. option('-E, --TSC_Errors', 'show error messages from Tsc'). option('--check-ts-as-source', 'check TS files as source files'). - option('--deveco-plugin-mode', 'run as IDE plugin'). option('-p, --project ', 'path to TS project config file'). option( '-f, --project-folder ', @@ -174,6 +220,18 @@ function createCommand(): Command { option('--ide-interactive', 'Migration Helper IDE interactive mode'). option('-w, --arkts-whole-project-path ', 'path to whole project'). option('--migrate', 'run as ArkTS migrator'). + option('--skip-linter', 'skip linter rule validation and autofix'). + option('--homecheck', 'added homecheck rule validation'). + option('--no-migration-backup-file', 'Disable the backup files in migration mode'). + option('--migration-max-pass ', 'Maximum number of migration passes'). + option('--migration-report', 'Generate migration report'). + option('--check-ts-and-js', 'check ts and js files'). + option( + '--only-arkts2-syntax-rules', + 'only syntax rules, excluding rules such as SDK, Arkui, Interop, Concurrent, etc' + ). + option('-o, --output-file-path ', 'path to store all log and result files'). + option('--verbose', 'set log level to see debug messages'). addOption(new Option('--warnings-as-errors', 'treat warnings as errors').hideHelp(true)). addOption(new Option('--no-check-ts-as-source', 'check TS files as third-party libary').hideHelp(true)). addOption(new Option('--no-use-rt-logic', 'run linter with SDK logic').hideHelp(true)). diff --git a/ets2panda/linter/src/cli/LinterCLI.ts b/ets2panda/linter/src/cli/LinterCLI.ts index 7b5b93a455858ac6d9209ad6891da6a44c5abb68..45bd9fddcd788362a353d59c33e646bac8156c4e 100644 --- a/ets2panda/linter/src/cli/LinterCLI.ts +++ b/ets2panda/linter/src/cli/LinterCLI.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -21,10 +21,12 @@ import type { CommandLineOptions } from '../lib/CommandLineOptions'; import { lint } from '../lib/LinterRunner'; import { Logger } from '../lib/Logger'; import type { ProblemInfo } from '../lib/ProblemInfo'; -import { TypeScriptLinter } from '../lib/TypeScriptLinter'; import { parseCommandLine } from './CommandLineParser'; -import { compileLintOptions } from './Compiler'; -import type { LinterConfig } from '../lib/LinterConfig'; +import { compileLintOptions, getEtsLoaderPath } from '../lib/ts-compiler/Compiler'; +import { logStatistics } from '../lib/statistics/StatisticsLogger'; +import { arkts2Rules, onlyArkts2SyntaxRules } from '../lib/utils/consts/ArkTS2Rules'; +import { MigrationTool } from 'homecheck'; +import { getHomeCheckConfigInfo, transferIssues2ProblemInfo } from '../lib/HomeCheck'; export function run(): void { const commandLineArgs = process.argv.slice(2); @@ -35,32 +37,92 @@ export function run(): void { const cmdOptions = parseCommandLine(commandLineArgs); - TypeScriptLinter.initGlobals(); - - if (!cmdOptions.linterOptions.ideMode && !cmdOptions.linterOptions.ideInteractive) { - const compileOptions = compileLintOptions(cmdOptions); - const result = lint(compileOptions, getEtsLoaderPath(compileOptions)); - process.exit(result.errorNodes > 0 ? 1 : 0); + if (cmdOptions.devecoPluginModeDeprecated) { + runIdeModeDeprecated(cmdOptions); } else if (cmdOptions.linterOptions.ideInteractive) { - runMigrationCliMode(cmdOptions); + runIdeInteractiveMode(cmdOptions); } else { - runIDEMode(cmdOptions); + const compileOptions = compileLintOptions(cmdOptions); + const result = lint(compileOptions); + logStatistics(result.projectStats); + process.exit(result.hasErrors ? 1 : 0); } } -async function runMigrationCliMode(cmdOptions: CommandLineOptions): Promise { +async function runIdeInteractiveMode(cmdOptions: CommandLineOptions): Promise { + cmdOptions.followSdkSettings = true; + cmdOptions.disableStrictDiagnostics = true; const compileOptions = compileLintOptions(cmdOptions); - const result = lint(compileOptions, getEtsLoaderPath(compileOptions)); - for (const [filePath, problems] of result.problemsInfos) { - await processSyncOut( - JSON.stringify({ - filePath, - problems - }) + '\n' - ); + let homeCheckResult = new Map(); + const mergedProblems = new Map(); + + if (cmdOptions.linterOptions.arkts2 && cmdOptions.homecheck) { + const { ruleConfigInfo, projectConfigInfo } = getHomeCheckConfigInfo(cmdOptions); + const migrationTool = new MigrationTool(ruleConfigInfo, projectConfigInfo); + await migrationTool.buildCheckEntry(); + const result = await migrationTool.start(); + + homeCheckResult = transferIssues2ProblemInfo(result); + for (const [filePath, problems] of homeCheckResult) { + if (!mergedProblems.has(filePath)) { + mergedProblems.set(filePath, []); + } + mergedProblems.get(filePath)!.push(...problems); + } + } + + if (!cmdOptions.skipLinter) { + const result = lint(compileOptions, getEtsLoaderPath(compileOptions), homeCheckResult); + for (const [filePath, problems] of result.problemsInfos) { + mergeLintProblems(filePath, problems, mergedProblems, cmdOptions); + } + } + + const reportData = Object.fromEntries(mergedProblems); + await generateReportFile(reportData, cmdOptions.outputFilePath); + + for (const [filePath, problems] of mergedProblems) { + const reportLine = JSON.stringify({ filePath, problems }) + '\n'; + await processSyncOut(reportLine); } await processSyncErr('{"content":"report finish","messageType":1,"indictor":1}\n'); - process.exit(result.errorNodes > 0 ? 1 : 0); + process.exit(0); +} + +function mergeLintProblems( + filePath: string, + problems: ProblemInfo[], + mergedProblems: Map, + cmdOptions: CommandLineOptions +): void { + if (!mergedProblems.has(filePath)) { + mergedProblems.set(filePath, []); + } + let filteredProblems = problems; + if (cmdOptions.linterOptions.arkts2) { + filteredProblems = problems.filter((problem) => { + return arkts2Rules.includes(problem.ruleTag); + }); + } + if (cmdOptions.onlySyntax) { + filteredProblems = problems.filter((problem) => { + return onlyArkts2SyntaxRules.has(problem.ruleTag); + }); + } + mergedProblems.get(filePath)!.push(...filteredProblems); +} + +async function generateReportFile(reportData, reportPath?: string): Promise { + let reportFilePath = path.join('scan-report.json'); + if (reportPath !== undefined) { + reportFilePath = path.join(path.normalize(reportPath), 'scan-report.json'); + } + try { + await fs.promises.mkdir(path.dirname(reportFilePath), { recursive: true }); + await fs.promises.writeFile(reportFilePath, JSON.stringify(reportData, null, 2)); + } catch (error) { + console.error('Error generating report file:', error); + } } async function processSyncOut(message: string): Promise { @@ -100,8 +162,7 @@ function showJSONMessage(problems: ProblemInfo[][]): void { Logger.info(`{"linter messages":${JSON.stringify(jsonMessage)}}`); } -function runIDEMode(cmdOptions: CommandLineOptions): void { - cmdOptions.linterOptions.ideMode = true; +function runIdeModeDeprecated(cmdOptions: CommandLineOptions): void { const tmpFileName = getTempFileName(); // read data from stdin const writeStream = fs.createWriteStream(tmpFileName, { flags: 'w' }); @@ -122,7 +183,7 @@ function runIDEMode(cmdOptions: CommandLineOptions): void { cmdOptions.parsedConfigFile.fileNames.push(tmpFileName); } const compileOptions = compileLintOptions(cmdOptions); - const result = lint(compileOptions, getEtsLoaderPath(compileOptions)); + const result = lint(compileOptions); const problems = Array.from(result.problemsInfos.values()); if (problems.length === 1) { showJSONMessage(problems); @@ -132,8 +193,3 @@ function runIDEMode(cmdOptions: CommandLineOptions): void { fs.unlinkSync(tmpFileName); }); } - -export function getEtsLoaderPath(linterConfig: LinterConfig): string | undefined { - const tsProgram = linterConfig.tscCompiledProgram.getProgram(); - return tsProgram.getCompilerOptions().etsLoaderPath; -} diff --git a/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts b/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts new file mode 100644 index 0000000000000000000000000000000000000000..82bf349ba604f6c291540d90ddbdf5d52cd3fea3 --- /dev/null +++ b/ets2panda/linter/src/lib/BaseTypeScriptLinter.ts @@ -0,0 +1,112 @@ +/* + * 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 { ProblemInfo } from './ProblemInfo'; +import type { Autofix } from './autofixes/Autofixer'; +import { FileStatistics } from './statistics/FileStatistics'; +import { TsUtils } from './utils/TsUtils'; +import { cookBookRefToFixTitle } from './autofixes/AutofixTitles'; +import { faultDesc } from './FaultDesc'; +import { TypeScriptLinterConfig } from './TypeScriptLinterConfig'; +import { faultsAttrs } from './FaultAttrs'; +import { cookBookTag } from './CookBookMsg'; +import { FaultID } from './Problems'; +import { ProblemSeverity } from './ProblemSeverity'; + +export abstract class BaseTypeScriptLinter { + problemsInfos: ProblemInfo[] = []; + fileStats: FileStatistics; + tsUtils: TsUtils; + + constructor( + protected readonly tsTypeChecker: ts.TypeChecker, + readonly options: LinterOptions, + protected sourceFile: ts.SourceFile + ) { + this.tsUtils = new TsUtils(this.tsTypeChecker, options); + this.fileStats = new FileStatistics(sourceFile, this.problemsInfos); + } + + protected getLineAndCharacterOfNode(node: ts.Node | ts.CommentRange): ts.LineAndCharacter { + const startPos = TsUtils.getStartPos(node); + const { line, character } = this.sourceFile.getLineAndCharacterOfPosition(startPos); + // TSC counts lines and columns from zero + return { line: line + 1, character: character + 1 }; + } + + abstract lint(): void; + + protected updateFileStats(faultId: number, line: number): void { + this.fileStats.nodeCounters[faultId]++; + this.fileStats.lineCounters[faultId].add(line); + } + + protected static addLineColumnInfoInAutofix( + autofix: Autofix[], + startPos: ts.LineAndCharacter, + endPos: ts.LineAndCharacter + ): Autofix[] { + return autofix?.map((autofixElem) => { + autofixElem.line = startPos.line + 1; + autofixElem.column = startPos.character + 1; + autofixElem.endLine = endPos.line + 1; + autofixElem.endColumn = endPos.character + 1; + return autofixElem; + }); + } + + protected incrementCounters(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { + const [startOffset, endOffset] = TsUtils.getHighlightRange(node, faultId); + const startPos = this.sourceFile.getLineAndCharacterOfPosition(startOffset); + const endPos = this.sourceFile.getLineAndCharacterOfPosition(endOffset); + + const faultDescr = faultDesc[faultId]; + const faultType = TypeScriptLinterConfig.tsSyntaxKindNames[node.kind]; + + const cookBookMsgNum = faultsAttrs[faultId] ? faultsAttrs[faultId].cookBookRef : 0; + const cookBookTg = cookBookTag[cookBookMsgNum]; + const severity = faultsAttrs[faultId]?.severity ?? ProblemSeverity.ERROR; + const isMsgNumValid = cookBookMsgNum > 0; + autofix = autofix ? BaseTypeScriptLinter.addLineColumnInfoInAutofix(autofix, startPos, endPos) : autofix; + const badNodeInfo: ProblemInfo = { + line: startPos.line + 1, + column: startPos.character + 1, + endLine: endPos.line + 1, + endColumn: endPos.character + 1, + start: startOffset, + end: endOffset, + type: faultType, + severity: severity, + faultId: faultId, + problem: FaultID[faultId], + suggest: '', + // eslint-disable-next-line no-nested-ternary + rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, + ruleTag: cookBookMsgNum, + autofixable: !!autofix, + autofix: autofix, + autofixTitle: isMsgNumValid && autofix !== undefined ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined + }; + this.problemsInfos.push(badNodeInfo); + this.updateFileStats(faultId, badNodeInfo.line); + + // problems with autofixes might be collected separately + if (this.options.reportAutofixCb && badNodeInfo.autofix) { + this.options.reportAutofixCb(badNodeInfo); + } + } +} diff --git a/ets2panda/linter/src/lib/CommandLineOptions.ts b/ets2panda/linter/src/lib/CommandLineOptions.ts index 2cf9dd3baacdc501d3744f93356e2b7b2662675f..cbcc81f622d95eefffeee129a70e56b593cf8904 100644 --- a/ets2panda/linter/src/lib/CommandLineOptions.ts +++ b/ets2panda/linter/src/lib/CommandLineOptions.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -25,4 +25,12 @@ export interface CommandLineOptions { sdkDefaultApiPath?: string; sdkExternalApiPath?: string[]; arktsWholeProjectPath?: string; + skipLinter?: boolean; + homecheck?: boolean; + onlySyntax?: boolean; + followSdkSettings?: boolean; + devecoPluginModeDeprecated?: boolean; + disableStrictDiagnostics?: boolean; + outputFilePath?: string; + verbose?: boolean; } diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index 2e67da47f5bea5ce6ae707402e4e3f7a8426cff8..4fe5be46599a545efdd9b46e0f139b7742585557 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -16,10 +16,6 @@ export const cookBookMsg: string[] = []; export const cookBookTag: string[] = []; -for (let i = 0; i <= 300; i++) { - cookBookMsg[i] = ''; -} - 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)'; @@ -175,7 +171,7 @@ cookBookTag[147] = 'No dependencies on TypeScript code are currently allowed (ar cookBookTag[148] = ''; cookBookTag[149] = 'Classes cannot be used as objects (arkts-no-classes-as-obj)'; cookBookTag[150] = '"import" statements after other statements are not allowed (arkts-no-misplaced-imports)'; -cookBookTag[151] = 'Usage of \'ESObject\' type is restricted (arkts-limited-esobj)'; +cookBookTag[151] = 'Usage of \'ESValue\' type is restricted (arkts-limited-esobj)'; cookBookTag[152] = '\'Function.apply\', \'Function.call\' are not supported (arkts-no-func-apply-call)'; cookBookTag[153] = 'The inheritance for "Sendable" classes is limited (arkts-sendable-class-inheritance)'; cookBookTag[154] = @@ -233,24 +229,30 @@ cookBookTag[187] = 'function "Math.pow()" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)'; cookBookTag[189] = 'Numeric semantics is different for integer values (arkts-numeric-semantic)'; cookBookTag[190] = 'Stricter assignments into variables of function type (arkts-incompatible-function-types)'; +cookBookTag[191] = 'ASON is not supported. (arkts-no-need-stdlib-ason)'; cookBookTag[192] = 'Type "void" has no instances.(arkts-limited-void-type)'; cookBookTag[193] = '"void" operator is not supported (arkts-no-void-operator)'; cookBookTag[198] = 'Class TS overloading is not supported(arkts-no-ts-overload)'; +cookBookTag[199] = 'Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)'; cookBookTag[202] = 'Literal types are restricted(arkts-limited-literal-types)'; cookBookTag[203] = 'exponent opartions "**" and "**=" are disabled (arkts-no-exponent-op)'; cookBookTag[206] = '"debugger" is not supported (arkts-no-debugger-stmt)'; cookBookTag[207] = 'Special arguments object inside functions are not supported (arkts-no-arguments-obj)'; cookBookTag[208] = 'Tagged templates are not supported (arkts-no-tagged-templates)'; cookBookTag[209] = 'The index expression must be of a numeric type (arkts-array-index-expr-type)'; -cookBookTag[210] = 'The switch expression type must be of type number,string or enum (arkts-switch-expr)'; +cookBookTag[210] = + 'The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)'; cookBookTag[211] = 'No two case constant expressions have identical values.(arkts-case-expr)'; cookBookTag[212] = 'The index expression must be zero or positive value.(arkts-array-index-negative)'; +cookBookTag[213] = 'Class cannot have static codeblocks. (arkts-class-lazy-import)'; +cookBookTag[214] = 'The Class object does not have a constructor. (arkts-no-arkts-constructor)'; +cookBookTag[215] = 'Array bound not checked. (arkts-runtime-array-check)'; cookBookTag[222] = 'Import for side-effect only is prohibited.(arkts-no-side-effect-import)'; cookBookTag[232] = 'Lazy import is not supported(arkts-no-lazy-import)'; cookBookTag[233] = 'Dynamic import is not supported(arkts-no-dynamic-import)'; cookBookTag[234] = 'Decorators are not supported(arkts-no-ts-decorators)'; cookBookTag[235] = 'Avoid using union types (arkts-common-union-member-access)'; -cookBookTag[236] = 'Method cant\'t override filed in interface implemented (arkts-no-method-overriding-field)'; +cookBookTag[236] = 'Method can\'t override filed in interface implemented (arkts-no-method-overriding-field)'; cookBookTag[237] = 'Array and tuple are different type(arkts-no-tuples-arrays)'; cookBookTag[238] = 'The static property has no initializer (arkts-class-static-initialization)'; cookBookTag[239] = 'This keyword cannot be used as identifiers (arkts-invalid-identifier)'; @@ -258,17 +260,114 @@ cookBookTag[251] = '"!!" for bidirectional data binding is not supported (arkui- cookBookTag[252] = '"$$" for bidirectional data binding is not supported (arkui-no-$$-bidirectional-data-binding)'; cookBookTag[253] = '"${variable}" for decorator binding is not supported (arkui-link-decorator-passing)'; cookBookTag[254] = '"@Extend" decorator is not supported (arkui-no-extend-decorator)'; -cookBookTag[255] = 'Extends or implemetns expression are not supported(arkts-no-extends-expression)'; +cookBookTag[255] = 'Extends or implements expression are not supported(arkts-no-extends-expression)'; cookBookTag[256] = '"@Styles" decorator is not supported (arkui-no-styles-decorator)'; cookBookTag[257] = '"@AnimatableExtend" decorator should be transformed to use receiver (arkui-animatableextend-use-receiver)'; cookBookTag[258] = 'Data observation needs to add "@Observed" (arkui-data-observation)'; cookBookTag[259] = 'ArkUI interface should be imported before using (arkui-modular-interface)'; -cookBookTag[300] = 'The function type should be explicit (arkts-no-ts-like-function)'; +cookBookTag[260] = 'The "@Entry" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)'; +cookBookTag[262] = 'The makeObserved function is not supported (arkui-no-makeobserved-function)'; +cookBookTag[263] = + 'The "@Provide" annotation does not support dynamic parameters (arkui-provide-annotation-parameters)'; +cookBookTag[264] = 'Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)'; +cookBookTag[265] = 'Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)'; +cookBookTag[266] = 'Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)'; +cookBookTag[267] = 'Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)'; +cookBookTag[268] = 'Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)'; +cookBookTag[269] = + 'Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)'; +cookBookTag[270] = 'Trying to catch JS errors is not permitted (arkts-interop-js2s-js-exception)'; +cookBookTag[274] = + 'The subclass constructor must call the parent class\'s parametered constructor (arkts-subclass-must-call-super-constructor-with-args)'; +cookBookTag[275] = + 'Custom components with custom layout capability need to add the "@Layoutable" decorator (arkui-custom-layout-need-add-decorator)'; +cookBookTag[281] = '"@Prop" decorator is not supported (arkui-no-prop-decorator)'; +cookBookTag[282] = '"@StorageProp" decorator is not supported (arkui-no-storageprop-decorator)'; +cookBookTag[283] = '"@LocalStorageProp" decorator is not supported (arkui-no-localstorageprop-decorator)'; +cookBookTag[284] = '"prop" function is not supported (arkui-no-prop-function)'; +cookBookTag[285] = '"setAndProp" function is not supported (arkui-no-setandprop-function)'; +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[302] = - 'Class type is not compatible with "Object" parameter in interop call (arkts-interop-call-object-param)'; + 'Class type is not compatible with "Object" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)'; cookBookTag[303] = - 'Reflect API usage is not allowed in interop calls when an "Object" parameter receives a class instance (arkts-interop-call-reflect)'; + 'Reflect API usage is not allowed in interop calls when an "Object" parameter receives a class instance (arkts-interop-d2s-static-reflect-on-dynamic-instance)'; cookBookTag[304] = 'Duplicate function name in namespace are not allowed (arkts-no-duplicate-function-name)'; -cookBookTag[305] = 'Typescript class decorators are not allowed (arkts-interop-no-decorators)'; +cookBookTag[306] = 'Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)'; +cookBookTag[307] = 'Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)'; +cookBookTag[308] = 'Type "void" has no instances.(sdk-limited-void-type)'; +cookBookTag[309] = 'API no longer supports optional methods (sdk-optional-methods)'; +cookBookTag[310] = + 'Properties in "Sendable" classes and interfaces must have a Sendable data type (sdk-no-sendable-prop-types)'; +cookBookTag[311] = 'Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)'; +cookBookTag[312] = 'Indexed access is not supported for fields (sdk-no-props-by-index)'; +cookBookTag[313] = 'Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)'; +cookBookTag[314] = + 'Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)'; +cookBookTag[315] = 'API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)'; +cookBookTag[316] = 'Using typeof as a type is not allowed in this API (sdk-type-query)'; +cookBookTag[317] = '"use shared" is not supported (arkts-limited-stdlib-no-use-shared)'; +cookBookTag[318] = '"use concurrent" is not supported (arkts-limited-stdlib-no-use-concurrent)'; +cookBookTag[319] = + 'Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)'; +cookBookTag[321] = 'Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)'; +cookBookTag[322] = 'isConcurrent is not supported (arkts-limited-stdlib-no-support-isConcurrent)'; +cookBookTag[323] = 'Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)'; +cookBookTag[324] = 'Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)'; +cookBookTag[325] = + 'Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)'; +cookBookTag[326] = 'It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)'; +cookBookTag[327] = + 'Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)'; +cookBookTag[328] = + 'Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)'; +cookBookTag[329] = 'Enum cannot get member name by member value (arkts-unsupport-prop-name-from-value)'; +cookBookTag[330] = 'Importing directly from "JS" module is not supported (arkts-interop-js2s-import-js)'; +cookBookTag[331] = 'ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)'; +cookBookTag[332] = 'Properties of interop objects can\'t be accessed directly (arkts-interop-js2s-access-js-prop)'; +cookBookTag[333] = 'Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)'; +cookBookTag[334] = 'The "typeof" expression can\'t be used with interop JS objects (arkts-interop-js2s-typeof-js-type)'; +cookBookTag[335] = 'Interop object does not have property num (arkts-interop-js2s-unary-op)'; +cookBookTag[336] = 'Binary operations on js objects (arkts-interop-js2s-binary-op)'; +cookBookTag[337] = + 'Importing data directly from the "JS" module for comparison is not supported (arkts-interop-js2s-compare-js-data)'; +cookBookTag[338] = + '"JS" objects can\'t be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)'; +cookBookTag[339] = 'Interop objects can\'t be indexed directly (arkts-interop-js2s-access-js-index)'; +cookBookTag[340] = '"Await" operator can\'t be used with interop objects (arkts-interop-js2s-await-js-promise)'; +cookBookTag[341] = 'ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)'; +cookBookTag[342] = + 'Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)'; +cookBookTag[343] = + 'Usage of "instanceof" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)'; +cookBookTag[344] = 'Interop objects can\'t be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)'; +cookBookTag[345] = 'Using thisArgs as a type is not allowed in this API (arkts-builtin-thisArgs)'; +cookBookTag[346] = 'Using "Symbol.iterator" is not allowed in this API (arkts-builtin-symbol-iterator)'; +cookBookTag[347] = 'Not support propertydescriptor (arkts-builtin-no-property-descriptor)'; +cookBookTag[348] = 'API is not support ctor signature and func (arkts-builtin-cotr)'; +cookBookTag[349] = 'SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)'; +cookBookTag[350] = + 'The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)'; +cookBookTag[351] = + 'The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)'; +cookBookTag[355] = 'Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)'; +cookBookTag[356] = 'Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)'; +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[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)'; +cookBookTag[373] = 'Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)'; +cookBookTag[374] = 'Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)'; +cookBookTag[375] = 'TS catch type are not supported (arkts-no-ts-like-catch-type)'; +cookBookTag[376] = 'Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)'; +cookBookTag[377] = + 'Non-decimal BigInt literals (0x/0o/0b) are not supported. Use decimal format instead (arkts-only-support-decimal-bigint-literal)'; +cookBookTag[378] = 'Operator is not support (arkts-unsupport-operator)'; + +for (let i = 0; i <= cookBookTag.length; i++) { + cookBookMsg[i] = ''; +} diff --git a/ets2panda/linter/src/lib/FaultAttrs.ts b/ets2panda/linter/src/lib/FaultAttrs.ts index 3abdb44b86d3dba6fcf46103093340b5158535b3..e198eb4e83e03202f44a2b1107cfeae61ff7c500 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -108,8 +108,8 @@ faultsAttrs[FaultID.ErrorSuppression] = new FaultAttributes(146); faultsAttrs[FaultID.ClassAsObject] = new FaultAttributes(149, ProblemSeverity.WARNING); faultsAttrs[FaultID.ClassAsObjectError] = new FaultAttributes(149); faultsAttrs[FaultID.ImportAfterStatement] = new FaultAttributes(150); -faultsAttrs[FaultID.EsObjectType] = new FaultAttributes(151, ProblemSeverity.WARNING); -faultsAttrs[FaultID.EsObjectTypeError] = new FaultAttributes(151); +faultsAttrs[FaultID.EsValueType] = new FaultAttributes(151, ProblemSeverity.WARNING); +faultsAttrs[FaultID.EsValueTypeError] = new FaultAttributes(151); faultsAttrs[FaultID.FunctionApplyCall] = new FaultAttributes(152); faultsAttrs[FaultID.SendableClassInheritance] = new FaultAttributes(153); faultsAttrs[FaultID.SendablePropType] = new FaultAttributes(154); @@ -148,9 +148,11 @@ faultsAttrs[FaultID.DynamicCtorCall] = new FaultAttributes(186); faultsAttrs[FaultID.MathPow] = new FaultAttributes(187); faultsAttrs[FaultID.NumericSemantics] = new FaultAttributes(189); faultsAttrs[FaultID.IncompationbleFunctionType] = new FaultAttributes(190); +faultsAttrs[FaultID.LimitedStdLibNoASON] = new FaultAttributes(191); faultsAttrs[FaultID.LimitedVoidType] = new FaultAttributes(192); faultsAttrs[FaultID.VoidOperator] = new FaultAttributes(193); faultsAttrs[FaultID.TsOverload] = new FaultAttributes(198); +faultsAttrs[FaultID.NoNeedStdLibSendableContainer] = new FaultAttributes(199); faultsAttrs[FaultID.LimitedLiteralType] = new FaultAttributes(202); faultsAttrs[FaultID.ExponentOp] = new FaultAttributes(203); faultsAttrs[FaultID.DebuggerStatement] = new FaultAttributes(206); @@ -160,6 +162,9 @@ faultsAttrs[FaultID.ArrayIndexExprType] = new FaultAttributes(209); faultsAttrs[FaultID.SwitchExpression] = new FaultAttributes(210); faultsAttrs[FaultID.CaseExpression] = new FaultAttributes(211); faultsAttrs[FaultID.IndexNegative] = new FaultAttributes(212); +faultsAttrs[FaultID.NoStaticOnClass] = new FaultAttributes(213); +faultsAttrs[FaultID.NoConstructorOnClass] = new FaultAttributes(214); +faultsAttrs[FaultID.RuntimeArrayCheck] = new FaultAttributes(215); faultsAttrs[FaultID.NoSideEffectImport] = new FaultAttributes(222); faultsAttrs[FaultID.ImportLazyIdentifier] = new FaultAttributes(232); faultsAttrs[FaultID.DynamicImport] = new FaultAttributes(233); @@ -178,9 +183,84 @@ faultsAttrs[FaultID.StylesDecoratorNotSupported] = new FaultAttributes(256); faultsAttrs[FaultID.AnimatableExtendDecoratorTransform] = new FaultAttributes(257); faultsAttrs[FaultID.DataObservation] = new FaultAttributes(258); faultsAttrs[FaultID.UIInterfaceImport] = new FaultAttributes(259); +faultsAttrs[FaultID.EntryAnnotation] = new FaultAttributes(260); +faultsAttrs[FaultID.MakeObservedIsNotSupported] = new FaultAttributes(262); +faultsAttrs[FaultID.ProvideAnnotation] = new FaultAttributes(263); +faultsAttrs[FaultID.InteropJsObjectUsage] = new FaultAttributes(264); +faultsAttrs[FaultID.InteropJsObjectInheritance] = new FaultAttributes(265); +faultsAttrs[FaultID.InteropJsObjectTraverseJsInstance] = new FaultAttributes(266); +faultsAttrs[FaultID.InteropJsObjectCallStaticFunc] = new FaultAttributes(267); +faultsAttrs[FaultID.InteropJsObjectConditionJudgment] = new FaultAttributes(268); +faultsAttrs[FaultID.InteropJsObjectExpandStaticInstance] = new FaultAttributes(269); +faultsAttrs[FaultID.InteropJSFunctionInvoke] = new FaultAttributes(270); +faultsAttrs[FaultID.MissingSuperCall] = new FaultAttributes(274); +faultsAttrs[FaultID.CustomLayoutNeedAddDecorator] = new FaultAttributes(275); +faultsAttrs[FaultID.PropDecoratorNotSupported] = new FaultAttributes(281); +faultsAttrs[FaultID.StoragePropDecoratorNotSupported] = new FaultAttributes(282); +faultsAttrs[FaultID.LocalStoragePropDecoratorNotSupported] = new FaultAttributes(283); +faultsAttrs[FaultID.PropFunctionNotSupported] = new FaultAttributes(284); +faultsAttrs[FaultID.SetAndPropFunctionNotSupported] = new FaultAttributes(285); faultsAttrs[FaultID.ExplicitFunctionType] = new FaultAttributes(300); faultsAttrs[FaultID.OhmUrlFullPath] = new FaultAttributes(301); faultsAttrs[FaultID.InteropCallObjectParam] = new FaultAttributes(302); faultsAttrs[FaultID.InteropCallReflect] = new FaultAttributes(303); faultsAttrs[FaultID.NoDuplicateFunctionName] = new FaultAttributes(304); -faultsAttrs[FaultID.InteropNoDecorators] = new FaultAttributes(305); +faultsAttrs[FaultID.InteropDirectAccessToTSTypes] = new FaultAttributes(306); +faultsAttrs[FaultID.InteropTSFunctionInvoke] = new FaultAttributes(307); +faultsAttrs[FaultID.LimitedVoidTypeFromSdk] = new FaultAttributes(308); +faultsAttrs[FaultID.OptionalMethodFromSdk] = new FaultAttributes(309); +faultsAttrs[FaultID.SendablePropTypeFromSdk] = new FaultAttributes(310); +faultsAttrs[FaultID.ConstructorIfaceFromSdk] = new FaultAttributes(311); +faultsAttrs[FaultID.PropertyAccessByIndexFromSdk] = new FaultAttributes(312); +faultsAttrs[FaultID.ConstructorTypesDeprecated] = new FaultAttributes(313); +faultsAttrs[FaultID.QuotedHyphenPropsDeprecated] = new FaultAttributes(314); +faultsAttrs[FaultID.DuplicateDeclNameFromSdk] = new FaultAttributes(315); +faultsAttrs[FaultID.SdkTypeQuery] = new FaultAttributes(316); +faultsAttrs[FaultID.UseSharedDeprecated] = new FaultAttributes(317); +faultsAttrs[FaultID.UseConcurrentDeprecated] = new FaultAttributes(318); +faultsAttrs[FaultID.MethodInheritRule] = new FaultAttributes(319); +faultsAttrs[FaultID.LimitedStdLibNoImportConcurrency] = new FaultAttributes(321); +faultsAttrs[FaultID.IsConcurrentDeprecated] = new FaultAttributes(322); +faultsAttrs[FaultID.InteropJsObjectExport] = new FaultAttributes(323); +faultsAttrs[FaultID.InteropArkTs1ObjectExport] = new FaultAttributes(324); +faultsAttrs[FaultID.DefaultArgsBehindRequiredArgs] = new FaultAttributes(325); +faultsAttrs[FaultID.InteropStaticObjectLiterals] = new FaultAttributes(326); +faultsAttrs[FaultID.InteropObjectLiteralAmbiguity] = new FaultAttributes(327); +faultsAttrs[FaultID.InteropObjectLiteralClass] = new FaultAttributes(328); +faultsAttrs[FaultID.UnsupportPropNameFromValue] = new FaultAttributes(329); +faultsAttrs[FaultID.InterOpImportJs] = new FaultAttributes(330); +faultsAttrs[FaultID.CallJSFunction] = new FaultAttributes(331); +faultsAttrs[FaultID.InteropObjectProperty] = new FaultAttributes(332); +faultsAttrs[FaultID.InterOpConvertImport] = new FaultAttributes(333); +faultsAttrs[FaultID.InterOpImportJsForTypeOf] = new FaultAttributes(334); +faultsAttrs[FaultID.InteropNoHaveNum] = new FaultAttributes(335); +faultsAttrs[FaultID.BinaryOperations] = new FaultAttributes(336); +faultsAttrs[FaultID.InterOpImportJsDataCompare] = new FaultAttributes(337); +faultsAttrs[FaultID.InteropEqualityJudgment] = new FaultAttributes(338); +faultsAttrs[FaultID.InterOpImportJsIndex] = new FaultAttributes(339); +faultsAttrs[FaultID.NoAwaitJsPromise] = new FaultAttributes(340); +faultsAttrs[FaultID.InstantiatedJsOjbect] = new FaultAttributes(341); +faultsAttrs[FaultID.InteropCallObjectMethods] = new FaultAttributes(342); +faultsAttrs[FaultID.InteropJsInstanceof] = new FaultAttributes(343); +faultsAttrs[FaultID.InteropIncrementDecrement] = new FaultAttributes(344); +faultsAttrs[FaultID.BuiltinThisArgs] = new FaultAttributes(345); +faultsAttrs[FaultID.BuiltinSymbolIterator] = new FaultAttributes(346); +faultsAttrs[FaultID.NoPropertyDescriptor] = new FaultAttributes(347); +faultsAttrs[FaultID.BuiltinNoCtorFunc] = new FaultAttributes(348); +faultsAttrs[FaultID.SharedArrayBufferDeprecated] = new FaultAttributes(349); +faultsAttrs[FaultID.SetCloneListDeprecated] = new FaultAttributes(350); +faultsAttrs[FaultID.SetTransferListDeprecated] = new FaultAttributes(351); +faultsAttrs[FaultID.LimitedStdLibNoSendableDecorator] = new FaultAttributes(355); +faultsAttrs[FaultID.LimitedStdLibNoDoncurrentDecorator] = new FaultAttributes(356); +faultsAttrs[FaultID.NoNeedStdlibWorker] = new FaultAttributes(357); +faultsAttrs[FaultID.BuiltinGetOwnPropertyNames] = new FaultAttributes(358); +faultsAttrs[FaultID.LocalBuilderDecoratorNotSupported] = new FaultAttributes(359); +faultsAttrs[FaultID.NosparseArray] = new FaultAttributes(370); +faultsAttrs[FaultID.NoEnumPropAsType] = new FaultAttributes(371); +faultsAttrs[FaultID.NoTsLikeSmartType] = new FaultAttributes(372); +faultsAttrs[FaultID.ArrayTypeImmutable] = new FaultAttributes(373); +faultsAttrs[FaultID.CreatingPrimitiveTypes] = new FaultAttributes(374); +faultsAttrs[FaultID.TsLikeCatchType] = new FaultAttributes(375); +faultsAttrs[FaultID.NumericBigintCompare] = new FaultAttributes(376); +faultsAttrs[FaultID.NondecimalBigint] = new FaultAttributes(377); +faultsAttrs[FaultID.UnsupportOperator] = new FaultAttributes(378); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index 5525d62eb325857492a9e62032d75667ad75911c..1dd89ea9683eb89562c10a9966f010372cb8b9b8 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -65,6 +65,9 @@ faultDesc[FaultID.NonDeclarationInNamespace] = 'Non-declaration statements in na faultDesc[FaultID.GeneratorFunction] = 'Generator functions'; faultDesc[FaultID.FunctionContainsThis] = 'Functions containing "this"'; faultDesc[FaultID.PropertyAccessByIndex] = 'property access by index'; +faultDesc[FaultID.NoStaticOnClass] = 'No static blocks on classes'; +faultDesc[FaultID.NoConstructorOnClass] = 'No constructor field on object'; +faultDesc[FaultID.RuntimeArrayCheck] = 'Array bound not checked'; faultDesc[FaultID.JsxElement] = 'JSX Elements'; faultDesc[FaultID.EnumMemberNonConstInit] = 'Enum members with non-constant initializer'; faultDesc[FaultID.ImplementsClass] = 'Class type mentioned in "implements" clause'; @@ -93,10 +96,12 @@ faultDesc[FaultID.ConstAssertion] = '"as const" assertion'; faultDesc[FaultID.ImportAssertion] = 'Import assertion'; faultDesc[FaultID.SpreadOperator] = 'Spread operation'; faultDesc[FaultID.LimitedStdLibApi] = 'Limited standard library API'; +faultDesc[FaultID.LimitedStdLibNoASON] = 'Cannot find symbol ASON.'; +faultDesc[FaultID.NoNeedStdLibSendableContainer] = 'Sendable Containers not supported'; faultDesc[FaultID.ErrorSuppression] = 'Error suppression annotation'; faultDesc[FaultID.StrictDiagnostic] = 'Strict diagnostic'; faultDesc[FaultID.ImportAfterStatement] = 'Import declaration after other declaration or statement'; -faultDesc[FaultID.EsObjectType] = faultDesc[FaultID.EsObjectTypeError] = 'Restricted "ESObject" type'; +faultDesc[FaultID.EsValueType] = faultDesc[FaultID.EsValueTypeError] = 'Restricted "ESValue" type'; faultDesc[FaultID.SendableClassInheritance] = 'Sendable class inheritance'; faultDesc[FaultID.SendablePropType] = 'Sendable class property'; faultDesc[FaultID.SendableDefiniteAssignment] = 'Use of definite assignment assertion in "Sendable" class'; @@ -156,6 +161,9 @@ faultDesc[FaultID.DoubleDollarBindingNotSupported] = 'Incorrect bidirectional da faultDesc[FaultID.DollarBindingNotSupported] = 'Link decorator passing'; faultDesc[FaultID.ExtendDecoratorNotSupported] = '"@Extend" decorator'; faultDesc[FaultID.MethodOverridingField] = '"Method overriding field" to keep style consistent'; +faultDesc[FaultID.InteropJsObjectConditionJudgment] = 'Interop JS Object usage in a condition'; +faultDesc[FaultID.InteropJsObjectExpandStaticInstance] = 'Interop JS function usage'; +faultDesc[FaultID.InteropJSFunctionInvoke] = 'Interop JS function invoke'; faultDesc[FaultID.ExplicitFunctionType] = 'Not explicit function type'; faultDesc[FaultID.ClassstaticInitialization] = 'The static properties of a class need to have initial values'; faultDesc[FaultID.AvoidUnionTypes] = 'Union types'; @@ -164,6 +172,9 @@ faultDesc[FaultID.InvalidIdentifier] = 'Invalid identifiers'; faultDesc[FaultID.ExtendsExpression] = 'Extends Expression'; faultDesc[FaultID.NumericSemantics] = 'Numeric semantics'; faultDesc[FaultID.AnimatableExtendDecoratorTransform] = '"@AnimatableExtend" decorator'; +faultDesc[FaultID.InteropJsObjectExport] = 'Interop JS object export'; +faultDesc[FaultID.InteropArkTs1ObjectExport] = 'Interop ArkTS1.0 object export'; +faultDesc[FaultID.DefaultArgsBehindRequiredArgs] = 'Default parameters before mandatory'; faultDesc[FaultID.NoDuplicateFunctionName] = 'No duplicate function name'; faultDesc[FaultID.OhmUrlFullPath] = 'Require full path file name'; faultDesc[FaultID.UIInterfaceImport] = 'UI interface'; @@ -171,4 +182,73 @@ faultDesc[FaultID.StylesDecoratorNotSupported] = '"@Styles" decorator'; faultDesc[FaultID.DataObservation] = 'Data observation'; faultDesc[FaultID.InteropCallReflect] = 'Interop call with Reflect API'; faultDesc[FaultID.InteropCallObjectParam] = 'Interop call with "Object" parameter'; -faultDesc[FaultID.InteropNoDecorators] = 'Interop decorators not supported'; +faultDesc[FaultID.InteropDirectAccessToTSTypes] = 'TS Types Access'; +faultDesc[FaultID.InteropTSFunctionInvoke] = 'TS Function Invoke'; +faultDesc[FaultID.LimitedVoidTypeFromSdk] = 'Limited void type from sdk'; +faultDesc[FaultID.UseSharedDeprecated] = '"use shared" is not supported'; +faultDesc[FaultID.UseConcurrentDeprecated] = '"use concurrent" is not supported'; +faultDesc[FaultID.MethodInheritRule] = 'Method parameters/returns violate inheritance principles'; +faultDesc[FaultID.EntryAnnotation] = '"@Entry" decorator parameter'; +faultDesc[FaultID.ProvideAnnotation] = '"@Provide" decorator parameter'; +faultDesc[FaultID.InteropJsObjectUsage] = 'Interop JS object usage'; +faultDesc[FaultID.InteropJsObjectInheritance] = 'Interop JS class inheritance'; +faultDesc[FaultID.InteropJsObjectTraverseJsInstance] = 'Interop JS object traverse usage'; +faultDesc[FaultID.InteropJsObjectCallStaticFunc] = 'Interop JS function usage'; +faultDesc[FaultID.OptionalMethodFromSdk] = 'Optional method from sdk'; +faultDesc[FaultID.SendablePropTypeFromSdk] = 'ISendable is no longer supported'; +faultDesc[FaultID.ConstructorIfaceFromSdk] = 'Construct signatures are not supported in interfaces from sdk'; +faultDesc[FaultID.PropertyAccessByIndexFromSdk] = 'property access by index from sdk'; +faultDesc[FaultID.ConstructorTypesDeprecated] = 'Constructor funcs'; +faultDesc[FaultID.QuotedHyphenPropsDeprecated] = 'Quoted hyphen props deprecated'; +faultDesc[FaultID.DuplicateDeclNameFromSdk] = 'The API path has been changed due to the duplicate names in sdk.'; +faultDesc[FaultID.SdkTypeQuery] = 'No typeof as a type in API'; +faultDesc[FaultID.IsConcurrentDeprecated] = 'isConcurrent is not supported'; +faultDesc[FaultID.InteropStaticObjectLiterals] = 'Interop call object literals'; +faultDesc[FaultID.LimitedStdLibNoImportConcurrency] = 'Import Concurrency Deprecated'; +faultDesc[FaultID.MissingSuperCall] = 'Missing super call with args'; +faultDesc[FaultID.InterOpImportJs] = 'No JS import'; +faultDesc[FaultID.InteropObjectLiteralAmbiguity] = 'Interop Object Literal ambiguity'; +faultDesc[FaultID.InteropObjectLiteralClass] = 'Interop Object Literal incompatible with class'; +faultDesc[FaultID.UnsupportPropNameFromValue] = 'Enum cannot get member name by value'; +faultDesc[FaultID.CallJSFunction] = 'Call JS Function'; +faultDesc[FaultID.InteropObjectProperty] = 'Interop property access'; +faultDesc[FaultID.InterOpConvertImport] = 'No import primitive types from js file'; +faultDesc[FaultID.InterOpImportJsForTypeOf] = 'TypeOf import from JS'; +faultDesc[FaultID.InteropNoHaveNum] = 'Interop obj with "num" property'; +faultDesc[FaultID.BinaryOperations] = 'Binary operations on js objects'; +faultDesc[FaultID.InterOpImportJsDataCompare] = 'NO js import data compare'; +faultDesc[FaultID.InteropEqualityJudgment] = 'Equality operator with JS objects'; +faultDesc[FaultID.InterOpImportJsIndex] = 'No js index import'; +faultDesc[FaultID.InstantiatedJsOjbect] = 'Instantiated js ojbect'; +faultDesc[FaultID.InteropCallObjectMethods] = 'Interop call methods in object'; +faultDesc[FaultID.InteropJsInstanceof] = 'Instanceof operator with interop'; +faultDesc[FaultID.InteropIncrementDecrement] = 'Interop increment or decrement'; +faultDesc[FaultID.BuiltinThisArgs] = 'No thisArgs as a type in API'; +faultDesc[FaultID.BuiltinSymbolIterator] = 'No "Symbol.iterator" in API'; +faultDesc[FaultID.NoPropertyDescriptor] = 'Not support property descriptor'; +faultDesc[FaultID.BuiltinNoCtorFunc] = 'Api is not support ctor-signature and call-signature'; +faultDesc[FaultID.SharedArrayBufferDeprecated] = 'SharedArrayBuffer is not supported'; +faultDesc[FaultID.SetCloneListDeprecated] = 'setCloneList is not supported'; +faultDesc[FaultID.SetTransferListDeprecated] = 'setTransferList is not supported'; +faultDesc[FaultID.LimitedStdLibNoSendableDecorator] = 'Limited stdlib no sendable decorator'; +faultDesc[FaultID.LimitedStdLibNoDoncurrentDecorator] = 'Limited stdlib no concurrent decorator'; +faultDesc[FaultID.NoNeedStdlibWorker] = 'No need stdlib worker'; +faultDesc[FaultID.BuiltinGetOwnPropertyNames] = 'No "Object.getOwnPropertyNames" in API'; +faultDesc[FaultID.LocalBuilderDecoratorNotSupported] = '"@LocalBuilder" decorator'; +faultDesc[FaultID.MakeObservedIsNotSupported] = 'MakeObserved is not supported'; +faultDesc[FaultID.NoEnumPropAsType] = 'No enum prop as type'; +faultDesc[FaultID.NoAwaitJsPromise] = 'No await js promise'; +faultDesc[FaultID.NosparseArray] = 'No sparse array'; +faultDesc[FaultID.NoTsLikeSmartType] = 'No ts like smart type'; +faultDesc[FaultID.ArrayTypeImmutable] = 'Array type immutable'; +faultDesc[FaultID.CreatingPrimitiveTypes] = 'Creating primitive types'; +faultDesc[FaultID.TsLikeCatchType] = 'TS like catch type'; +faultDesc[FaultID.NumericBigintCompare] = 'No Comparison number between bigint'; +faultDesc[FaultID.NondecimalBigint] = 'No non decimal'; +faultDesc[FaultID.UnsupportOperator] = 'Unsupport operator'; +faultDesc[FaultID.CustomLayoutNeedAddDecorator] = 'Custom layout need add decorator'; +faultDesc[FaultID.PropDecoratorNotSupported] = '"@Prop" decorator is not supported'; +faultDesc[FaultID.StoragePropDecoratorNotSupported] = '"@StorageProp" decorator is not supported'; +faultDesc[FaultID.LocalStoragePropDecoratorNotSupported] = '"@LocalStorageProp" decorator is not supported'; +faultDesc[FaultID.PropFunctionNotSupported] = '"prop" function is not supported'; +faultDesc[FaultID.SetAndPropFunctionNotSupported] = '"setAndProp" function is not supported'; diff --git a/ets2panda/linter/src/lib/HomeCheck.ts b/ets2panda/linter/src/lib/HomeCheck.ts new file mode 100644 index 0000000000000000000000000000000000000000..abf128b57f1fe8b3dbe44e45c24c46868ad456cf --- /dev/null +++ b/ets2panda/linter/src/lib/HomeCheck.ts @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2022-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 * as path from 'node:path'; +import type { FileIssues, RuleFix } from 'homecheck'; +import type { CommandLineOptions } from './CommandLineOptions'; +import type { ProblemInfo } from './ProblemInfo'; +import { FaultID } from './Problems'; + +interface RuleConfigInfo { + ruleSet: string[]; +} + +interface ProjectConfigInfo { + projectName: string | undefined; + projectPath: string | undefined; + logPath: string; + arkCheckPath: string; + ohosSdkPath: string; + hmsSdkPath: string; + reportDir: string; + languageTags: Map; + fileOrFolderToCheck: string[]; +} + +export function getHomeCheckConfigInfo(cmdOptions: CommandLineOptions): { + ruleConfigInfo: RuleConfigInfo; + projectConfigInfo: ProjectConfigInfo; +} { + const languageTags = new Map(); + const inputFiles = cmdOptions.inputFiles; + const ruleConfigInfo = { + ruleSet: ['plugin:@migration/all'], + files: ['**/*.ets', '**/*.ts', '**/*.js'] + }; + const projectConfigInfo = { + projectName: cmdOptions.arktsWholeProjectPath, + projectPath: cmdOptions.arktsWholeProjectPath, + logPath: cmdOptions.outputFilePath ? path.join(cmdOptions.outputFilePath, 'HomeCheck.log') : './HomeCheck.log', + arkCheckPath: './node_modules/homecheck', + ohosSdkPath: cmdOptions.sdkDefaultApiPath ? cmdOptions.sdkDefaultApiPath : '', + hmsSdkPath: cmdOptions.sdkExternalApiPath ? cmdOptions.sdkExternalApiPath[0] : '', + reportDir: './', + languageTags: languageTags, + fileOrFolderToCheck: inputFiles, + logLevel: cmdOptions.verbose ? 'DEBUG' : 'INFO', + arkAnalyzerLogLevel: cmdOptions.verbose ? 'DEBUG' : 'ERROR' + }; + return { ruleConfigInfo, projectConfigInfo }; +} + +export function transferIssues2ProblemInfo(fileIssuesArray: FileIssues[]): Map { + const result = new Map(); + fileIssuesArray.forEach((fileIssues) => { + fileIssues.issues.forEach((issueReport) => { + const defect = issueReport.defect; + const problemInfo: ProblemInfo = { + line: defect.reportLine, + column: defect.reportColumn, + endLine: defect.reportLine, + endColumn: defect.reportColumn, + start: 0, + end: 0, + type: '', + severity: defect.severity, + faultId: FaultID.LAST_ID, + problem: defect.problem, + suggest: '', + rule: defect.description, + ruleTag: -1, + autofixable: defect.fixable + }; + if (problemInfo.autofixable) { + const fix = issueReport.fix as RuleFix; + const replacementText = fix.text; + const start = fix.range[0]; + const end = fix.range[1]; + problemInfo.autofix = [{ replacementText, start, end }]; + problemInfo.autofixTitle = defect.ruleId; + } + const filePath = path.normalize(defect.mergeKey.split('%')[0]); + const problems = result.get(filePath) || []; + problems.push(problemInfo); + result.set(filePath, problems); + }); + }); + return result; +} diff --git a/ets2panda/linter/src/lib/InteropTypescriptLinter.ts b/ets2panda/linter/src/lib/InteropTypescriptLinter.ts index f171370910a3d2b4ec998ffe4a252624626fc70a..c9247e36eacfe93600fb13fdb7309dabe3cc197b 100644 --- a/ets2panda/linter/src/lib/InteropTypescriptLinter.ts +++ b/ets2panda/linter/src/lib/InteropTypescriptLinter.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -15,21 +15,14 @@ import * as fs from 'fs'; import * as path from 'node:path'; import * as ts from 'typescript'; -import { cookBookTag } from './CookBookMsg'; -import { faultsAttrs } from './FaultAttrs'; -import { faultDesc } from './FaultDesc'; -import { Logger } from './Logger'; -import type { ProblemInfo } from './ProblemInfo'; -import { ProblemSeverity } from './ProblemSeverity'; import { FaultID } from './Problems'; -import { LinterConfig } from './TypeScriptLinterConfig'; -import { cookBookRefToFixTitle } from './autofixes/AutofixTitles'; -import type { Autofix } from './autofixes/Autofixer'; +import { TypeScriptLinterConfig } from './TypeScriptLinterConfig'; import { TsUtils } from './utils/TsUtils'; import { ARKTS_COLLECTIONS_D_ETS, ARKTS_LANG_D_ETS } from './utils/consts/SupportedDetsIndexableTypes'; import { D_ETS, D_TS, ETS, KIT } from './utils/consts/TsSuffix'; import { forEachNodeInSubtree } from './utils/functions/ForEachNodeInSubtree'; import type { LinterOptions } from './LinterOptions'; +import { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; export interface KitSymbol { source: string; @@ -42,24 +35,7 @@ export interface KitInfo { symbols?: KitSymbols; } -export class InteropTypescriptLinter { - totalVisitedNodes: number = 0; - nodeCounters: number[] = []; - lineCounters: number[] = []; - - totalErrorLines: number = 0; - errorLineNumbersString: string = ''; - totalWarningLines: number = 0; - warningLineNumbersString: string = ''; - - problemsInfos: ProblemInfo[] = []; - - tsUtils: TsUtils; - - currentErrorLine: number; - currentWarningLine: number; - - private sourceFile?: ts.SourceFile; +export class InteropTypescriptLinter extends BaseTypeScriptLinter { private isInSdk?: boolean; static kitInfos = new Map(); private static etsLoaderPath?: string; @@ -69,25 +45,15 @@ export class InteropTypescriptLinter { InteropTypescriptLinter.kitInfos = new Map(); } - private initCounters(): void { - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; - } - } - constructor( - private readonly tsTypeChecker: ts.TypeChecker, - private readonly compileOptions: ts.CompilerOptions, - readonly options: LinterOptions, - etsLoaderPath: string | undefined + tsTypeChecker: ts.TypeChecker, + readonly compileOptions: ts.CompilerOptions, + options: LinterOptions, + sourceFile: ts.SourceFile ) { - this.tsUtils = new TsUtils(this.tsTypeChecker, options); - this.currentErrorLine = 0; - this.currentWarningLine = 0; - InteropTypescriptLinter.etsLoaderPath = etsLoaderPath; - InteropTypescriptLinter.sdkPath = etsLoaderPath ? path.resolve(etsLoaderPath, '../..') : undefined; - this.initCounters(); + super(tsTypeChecker, options, sourceFile); + InteropTypescriptLinter.etsLoaderPath = options.etsLoaderPath; + InteropTypescriptLinter.sdkPath = options.etsLoaderPath ? path.resolve(options.etsLoaderPath, '../..') : undefined; } readonly handlersMap = new Map([ @@ -102,84 +68,9 @@ export class InteropTypescriptLinter { [ts.SyntaxKind.ExportAssignment, this.handleExportAssignment] ]); - private getLineAndCharacterOfNode(node: ts.Node | ts.CommentRange): ts.LineAndCharacter { - const startPos = TsUtils.getStartPos(node); - const { line, character } = this.sourceFile!.getLineAndCharacterOfPosition(startPos); - // TSC counts lines and columns from zero - return { line: line + 1, character: character + 1 }; - } - - incrementCounters(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { - this.nodeCounters[faultId]++; - const { line, character } = this.getLineAndCharacterOfNode(node); - if (this.options.ideMode) { - this.incrementCountersIdeMode(node, faultId, autofix); - } else { - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - Logger.info( - `Warning: ${this.sourceFile!.fileName} (${line}, ${character}): ${faultDescr ? faultDescr : faultType}` - ); - } - this.lineCounters[faultId]++; - switch (faultsAttrs[faultId].severity) { - case ProblemSeverity.ERROR: { - this.currentErrorLine = line; - ++this.totalErrorLines; - this.errorLineNumbersString += line + ', '; - break; - } - case ProblemSeverity.WARNING: { - if (line === this.currentWarningLine) { - break; - } - this.currentWarningLine = line; - ++this.totalWarningLines; - this.warningLineNumbersString += line + ', '; - break; - } - default: - } - } - - private incrementCountersIdeMode(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { - if (!this.options.ideMode) { - return; - } - const [startOffset, endOffset] = TsUtils.getHighlightRange(node, faultId); - const startPos = this.sourceFile!.getLineAndCharacterOfPosition(startOffset); - const endPos = this.sourceFile!.getLineAndCharacterOfPosition(endOffset); - - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - - const cookBookMsgNum = faultsAttrs[faultId] ? faultsAttrs[faultId].cookBookRef : 0; - const cookBookTg = cookBookTag[cookBookMsgNum]; - const severity = faultsAttrs[faultId]?.severity ?? ProblemSeverity.ERROR; - const isMsgNumValid = cookBookMsgNum > 0; - const badNodeInfo: ProblemInfo = { - line: startPos.line + 1, - column: startPos.character + 1, - endLine: endPos.line + 1, - endColumn: endPos.character + 1, - start: startOffset, - end: endOffset, - type: faultType, - severity: severity, - problem: FaultID[faultId], - suggest: '', - // eslint-disable-next-line no-nested-ternary - rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, - ruleTag: cookBookMsgNum, - autofix: autofix, - autofixTitle: isMsgNumValid && autofix !== undefined ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined - }; - this.problemsInfos.push(badNodeInfo); - } - private visitSourceFile(sf: ts.SourceFile): void { const callback = (node: ts.Node): void => { - this.totalVisitedNodes++; + this.fileStats.visitedNodes++; const handler = this.handlersMap.get(node.kind); if (handler !== undefined) { @@ -194,7 +85,7 @@ export class InteropTypescriptLinter { if (!node) { return true; } - if (LinterConfig.terminalTokens.has(node.kind)) { + if (TypeScriptLinterConfig.terminalTokens.has(node.kind)) { return true; } return false; @@ -545,8 +436,7 @@ export class InteropTypescriptLinter { kitInfo.symbols[element.name.text].source; } - lint(sourceFile: ts.SourceFile): void { - this.sourceFile = sourceFile; + lint(): void { this.isInSdk = InteropTypescriptLinter.sdkPath ? path.normalize(this.sourceFile.fileName).indexOf(InteropTypescriptLinter.sdkPath) === 0 : false; diff --git a/ets2panda/linter/src/lib/LintRunResult.ts b/ets2panda/linter/src/lib/LintRunResult.ts index d3d6ff56fc1f4674fe07a8d6234c0eeffb883919..3397a3941a433ce685b7daca2e52ca52e2b2d678 100644 --- a/ets2panda/linter/src/lib/LintRunResult.ts +++ b/ets2panda/linter/src/lib/LintRunResult.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -14,8 +14,10 @@ */ import type { ProblemInfo } from './ProblemInfo'; +import type { ProjectStatistics } from './statistics/ProjectStatistics'; export interface LintRunResult { - errorNodes: number; + hasErrors: boolean; problemsInfos: Map; + projectStats: ProjectStatistics; } diff --git a/ets2panda/linter/src/lib/LinterOptions.ts b/ets2panda/linter/src/lib/LinterOptions.ts index d8cc2cdc4655e15d9d96e68a356d95af4a5e7432..f6124ac4ab079343ddac9223baed63f1b58d53ca 100644 --- a/ets2panda/linter/src/lib/LinterOptions.ts +++ b/ets2panda/linter/src/lib/LinterOptions.ts @@ -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 @@ -22,7 +22,6 @@ import type { ReportAutofixCallback } from './autofixes/ReportAutofixCallback'; // Common options interface, additional fields may be used by plugins export interface LinterOptions { checkTsAsSource?: boolean; - ideMode?: boolean; ideInteractive?: boolean; migratorMode?: boolean; warningsAsErrors?: boolean; @@ -39,4 +38,11 @@ export interface LinterOptions { interopCheckMode?: boolean; compatibleSdkVersion?: number; compatibleSdkVersionStage?: string; + etsLoaderPath?: string; + migrationMaxPass?: number; + migrationFilePathMap?: Map; + noMigrationBackupFile?: boolean; + migrationReport?: boolean; + wholeProjectPath?: string; + checkTsAndJs?: boolean; } diff --git a/ets2panda/linter/src/lib/LinterRunner.ts b/ets2panda/linter/src/lib/LinterRunner.ts index b3607a2c8c2edaac2c6b21d3d4e9fd4e5dcabed7..04fc4174f4645cbc2b78ca289d286cebc7dfa497 100644 --- a/ets2panda/linter/src/lib/LinterRunner.ts +++ b/ets2panda/linter/src/lib/LinterRunner.ts @@ -13,19 +13,16 @@ * limitations under the License. */ +import * as fs from 'node:fs'; import * as path from 'node:path'; -import type * as ts from 'typescript'; +import * as ts from 'typescript'; import type { CommandLineOptions } from './CommandLineOptions'; -import { faultsAttrs } from './FaultAttrs'; -import { faultDesc } from './FaultDesc'; import { InteropTypescriptLinter } from './InteropTypescriptLinter'; import type { LinterConfig } from './LinterConfig'; import type { LinterOptions } from './LinterOptions'; import type { LintRunResult } from './LintRunResult'; import { Logger } from './Logger'; import type { ProblemInfo } from './ProblemInfo'; -import { ProblemSeverity } from './ProblemSeverity'; -import { FaultID } from './Problems'; import { TypeScriptLinter } from './TypeScriptLinter'; import { getTscDiagnostics } from './ts-diagnostics/GetTscDiagnostics'; import { transformTscDiagnostics } from './ts-diagnostics/TransformTscDiagnostics'; @@ -34,22 +31,15 @@ import { ARKTS_IGNORE_DIRS_OH_MODULES, ARKTS_IGNORE_FILES } from './utils/consts/ArktsIgnorePaths'; +import { EXTNAME_TS, EXTNAME_JS } from './utils/consts/ExtensionName'; import { mergeArrayMaps } from './utils/functions/MergeArrayMaps'; import { clearPathHelperCache, pathContainsDirectory } from './utils/functions/PathHelper'; import { LibraryTypeCallDiagnosticChecker } from './utils/functions/LibraryTypeCallDiagnosticChecker'; -import { compileLintOptions } from '../cli/Compiler'; +import type { createProgramCallback } from './ts-compiler/Compiler'; +import { compileLintOptions } from './ts-compiler/Compiler'; import * as qEd from './autofixes/QuasiEditor'; - -export function consoleLog(linterOptions: LinterOptions, ...args: unknown[]): void { - if (linterOptions.ideMode || linterOptions.ideInteractive) { - return; - } - let outLine = ''; - for (let k = 0; k < args.length; k++) { - outLine += `${args[k]} `; - } - Logger.info(outLine); -} +import { ProjectStatistics } from './statistics/ProjectStatistics'; +import type { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; function prepareInputFilesList(cmdOptions: CommandLineOptions): string[] { let inputFiles = cmdOptions.inputFiles; @@ -81,28 +71,19 @@ function prepareInputFilesList(cmdOptions: CommandLineOptions): string[] { return inputFiles; } -function countProblems(linter: TypeScriptLinter | InteropTypescriptLinter): [number, number] { - let errorNodesTotal = 0; - let warningNodes = 0; - for (let i = 0; i < FaultID.LAST_ID; i++) { - switch (faultsAttrs[i].severity) { - case ProblemSeverity.ERROR: - errorNodesTotal += linter.nodeCounters[i]; - break; - case ProblemSeverity.WARNING: - warningNodes += linter.nodeCounters[i]; - break; - default: - } +export function lint( + config: LinterConfig, + etsLoaderPath?: string, + hcResults?: Map +): LintRunResult { + if (etsLoaderPath) { + config.cmdOptions.linterOptions.etsLoaderPath = etsLoaderPath; } - - return [errorNodesTotal, warningNodes]; + const lintResult = lintImpl(config); + return config.cmdOptions.linterOptions.migratorMode ? migrate(config, lintResult, hcResults) : lintResult; } -let linterConfig: LinterConfig; - -export function lint(config: LinterConfig, etsLoaderPath: string | undefined): LintRunResult { - linterConfig = config; +function lintImpl(config: LinterConfig): LintRunResult { const { cmdOptions, tscCompiledProgram } = config; const tsProgram = tscCompiledProgram.getProgram(); const options = cmdOptions.linterOptions; @@ -122,170 +103,150 @@ export function lint(config: LinterConfig, etsLoaderPath: string | undefined): L const tscStrictDiagnostics = getTscDiagnostics(tscCompiledProgram, srcFiles); LibraryTypeCallDiagnosticChecker.instance.rebuildTscDiagnostics(tscStrictDiagnostics); - const linter = !options.interopCheckMode ? - new TypeScriptLinter(tsProgram.getTypeChecker(), options, tscStrictDiagnostics) : - new InteropTypescriptLinter(tsProgram.getTypeChecker(), tsProgram.getCompilerOptions(), options, etsLoaderPath); - const { errorNodes, problemsInfos } = lintFiles(srcFiles, linter); + const lintResult = lintFiles(tsProgram, srcFiles, options, tscStrictDiagnostics); LibraryTypeCallDiagnosticChecker.instance.clear(); - consoleLog(options, '\n\n\nFiles scanned: ', srcFiles.length); - consoleLog(options, '\nFiles with problems: ', errorNodes); - const [errorNodesTotal, warningNodes] = countProblems(linter); - logTotalProblemsInfo(errorNodesTotal, warningNodes, linter); - logProblemsPercentageByFeatures(linter); + if (!options.ideInteractive) { + lintResult.problemsInfos = mergeArrayMaps(lintResult.problemsInfos, transformTscDiagnostics(tscStrictDiagnostics)); + } freeMemory(); - let problemsInfosValues = problemsInfos; - if (!options.ideInteractive) { - problemsInfosValues = mergeArrayMaps(problemsInfos, transformTscDiagnostics(tscStrictDiagnostics)); + return lintResult; +} + +function lintFiles( + tsProgram: ts.Program, + srcFiles: ts.SourceFile[], + options: LinterOptions, + tscStrictDiagnostics: Map +): LintRunResult { + const projectStats: ProjectStatistics = new ProjectStatistics(); + const problemsInfos: Map = new Map(); + + TypeScriptLinter.initGlobals(); + InteropTypescriptLinter.initGlobals(); + + 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); } return { - errorNodes: errorNodesTotal, - problemsInfos: problemsInfosValues + hasErrors: projectStats.hasError(), + problemsInfos, + projectStats }; } -function applyFixes(srcFile: ts.SourceFile, linter: TypeScriptLinter | InteropTypescriptLinter): void { - for (let pass = 0; pass < qEd.MAX_AUTOFIX_PASSES; pass++) { - const qe: qEd.QuasiEditor = new qEd.QuasiEditor(srcFile); - if (pass === 0) { - qe.backupSrcFile(); - } - qe.fix(linter.problemsInfos); - if (qe.wasError) { - Logger.error(`Error: fix-all converged for (${srcFile.fileName}) on pass #${pass}`); - break; - } - const tmpLinterConfig = compileLintOptions(linterConfig.cmdOptions); - const recompiledFile = tmpLinterConfig.tscCompiledProgram.getProgram().getSourceFile(srcFile.fileName); +function migrate( + initialConfig: LinterConfig, + initialLintResult: LintRunResult, + hcResults?: Map +): LintRunResult { + let linterConfig = initialConfig; + const { cmdOptions } = initialConfig; + const updatedSourceTexts: Map = new Map(); + let lintResult: LintRunResult = initialLintResult; + const problemsInfosBeforeMigrate = lintResult.problemsInfos; + + for (let pass = 0; pass < (cmdOptions.linterOptions.migrationMaxPass ?? qEd.DEFAULT_MAX_AUTOFIX_PASSES); pass++) { + const appliedFix = fix(linterConfig, lintResult, updatedSourceTexts, hcResults); + hcResults = undefined; - if (!recompiledFile) { - Logger.error(`Error: recompilation failed for (${srcFile.fileName}) on pass #${pass}`); + if (!appliedFix) { + // No fixes were applied, migration is finished. break; } - linter.problemsInfos = []; - linter.lint(recompiledFile); - } -} -function lintFiles(srcFiles: ts.SourceFile[], linter: TypeScriptLinter | InteropTypescriptLinter): LintRunResult { - let problemFiles = 0; - const problemsInfos: Map = new Map(); + // Re-compile and re-lint project after applying the fixes. + linterConfig = compileLintOptions(cmdOptions, getMigrationCreateProgramCallback(updatedSourceTexts)); + lintResult = lintImpl(linterConfig); + } - for (const srcFile of srcFiles) { - const prevVisitedNodes = linter.totalVisitedNodes; - const prevErrorLines = linter.totalErrorLines; - const prevWarningLines = linter.totalWarningLines; - linter.errorLineNumbersString = ''; - linter.warningLineNumbersString = ''; - const nodeCounters: number[] = []; - - for (let i = 0; i < FaultID.LAST_ID; i++) { - nodeCounters[i] = linter.nodeCounters[i]; - } - linter.lint(srcFile); - if (linter.options.migratorMode) { - applyFixes(srcFile, linter); + // Write new text for updated source files. + updatedSourceTexts.forEach((newText, fileName) => { + if (!cmdOptions.linterOptions.noMigrationBackupFile) { + qEd.QuasiEditor.backupSrcFile(fileName); } - problemsInfos.set(path.normalize(srcFile.fileName), [...linter.problemsInfos]); - linter.problemsInfos.length = 0; - problemFiles = countProblemFiles( - nodeCounters, - problemFiles, - srcFile, - linter.totalVisitedNodes - prevVisitedNodes, - linter.totalErrorLines - prevErrorLines, - linter.totalWarningLines - prevWarningLines, - linter - ); + const filePathMap = cmdOptions.linterOptions.migrationFilePathMap; + const writeFileName = filePathMap?.get(fileName) ?? fileName; + fs.writeFileSync(writeFileName, newText); + }); + + if (cmdOptions.linterOptions.ideInteractive) { + lintResult.problemsInfos = problemsInfosBeforeMigrate; } - return { - errorNodes: problemFiles, - problemsInfos: problemsInfos - }; + + return lintResult; } -// eslint-disable-next-line max-lines-per-function, max-params -function countProblemFiles( - nodeCounters: number[], - filesNumber: number, - tsSrcFile: ts.SourceFile, - fileNodes: number, - fileErrorLines: number, - fileWarningLines: number, - linter: TypeScriptLinter | InteropTypescriptLinter -): number { - let errorNodes = 0; - let warningNodes = 0; - for (let i = 0; i < FaultID.LAST_ID; i++) { - const nodeCounterDiff = linter.nodeCounters[i] - nodeCounters[i]; - switch (faultsAttrs[i].severity) { - case ProblemSeverity.ERROR: - errorNodes += nodeCounterDiff; - break; - case ProblemSeverity.WARNING: - warningNodes += nodeCounterDiff; - break; - default: +function fix( + linterConfig: LinterConfig, + lintResult: LintRunResult, + updatedSourceTexts: Map, + hcResults?: Map +): boolean { + const program = linterConfig.tscCompiledProgram.getProgram(); + let appliedFix = false; + const mergedProblems = lintResult.problemsInfos; + if (hcResults !== undefined) { + for (const [filePath, problems] of hcResults) { + if (mergedProblems.has(filePath)) { + mergedProblems.get(filePath)!.push(...problems); + } else { + mergedProblems.set(filePath, problems); + } } } - if (errorNodes > 0) { - // eslint-disable-next-line no-param-reassign - filesNumber++; - const errorRate = (errorNodes / fileNodes * 100).toFixed(2); - const warningRate = (warningNodes / fileNodes * 100).toFixed(2); - consoleLog(linter.options, tsSrcFile.fileName, ': ', '\n\tError lines: ', linter.errorLineNumbersString); - consoleLog(linter.options, tsSrcFile.fileName, ': ', '\n\tWarning lines: ', linter.warningLineNumbersString); - consoleLog( - linter.options, - '\n\tError constructs (%): ', - errorRate, - '\t[ of ', - fileNodes, - ' constructs ], \t', - fileErrorLines, - ' lines' - ); - consoleLog( - linter.options, - '\n\tWarning constructs (%): ', - warningRate, - '\t[ of ', - fileNodes, - ' constructs ], \t', - fileWarningLines, - ' lines' + mergedProblems.forEach((problemInfos, fileName) => { + // If nothing to fix, skip file + if (!qEd.QuasiEditor.hasAnyAutofixes(problemInfos)) { + return; + } + + const srcFile = program.getSourceFile(fileName); + if (!srcFile) { + Logger.error(`Failed to retrieve source file: ${fileName}`); + return; + } + + const qe: qEd.QuasiEditor = new qEd.QuasiEditor( + fileName, + srcFile.text, + linterConfig.cmdOptions.linterOptions, + undefined, + linterConfig.cmdOptions.outputFilePath ); - } - return filesNumber; -} + updatedSourceTexts.set(fileName, qe.fix(problemInfos)); + appliedFix = true; + }); -function logTotalProblemsInfo( - errorNodes: number, - warningNodes: number, - linter: TypeScriptLinter | InteropTypescriptLinter -): void { - const errorRate = (errorNodes / linter.totalVisitedNodes * 100).toFixed(2); - const warningRate = (warningNodes / linter.totalVisitedNodes * 100).toFixed(2); - consoleLog(linter.options, '\nTotal error constructs (%): ', errorRate); - consoleLog(linter.options, '\nTotal warning constructs (%): ', warningRate); - consoleLog(linter.options, '\nTotal error lines:', linter.totalErrorLines, ' lines\n'); - consoleLog(linter.options, '\nTotal warning lines:', linter.totalWarningLines, ' lines\n'); + return appliedFix; } -function logProblemsPercentageByFeatures(linter: TypeScriptLinter | InteropTypescriptLinter): void { - consoleLog(linter.options, '\nPercent by features: '); - for (let i = 0; i < FaultID.LAST_ID; i++) { - const nodes = linter.nodeCounters[i]; - const lines = linter.lineCounters[i]; - const pecentage = (nodes / linter.totalVisitedNodes * 100).toFixed(2).padEnd(7, ' '); - - consoleLog(linter.options, faultDesc[i].padEnd(55, ' '), pecentage, '[', nodes, ' constructs / ', lines, ' lines]'); - } +function getMigrationCreateProgramCallback(updatedSourceTexts: Map): createProgramCallback { + return (createProgramOptions: ts.CreateProgramOptions): ts.Program => { + const compilerHost = createProgramOptions.host || ts.createCompilerHost(createProgramOptions.options, true); + const originalReadFile = compilerHost.readFile; + compilerHost.readFile = (fileName: string): string | undefined => { + const newText = updatedSourceTexts.get(path.normalize(fileName)); + return newText || originalReadFile(fileName); + }; + createProgramOptions.host = compilerHost; + return ts.createProgram(createProgramOptions); + }; } function shouldProcessFile(options: LinterOptions, fileFsPath: string): boolean { + if (!options.checkTsAndJs && (path.extname(fileFsPath) === EXTNAME_TS || path.extname(fileFsPath) === EXTNAME_JS)) { + return false; + } + if ( ARKTS_IGNORE_FILES.some((ignore) => { return path.basename(fileFsPath) === ignore; diff --git a/ets2panda/linter/src/lib/ProblemInfo.ts b/ets2panda/linter/src/lib/ProblemInfo.ts index f146ac4d2878da6efdde5aa397a06edc30a54c7e..955579e4bef45d9a73f890b43d408f12bba5482e 100644 --- a/ets2panda/linter/src/lib/ProblemInfo.ts +++ b/ets2panda/linter/src/lib/ProblemInfo.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -14,6 +14,7 @@ */ import type { Autofix } from './autofixes/Autofixer'; +import type { FaultID } from './Problems'; export interface ProblemInfo { line: number; @@ -24,6 +25,7 @@ export interface ProblemInfo { end: number; type: string; severity: number; + faultId: FaultID; problem: string; suggest: string; rule: string; diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index 36db28e8ea6248723458850591550986d67a1575..efdc8dacaad2adadca4a031f52a5029a8d431996 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -66,6 +66,9 @@ export enum FaultID { JsxElement, EnumMemberNonConstInit, ImplementsClass, + NoStaticOnClass, + NoConstructorOnClass, + RuntimeArrayCheck, MethodReassignment, MultipleStaticBlocks, ThisType, @@ -94,11 +97,13 @@ export enum FaultID { ImportAssertion, SpreadOperator, LimitedStdLibApi, + LimitedStdLibNoASON, + NoNeedStdLibSendableContainer, ErrorSuppression, StrictDiagnostic, ImportAfterStatement, - EsObjectType, - EsObjectTypeError, + EsValueType, + EsValueTypeError, SendableClassInheritance, SendablePropType, SendableDefiniteAssignment, @@ -157,6 +162,8 @@ export enum FaultID { DollarBindingNotSupported, ExtendDecoratorNotSupported, MethodOverridingField, + InteropJsObjectConditionJudgment, + InteropJsObjectExpandStaticInstance, ExplicitFunctionType, ClassstaticInitialization, TaggedTemplates, @@ -172,7 +179,80 @@ export enum FaultID { DataObservation, InteropCallReflect, InteropCallObjectParam, - InteropNoDecorators, + InteropDirectAccessToTSTypes, + InteropTSFunctionInvoke, + InteropJSFunctionInvoke, + LimitedVoidTypeFromSdk, + EntryAnnotation, + ProvideAnnotation, + UseSharedDeprecated, + UseConcurrentDeprecated, + MethodInheritRule, + OptionalMethodFromSdk, + SendablePropTypeFromSdk, + ConstructorIfaceFromSdk, + PropertyAccessByIndexFromSdk, + ConstructorTypesDeprecated, + QuotedHyphenPropsDeprecated, + DuplicateDeclNameFromSdk, + SdkTypeQuery, + IsConcurrentDeprecated, + InteropStaticObjectLiterals, + InteropJsObjectUsage, + InteropJsObjectInheritance, + InteropJsObjectTraverseJsInstance, + InteropJsObjectCallStaticFunc, + InteropJsObjectExport, + InteropArkTs1ObjectExport, + DefaultArgsBehindRequiredArgs, + LimitedStdLibNoImportConcurrency, + MissingSuperCall, + InteropObjectLiteralAmbiguity, + InteropObjectLiteralClass, + UnsupportPropNameFromValue, + InterOpImportJs, + CallJSFunction, + InteropObjectProperty, + InterOpConvertImport, + InterOpImportJsForTypeOf, + InteropNoHaveNum, + BinaryOperations, + InterOpImportJsDataCompare, + InteropEqualityJudgment, + InterOpImportJsIndex, + InstantiatedJsOjbect, + InteropCallObjectMethods, + InteropJsInstanceof, + InteropIncrementDecrement, + BuiltinThisArgs, + BuiltinSymbolIterator, + NoPropertyDescriptor, + BuiltinNoCtorFunc, + SharedArrayBufferDeprecated, + SetCloneListDeprecated, + SetTransferListDeprecated, + LimitedStdLibNoSendableDecorator, + LimitedStdLibNoDoncurrentDecorator, + NoNeedStdlibWorker, + BuiltinGetOwnPropertyNames, + LocalBuilderDecoratorNotSupported, + MakeObservedIsNotSupported, + NoEnumPropAsType, + NoAwaitJsPromise, + NosparseArray, + NoTsLikeSmartType, + ArrayTypeImmutable, + CreatingPrimitiveTypes, + TsLikeCatchType, + NumericBigintCompare, + NondecimalBigint, + UnsupportOperator, + CustomLayoutNeedAddDecorator, + PropDecoratorNotSupported, + StoragePropDecoratorNotSupported, + LocalStoragePropDecoratorNotSupported, + PropFunctionNotSupported, + SetAndPropFunctionNotSupported, // 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 332f8bb33750dccc5086cad766c9f0fd74b11f61..ce3a05264e15bfc7722d0564b5428a8bcd3a7783 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -15,23 +15,28 @@ import * as path from 'node:path'; import * as ts from 'typescript'; -import { cookBookTag } from './CookBookMsg'; -import { faultsAttrs } from './FaultAttrs'; -import { faultDesc } from './FaultDesc'; -import { Logger } from './Logger'; -import type { ProblemInfo } from './ProblemInfo'; -import { ProblemSeverity } from './ProblemSeverity'; import { FaultID } from './Problems'; -import { LinterConfig } from './TypeScriptLinterConfig'; -import { cookBookRefToFixTitle } from './autofixes/AutofixTitles'; +import { TypeScriptLinterConfig } from './TypeScriptLinterConfig'; import type { Autofix } from './autofixes/Autofixer'; import { Autofixer } from './autofixes/Autofixer'; import { SYMBOL, SYMBOL_CONSTRUCTOR, TsUtils } from './utils/TsUtils'; import { FUNCTION_HAS_NO_RETURN_ERROR_CODE } from './utils/consts/FunctionHasNoReturnErrorCode'; import { LIMITED_STANDARD_UTILITY_TYPES } from './utils/consts/LimitedStandardUtilityTypes'; -import { arkts2Rules } from './utils/consts/ArkTS2Rules'; import { LIKE_FUNCTION } from './utils/consts/LikeFunction'; -import { STRINGLITERAL_NUMBER, STRINGLITERAL_STRING, STRINGLITERAL_INT } from './utils/consts/StringLiteral'; +import { METHOD_DECLARATION } from './utils/consts/MethodDeclaration'; +import { METHOD_SIGNATURE } from './utils/consts/MethodSignature'; +import { OPTIONAL_METHOD } from './utils/consts/OptionalMethod'; +import { + STRINGLITERAL_NUMBER, + STRINGLITERAL_STRING, + STRINGLITERAL_INT, + STRINGLITERAL_BYTE, + STRINGLITERAL_SHORT, + STRINGLITERAL_CHAR, + STRINGLITERAL_LONG, + STRINGLITERAL_FROM, + STRINGLITERAL_ARRAY +} from './utils/consts/StringLiteral'; import { NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS, NON_INITIALIZABLE_PROPERTY_DECORATORS, @@ -41,6 +46,8 @@ import { NON_RETURN_FUNCTION_DECORATORS } from './utils/consts/NonReturnFunction import { PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE } from './utils/consts/PropertyHasNoInitializerErrorCode'; import { CONCURRENT_DECORATOR, + ISCONCURRENT, + TASKPOOL, SENDABLE_DECORATOR, SENDABLE_DECORATOR_NODES, SENDABLE_FUNCTION_UNSUPPORTED_STAGES_IN_API12, @@ -61,7 +68,8 @@ import { LIMITED_STD_GLOBAL_API, LIMITED_STD_OBJECT_API, LIMITED_STD_PROXYHANDLER_API, - LIMITED_STD_REFLECT_API + LIMITED_STD_REFLECT_API, + MODULE_IMPORTS } from './utils/consts/LimitedStdAPI'; import { SupportedStdCallApiChecker } from './utils/functions/SupportedStdCallAPI'; import { identiferUseInValueContext } from './utils/functions/identiferUseInValueContext'; @@ -72,6 +80,9 @@ import { BUILTIN_GENERIC_CONSTRUCTORS } from './utils/consts/BuiltinGenericConst import { DEFAULT_DECORATOR_WHITE_LIST } from './utils/consts/DefaultDecoratorWhitelist'; import { INVALID_IDENTIFIER_KEYWORDS } from './utils/consts/InValidIndentifierKeywords'; import { WORKER_MODULES, WORKER_TEXT } from './utils/consts/WorkerAPI'; +import { COLLECTIONS_TEXT, COLLECTIONS_MODULES } from './utils/consts/CollectionsAPI'; +import { ASON_TEXT, ASON_MODULES, ARKTS_UTILS_TEXT } from './utils/consts/ArkTSUtilsAPI'; +import { interanlFunction } from './utils/consts/InternalFunction'; import { ETS_PART, PATH_SEPARATOR } from './utils/consts/OhmUrl'; import { DOUBLE_DOLLAR_IDENTIFIER, @@ -79,45 +90,140 @@ import { STATE_STYLES, CustomDecoratorName, observedDecoratorName, - skipImportDecoratorName + skipImportDecoratorName, + ENTRY_DECORATOR_NAME, + PROVIDE_DECORATOR_NAME, + PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME, + ARKUI_PACKAGE_NAME, + MAKE_OBSERVED, + ARKUI_STATE_MANAGEMENT, + PropDecoratorName, + PropFunctionName, + StorageTypeName, + customLayoutFunctionName } from './utils/consts/ArkuiConstants'; import { arkuiImportList } from './utils/consts/ArkuiImportList'; -import { REFLECT_PROPERTIES, USE_STATIC } from './utils/consts/InteropAPI'; -import { EXTNAME_TS } from './utils/consts/ExtensionName'; - -export class TypeScriptLinter { - totalVisitedNodes: number = 0; - nodeCounters: number[] = []; - lineCounters: number[] = []; - - totalErrorLines: number = 0; - errorLineNumbersString: string = ''; - totalWarningLines: number = 0; - warningLineNumbersString: string = ''; - - problemsInfos: ProblemInfo[] = []; - - tsUtils: TsUtils; +import type { ForbidenAPICheckResult } from './utils/consts/InteropAPI'; +import { + NONE, + OBJECT_LITERAL, + OBJECT_PROPERTIES, + REFLECT_LITERAL, + REFLECT_PROPERTIES, + USE_STATIC +} from './utils/consts/InteropAPI'; +import { EXTNAME_TS, EXTNAME_D_TS, EXTNAME_JS } from './utils/consts/ExtensionName'; +import { ARKTS_IGNORE_DIRS_OH_MODULES } from './utils/consts/ArktsIgnorePaths'; +import type { ApiInfo, ApiListItem } from './utils/consts/SdkWhitelist'; +import { ApiList, SdkProblem, SdkNameInfo } from './utils/consts/SdkWhitelist'; +import * as apiWhiteList from './data/SdkWhitelist.json'; +import * as builtinWhiteList from './data/BuiltinList.json'; +import { + BuiltinProblem, + SYMBOL_ITERATOR, + BUILTIN_DISABLE_CALLSIGNATURE, + GET_OWN_PROPERTY_NAMES_TEXT +} from './utils/consts/BuiltinWhiteList'; +import { + USE_SHARED, + USE_CONCURRENT, + ESLIB_SHAREDMEMORY_FILENAME, + ESLIB_SHAREDARRAYBUFFER, + TASKPOOL_MODULES +} from './utils/consts/ConcurrentAPI'; +import { + DEPRECATED_TASKPOOL_METHOD_SETCLONELIST, + DEPRECATED_TASKPOOL_METHOD_SETTRANSFERLIST, + STDLIB_TASK_CLASS_NAME, + STDLIB_TASKPOOL_OBJECT_NAME +} from './utils/consts/TaskpoolAPI'; +import { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; +import type { ArrayAccess, UncheckedIdentifier, CheckedIdentifier } from './utils/consts/RuntimeCheckAPI'; +import { CheckResult } from './utils/consts/RuntimeCheckAPI'; +import { NUMBER_LITERAL } from './utils/consts/RuntimeCheckAPI'; + +interface InterfaceSymbolTypeResult { + propNames: string[]; + typeNames: string[]; + allProps: Map; +} +interface InterfaceSymbolTypePropertyNames { + propertyNames: string[]; + typeNames: string[]; +} - currentErrorLine: number; - currentWarningLine: number; +export class TypeScriptLinter extends BaseTypeScriptLinter { supportedStdCallApiChecker: SupportedStdCallApiChecker; autofixer: Autofixer | undefined; private fileExportDeclCaches: Set | undefined; - private sourceFile?: ts.SourceFile; + private useStatic?: boolean; + private readonly compatibleSdkVersion: number; private readonly compatibleSdkVersionStage: string; private static sharedModulesCache: Map; static nameSpaceFunctionCache: Map>; private readonly constVariableInitCache: Map = new Map(); + static funcMap: Map>> = new Map>>(); + private interfaceMap: Map> = new Map>(); + static pathMap: Map>; + static indexedTypeSet: Set; + static globalApiInfo: Map>; + static symbotIterSet: Set; + static missingAttributeSet: Set; + static literalAsPropertyNameTypeSet: Set; + private localApiListItem: ApiListItem | undefined = undefined; static initGlobals(): void { TypeScriptLinter.sharedModulesCache = new Map(); TypeScriptLinter.nameSpaceFunctionCache = new Map>(); + TypeScriptLinter.pathMap = new Map>(); + TypeScriptLinter.globalApiInfo = new Map>(); + TypeScriptLinter.funcMap = new Map>>(); + TypeScriptLinter.symbotIterSet = new Set(); + TypeScriptLinter.missingAttributeSet = new Set(); + TypeScriptLinter.initSdkWhitelist(); + TypeScriptLinter.initSdkBuiltinInfo(); + TypeScriptLinter.initBuiltinlist(); + } + + initSdkInfo(): void { + this.interfaceMap = new Map>(); + } + + static initSdkBuiltinInfo(): void { + const list: ApiList = new ApiList(builtinWhiteList); + if (list?.api_list?.length > 0) { + for (const item of list.api_list) { + switch (item.api_info.problem) { + case BuiltinProblem.MissingAttributes: + TypeScriptLinter.missingAttributeSet.add(item.file_path); + break; + case BuiltinProblem.SymbolIterator: + TypeScriptLinter.symbotIterSet.add(item.file_path); + break; + case BuiltinProblem.LimitedThisArg: + TypeScriptLinter.initSdkBuiltinThisArgsWhitelist(item); + break; + default: + } + } + } } + static initSdkBuiltinThisArgsWhitelist(item: ApiListItem): void { + if (item.file_path === '' || !item.api_info.api_name) { + return; + } + + let funcApiInfos: Map> | undefined = TypeScriptLinter.funcMap.get(item.api_info.api_name); + if (!funcApiInfos) { + funcApiInfos = new Map>(); + TypeScriptLinter.funcMap.set(item.api_info.api_name, funcApiInfos); + } + TypeScriptLinter.addOrUpdateData(funcApiInfos, item.file_path, item.api_info); + } private initEtsHandlers(): void { @@ -131,26 +237,79 @@ export class TypeScriptLinter { } } - private initCounters(): void { - for (let i = 0; i < FaultID.LAST_ID; i++) { - this.nodeCounters[i] = 0; - this.lineCounters[i] = 0; + private static addSdkIndexedTypeSetData(item: ApiListItem): void { + if (item.api_info.problem === SdkProblem.IndexedAccessType) { + TypeScriptLinter.indexedTypeSet.add(item); + } + } + + private static addSdkliteralAsPropertyNameTypeSetData(item: ApiListItem): void { + if (item.api_info.problem === SdkProblem.LiteralAsPropertyName) { + TypeScriptLinter.literalAsPropertyNameTypeSet.add(item); + } + } + + private static addGlobalApiInfosCollocetionData(item: ApiListItem): void { + const problemType = item.api_info.problem; + const isGlobal = item.is_global; + if (isGlobal) { + if (!TypeScriptLinter.globalApiInfo.has(problemType)) { + TypeScriptLinter.globalApiInfo.set(problemType, new Set()); + } + const setApiListItem = TypeScriptLinter.globalApiInfo.get(problemType); + setApiListItem?.add(item); + } + } + + private static initSdkWhitelist(): void { + TypeScriptLinter.indexedTypeSet = new Set(); + TypeScriptLinter.literalAsPropertyNameTypeSet = new Set(); + const list: ApiList = new ApiList(apiWhiteList); + if (list?.api_list?.length > 0) { + for (const item of list.api_list) { + if (item.file_path !== '') { + TypeScriptLinter.addOrUpdateData(TypeScriptLinter.pathMap, `'${item.file_path}'`, item.api_info); + } + item.import_path.forEach((path) => { + TypeScriptLinter.addOrUpdateData(TypeScriptLinter.pathMap, `'${path}'`, item.api_info); + }); + TypeScriptLinter.addSdkIndexedTypeSetData(item); + TypeScriptLinter.addSdkliteralAsPropertyNameTypeSetData(item); + TypeScriptLinter.addGlobalApiInfosCollocetionData(item); + } + } + } + + private static initBuiltinlist(): void { + const list: ApiList = new ApiList(builtinWhiteList); + if (list?.api_list?.length > 0) { + for (const item of list.api_list) { + TypeScriptLinter.addGlobalApiInfosCollocetionData(item); + } + } + } + + private static addOrUpdateData(map: Map>, path: string, data: ApiInfo): void { + let apiInfos = map.get(path); + if (!apiInfos) { + apiInfos = new Set(); + map.set(path, apiInfos); } + apiInfos.add(data); } constructor( - private readonly tsTypeChecker: ts.TypeChecker, - readonly options: LinterOptions, - private readonly tscStrictDiagnostics?: Map + tsTypeChecker: ts.TypeChecker, + options: LinterOptions, + sourceFile: ts.SourceFile, + readonly tscStrictDiagnostics?: Map ) { - this.tsUtils = new TsUtils(this.tsTypeChecker, options); - this.currentErrorLine = 0; - this.currentWarningLine = 0; + super(tsTypeChecker, options, sourceFile); this.supportedStdCallApiChecker = new SupportedStdCallApiChecker(this.tsUtils, this.tsTypeChecker); this.compatibleSdkVersion = options.compatibleSdkVersion || DEFAULT_COMPATIBLE_SDK_VERSION; this.compatibleSdkVersionStage = options.compatibleSdkVersionStage || DEFAULT_COMPATIBLE_SDK_VERSION_STAGE; this.initEtsHandlers(); - this.initCounters(); + this.initSdkInfo(); } readonly handlersMap = new Map([ @@ -159,11 +318,13 @@ export class TypeScriptLinter { [ts.SyntaxKind.Parameter, this.handleParameter], [ts.SyntaxKind.EnumDeclaration, this.handleEnumDeclaration], [ts.SyntaxKind.InterfaceDeclaration, this.handleInterfaceDeclaration], + [ts.SyntaxKind.TryStatement, this.handleTryStatement], [ts.SyntaxKind.ThrowStatement, this.handleThrowStatement], [ts.SyntaxKind.ImportClause, this.handleImportClause], [ts.SyntaxKind.ForStatement, this.handleForStatement], [ts.SyntaxKind.ForInStatement, this.handleForInStatement], [ts.SyntaxKind.ForOfStatement, this.handleForOfStatement], + [ts.SyntaxKind.IfStatement, this.handleIfStatement], [ts.SyntaxKind.ImportDeclaration, this.handleImportDeclaration], [ts.SyntaxKind.PropertyAccessExpression, this.handlePropertyAccessExpression], [ts.SyntaxKind.PropertyDeclaration, this.handlePropertyDeclaration], @@ -200,6 +361,7 @@ export class TypeScriptLinter { [ts.SyntaxKind.SpreadAssignment, this.handleSpreadOp], [ts.SyntaxKind.GetAccessor, this.handleGetAccessor], [ts.SyntaxKind.SetAccessor, this.handleSetAccessor], + [ts.SyntaxKind.StringLiteral, this.handleStringLiteral], [ts.SyntaxKind.ConstructSignature, this.handleConstructSignature], [ts.SyntaxKind.ExpressionWithTypeArguments, this.handleExpressionWithTypeArguments], [ts.SyntaxKind.ComputedPropertyName, this.handleComputedPropertyName], @@ -222,147 +384,37 @@ export class TypeScriptLinter { [ts.SyntaxKind.ArrayType, this.handleArrayType], [ts.SyntaxKind.LiteralType, this.handleLimitedLiteralType], [ts.SyntaxKind.NonNullExpression, this.handleNonNullExpression], - [ts.SyntaxKind.HeritageClause, this.checkExtendsExpression], + [ts.SyntaxKind.HeritageClause, this.handleHeritageClause], [ts.SyntaxKind.TaggedTemplateExpression, this.handleTaggedTemplatesExpression], - [ts.SyntaxKind.StructDeclaration, this.handleStructDeclaration] + [ts.SyntaxKind.StructDeclaration, this.handleStructDeclaration], + [ts.SyntaxKind.TypeOfExpression, this.handleInterOpImportJsOnTypeOfNode], + [ts.SyntaxKind.AwaitExpression, this.handleAwaitExpression], + [ts.SyntaxKind.PostfixUnaryExpression, this.handlePostfixUnaryExpression], + [ts.SyntaxKind.BigIntLiteral, this.handleBigIntLiteral], + [ts.SyntaxKind.NumericLiteral, this.handleNumericLiteral] ]); - private getLineAndCharacterOfNode(node: ts.Node | ts.CommentRange): ts.LineAndCharacter { - const startPos = TsUtils.getStartPos(node); - const { line, character } = this.sourceFile!.getLineAndCharacterOfPosition(startPos); - // TSC counts lines and columns from zero - return { line: line + 1, character: character + 1 }; - } - - incrementCounters(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { - this.nodeCounters[faultId]++; - const { line, character } = this.getLineAndCharacterOfNode(node); - if ((this.options.ideMode || this.options.migratorMode) && !this.options.ideInteractive) { - this.incrementCountersIdeMode(node, faultId, autofix); - } else if (this.options.ideInteractive) { - this.incrementCountersIdeInteractiveMode(node, faultId, autofix); - } else { - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - Logger.info( - `Warning: ${this.sourceFile!.fileName} (${line}, ${character}): ${faultDescr ? faultDescr : faultType}` - ); - } - this.lineCounters[faultId]++; - switch (faultsAttrs[faultId].severity) { - case ProblemSeverity.ERROR: { - this.currentErrorLine = line; - ++this.totalErrorLines; - this.errorLineNumbersString += line + ', '; - break; - } - case ProblemSeverity.WARNING: { - if (line === this.currentWarningLine) { - break; - } - this.currentWarningLine = line; - ++this.totalWarningLines; - this.warningLineNumbersString += line + ', '; - break; - } - default: - } - } - - private incrementCountersIdeMode(node: ts.Node | ts.CommentRange, faultId: number, autofix?: Autofix[]): void { - if (!this.options.ideMode && !this.options.migratorMode) { - return; - } - const [startOffset, endOffset] = TsUtils.getHighlightRange(node, faultId); - const startPos = this.sourceFile!.getLineAndCharacterOfPosition(startOffset); - const endPos = this.sourceFile!.getLineAndCharacterOfPosition(endOffset); - - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - - const cookBookMsgNum = faultsAttrs[faultId] ? faultsAttrs[faultId].cookBookRef : 0; - const cookBookTg = cookBookTag[cookBookMsgNum]; - const severity = faultsAttrs[faultId]?.severity ?? ProblemSeverity.ERROR; - const isMsgNumValid = cookBookMsgNum > 0; - const badNodeInfo: ProblemInfo = { - line: startPos.line + 1, - column: startPos.character + 1, - endLine: endPos.line + 1, - endColumn: endPos.character + 1, - start: startOffset, - end: endOffset, - type: faultType, - severity: severity, - problem: FaultID[faultId], - suggest: '', - // eslint-disable-next-line no-nested-ternary - rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, - ruleTag: cookBookMsgNum, - autofix: autofix, - autofixTitle: isMsgNumValid && autofix !== undefined ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined - }; - this.problemsInfos.push(badNodeInfo); - // problems with autofixes might be collected separately - if (this.options.reportAutofixCb && badNodeInfo.autofix) { - this.options.reportAutofixCb(badNodeInfo); + lint(): void { + if (this.options.enableAutofix || this.options.migratorMode) { + this.autofixer = new Autofixer(this.tsTypeChecker, this.tsUtils, this.sourceFile, this.options.cancellationToken); } - } - private incrementCountersIdeInteractiveMode( - node: ts.Node | ts.CommentRange, - faultId: number, - autofix?: Autofix[] - ): void { - if (!this.options.ideInteractive) { - return; - } - const [startOffset, endOffset] = TsUtils.getHighlightRange(node, faultId); - const startPos = this.sourceFile!.getLineAndCharacterOfPosition(startOffset); - const endPos = this.sourceFile!.getLineAndCharacterOfPosition(endOffset); - - const faultDescr = faultDesc[faultId]; - const faultType = LinterConfig.tsSyntaxKindNames[node.kind]; - - const cookBookMsgNum = faultsAttrs[faultId] ? faultsAttrs[faultId].cookBookRef : 0; - if (!arkts2Rules.includes(cookBookMsgNum) && this.options.arkts2) { - return; - } - const cookBookTg = cookBookTag[cookBookMsgNum]; - const severity = faultsAttrs[faultId]?.severity ?? ProblemSeverity.ERROR; - const isMsgNumValid = cookBookMsgNum > 0; - const badNodeInfo: ProblemInfo = { - line: startPos.line + 1, - column: startPos.character + 1, - endLine: endPos.line + 1, - endColumn: endPos.character + 1, - start: startOffset, - end: endOffset, - type: faultType, - severity: severity, - problem: FaultID[faultId], - suggest: '', - // eslint-disable-next-line no-nested-ternary - rule: isMsgNumValid && cookBookTg !== '' ? cookBookTg : faultDescr ? faultDescr : faultType, - ruleTag: cookBookMsgNum, - autofixable: !!autofix, - autofix: autofix, - autofixTitle: isMsgNumValid && autofix !== undefined ? cookBookRefToFixTitle.get(cookBookMsgNum) : undefined - }; - this.problemsInfos.push(badNodeInfo); - // problems with autofixes might be collected separately - if (this.options.reportAutofixCb && badNodeInfo.autofix) { - this.options.reportAutofixCb(badNodeInfo); - } + this.useStatic = TsUtils.isArkts12File(this.sourceFile); + this.fileExportDeclCaches = undefined; + this.extractImportedNames(this.sourceFile); + this.visitSourceFile(this.sourceFile); + this.handleCommentDirectives(this.sourceFile); + this.processInterfacesToImport(this.sourceFile); } private visitSourceFile(sf: ts.SourceFile): void { const callback = (node: ts.Node): void => { - this.totalVisitedNodes++; + this.fileStats.visitedNodes++; if (isStructDeclaration(node)) { // early exit via exception if cancellation was requested this.options.cancellationToken?.throwIfCancellationRequested(); } - const incrementedType = LinterConfig.incrementOnlyTokens.get(node.kind); + const incrementedType = TypeScriptLinterConfig.incrementOnlyTokens.get(node.kind); if (incrementedType !== undefined) { this.incrementCounters(node, incrementedType); } else { @@ -388,7 +440,7 @@ export class TypeScriptLinter { if (node.parent && isStructDeclaration(node.parent) && ts.isConstructorDeclaration(node)) { return true; } - if (LinterConfig.terminalTokens.has(node.kind)) { + if (TypeScriptLinterConfig.terminalTokens.has(node.kind)) { return true; } return false; @@ -544,15 +596,27 @@ export class TypeScriptLinter { objectLiteralType: ts.Type | undefined, objectLiteralExpr: ts.ObjectLiteralExpression ): void { - const isRecordObject = objectLiteralType && this.tsUtils.isStdRecordType(objectLiteralType); - for (const prop of objectLiteralExpr.properties) { - if ( - isRecordObject && !(prop.name && this.tsUtils.isValidRecordObjectLiteralKey(prop.name)) || - !isRecordObject && !(ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) - ) { - const faultNode = ts.isPropertyAssignment(prop) ? prop.name : prop; - this.incrementCounters(faultNode, FaultID.ObjectLiteralProperty); + let objLiteralAutofix: Autofix[] | undefined; + const invalidProps = objectLiteralExpr.properties.filter((prop) => { + return !ts.isPropertyAssignment(prop); + }); + + if ( + invalidProps.some((prop) => { + return ts.isMethodDeclaration(prop) || ts.isAccessor(prop); + }) + ) { + objLiteralAutofix = this.autofixer?.fixTypedObjectLiteral(objectLiteralExpr, objectLiteralType); + } + + for (const prop of invalidProps) { + if (ts.isShorthandPropertyAssignment(prop) && !TsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(prop))) { + continue; } + const autofix = ts.isShorthandPropertyAssignment(prop) ? + this.autofixer?.fixShorthandPropertyAssignment(prop) : + objLiteralAutofix; + this.incrementCounters(prop, FaultID.ObjectLiteralProperty, autofix); } } @@ -593,16 +657,21 @@ export class TypeScriptLinter { if (elementContextType) { this.checkAssignmentMatching(element, elementContextType, element, true); } + if (this.options.arkts2 && ts.isOmittedExpression(element)) { + this.incrementCounters(element, FaultID.NosparseArray); + } } if (emptyContextTypeForArrayLiteral) { this.incrementCounters(node, FaultID.ArrayLiteralNoContextType); } + this.handleObjectLiteralAssignmentToClass(arrayLitNode); } private handleStructDeclaration(node: ts.StructDeclaration): void { if (!this.options.arkts2) { - return; + return; } + this.handleStructDeclarationForLayout(node); this.handleInvalidIdentifier(node); } @@ -614,10 +683,12 @@ export class TypeScriptLinter { this.handleDeclarationDestructuring(tsParam); this.handleDeclarationInferredType(tsParam); this.handleInvalidIdentifier(tsParam); + this.handleSdkDuplicateDeclName(tsParam); const typeNode = tsParam.type; if (this.options.arkts2 && typeNode && typeNode.kind === ts.SyntaxKind.VoidKeyword) { this.incrementCounters(typeNode, FaultID.LimitedVoidType); } + this.handlePropertyDescriptorInScenarios(tsParam); } private handleEnumDeclaration(node: ts.Node): void { @@ -631,6 +702,9 @@ export class TypeScriptLinter { if (!enumDecls) { return; } + if (this.options.arkts2) { + this.handleInvalidIdentifier(enumNode); + } /* * Since type checker merges all declarations with the same name @@ -661,6 +735,11 @@ export class TypeScriptLinter { this.options.cancellationToken?.throwIfCancellationRequested(); const interfaceNode = node as ts.InterfaceDeclaration; + + if (this.options.arkts2) { + this.handleInvalidIdentifier(interfaceNode); + } + const iSymbol = this.tsUtils.trueSymbolAtLocation(interfaceNode.name); const iDecls = iSymbol ? iSymbol.getDeclarations() : null; if (iDecls) { @@ -687,6 +766,81 @@ export class TypeScriptLinter { this.countDeclarationsWithDuplicateName(interfaceNode.name, interfaceNode); } + private handleTryStatement(node: ts.TryStatement): void { + if (!this.options.arkts2) { + return; + } + + for (const stmt of node.tryBlock.statements) { + if (!ts.isExpressionStatement(stmt)) { + continue; + } + const callExpr = stmt.expression; + if (!ts.isCallExpression(callExpr)) { + continue; + } + const ident = callExpr.expression; + if (!ts.isIdentifier(ident)) { + continue; + } + + this.handleTsInterop(ident, () => { + this.tsFunctionInteropHandler(callExpr); + }); + + this.handleJsInterop(ident, () => { + this.jsFunctionInteropHandler(callExpr); + }); + } + } + + private tsFunctionInteropHandler(callExpr: ts.CallExpression): void { + this.checkInteropFunctionThrows(callExpr, FaultID.InteropTSFunctionInvoke); + } + + private jsFunctionInteropHandler(callExpr: ts.CallExpression): void { + this.checkInteropFunctionThrows(callExpr, FaultID.InteropJSFunctionInvoke); + } + + private checkInteropFunctionThrows(callExpr: ts.CallExpression, faultId: FaultID): void { + const signature = this.tsTypeChecker.getResolvedSignature(callExpr); + if (!signature) { + return; + } + + if (!signature.declaration) { + return; + } + + const functionSymbol = this.getFunctionSymbol(signature.declaration); + const functionDeclaration = functionSymbol?.valueDeclaration; + if (!functionDeclaration) { + return; + } + + if (!TypeScriptLinter.isFunctionLike(functionDeclaration)) { + return; + } + if (this.containsThrowNonError(functionDeclaration)) { + this.incrementCounters(callExpr, faultId); + } + } + + private containsThrowNonError(node: ts.FunctionDeclaration | ts.MethodDeclaration | ts.FunctionExpression): boolean { + if (!node.body) { + return false; + } + + const statements = node.body.statements; + for (const stmt of statements) { + if (!ts.isThrowStatement(stmt)) { + continue; + } + return this.tsUtils.checkStatementForErrorClass(stmt); + } + return false; + } + private handleThrowStatement(node: ts.Node): void { const throwStmt = node as ts.ThrowStatement; const throwExprType = this.tsTypeChecker.getTypeAtLocation(throwStmt.expression); @@ -713,4117 +867,8234 @@ export class TypeScriptLinter { } } + /* + * this should report the point of access to the array + * and also should report the identifier type + */ + private checkElementAccessOfArray(statement: ts.Node): ArrayAccess | false { + if (ts.isElementAccessExpression(statement)) { + return this.isElementAccessOfArray(statement); + } + + for (const children of statement.getChildren()) { + return this.checkElementAccessOfArray(children); + } + return false; + } + + private isElementAccessOfArray(expr: ts.ElementAccessExpression): false | ArrayAccess { + if (!ts.isIdentifier(expr.expression)) { + return false; + } + const type = this.tsTypeChecker.getTypeAtLocation(expr.expression); + if (!this.tsUtils.isArray(type)) { + return false; + } + const accessArgument = expr.argumentExpression; + if (ts.isNumericLiteral(accessArgument)) { + return { + pos: expr.getEnd(), + accessingIdentifier: NUMBER_LITERAL, + arrayIdent: expr.expression + }; + } + + if (ts.isIdentifier(accessArgument)) { + return { + pos: expr.getEnd(), + accessingIdentifier: accessArgument, + arrayIdent: expr.expression + }; + } + return false; + } + private handleForStatement(node: ts.Node): void { const tsForStmt = node as ts.ForStatement; const tsForInit = tsForStmt.initializer; if (tsForInit) { + this.checkStaticArrayControl(tsForStmt); this.checkForLoopDestructuring(tsForInit); } } - private handleForInStatement(node: ts.Node): void { - const tsForInStmt = node as ts.ForInStatement; - const tsForInInit = tsForInStmt.initializer; - this.checkForLoopDestructuring(tsForInInit); - this.incrementCounters(node, FaultID.ForInStatement); - } + private checkStaticArrayControl(tsForStmt: ts.ForStatement): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } - private handleForOfStatement(node: ts.Node): void { - const tsForOfStmt = node as ts.ForOfStatement; - const tsForOfInit = tsForOfStmt.initializer; - this.checkForLoopDestructuring(tsForOfInit); - } + if (!ts.isBlock(tsForStmt.statement)) { + return; + } - private handleImportDeclaration(node: ts.Node): void { - // early exit via exception if cancellation was requested - this.options.cancellationToken?.throwIfCancellationRequested(); - const importDeclNode = node as ts.ImportDeclaration; - this.handleImportModule(importDeclNode); - if (this.options.arkts2) { - const importClause = importDeclNode.importClause; - if (!importClause || !importClause.name && !importClause.namedBindings) { - this.incrementCounters(node, FaultID.NoSideEffectImport); - } + const loopBody = tsForStmt.statement; + const arrayAccessInfo = this.checkBodyHasArrayAccess(loopBody); + const loopCondition = tsForStmt.condition; + + if (!arrayAccessInfo) { + return; } - for (const stmt of importDeclNode.parent.statements) { - if (stmt === importDeclNode) { - break; - } - if (!ts.isImportDeclaration(stmt)) { - this.incrementCounters(node, FaultID.ImportAfterStatement); - break; - } + if (!loopCondition) { + this.incrementCounters(arrayAccessInfo.arrayIdent.parent, FaultID.RuntimeArrayCheck); + return; + } + const arraySymbol = this.tsUtils.trueSymbolAtLocation(arrayAccessInfo.arrayIdent); + if (!arraySymbol) { + return; } - const expr = importDeclNode.moduleSpecifier; - if (expr.kind === ts.SyntaxKind.StringLiteral) { - if (importDeclNode.assertClause) { - this.incrementCounters(importDeclNode.assertClause, FaultID.ImportAssertion); - } + const arrayCheckedAgainst = this.checkConditionForArrayAccess(loopCondition, arraySymbol); + if (!arrayCheckedAgainst) { + this.incrementCounters(arrayAccessInfo.arrayIdent.parent, FaultID.RuntimeArrayCheck); + return; } - // handle no side effect import in sendable module - this.handleSharedModuleNoSideEffectImport(importDeclNode); - this.handleInvalidIdentifier(importDeclNode); + this.checkIfAccessAndCheckVariablesMatch(arrayAccessInfo, arrayCheckedAgainst); } - private handleImportModule(importDeclNode: ts.ImportDeclaration): void { - if (!this.options.arkts2) { + private checkIfAccessAndCheckVariablesMatch(accessInfo: ArrayAccess, checkedAgainst: CheckedIdentifier): void { + const { arrayIdent, accessingIdentifier } = accessInfo; + + if (accessingIdentifier === NUMBER_LITERAL) { + if (checkedAgainst === NUMBER_LITERAL) { + return; + } + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); return; } - const modulePath = importDeclNode.moduleSpecifier.getText().slice(1, -1); - if (modulePath.startsWith('./') || modulePath.startsWith('../')) { - - /* - * Reason for this method to check the oh module imports, - * We do not use relative paths when importing from OhModules, - * So we do not check the relative paths - */ + if (checkedAgainst === NUMBER_LITERAL) { + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); return; } - if (TsUtils.isValidOhModulePath(modulePath) || !TsUtils.isOhModule(modulePath)) { - // Valid or paths that we do not check because they are not ohModules + const checkedAgainstSym = this.tsUtils.trueSymbolAtLocation(checkedAgainst); + if (!checkedAgainstSym) { return; } - const pathParts = modulePath.split(PATH_SEPARATOR); - const etsIdx = pathParts.indexOf(ETS_PART); + const accessingIdentSym = this.tsUtils.trueSymbolAtLocation(accessingIdentifier); - if (etsIdx === 0) { - this.incrementCounters(importDeclNode, FaultID.OhmUrlFullPath); + if (checkedAgainstSym !== accessingIdentSym) { + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); return; } - const autofix = Autofixer.fixImportPath(pathParts, etsIdx, importDeclNode); - this.incrementCounters(importDeclNode, FaultID.OhmUrlFullPath, autofix); + if (this.isChangedAfterCheck(arrayIdent.getSourceFile(), checkedAgainstSym)) { + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); + } } - private handleSharedModuleNoSideEffectImport(node: ts.ImportDeclaration): void { - // check 'use shared' - if (TypeScriptLinter.inSharedModule(node) && !node.importClause) { - this.incrementCounters(node, FaultID.SharedNoSideEffectImport); + private checkConditionForArrayAccess(condition: ts.Expression, arraySymbol: ts.Symbol): UncheckedIdentifier { + if (!ts.isBinaryExpression(condition)) { + return undefined; } - } + const { left, right } = condition; - private static inSharedModule(node: ts.Node): boolean { - const sourceFile: ts.SourceFile = node.getSourceFile(); - const modulePath = path.normalize(sourceFile.fileName); - if (TypeScriptLinter.sharedModulesCache.has(modulePath)) { - return TypeScriptLinter.sharedModulesCache.get(modulePath)!; + if (ts.isBinaryExpression(left)) { + return this.checkConditionForArrayAccess(left, arraySymbol); + } + if (ts.isBinaryExpression(right)) { + return this.checkConditionForArrayAccess(right, arraySymbol); } - const isSharedModule: boolean = TsUtils.isSharedModule(sourceFile); - TypeScriptLinter.sharedModulesCache.set(modulePath, isSharedModule); - return isSharedModule; - } - private handlePropertyAccessExpression(node: ts.Node): void { - this.handleDoubleDollar(node); + if (this.isArrayLengthAccess(left, arraySymbol)) { + if (ts.isNumericLiteral(right)) { + return NUMBER_LITERAL; + } + if (!ts.isIdentifier(right)) { + return undefined; + } + return right; + } - this.checkUnionTypes(node as ts.PropertyAccessExpression); - if (ts.isCallExpression(node.parent) && node === node.parent.expression) { - return; + if (this.isArrayLengthAccess(right, arraySymbol)) { + if (ts.isNumericLiteral(left)) { + return NUMBER_LITERAL; + } + if (!ts.isIdentifier(left)) { + return undefined; + } + return left; } - const propertyAccessNode = node as ts.PropertyAccessExpression; - const exprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode); - const baseExprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode.expression); - const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); + return undefined; + } - if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { - this.incrementCounters(propertyAccessNode.name, FaultID.Prototype); + private isArrayLengthAccess(expr: ts.Expression, arraySymbol: ts.Symbol): boolean { + if (!ts.isPropertyAccessExpression(expr)) { + return false; + } + if (this.tsUtils.trueSymbolAtLocation(expr.expression) !== arraySymbol) { + return false; + } + if (expr.name.text !== 'length') { + return false; } - if ( - !this.options.arkts2 && - !!exprSym && - this.tsUtils.isStdSymbolAPI(exprSym) && - !ALLOWED_STD_SYMBOL_API.includes(exprSym.getName()) - ) { - this.incrementCounters(propertyAccessNode, FaultID.SymbolType); - } - if (this.options.advancedClassChecks && this.tsUtils.isClassObjectExpression(propertyAccessNode.expression)) { - // missing exact rule - this.incrementCounters(propertyAccessNode.expression, FaultID.ClassAsObject); - } + return true; + } - if (!!baseExprSym && TsUtils.symbolHasEsObjectType(baseExprSym)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(propertyAccessNode, faultId); - } - if (TsUtils.isSendableFunction(baseExprType) || this.tsUtils.hasSendableTypeAlias(baseExprType)) { - this.incrementCounters(propertyAccessNode, FaultID.SendableFunctionProperty); + private checkBodyHasArrayAccess(loopBody: ts.Block): ArrayAccess | undefined { + let arrayAccessResult: undefined | ArrayAccess; + // check if this element access expression is of an array. + for (const child of loopBody.statements) { + const result = this.checkElementAccessOfArray(child); + if (!result) { + continue; + } + arrayAccessResult = result; } - this.checkFunctionProperty(propertyAccessNode, baseExprSym, baseExprType); + return arrayAccessResult; } - checkFunctionProperty( - node: ts.PropertyAccessExpression, - baseExprSym: ts.Symbol | undefined, - baseExprType: ts.Type - ): void { - if (!this.options.arkts2) { + private checkArrayUsageWithoutBound(accessExpr: ts.ElementAccessExpression): void { + if (!this.options.arkts2 || !this.useStatic) { return; } - if ( - baseExprSym && TsUtils.isFunctionSymbol(baseExprSym) || - this.tsUtils.isStdFunctionType(baseExprType) || - TsUtils.isFunctionalType(baseExprType) && TsUtils.isAnonymousType(baseExprType) - ) { - this.incrementCounters(node.expression, FaultID.PropertyDeclOnFunction); - } - } - - checkUnionTypes(propertyAccessNode: ts.PropertyAccessExpression): void { - if (!this.options.arkts2) { + const arrayAccessInfo = this.isElementAccessOfArray(accessExpr); + if (!arrayAccessInfo) { return; } - const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); - if (!baseExprType.isUnion()) { + + const { arrayIdent } = arrayAccessInfo; + const arraySym = this.tsUtils.trueSymbolAtLocation(arrayIdent); + if (!arraySym) { return; } - const allType = baseExprType.types; - const commonPropertyType = allType.filter((type) => { - return this.tsUtils.findProperty(type, propertyAccessNode.name.getText()) !== undefined; - }); - const typeMap = new Map(); - if (commonPropertyType.length === allType.length) { - allType.forEach((type) => { - const propertySymbol = this.tsUtils.findProperty(type, propertyAccessNode.name.getText()); - if (propertySymbol?.declarations) { - const propertyType = this.tsTypeChecker.getTypeOfSymbolAtLocation( - propertySymbol, - propertySymbol.declarations[0] - ); - typeMap.set(propertyType, propertyAccessNode.name.getText()); - } - }); - if (typeMap.size > 1) { - this.incrementCounters(propertyAccessNode, FaultID.AvoidUnionTypes); + const sourceFile = arrayIdent.getSourceFile(); + let boundChecked = true; + + for (const statement of sourceFile.statements) { + const checkResult = this.checkStatementForArrayAccess(statement, arrayAccessInfo, arraySym); + if (checkResult === CheckResult.SKIP) { + boundChecked = false; + continue; + } + + if (checkResult === CheckResult.HAS_ARRAY_ACCES) { + continue; + } + + if (checkResult === CheckResult.CHECKED) { + boundChecked = true; + break; } } - } - private handleLiteralAsPropertyName(node: ts.PropertyDeclaration): void { - const propName = node.name; - if (!!propName && (ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { - const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyName(propName); - this.incrementCounters(node.name, FaultID.LiteralAsPropertyName, autofix); + if (!boundChecked) { + this.incrementCounters(arrayIdent.parent, FaultID.RuntimeArrayCheck); } } - private handlePropertyDeclaration(node: ts.PropertyDeclaration): void { - this.handleDataObservation(node); - const propName = node.name; - if (!!propName && (ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { - const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyName(propName); - this.incrementCounters(node.name, FaultID.LiteralAsPropertyName, autofix); - } - this.handleLiteralAsPropertyName(node); - const decorators = ts.getDecorators(node); - this.filterOutDecoratorsDiagnostics( - decorators, - this.options.useRtLogic ? NON_INITIALIZABLE_PROPERTY_DECORATORS : NON_INITIALIZABLE_PROPERTY_DECORATORS_TSC, - { begin: propName.getStart(), end: propName.getStart() }, - PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE - ); - const classDecorators = ts.getDecorators(node.parent); - const propType = node.type?.getText(); - if (this.options.arkts2 && propType === 'void' && node.type) { - this.incrementCounters(node.type, FaultID.LimitedVoidType); - } - this.filterOutDecoratorsDiagnostics( - classDecorators, - NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS, - { begin: propName.getStart(), end: propName.getStart() }, - PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE, - propType - ); - if (node.type && node.initializer) { - this.checkAssignmentMatching(node, this.tsTypeChecker.getTypeAtLocation(node.type), node.initializer, true); - this.checkFunctionTypeCompatible(node.type, node.initializer); + private checkStatementForArrayAccess( + statement: ts.Statement, + accessInfo: ArrayAccess, + arraySym: ts.Symbol + ): CheckResult { + if (ts.isForStatement(statement)) { + return this.isThisArrayAccess(statement.statement as ts.Block, accessInfo.arrayIdent); } - this.handleDeclarationInferredType(node); - this.handleDefiniteAssignmentAssertion(node); - this.handleSendableClassProperty(node); - this.checkAssignmentNumericSemanticslyPro(node); - this.handleInvalidIdentifier(node); - this.handleStructPropertyDecl(node); - } - private handleSendableClassProperty(node: ts.PropertyDeclaration): void { - const classNode = node.parent; - if (!ts.isClassDeclaration(classNode) || !TsUtils.hasSendableDecorator(classNode)) { - return; + if (!ts.isIfStatement(statement)) { + return CheckResult.SKIP; } - const typeNode = node.type; - if (!typeNode) { - const autofix = this.autofixer?.fixSendableExplicitFieldType(node); - this.incrementCounters(node, FaultID.SendableExplicitFieldType, autofix); - return; + + const thisArrayAccess = this.isThisArrayAccess(statement.thenStatement as ts.Block, accessInfo.arrayIdent); + if (thisArrayAccess !== CheckResult.SKIP) { + return thisArrayAccess; } - TsUtils.getDecoratorsIfInSendableClass(node)?.forEach((decorator) => { - this.incrementCounters(decorator, FaultID.SendableClassDecorator); - }); - if (!this.tsUtils.isSendableTypeNode(typeNode)) { - this.incrementCounters(node, FaultID.SendablePropType); + + const checkedAgainst = this.checkConditionForArrayAccess(statement.expression, arraySym); + if (!checkedAgainst) { + return CheckResult.SKIP; } - } - private handlePropertyAssignment(node: ts.PropertyAssignment): void { - this.handleDollarBind(node); + this.checkIfAccessAndCheckVariablesMatch(accessInfo, checkedAgainst); + return CheckResult.CHECKED; + } - const propName = node.name; - if (!(!!propName && ts.isNumericLiteral(propName))) { - return; + private isThisArrayAccess(block: ts.Block, arrayIdent: ts.Identifier): CheckResult { + const info = this.checkBodyHasArrayAccess(block); + if (!info) { + return CheckResult.SKIP; } - /* - * We can use literals as property names only when creating Record or any interop instances. - * We can also initialize with constant string literals. - * Assignment with string enum values is handled in handleComputedPropertyName - */ - let isRecordObjectInitializer = false; - let isLibraryType = false; - let isDynamic = false; - const objectLiteralType = this.tsTypeChecker.getContextualType(node.parent); - if (objectLiteralType) { - isRecordObjectInitializer = this.tsUtils.checkTypeSet(objectLiteralType, this.tsUtils.isStdRecordType); - isLibraryType = this.tsUtils.isLibraryType(objectLiteralType); + if (info.arrayIdent === arrayIdent) { + return CheckResult.CHECKED; } - isDynamic = isLibraryType || this.tsUtils.isDynamicLiteralInitializer(node.parent); - if (!isRecordObjectInitializer && !isDynamic) { - const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyAssignment(node); - this.incrementCounters(node.name, FaultID.LiteralAsPropertyName, autofix); - } + return CheckResult.HAS_ARRAY_ACCES; } - private static getAllClassesFromSourceFile(sourceFile: ts.SourceFile): ts.ClassDeclaration[] { - const allClasses: ts.ClassDeclaration[] = []; - function visit(node: ts.Node): void { - if (ts.isClassDeclaration(node)) { - allClasses.push(node); + private isChangedAfterCheck(sourceFile: ts.SourceFile, sym: ts.Symbol): boolean { + for (const statement of sourceFile.statements) { + if (!ts.isExpressionStatement(statement)) { + continue; } - ts.forEachChild(node, visit); - } - visit(sourceFile); - return allClasses; - } - - private static getAllInterfaceFromSourceFile(sourceFile: ts.SourceFile): ts.InterfaceDeclaration[] { - const allInterfaces: ts.InterfaceDeclaration[] = []; - function visit(node: ts.Node): void { - if (ts.isInterfaceDeclaration(node)) { - allInterfaces.push(node); + if (!ts.isBinaryExpression(statement.expression)) { + continue; + } + if (!ts.isIdentifier(statement.expression.left)) { + continue; + } + if (statement.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { + continue; } - ts.forEachChild(node, visit); - } - visit(sourceFile); - return allInterfaces; - } - private handlePropertySignature(node: ts.PropertySignature): void { - const propName = node.name; - this.handleInterfaceProperty(node); - if (!!propName && (ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { - const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyName(propName); - this.incrementCounters(node.name, FaultID.LiteralAsPropertyName, autofix); - } - if (!!propName && (ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { - const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyName(propName); - this.incrementCounters(node.name, FaultID.LiteralAsPropertyName, autofix); - } - this.handleSendableInterfaceProperty(node); - this.handleInvalidIdentifier(node); - } + const leftSym = this.tsUtils.trueSymbolAtLocation(statement.expression.left); + if (!leftSym) { + continue; + } - private handleInterfaceProperty(node: ts.PropertySignature): void { - if (this.options.arkts2 && ts.isInterfaceDeclaration(node.parent)) { - if (node.type && ts.isFunctionTypeNode(node.type)) { - const interfaceName = node.parent.name.getText(); - const propertyName = node.name.getText(); - const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile!); - const allInterfaces = TypeScriptLinter.getAllInterfaceFromSourceFile(this.sourceFile!); - this.visitClassMembers(allClasses, interfaceName, propertyName); - this.visitInterfaceMembers(allInterfaces, interfaceName, propertyName); + if (leftSym === sym) { + return true; } + continue; } + + return false; } - private visitInterfaceMembers( - interfaces: ts.InterfaceDeclaration[], - interfaceName: string, - propertyName: string - ): void { - void this; - interfaces.some((interfaceDecl) => { - const implementsClause = this.getExtendsClause(interfaceDecl); - if ( - implementsClause?.types.some((type) => { - return type.getText() === interfaceName; - }) - ) { - this.checkInterfaceForProperty(interfaceDecl, propertyName); - } - }); + private handleForInStatement(node: ts.Node): void { + const tsForInStmt = node as ts.ForInStatement; + const tsForInInit = tsForInStmt.initializer; + this.checkForLoopDestructuring(tsForInInit); + this.incrementCounters(node, FaultID.ForInStatement); } - private getExtendsClause(interfaceDecl: ts.InterfaceDeclaration): ts.HeritageClause | undefined { - void this; - return interfaceDecl.heritageClauses?.find((clause) => { - return clause.token === ts.SyntaxKind.ExtendsKeyword; - }); + private handleForOfStatement(node: ts.Node): void { + const tsForOfStmt = node as ts.ForOfStatement; + const tsForOfInit = tsForOfStmt.initializer; + this.checkForLoopDestructuring(tsForOfInit); } - private checkInterfaceForProperty(interfaceDecl: ts.InterfaceDeclaration, propertyName: string): void { - for (const member of interfaceDecl.members) { - if (ts.isMethodSignature(member) && member.name.getText() === propertyName) { - this.incrementCounters(member, FaultID.MethodOverridingField); - } + private handleIfStatement(ifStatement: ts.IfStatement): void { + if (this.options.arkts2 && this.useStatic) { + this.checkIfStatementForArrayUsage(ifStatement); } } - private getImplementsClause(classDecl: ts.ClassDeclaration): ts.HeritageClause | undefined { - void this; - return classDecl.heritageClauses?.find((clause) => { - return clause.token === ts.SyntaxKind.ImplementsKeyword; - }); + private checkIfStatementForArrayUsage(ifStatement: ts.IfStatement): void { + if (!ts.isBlock(ifStatement.thenStatement)) { + return; + } + + const accessInfo = this.checkBodyHasArrayAccess(ifStatement.thenStatement); + if (!accessInfo) { + return; + } + const { arrayIdent } = accessInfo; + + const arraySymbol = this.tsUtils.trueSymbolAtLocation(arrayIdent); + if (!arraySymbol) { + return; + } + + const checkedAgainst = this.checkConditionForArrayAccess(ifStatement.expression, arraySymbol); + if (!checkedAgainst) { + this.incrementCounters(arrayIdent, FaultID.RuntimeArrayCheck); + return; + } + + this.checkIfAccessAndCheckVariablesMatch(accessInfo, checkedAgainst); } - private checkClassForProperty(classDecl: ts.ClassDeclaration, propertyName: string): void { - for (const member of classDecl.members) { - if (ts.isMethodDeclaration(member) && member.name.getText() === propertyName) { - this.incrementCounters(member, FaultID.MethodOverridingField); + private updateDataSdkJsonInfo(importDeclNode: ts.ImportDeclaration, importClause: ts.ImportClause): void { + const sdkInfo = TypeScriptLinter.pathMap.get(importDeclNode.moduleSpecifier.getText()); + if (sdkInfo && importClause.namedBindings) { + const namedImports = importClause.namedBindings as ts.NamedImports; + if (!namedImports.elements) { + return; } + namedImports.elements.forEach((element) => { + const elementName = element.name.getText(); + sdkInfo.forEach((info) => { + TypeScriptLinter.addOrUpdateData(this.interfaceMap, elementName, info); + }); + }); } } - private visitClassMembers(classes: ts.ClassDeclaration[], interfaceName: string, propertyName: string): void { - void this; - classes.some((classDecl) => { - const implementsClause = this.getImplementsClause(classDecl); - if ( - implementsClause?.types.some((type) => { - return type.getText() === interfaceName; - }) - ) { - this.checkClassForProperty(classDecl, propertyName); + private handleImportDeclaration(node: ts.Node): void { + // early exit via exception if cancellation was requested + this.options.cancellationToken?.throwIfCancellationRequested(); + const importDeclNode = node as ts.ImportDeclaration; + this.handleImportModule(importDeclNode); + if (this.options.arkts2) { + const importClause = importDeclNode.importClause; + if (!importClause || !importClause.name && !importClause.namedBindings) { + this.incrementCounters(node, FaultID.NoSideEffectImport); + } else { + this.updateDataSdkJsonInfo(importDeclNode, importClause); } - }); + } + if (importDeclNode.parent.statements) { + for (const stmt of importDeclNode.parent.statements) { + if (stmt === importDeclNode) { + break; + } + if (!ts.isImportDeclaration(stmt)) { + this.incrementCounters(node, FaultID.ImportAfterStatement); + break; + } + } + } + + const expr = importDeclNode.moduleSpecifier; + if (expr.kind === ts.SyntaxKind.StringLiteral) { + if (importDeclNode.assertClause) { + this.incrementCounters(importDeclNode.assertClause, FaultID.ImportAssertion); + } + const stringLiteral = expr as ts.StringLiteral; + this.handleSdkSendable(stringLiteral); + } + + // handle no side effect import in sendable module + this.handleSharedModuleNoSideEffectImport(importDeclNode); + this.handleInvalidIdentifier(importDeclNode); + this.checkStdLibConcurrencyImport(importDeclNode); + this.handleInterOpImportJs(importDeclNode); + this.checkForDeprecatedModules(node); } - private handleSendableInterfaceProperty(node: ts.PropertySignature): void { - const typeNode = node.type; - if (!typeNode) { + private checkForDeprecatedModules(node: ts.Node): void { + if (!ts.isImportDeclaration(node)) { return; } - const interfaceNode = node.parent; - const interfaceNodeType = this.tsTypeChecker.getTypeAtLocation(interfaceNode); - if (!ts.isInterfaceDeclaration(interfaceNode) || !this.tsUtils.isSendableClassOrInterface(interfaceNodeType)) { + + const deprecatedModules = ['@ohos.file.sendablePhotoAccessHelper']; + + const importDecl = node; + const moduleSpecifier = importDecl.moduleSpecifier; + + if (ts.isStringLiteral(moduleSpecifier)) { + const moduleName = moduleSpecifier.text; + if (deprecatedModules.includes(moduleName)) { + this.incrementCounters(moduleSpecifier, FaultID.SdkTypeQuery); + } + } + } + + private handleSdkSendable(tsStringLiteral: ts.StringLiteral): void { + if (!this.options.arkts2) { return; } - if (!this.tsUtils.isSendableTypeNode(typeNode)) { - this.incrementCounters(node, FaultID.SendablePropType); + + const moduleSpecifierValue = tsStringLiteral.getText(); + const sdkInfos = TypeScriptLinter.pathMap.get(moduleSpecifierValue); + + if (!sdkInfos || sdkInfos.size === 0) { + return; + } + if (moduleSpecifierValue.includes('sendable')) { + this.incrementCounters(tsStringLiteral, FaultID.SendablePropTypeFromSdk); } } - private filterOutDecoratorsDiagnostics( - decorators: readonly ts.Decorator[] | undefined, - expectedDecorators: readonly string[], - range: { begin: number; end: number }, - code: number, - propType?: string - ): void { - // Filter out non-initializable property decorators from strict diagnostics. - if (this.tscStrictDiagnostics && this.sourceFile) { - if ( - decorators?.some((decorator) => { - const decoratorName = TsUtils.getDecoratorName(decorator); - // special case for property of type CustomDialogController of the @CustomDialog-decorated class - if (expectedDecorators.includes(NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS[0])) { - return expectedDecorators.includes(decoratorName) && propType === 'CustomDialogController'; - } - return expectedDecorators.includes(decoratorName); - }) - ) { - this.filterOutDiagnostics(range, code); - } + private handleImportModule(importDeclNode: ts.ImportDeclaration): void { + if (!this.options.arkts2) { + return; } - } - private filterOutDiagnostics(range: { begin: number; end: number }, code: number): void { - // Filter out strict diagnostics within the given range with the given code. - if (!this.tscStrictDiagnostics || !this.sourceFile) { + const modulePath = importDeclNode.moduleSpecifier.getText().slice(1, -1); + if (modulePath.startsWith('./') || modulePath.startsWith('../')) { + + /* + * Reason for this method to check the oh module imports, + * We do not use relative paths when importing from OhModules, + * So we do not check the relative paths + */ return; } - const file = path.normalize(this.sourceFile.fileName); - const tscDiagnostics = this.tscStrictDiagnostics.get(file); - if (tscDiagnostics) { - const filteredDiagnostics = tscDiagnostics.filter((val) => { - if (val.code !== code) { - return true; - } - if (val.start === undefined) { - return true; - } - if (val.start < range.begin) { - return true; - } - if (val.start > range.end) { - return true; - } - return false; - }); - this.tscStrictDiagnostics.set(file, filteredDiagnostics); + if (!importDeclNode.importClause) { + return; } - } - private static isClassLikeOrIface(node: ts.Node): boolean { - return ts.isClassLike(node) || ts.isInterfaceDeclaration(node); - } + const pathParts = modulePath.split(PATH_SEPARATOR); + const etsIdx = pathParts.indexOf(ETS_PART); - private handleFunctionExpression(node: ts.Node): void { - const funcExpr = node as ts.FunctionExpression; - const isGenerator = funcExpr.asteriskToken !== undefined; - const [hasUnfixableReturnType, newRetTypeNode] = this.handleMissingReturnType(funcExpr); - const autofix = this.autofixer?.fixFunctionExpression( - funcExpr, - newRetTypeNode, - ts.getModifiers(funcExpr), - isGenerator, - hasUnfixableReturnType - ); - this.incrementCounters(funcExpr, FaultID.FunctionExpression, autofix); - if (isGenerator) { - this.incrementCounters(funcExpr, FaultID.GeneratorFunction); + if (this.options.wholeProjectPath) { + if (TsUtils.checkFileExists(etsIdx !== 0, importDeclNode, modulePath, this.options.wholeProjectPath)) { + return; + } } - if (!hasPredecessor(funcExpr, TypeScriptLinter.isClassLikeOrIface)) { - this.reportThisKeywordsInScope(funcExpr.body); + + if (TsUtils.isValidOhModulePath(modulePath) || !TsUtils.isOhModule(modulePath)) { + // Valid or paths that we do not check because they are not ohModules + return; } - if (hasUnfixableReturnType) { - this.incrementCounters(funcExpr, FaultID.LimitedReturnTypeInference); + + if (etsIdx === 0) { + const autofix = this.autofixer?.addDefaultModuleToPath(pathParts, importDeclNode); + this.incrementCounters(importDeclNode, FaultID.OhmUrlFullPath, autofix); + return; } + + const autofix = this.autofixer?.fixImportPath(pathParts, etsIdx, importDeclNode); + this.incrementCounters(importDeclNode, FaultID.OhmUrlFullPath, autofix); } - private handleArrowFunction(node: ts.Node): void { - const arrowFunc = node as ts.ArrowFunction; - if (!hasPredecessor(arrowFunc, TypeScriptLinter.isClassLikeOrIface)) { - this.reportThisKeywordsInScope(arrowFunc.body); + private handleSharedModuleNoSideEffectImport(node: ts.ImportDeclaration): void { + // check 'use shared' + if (TypeScriptLinter.inSharedModule(node) && !node.importClause) { + this.incrementCounters(node, FaultID.SharedNoSideEffectImport); } - const contextType = this.tsTypeChecker.getContextualType(arrowFunc); - if (!(contextType && this.tsUtils.isLibraryType(contextType))) { - if (!arrowFunc.type) { - this.handleMissingReturnType(arrowFunc); - } + } + + private static inSharedModule(node: ts.Node): boolean { + const sourceFile: ts.SourceFile = node.getSourceFile(); + const modulePath = path.normalize(sourceFile.fileName); + if (TypeScriptLinter.sharedModulesCache.has(modulePath)) { + return TypeScriptLinter.sharedModulesCache.get(modulePath)!; } + const isSharedModule: boolean = TsUtils.isSharedModule(sourceFile); + TypeScriptLinter.sharedModulesCache.set(modulePath, isSharedModule); + return isSharedModule; } - private handleFunctionDeclaration(node: ts.Node): void { - // early exit via exception if cancellation was requested - this.options.cancellationToken?.throwIfCancellationRequested(); + private handlePropertyAccessExpression(node: ts.Node): void { + this.handleMakeObserved(node as ts.PropertyAccessExpression); + this.handleStateStyles(node as ts.PropertyAccessExpression); + this.handleDoubleDollar(node); + this.handleQuotedHyphenPropsDeprecated(node as ts.PropertyAccessExpression); + this.handleSdkTypeQuery(node as ts.PropertyAccessExpression); + this.checkUnionTypes(node as ts.PropertyAccessExpression); + this.handleLimitedVoidTypeFromSdkOnPropertyAccessExpression(node as ts.PropertyAccessExpression); + this.checkDepricatedIsConcurrent(node as ts.PropertyAccessExpression); + this.propertyAccessExpressionForBuiltin(node as ts.PropertyAccessExpression); - const tsFunctionDeclaration = node as ts.FunctionDeclaration; - if (!tsFunctionDeclaration.type) { - this.handleMissingReturnType(tsFunctionDeclaration); + if (ts.isCallExpression(node.parent) && node === node.parent.expression) { + return; } - if (tsFunctionDeclaration.name) { - this.countDeclarationsWithDuplicateName(tsFunctionDeclaration.name, tsFunctionDeclaration); + + const propertyAccessNode = node as ts.PropertyAccessExpression; + const exprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode); + const baseExprSym = this.tsUtils.trueSymbolAtLocation(propertyAccessNode.expression); + const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); + this.handleTsInterop(propertyAccessNode, () => { + this.checkInteropForPropertyAccess(propertyAccessNode); + }); + this.propertyAccessExpressionForInterop(propertyAccessNode); + if (this.isPrototypePropertyAccess(propertyAccessNode, exprSym, baseExprSym, baseExprType)) { + this.incrementCounters(propertyAccessNode.name, FaultID.Prototype); } - if (tsFunctionDeclaration.body) { - this.reportThisKeywordsInScope(tsFunctionDeclaration.body); + if ( + !this.options.arkts2 && + !!exprSym && + this.tsUtils.isStdSymbolAPI(exprSym) && + !ALLOWED_STD_SYMBOL_API.includes(exprSym.getName()) + ) { + this.incrementCounters(propertyAccessNode, FaultID.SymbolType); } - const funcDeclParent = tsFunctionDeclaration.parent; - if (!ts.isSourceFile(funcDeclParent) && !ts.isModuleBlock(funcDeclParent)) { - const autofix = this.autofixer?.fixNestedFunction(tsFunctionDeclaration); - this.incrementCounters(tsFunctionDeclaration, FaultID.LocalFunction, autofix); + if (this.options.advancedClassChecks && this.tsUtils.isClassObjectExpression(propertyAccessNode.expression)) { + this.incrementCounters(propertyAccessNode.expression, FaultID.ClassAsObject); } - if (tsFunctionDeclaration.asteriskToken) { - this.incrementCounters(node, FaultID.GeneratorFunction); + + if (!!baseExprSym && TsUtils.symbolHasEsObjectType(baseExprSym)) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(propertyAccessNode, faultId); } - if (TsUtils.hasSendableDecoratorFunctionOverload(tsFunctionDeclaration)) { - if (!this.isSendableDecoratorValid(tsFunctionDeclaration)) { - return; - } - TsUtils.getNonSendableDecorators(tsFunctionDeclaration)?.forEach((decorator) => { - this.incrementCounters(decorator, FaultID.SendableFunctionDecorator); - }); - if (!TsUtils.hasSendableDecorator(tsFunctionDeclaration)) { - const autofix = this.autofixer?.addSendableDecorator(tsFunctionDeclaration); - this.incrementCounters(tsFunctionDeclaration, FaultID.SendableFunctionOverloadDecorator, autofix); - } - this.scanCapturedVarsInSendableScope( - tsFunctionDeclaration, - tsFunctionDeclaration, - FaultID.SendableFunctionImportedVariables - ); + if (TsUtils.isSendableFunction(baseExprType) || this.tsUtils.hasSendableTypeAlias(baseExprType)) { + this.incrementCounters(propertyAccessNode, FaultID.SendableFunctionProperty); } - this.handleTSOverload(tsFunctionDeclaration); - this.checkAssignmentNumericSemanticsFuntion(tsFunctionDeclaration); - this.handleInvalidIdentifier(tsFunctionDeclaration); + this.checkFunctionProperty(propertyAccessNode, baseExprSym, baseExprType); + this.handleSdkForConstructorFuncs(propertyAccessNode); + this.fixJsImportPropertyAccessExpression(node); } - private handleMissingReturnType( - funcLikeDecl: ts.FunctionLikeDeclaration | ts.MethodSignature - ): [boolean, ts.TypeNode | undefined] { - if (this.options.useRtLogic && funcLikeDecl.type) { - return [false, funcLikeDecl.type]; + propertyAccessExpressionForBuiltin(decl: ts.PropertyAccessExpression): void { + if (this.options.arkts2) { + this.handleSymbolIterator(decl); + this.handleGetOwnPropertyNames(decl); + this.handlePropertyDescriptorInScenarios(decl); } + } - // Note: Return type can't be inferred for function without body. - const isSignature = ts.isMethodSignature(funcLikeDecl); - if (isSignature || !funcLikeDecl.body) { - // Ambient flag is not exposed, so we apply dirty hack to make it visible - const isDeclareDeclaration = TsUtils.isAmbientNode(funcLikeDecl); - if ((isSignature || isDeclareDeclaration) && !funcLikeDecl.type) { - this.incrementCounters(funcLikeDecl, FaultID.LimitedReturnTypeInference); - } - return [false, undefined]; + propertyAccessExpressionForInterop(propertyAccessNode: ts.PropertyAccessExpression): void { + if (!this.useStatic || !this.options.arkts2) { + return; } - return this.tryAutofixMissingReturnType(funcLikeDecl); - } + const getFirstObjectNode = (propertyAccessNode: ts.PropertyAccessExpression): ts.Expression => { + let current: ts.Expression = propertyAccessNode.expression; + while (ts.isPropertyAccessExpression(current)) { + current = current.expression; + } - private tryAutofixMissingReturnType(funcLikeDecl: ts.FunctionLikeDeclaration): [boolean, ts.TypeNode | undefined] { - if (!funcLikeDecl.body) { - return [false, undefined]; + return current; } - let autofix: Autofix[] | undefined; - let newRetTypeNode: ts.TypeNode | undefined; - const isFuncExpr = ts.isFunctionExpression(funcLikeDecl); + const firstObjNode = getFirstObjectNode(propertyAccessNode); + const isFromJs = this.tsUtils.isJsImport(firstObjNode); - /* - * Currently, ArkTS can't infer return type of function, when expression - * in the return statement is a call to a function or method whose return - * value type is omitted. In that case, we attempt to prepare an autofix. - */ - let hasLimitedRetTypeInference = this.hasLimitedTypeInferenceFromReturnExpr(funcLikeDecl.body); - const tsSignature = this.tsTypeChecker.getSignatureFromDeclaration(funcLikeDecl); - if (tsSignature) { - const tsRetType = this.tsTypeChecker.getReturnTypeOfSignature(tsSignature); - if ( - !tsRetType || - !this.options.arkts2 && TsUtils.isUnsupportedType(tsRetType) || - this.options.arkts2 && this.tsUtils.isUnsupportedTypeArkts2(tsRetType) - ) { - hasLimitedRetTypeInference = true; - } else if (hasLimitedRetTypeInference) { - newRetTypeNode = this.tsTypeChecker.typeToTypeNode(tsRetType, funcLikeDecl, ts.NodeBuilderFlags.None); - if (this.autofixer !== undefined && newRetTypeNode && !isFuncExpr) { - autofix = this.autofixer.fixMissingReturnType(funcLikeDecl, newRetTypeNode); - } + if(isFromJs) { + if (ts.isBinaryExpression(propertyAccessNode.parent) && + propertyAccessNode.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { + const autofix = this.autofixer?.fixInteropBinaryExpression(propertyAccessNode.parent); + this.incrementCounters(propertyAccessNode.parent, FaultID.InteropObjectProperty, autofix); + } else { + const autofix = this.autofixer?.fixInteropPropertyAccessExpression(propertyAccessNode); + this.incrementCounters(propertyAccessNode, FaultID.InteropObjectProperty, autofix); } } - - /* - * Don't report here if in function expression context. - * See handleFunctionExpression for details. - */ - if (hasLimitedRetTypeInference && !isFuncExpr) { - this.incrementCounters(funcLikeDecl, FaultID.LimitedReturnTypeInference, autofix); - } - - return [hasLimitedRetTypeInference && !newRetTypeNode, newRetTypeNode]; } - private hasLimitedTypeInferenceFromReturnExpr(funBody: ts.ConciseBody): boolean { - let hasLimitedTypeInference = false; - const callback = (node: ts.Node): void => { - if (hasLimitedTypeInference) { - return; - } - if ( - ts.isReturnStatement(node) && - node.expression && - this.tsUtils.isCallToFunctionWithOmittedReturnType(TsUtils.unwrapParenthesized(node.expression)) - ) { - hasLimitedTypeInference = true; - } - }; - // Don't traverse other nested function-like declarations. - const stopCondition = (node: ts.Node): boolean => { - return ( - ts.isFunctionDeclaration(node) || - ts.isFunctionExpression(node) || - ts.isMethodDeclaration(node) || - ts.isAccessor(node) || - ts.isArrowFunction(node) - ); - }; - if (ts.isBlock(funBody)) { - forEachNodeInSubtree(funBody, callback, stopCondition); - } else { - const tsExpr = TsUtils.unwrapParenthesized(funBody); - hasLimitedTypeInference = this.tsUtils.isCallToFunctionWithOmittedReturnType(tsExpr); + private checkDepricatedIsConcurrent(node: ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { + return; + } + if (!ts.isCallExpression(node.parent)) { + return; } - return hasLimitedTypeInference; - } - - private isValidTypeForUnaryArithmeticOperator(type: ts.Type): boolean { - const typeFlags = type.getFlags(); - const numberLiteralFlags = ts.TypeFlags.BigIntLiteral | ts.TypeFlags.NumberLiteral; - const numberLikeFlags = ts.TypeFlags.BigIntLike | ts.TypeFlags.NumberLike; - const isNumberLike = !!(typeFlags & (numberLiteralFlags | numberLikeFlags)); - - const isAllowedNumericType = this.tsUtils.isStdBigIntType(type) || this.tsUtils.isStdNumberType(type); - return isNumberLike || isAllowedNumericType; - } + const methodName = node.name.getText(); - private handlePrefixUnaryExpression(node: ts.Node): void { - const tsUnaryArithm = node as ts.PrefixUnaryExpression; - const tsUnaryOp = tsUnaryArithm.operator; - const tsUnaryOperand = tsUnaryArithm.operand; - if ( - tsUnaryOp === ts.SyntaxKind.PlusToken || - tsUnaryOp === ts.SyntaxKind.MinusToken || - tsUnaryOp === ts.SyntaxKind.TildeToken - ) { - const tsOperatndType = this.tsTypeChecker.getTypeAtLocation(tsUnaryOperand); - const isTilde = tsUnaryOp === ts.SyntaxKind.TildeToken; - const isInvalidTilde = - isTilde && ts.isNumericLiteral(tsUnaryOperand) && !this.tsUtils.isIntegerConstantValue(tsUnaryOperand); - if (!this.isValidTypeForUnaryArithmeticOperator(tsOperatndType) || isInvalidTilde) { - this.incrementCounters(node, FaultID.UnaryArithmNotNumber); - } + if (methodName !== ISCONCURRENT) { + return; } - } - private handleBinaryExpression(node: ts.Node): void { - const tsBinaryExpr = node as ts.BinaryExpression; - const tsLhsExpr = tsBinaryExpr.left; - const tsRhsExpr = tsBinaryExpr.right; - if (isAssignmentOperator(tsBinaryExpr.operatorToken)) { - this.processBinaryAssignment(tsBinaryExpr, tsLhsExpr, tsRhsExpr); - } - const leftOperandType = this.tsTypeChecker.getTypeAtLocation(tsLhsExpr); - const typeNode = this.tsUtils.getVariableDeclarationTypeNode(tsLhsExpr); - switch (tsBinaryExpr.operatorToken.kind) { - // FaultID.BitOpWithWrongType - removed as rule #61 - case ts.SyntaxKind.CommaToken: - this.processBinaryComma(tsBinaryExpr); - break; - case ts.SyntaxKind.InstanceOfKeyword: - this.processBinaryInstanceOf(node, tsLhsExpr, leftOperandType); - break; - case ts.SyntaxKind.InKeyword: - this.incrementCounters(tsBinaryExpr.operatorToken, FaultID.InOperator); - break; - case ts.SyntaxKind.EqualsToken: - this.checkAssignmentMatching(tsBinaryExpr, leftOperandType, tsRhsExpr); - this.checkFunctionTypeCompatible(typeNode, tsRhsExpr); - this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); - break; - default: + const symbol = this.tsUtils.trueSymbolAtLocation(node.expression); + if (!symbol) { + return; } - this.checkNumericSemantics(tsBinaryExpr); - } - private processBinaryAssignment( - binaryExpr: ts.BinaryExpression, - tsLhsExpr: ts.Expression, - tsRhsExpr: ts.Expression - ): void { - this.handleDestructuringAssignment(binaryExpr, tsLhsExpr, tsRhsExpr); + if (symbol.name === TASKPOOL) { + const decl = TsUtils.getDeclaration(symbol); - if (ts.isPropertyAccessExpression(tsLhsExpr)) { - const tsLhsSymbol = this.tsUtils.trueSymbolAtLocation(tsLhsExpr); - const tsLhsBaseSymbol = this.tsUtils.trueSymbolAtLocation(tsLhsExpr.expression); - if (tsLhsSymbol && tsLhsSymbol.flags & ts.SymbolFlags.Method) { - this.incrementCounters(tsLhsExpr, FaultID.MethodReassignment); + if (!decl) { + return; } + + const sourceFile = decl.getSourceFile(); + const fileName = path.basename(sourceFile.fileName); + if ( - !this.options.arkts2 && - TsUtils.isMethodAssignment(tsLhsSymbol) && - tsLhsBaseSymbol && - (tsLhsBaseSymbol.flags & ts.SymbolFlags.Function) !== 0 + TASKPOOL_MODULES.some((moduleName) => { + return fileName.startsWith(moduleName); + }) ) { - this.incrementCounters(tsLhsExpr, FaultID.PropertyDeclOnFunction); + this.incrementCounters(node.name, FaultID.IsConcurrentDeprecated); } } } - private checkNumericSemantics(binaryExpr: ts.BinaryExpression): void { + checkFunctionProperty( + node: ts.PropertyAccessExpression, + baseExprSym: ts.Symbol | undefined, + baseExprType: ts.Type + ): void { if (!this.options.arkts2) { return; } - if (isAssignmentOperator(binaryExpr.operatorToken)) { - this.checkAssignmentNumericSemantics(binaryExpr); - } else if (binaryExpr.operatorToken.kind === ts.SyntaxKind.SlashToken) { - this.checkDivisionNumericSemantics(binaryExpr); - } - } - private checkAssignmentNumericSemantics(binaryExpr: ts.BinaryExpression): void { - const sym = this.tsTypeChecker.getSymbolAtLocation(binaryExpr.left); - if (this.tsUtils.isIntegerVariable(sym) && !this.tsUtils.isIntegerValue(binaryExpr.right)) { - this.incrementCounters(binaryExpr, FaultID.NumericSemantics); + if ( + baseExprSym && TsUtils.isFunctionSymbol(baseExprSym) || + this.tsUtils.isStdFunctionType(baseExprType) || + TsUtils.isFunctionalType(baseExprType) && TsUtils.isAnonymousType(baseExprType) + ) { + this.incrementCounters(node.expression, FaultID.PropertyDeclOnFunction); } } - private checkDivisionNumericSemantics(binaryExpr: ts.BinaryExpression): void { - if (this.tsUtils.isIntegerValue(binaryExpr.left) && this.tsUtils.isIntegerValue(binaryExpr.right)) { - this.incrementCounters(binaryExpr, FaultID.NumericSemantics); + private checkInteropForPropertyAccess(pan: ts.PropertyAccessExpression): void { + if (ts.isBinaryExpression(pan.parent)) { + this.checkAssignmentOfPan(pan.parent, pan); + } else { + const type = this.tsTypeChecker.getTypeAtLocation(pan.expression); + this.checkUsageOfTsTypes(type, pan.expression); } } - private checkAssignmentNumericSemanticsly(node: ts.VariableDeclaration): void { - if (!this.options.arkts2) { - return; - } - const initializer = node.initializer; - const name = node.name; - if (node.type || !initializer || !ts.isIdentifier(name)) { + private checkAssignmentOfPan(binaryExpr: ts.BinaryExpression, pan: ts.PropertyAccessExpression): void { + if (binaryExpr.left !== pan) { return; } - const sym = this.tsTypeChecker.getSymbolAtLocation(name); - if (!sym) { + if (binaryExpr.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { + this.incrementCounters(pan, FaultID.InteropDirectAccessToTSTypes); return; } - const type = this.tsTypeChecker.getTypeOfSymbolAtLocation(sym, name); - const typeText = this.tsTypeChecker.typeToString(type); - const isEnum = this.isNumericEnumType(type); - if (TsUtils.isNumberLike(type, typeText, isEnum)) { - const autofix = this.autofixer?.fixVariableDeclaration(node, isEnum); - this.incrementCounters(node, FaultID.NumericSemantics, autofix); - } + const rhs = binaryExpr.right; + const lhs = binaryExpr.left as ts.PropertyAccessExpression; + + const autofix = this.autofixer?.fixInteropTsType(binaryExpr, lhs, rhs); + this.incrementCounters(pan, FaultID.InteropDirectAccessToTSTypes, autofix); } - private isEnumType(type: ts.Type): boolean { - if (type.flags & ts.TypeFlags.Enum) { - return true; + private checkUsageOfTsTypes(baseType: ts.Type, node: ts.Node): void { + if (this.tsUtils.isStringType(baseType)) { + return; } - - if (type.symbol?.flags & ts.SymbolFlags.Enum) { - return true; + if (this.tsUtils.isStdNumberType(baseType)) { + return; } - - if (type.flags & ts.TypeFlags.EnumLiteral) { - return true; + if (this.tsUtils.isStdBooleanType(baseType)) { + return; } - if (type.isUnion()) { - return type.types.some((t) => { - return this.isEnumType(t); - }); - } - return false; + this.incrementCounters(node, FaultID.InteropDirectAccessToTSTypes); } - private isNumericEnumType(type: ts.Type): boolean { - if (!this.isEnumType(type)) { - return false; + checkUnionTypes(propertyAccessNode: ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { + return; } - const declarations = type.symbol?.getDeclarations() || []; - const enumMemberDecl = declarations.find(ts.isEnumMember); - if (enumMemberDecl) { - const value = this.tsTypeChecker.getConstantValue(enumMemberDecl); - return typeof value === STRINGLITERAL_NUMBER; + const baseExprType = this.tsTypeChecker.getTypeAtLocation(propertyAccessNode.expression); + if (!baseExprType.isUnion() || this.tsTypeChecker.typeToString(baseExprType) === 'ArrayBufferLike') { + return; } - - const enumDecl = declarations.find(ts.isEnumDeclaration); - if (enumDecl) { - return enumDecl.members.every((member) => { - const memberType = this.tsTypeChecker.getTypeAtLocation(member.name); - return (memberType.flags & ts.TypeFlags.NumberLike) !== 0; + const allType = baseExprType.types; + const commonPropertyType = allType.filter((type) => { + return this.tsUtils.findProperty(type, propertyAccessNode.name.getText()) !== undefined; + }); + const typeMap = new Map(); + if (commonPropertyType.length === allType.length) { + allType.forEach((type) => { + const propertySymbol = this.tsUtils.findProperty(type, propertyAccessNode.name.getText()); + if (propertySymbol?.declarations) { + const propertyType = this.tsTypeChecker.getTypeOfSymbolAtLocation( + propertySymbol, + propertySymbol.declarations[0] + ); + typeMap.set(propertyType, propertyAccessNode.name.getText()); + } }); + if (typeMap.size > 1) { + this.incrementCounters(propertyAccessNode, FaultID.AvoidUnionTypes); + } } - return false; } - private checkAssignmentNumericSemanticsFuntion(node: ts.FunctionDeclaration): void { - if (!this.options.arkts2) { - return; + private handleLiteralAsPropertyName(node: ts.PropertyDeclaration | ts.PropertySignature): void { + const propName = node.name; + if (!!propName && (ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { + const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyName(propName); + this.incrementCounters(node.name, FaultID.LiteralAsPropertyName, autofix); } - for (const param of node.parameters) { - if (param.type) { - continue; - } - const sym = this.tsTypeChecker.getSymbolAtLocation(param.name); - if (!sym) { - continue; - } + } - const type = this.tsTypeChecker.getTypeOfSymbolAtLocation(sym, param.name); - const typeText = this.tsTypeChecker.typeToString(type); - if (typeText === STRINGLITERAL_NUMBER) { - const autofix = this.autofixer?.fixParameter(param); - if (autofix) { - this.incrementCounters(node, FaultID.NumericSemantics, autofix); - } - } + private handlePropertyDeclaration(node: ts.PropertyDeclaration): void { + const propName = node.name; + this.handleLiteralAsPropertyName(node); + const decorators = ts.getDecorators(node); + this.filterOutDecoratorsDiagnostics( + decorators, + this.options.useRtLogic ? NON_INITIALIZABLE_PROPERTY_DECORATORS : NON_INITIALIZABLE_PROPERTY_DECORATORS_TSC, + { begin: propName.getStart(), end: propName.getStart() }, + PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE + ); + const classDecorators = ts.getDecorators(node.parent); + const propType = node.type?.getText(); + if (this.options.arkts2 && propType === 'void' && node.type) { + this.incrementCounters(node.type, FaultID.LimitedVoidType); } - if (!node.type) { - const signature = this.tsTypeChecker.getSignatureFromDeclaration(node); - if (!signature) { - return; - } - const retType = this.tsTypeChecker.getReturnTypeOfSignature(signature); - if ((retType.getFlags() & ts.TypeFlags.Number) !== 0) { - const returnTypeNode = this.tsTypeChecker.typeToTypeNode(retType, node, ts.NodeBuilderFlags.None); - if (!returnTypeNode) { - return; - } - const autofix = this.autofixer?.fixMissingReturnType(node, returnTypeNode); - this.incrementCounters(node, FaultID.NumericSemantics, autofix); - } + this.filterOutDecoratorsDiagnostics( + classDecorators, + NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS, + { begin: propName.getStart(), end: propName.getStart() }, + PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE, + propType + ); + if (node.type && node.initializer) { + this.checkAssignmentMatching(node, this.tsTypeChecker.getTypeAtLocation(node.type), node.initializer, true); + this.checkFunctionTypeCompatible(node.type, node.initializer); } + this.handleDeclarationInferredType(node); + this.handleDefiniteAssignmentAssertion(node); + this.handleSendableClassProperty(node); + this.checkAssignmentNumericSemanticslyPro(node); + this.handleInvalidIdentifier(node); + this.handleStructPropertyDecl(node); + this.handlePropertyDeclarationForProp(node); + this.handleSdkDuplicateDeclName(node); + this.handleObjectLiteralAssignmentToClass(node); } - private checkAssignmentNumericSemanticslyPro(node: ts.PropertyDeclaration): void { - if (!this.options.arkts2) { + private handleSendableClassProperty(node: ts.PropertyDeclaration): void { + const classNode = node.parent; + if (!ts.isClassDeclaration(classNode) || !TsUtils.hasSendableDecorator(classNode)) { return; } - - const initializer = node.initializer; - const name = node.name; - if (node.type || !initializer || !ts.isIdentifier(name)) { + const typeNode = node.type; + if (!typeNode) { + const autofix = this.autofixer?.fixSendableExplicitFieldType(node); + this.incrementCounters(node, FaultID.SendableExplicitFieldType, autofix); return; } + TsUtils.getDecoratorsIfInSendableClass(node)?.forEach((decorator) => { + this.incrementCounters(decorator, FaultID.SendableClassDecorator); + }); + if (!this.tsUtils.isSendableTypeNode(typeNode)) { + this.incrementCounters(node, FaultID.SendablePropType); + } + } - const isNumberArray = ts.isArrayLiteralExpression(initializer) && TypeScriptLinter.isNumberArray(initializer); - const isNumber = !isNumberArray && TypeScriptLinter.isNumericInitializer(initializer); + private handlePropertyAssignment(node: ts.PropertyAssignment): void { + this.handleDollarBind(node); - const sym = this.tsTypeChecker.getSymbolAtLocation(name); - if (!sym) { + this.handleQuotedHyphenPropsDeprecated(node); + const propName = node.name; + if (!propName || !(ts.isNumericLiteral(propName) || this.options.arkts2 && ts.isStringLiteral(propName))) { return; } - if (!isNumber && !isNumberArray) { - return; + /* + * We can use literals as property names only when creating Record or any interop instances. + * We can also initialize with constant string literals. + * Assignment with string enum values is handled in handleComputedPropertyName + */ + let isRecordObjectInitializer = false; + let isLibraryType = false; + let isDynamic = false; + const objectLiteralType = this.tsTypeChecker.getContextualType(node.parent); + if (objectLiteralType) { + isRecordObjectInitializer = this.tsUtils.checkTypeSet(objectLiteralType, this.tsUtils.isStdRecordType); + isLibraryType = this.tsUtils.isLibraryType(objectLiteralType); } - const type = this.tsTypeChecker.getTypeOfSymbolAtLocation(sym, name); - const typeText = this.tsTypeChecker.typeToString(type); - const typeFlags = type.flags; - if (isNumber && (typeText === STRINGLITERAL_NUMBER || (typeFlags & ts.TypeFlags.NumberLiteral) !== 0)) { - const autofix = this.autofixer?.fixPropertyDeclaration(node); - this.incrementCounters(node, FaultID.NumericSemantics, autofix); + + isDynamic = isLibraryType || this.tsUtils.isDynamicLiteralInitializer(node.parent); + if (!isRecordObjectInitializer && !isDynamic) { + const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyAssignment(node); + this.incrementCounters(node.name, FaultID.LiteralAsPropertyName, autofix); } - this.checkAssignmentNumericSemanticsArray(node, isNumberArray); } - checkAssignmentNumericSemanticsArray(node: ts.PropertyDeclaration, isNumberArray: boolean): void { - if (isNumberArray) { - const autofix = this.autofixer?.fixPropertyDeclarationNumericSemanticsArray(node); - this.incrementCounters(node, FaultID.NumericSemantics, autofix); + private static getAllClassesFromSourceFile(sourceFile: ts.SourceFile): ts.ClassDeclaration[] { + const allClasses: ts.ClassDeclaration[] = []; + function visit(node: ts.Node): void { + if (ts.isClassDeclaration(node)) { + allClasses.push(node); + } + ts.forEachChild(node, visit); } + visit(sourceFile); + return allClasses; } - private static isNumericInitializer(node: ts.Node): boolean { - if (ts.isNumericLiteral(node)) { - return true; + private static getAllInterfaceFromSourceFile(sourceFile: ts.SourceFile): ts.InterfaceDeclaration[] { + const allInterfaces: ts.InterfaceDeclaration[] = []; + function visit(node: ts.Node): void { + if (ts.isInterfaceDeclaration(node)) { + allInterfaces.push(node); + } + ts.forEachChild(node, visit); } - if ( - ts.isPrefixUnaryExpression(node) && - node.operator === ts.SyntaxKind.MinusToken && - ts.isNumericLiteral(node.operand) - ) { - return true; + visit(sourceFile); + return allInterfaces; + } + + private handlePropertySignature(node: ts.PropertySignature): void { + this.handleInterfaceProperty(node); + this.handleLiteralAsPropertyName(node); + this.handleSendableInterfaceProperty(node); + this.handleInvalidIdentifier(node); + const typeNode = node.type; + if (this.options.arkts2 && typeNode && typeNode.kind === ts.SyntaxKind.VoidKeyword) { + this.incrementCounters(typeNode, FaultID.LimitedVoidType); } - return false; } - private static isNumberArray(arrayLiteral: ts.ArrayLiteralExpression): boolean { - return arrayLiteral.elements.every((element) => { - if (ts.isSpreadElement(element)) { - return false; + private handleInterfaceProperty(node: ts.PropertySignature): void { + if (this.options.arkts2 && ts.isInterfaceDeclaration(node.parent)) { + if (node.type && ts.isFunctionTypeNode(node.type)) { + const interfaceName = node.parent.name.getText(); + const propertyName = node.name.getText(); + const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile); + const allInterfaces = TypeScriptLinter.getAllInterfaceFromSourceFile(this.sourceFile); + this.visitClassMembers(allClasses, interfaceName, propertyName); + this.visitInterfaceMembers(allInterfaces, interfaceName, propertyName); } - return TypeScriptLinter.isNumericInitializer(element); - }); + } } - private handleDestructuringAssignment(node: ts.Node, tsLhsExpr: ts.Expression, tsRhsExpr: ts.Expression): void { - if (ts.isObjectLiteralExpression(tsLhsExpr)) { - const autofix = this.autofixer?.fixObjectLiteralExpressionDestructAssignment(node as ts.BinaryExpression); - this.incrementCounters(node, FaultID.DestructuringAssignment, autofix); - } else if (ts.isArrayLiteralExpression(tsLhsExpr)) { - // Array destructuring is allowed only for Arrays/Tuples and without spread operator. - const rhsType = this.tsTypeChecker.getTypeAtLocation(tsRhsExpr); - const isArrayOrTuple = - this.tsUtils.isOrDerivedFrom(rhsType, this.tsUtils.isArray) || - this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple); - const hasNestedObjectDestructuring = TsUtils.hasNestedObjectDestructuring(tsLhsExpr); - + private visitInterfaceMembers( + interfaces: ts.InterfaceDeclaration[], + interfaceName: string, + propertyName: string + ): void { + void this; + interfaces.some((interfaceDecl) => { + const implementsClause = this.getExtendsClause(interfaceDecl); if ( - !this.options.useRelaxedRules || - !isArrayOrTuple || - hasNestedObjectDestructuring || - TsUtils.destructuringAssignmentHasSpreadOperator(tsLhsExpr) + implementsClause?.types.some((type) => { + return type.expression.getText() === interfaceName; + }) ) { - const autofix = this.autofixer?.fixArrayBindingPatternAssignment(node as ts.BinaryExpression, isArrayOrTuple); - this.incrementCounters(node, FaultID.DestructuringAssignment, autofix); + this.checkInterfaceForProperty(interfaceDecl, propertyName); } - } + }); } - private processBinaryComma(tsBinaryExpr: ts.BinaryExpression): void { - // CommaOpertor is allowed in 'for' statement initalizer and incrementor - let tsExprNode: ts.Node = tsBinaryExpr; - let tsParentNode = tsExprNode.parent; - while (tsParentNode && tsParentNode.kind === ts.SyntaxKind.BinaryExpression) { - tsExprNode = tsParentNode; - tsParentNode = tsExprNode.parent; - if ((tsExprNode as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken) { - // Need to return if one comma enclosed in expression with another comma to avoid multiple reports on one line - return; - } - } - if (tsParentNode && tsParentNode.kind === ts.SyntaxKind.ForStatement) { - const tsForNode = tsParentNode as ts.ForStatement; - if (tsExprNode === tsForNode.initializer || tsExprNode === tsForNode.incrementor) { - return; - } - } - if (tsParentNode && tsParentNode.kind === ts.SyntaxKind.ExpressionStatement) { - const autofix = this.autofixer?.fixCommaOperator(tsExprNode); - this.incrementCounters(tsExprNode, FaultID.CommaOperator, autofix); - return; - } - - this.incrementCounters(tsBinaryExpr as ts.Node, FaultID.CommaOperator); + private getExtendsClause(interfaceDecl: ts.InterfaceDeclaration): ts.HeritageClause | undefined { + void this; + return interfaceDecl.heritageClauses?.find((clause) => { + return clause.token === ts.SyntaxKind.ExtendsKeyword; + }); } - private processBinaryInstanceOf(node: ts.Node, tsLhsExpr: ts.Expression, leftOperandType: ts.Type): void { - const leftExpr = TsUtils.unwrapParenthesized(tsLhsExpr); - const leftSymbol = this.tsUtils.trueSymbolAtLocation(leftExpr); - - /* - * In ETS, the left-hand side expression may be of any reference type, otherwise - * a compile-time error occurs. In addition, the left operand in ETS cannot be a type. - */ - if (tsLhsExpr.kind === ts.SyntaxKind.ThisKeyword) { - return; + private checkInterfaceForProperty(interfaceDecl: ts.InterfaceDeclaration, propertyName: string): void { + for (const member of interfaceDecl.members) { + if (ts.isMethodSignature(member) && member.name.getText() === propertyName) { + this.incrementCounters(member, FaultID.MethodOverridingField); + } } + } - if (TsUtils.isPrimitiveType(leftOperandType) || ts.isTypeNode(leftExpr) || TsUtils.isTypeSymbol(leftSymbol)) { - this.incrementCounters(node, FaultID.InstanceofUnsupported); - } + private getImplementsClause(classDecl: ts.ClassDeclaration): ts.HeritageClause | undefined { + void this; + return classDecl.heritageClauses?.find((clause) => { + return clause.token === ts.SyntaxKind.ImplementsKeyword; + }); } - private handleVariableDeclarationList(node: ts.Node): void { - const varDeclFlags = ts.getCombinedNodeFlags(node); - if (!(varDeclFlags & (ts.NodeFlags.Let | ts.NodeFlags.Const))) { - const autofix = this.autofixer?.fixVarDeclaration(node as ts.VariableDeclarationList); - this.incrementCounters(node, FaultID.VarDeclaration, autofix); + private checkClassForProperty(classDecl: ts.ClassDeclaration, propertyName: string): void { + for (const member of classDecl.members) { + if (ts.isMethodDeclaration(member) && member.name.getText() === propertyName) { + this.incrementCounters(member, FaultID.MethodOverridingField); + } } } - private handleVariableDeclaration(node: ts.Node): void { - const tsVarDecl = node as ts.VariableDeclaration; - if ( - !this.options.useRtLogic || - ts.isVariableDeclarationList(tsVarDecl.parent) && ts.isVariableStatement(tsVarDecl.parent.parent) - ) { - this.handleDeclarationDestructuring(tsVarDecl); - } - - // Check variable declaration for duplicate name. - this.checkVarDeclForDuplicateNames(tsVarDecl.name); - - if (tsVarDecl.type && tsVarDecl.initializer) { - this.checkAssignmentMatching( - tsVarDecl, - this.tsTypeChecker.getTypeAtLocation(tsVarDecl.type), - tsVarDecl.initializer - ); - this.checkFunctionTypeCompatible(tsVarDecl.type, tsVarDecl.initializer); - } - this.handleEsObjectDelaration(tsVarDecl); - this.handleDeclarationInferredType(tsVarDecl); - this.handleDefiniteAssignmentAssertion(tsVarDecl); - this.handleLimitedVoidType(tsVarDecl); - this.handleInvalidIdentifier(tsVarDecl); - this.checkAssignmentNumericSemanticsly(tsVarDecl); - } - - private handleDeclarationDestructuring(decl: ts.VariableDeclaration | ts.ParameterDeclaration): void { - const faultId = ts.isVariableDeclaration(decl) ? FaultID.DestructuringDeclaration : FaultID.DestructuringParameter; - if (ts.isObjectBindingPattern(decl.name)) { - const autofix = this.autofixer?.fixObjectBindingPatternDeclarations(decl, faultId); - this.incrementCounters(decl, faultId, autofix); - } else if (ts.isArrayBindingPattern(decl.name)) { - // Array destructuring is allowed only for Arrays/Tuples and without spread operator. - const rhsType = this.tsTypeChecker.getTypeAtLocation(decl.initializer ?? decl.name); - const isArrayOrTuple = - rhsType && - (this.tsUtils.isOrDerivedFrom(rhsType, this.tsUtils.isArray) || - this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple)); - const hasNestedObjectDestructuring = TsUtils.hasNestedObjectDestructuring(decl.name); - + private visitClassMembers(classes: ts.ClassDeclaration[], interfaceName: string, propertyName: string): void { + void this; + classes.some((classDecl) => { + const implementsClause = this.getImplementsClause(classDecl); if ( - !this.options.useRelaxedRules || - !isArrayOrTuple || - hasNestedObjectDestructuring || - TsUtils.destructuringDeclarationHasSpreadOperator(decl.name) + implementsClause?.types.some((type) => { + return type.expression.getText() === interfaceName; + }) ) { - const autofix = this.autofixer?.fixArrayBindingPatternDeclarations(decl, isArrayOrTuple); - this.incrementCounters(decl, faultId, autofix); + this.checkClassForProperty(classDecl, propertyName); } - } + }); } - private checkVarDeclForDuplicateNames(tsBindingName: ts.BindingName): void { - if (ts.isIdentifier(tsBindingName)) { - // The syntax kind of the declaration is defined here by the parent of 'BindingName' node. - this.countDeclarationsWithDuplicateName(tsBindingName, tsBindingName, tsBindingName.parent.kind); + private handleSendableInterfaceProperty(node: ts.PropertySignature): void { + const typeNode = node.type; + if (!typeNode) { return; } - for (const tsBindingElem of tsBindingName.elements) { - if (ts.isOmittedExpression(tsBindingElem)) { - continue; - } - - this.checkVarDeclForDuplicateNames(tsBindingElem.name); - } - } - - private handleEsObjectDelaration(node: ts.VariableDeclaration): void { - const isDeclaredESObject = !!node.type && TsUtils.isEsObjectType(node.type); - const initalizerTypeNode = node.initializer && this.tsUtils.getVariableDeclarationTypeNode(node.initializer); - const isInitializedWithESObject = !!initalizerTypeNode && TsUtils.isEsObjectType(initalizerTypeNode); - const isLocal = TsUtils.isInsideBlock(node); - if ((isDeclaredESObject || isInitializedWithESObject) && !isLocal) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(node, faultId); + const interfaceNode = node.parent; + const interfaceNodeType = this.tsTypeChecker.getTypeAtLocation(interfaceNode); + if (!ts.isInterfaceDeclaration(interfaceNode) || !this.tsUtils.isSendableClassOrInterface(interfaceNodeType)) { return; } + if (!this.tsUtils.isSendableTypeNode(typeNode)) { + this.incrementCounters(node, FaultID.SendablePropType); + } + } - if (node.initializer) { - this.handleEsObjectAssignment(node, node.type, node.initializer); + private filterOutDecoratorsDiagnostics( + decorators: readonly ts.Decorator[] | undefined, + expectedDecorators: readonly string[], + range: { begin: number; end: number }, + code: number, + propType?: string + ): void { + // Filter out non-initializable property decorators from strict diagnostics. + if (this.tscStrictDiagnostics && this.sourceFile) { + if ( + decorators?.some((decorator) => { + const decoratorName = TsUtils.getDecoratorName(decorator); + // special case for property of type CustomDialogController of the @CustomDialog-decorated class + if (expectedDecorators.includes(NON_INITIALIZABLE_PROPERTY_CLASS_DECORATORS[0])) { + return expectedDecorators.includes(decoratorName) && propType === 'CustomDialogController'; + } + return expectedDecorators.includes(decoratorName); + }) + ) { + this.filterOutDiagnostics(range, code); + } } } - private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node): void { - const isTypeAnnotated = !!nodeDeclType; - const isDeclaredESObject = isTypeAnnotated && TsUtils.isEsObjectType(nodeDeclType); - const initalizerTypeNode = this.tsUtils.getVariableDeclarationTypeNode(initializer); - const isInitializedWithESObject = !!initalizerTypeNode && TsUtils.isEsObjectType(initalizerTypeNode); - if (isTypeAnnotated && !isDeclaredESObject && isInitializedWithESObject) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(node, faultId); + private filterOutDiagnostics(range: { begin: number; end: number }, code: number): void { + // Filter out strict diagnostics within the given range with the given code. + if (!this.tscStrictDiagnostics || !this.sourceFile) { return; } - - if (isDeclaredESObject && !this.tsUtils.isValueAssignableToESObject(initializer)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(node, faultId); + const file = path.normalize(this.sourceFile.fileName); + const tscDiagnostics = this.tscStrictDiagnostics.get(file); + if (tscDiagnostics) { + const filteredDiagnostics = tscDiagnostics.filter((val) => { + if (val.code !== code) { + return true; + } + if (val.start === undefined) { + return true; + } + if (val.start < range.begin) { + return true; + } + if (val.start > range.end) { + return true; + } + return false; + }); + this.tscStrictDiagnostics.set(file, filteredDiagnostics); } } - private handleCatchClause(node: ts.Node): void { - const tsCatch = node as ts.CatchClause; - - /* - * In TS catch clause doesn't permit specification of the exception varible type except 'any' or 'unknown'. - * It is not compatible with ETS 'catch' where the exception variable has to be of type - * Error or derived from it. - * So each 'catch' which has explicit type for the exception object goes to problems. - */ - if (tsCatch.variableDeclaration?.type) { - const autofix = this.autofixer?.dropTypeOnVarDecl(tsCatch.variableDeclaration); - this.incrementCounters(node, FaultID.CatchWithUnsupportedType, autofix); - } + private static isClassLikeOrIface(node: ts.Node): boolean { + return ts.isClassLike(node) || ts.isInterfaceDeclaration(node); } - private handleClassExtends(tsClassDecl: ts.ClassDeclaration): void { - if (!this.options.arkts2) { - return; + private handleFunctionExpression(node: ts.Node): void { + const funcExpr = node as ts.FunctionExpression; + const isGenerator = funcExpr.asteriskToken !== undefined; + const [hasUnfixableReturnType, newRetTypeNode] = this.handleMissingReturnType(funcExpr); + const autofix = this.autofixer?.fixFunctionExpression( + funcExpr, + newRetTypeNode, + ts.getModifiers(funcExpr), + isGenerator, + hasUnfixableReturnType + ); + this.incrementCounters(funcExpr, FaultID.FunctionExpression, autofix); + if (isGenerator) { + this.incrementCounters(funcExpr, FaultID.GeneratorFunction); } - const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile!); - const classMap = new Map(); - allClasses.forEach((classDecl) => { - if (classDecl.name && !classDecl.heritageClauses) { - classMap.set(classDecl.name.getText(), classDecl); - } - }); - if (!tsClassDecl.heritageClauses) { - return; + if (!hasPredecessor(funcExpr, TypeScriptLinter.isClassLikeOrIface)) { + this.reportThisKeywordsInScope(funcExpr.body); + } + if (hasUnfixableReturnType) { + this.incrementCounters(funcExpr, FaultID.LimitedReturnTypeInference); } - tsClassDecl.heritageClauses.forEach((clause) => { - clause.types.forEach((type) => { - const baseClassName = type.expression.getText(); - const baseClass = classMap.get(baseClassName); - if (baseClass && ts.isClassDeclaration(baseClass)) { - this.checkMembersConsistency(tsClassDecl, baseClass); - } - }); - }); } - private checkMembersConsistency(derivedClass: ts.ClassDeclaration, baseClass: ts.ClassDeclaration): void { - const baseMethods = new Set(); - baseClass.members.forEach((member) => { - if (ts.isMethodDeclaration(member)) { - baseMethods.add(member.name.getText()); - } - }); - derivedClass.members.forEach((member) => { - const memberName = member.name?.getText(); - if (memberName && baseMethods.has(memberName)) { - if (ts.isPropertyDeclaration(member)) { - this.incrementCounters(member, FaultID.MethodOverridingField); - } + private handleArrowFunction(node: ts.Node): void { + const arrowFunc = node as ts.ArrowFunction; + if (!hasPredecessor(arrowFunc, TypeScriptLinter.isClassLikeOrIface)) { + this.reportThisKeywordsInScope(arrowFunc.body); + } + const contextType = this.tsTypeChecker.getContextualType(arrowFunc); + if (!(contextType && this.tsUtils.isLibraryType(contextType))) { + if (!arrowFunc.type) { + this.handleMissingReturnType(arrowFunc); } - }); + } + this.checkDefaultParamBeforeRequired(arrowFunc); } - private handleClassDeclaration(node: ts.Node): void { + private handleFunctionDeclaration(node: ts.Node): void { // early exit via exception if cancellation was requested this.options.cancellationToken?.throwIfCancellationRequested(); - const tsClassDecl = node as ts.ClassDeclaration; - this.handleClassExtends(tsClassDecl); - if (tsClassDecl.name) { - this.countDeclarationsWithDuplicateName(tsClassDecl.name, tsClassDecl); + const tsFunctionDeclaration = node as ts.FunctionDeclaration; + if (!tsFunctionDeclaration.type) { + this.handleMissingReturnType(tsFunctionDeclaration); } - this.countClassMembersWithDuplicateName(tsClassDecl); - - const isSendableClass = TsUtils.hasSendableDecorator(tsClassDecl); - if (isSendableClass) { - TsUtils.getNonSendableDecorators(tsClassDecl)?.forEach((decorator) => { - this.incrementCounters(decorator, FaultID.SendableClassDecorator); - }); - tsClassDecl.typeParameters?.forEach((typeParamDecl) => { - this.checkSendableTypeParameter(typeParamDecl); - }); + if (tsFunctionDeclaration.name) { + this.countDeclarationsWithDuplicateName(tsFunctionDeclaration.name, tsFunctionDeclaration); } - - if (tsClassDecl.heritageClauses) { - for (const hClause of tsClassDecl.heritageClauses) { - if (!hClause) { - continue; - } - this.checkClassDeclarationHeritageClause(hClause, isSendableClass); - } + if (tsFunctionDeclaration.body) { + this.reportThisKeywordsInScope(tsFunctionDeclaration.body); } - - // Check captured variables for sendable class - if (isSendableClass) { - tsClassDecl.members.forEach((classMember) => { - this.scanCapturedVarsInSendableScope(classMember, tsClassDecl, FaultID.SendableCapturedVars); - }); + const funcDeclParent = tsFunctionDeclaration.parent; + if (!ts.isSourceFile(funcDeclParent) && !ts.isModuleBlock(funcDeclParent)) { + const autofix = this.autofixer?.fixNestedFunction(tsFunctionDeclaration); + this.incrementCounters(tsFunctionDeclaration, FaultID.LocalFunction, autofix); } - - this.processClassStaticBlocks(tsClassDecl); - this.handleInvalidIdentifier(tsClassDecl); - } - - private handleNotSupportCustomDecorators(decorator: ts.Decorator): void { - if (!this.options.arkts2) { - return; + if (tsFunctionDeclaration.asteriskToken) { + this.incrementCounters(node, FaultID.GeneratorFunction); } + if (TsUtils.hasSendableDecoratorFunctionOverload(tsFunctionDeclaration)) { + if (!this.isSendableDecoratorValid(tsFunctionDeclaration)) { + return; + } + TsUtils.getNonSendableDecorators(tsFunctionDeclaration)?.forEach((decorator) => { + this.incrementCounters(decorator, FaultID.SendableFunctionDecorator); + }); + if (!TsUtils.hasSendableDecorator(tsFunctionDeclaration)) { + const autofix = this.autofixer?.addSendableDecorator(tsFunctionDeclaration); + this.incrementCounters(tsFunctionDeclaration, FaultID.SendableFunctionOverloadDecorator, autofix); + } + this.scanCapturedVarsInSendableScope( + tsFunctionDeclaration, + tsFunctionDeclaration, + FaultID.SendableFunctionImportedVariables + ); + } + this.handleTSOverload(tsFunctionDeclaration); + this.checkAssignmentNumericSemanticsFuntion(tsFunctionDeclaration); + this.handleInvalidIdentifier(tsFunctionDeclaration); + this.checkDefaultParamBeforeRequired(tsFunctionDeclaration); + } - let decoratorName; - if (ts.isCallExpression(decorator.expression)) { - decoratorName = decorator.expression.expression.getText(this.sourceFile); - } else { - decoratorName = decorator.expression.getText(this.sourceFile); + private handleMissingReturnType( + funcLikeDecl: ts.FunctionLikeDeclaration | ts.MethodSignature + ): [boolean, ts.TypeNode | undefined] { + if (this.options.useRtLogic && funcLikeDecl.type) { + return [false, funcLikeDecl.type]; } - if (!DEFAULT_DECORATOR_WHITE_LIST.includes(decoratorName)) { - this.incrementCounters(decorator, FaultID.DecoratorsNotSupported); + + // Note: Return type can't be inferred for function without body. + const isSignature = ts.isMethodSignature(funcLikeDecl); + if (isSignature || !funcLikeDecl.body) { + // Ambient flag is not exposed, so we apply dirty hack to make it visible + const isDeclareDeclaration = TsUtils.isAmbientNode(funcLikeDecl); + if ((isSignature || isDeclareDeclaration) && !funcLikeDecl.type) { + this.incrementCounters(funcLikeDecl, FaultID.LimitedReturnTypeInference); + } + return [false, undefined]; } + + return this.tryAutofixMissingReturnType(funcLikeDecl); } - private checkClassDeclarationHeritageClause(hClause: ts.HeritageClause, isSendableClass: boolean): void { - for (const tsTypeExpr of hClause.types) { + private tryAutofixMissingReturnType(funcLikeDecl: ts.FunctionLikeDeclaration): [boolean, ts.TypeNode | undefined] { + if (!funcLikeDecl.body) { + return [false, undefined]; + } - /* - * Always resolve type from 'tsTypeExpr' node, not from 'tsTypeExpr.expression' node, - * as for the latter, type checker will return incorrect type result for classes in - * 'extends' clause. Additionally, reduce reference, as mostly type checker returns - * the TypeReference type objects for classes and interfaces. - */ - const tsExprType = TsUtils.reduceReference(this.tsTypeChecker.getTypeAtLocation(tsTypeExpr)); - const isSendableBaseType = this.tsUtils.isSendableClassOrInterface(tsExprType); - if (tsExprType.isClass() && hClause.token === ts.SyntaxKind.ImplementsKeyword) { - this.incrementCounters(tsTypeExpr, FaultID.ImplementsClass); - } - if (!isSendableClass) { - // Non-Sendable class can not implements sendable interface / extends sendable class - if (isSendableBaseType) { - const autofix = this.autofixer?.addClassSendableDecorator(hClause, tsTypeExpr); - this.incrementCounters(tsTypeExpr, FaultID.SendableClassInheritance, autofix); - } - continue; - } + let autofix: Autofix[] | undefined; + let newRetTypeNode: ts.TypeNode | undefined; + const isFuncExpr = ts.isFunctionExpression(funcLikeDecl); - /* - * Sendable class can implements any interface / extends only sendable class - * Sendable class can not extends sendable class variable(local / import) - */ - if (hClause.token === ts.SyntaxKind.ExtendsKeyword) { - if (!isSendableBaseType) { - this.incrementCounters(tsTypeExpr, FaultID.SendableClassInheritance); - continue; - } - if (!this.tsUtils.isValidSendableClassExtends(tsTypeExpr)) { - this.incrementCounters(tsTypeExpr, FaultID.SendableClassInheritance); + /* + * Currently, ArkTS can't infer return type of function, when expression + * in the return statement is a call to a function or method whose return + * value type is omitted. In that case, we attempt to prepare an autofix. + */ + let hasLimitedRetTypeInference = this.hasLimitedTypeInferenceFromReturnExpr(funcLikeDecl.body); + const tsSignature = this.tsTypeChecker.getSignatureFromDeclaration(funcLikeDecl); + if (tsSignature) { + const tsRetType = this.tsTypeChecker.getReturnTypeOfSignature(tsSignature); + if ( + !tsRetType || + !this.options.arkts2 && TsUtils.isUnsupportedType(tsRetType) || + this.options.arkts2 && this.tsUtils.isUnsupportedTypeArkts2(tsRetType) + ) { + hasLimitedRetTypeInference = true; + } else if (hasLimitedRetTypeInference) { + newRetTypeNode = this.tsTypeChecker.typeToTypeNode(tsRetType, funcLikeDecl, ts.NodeBuilderFlags.None); + if (this.autofixer !== undefined && newRetTypeNode && !isFuncExpr) { + autofix = this.autofixer.fixMissingReturnType(funcLikeDecl, newRetTypeNode); } } } + + /* + * Don't report here if in function expression context. + * See handleFunctionExpression for details. + */ + if (hasLimitedRetTypeInference && !isFuncExpr) { + this.incrementCounters(funcLikeDecl, FaultID.LimitedReturnTypeInference, autofix); + } + + return [hasLimitedRetTypeInference && !newRetTypeNode, newRetTypeNode]; } - private checkSendableTypeParameter(typeParamDecl: ts.TypeParameterDeclaration): void { - const defaultTypeNode = typeParamDecl.default; - if (defaultTypeNode) { - if (!this.tsUtils.isSendableTypeNode(defaultTypeNode)) { - this.incrementCounters(defaultTypeNode, FaultID.SendableGenericTypes); + private hasLimitedTypeInferenceFromReturnExpr(funBody: ts.ConciseBody): boolean { + let hasLimitedTypeInference = false; + const callback = (node: ts.Node): void => { + if (hasLimitedTypeInference) { + return; + } + if ( + ts.isReturnStatement(node) && + node.expression && + this.tsUtils.isCallToFunctionWithOmittedReturnType(TsUtils.unwrapParenthesized(node.expression)) + ) { + hasLimitedTypeInference = true; } + }; + // Don't traverse other nested function-like declarations. + const stopCondition = (node: ts.Node): boolean => { + return ( + ts.isFunctionDeclaration(node) || + ts.isFunctionExpression(node) || + ts.isMethodDeclaration(node) || + ts.isAccessor(node) || + ts.isArrowFunction(node) + ); + }; + if (ts.isBlock(funBody)) { + forEachNodeInSubtree(funBody, callback, stopCondition); + } else { + const tsExpr = TsUtils.unwrapParenthesized(funBody); + hasLimitedTypeInference = this.tsUtils.isCallToFunctionWithOmittedReturnType(tsExpr); } + return hasLimitedTypeInference; } - private processClassStaticBlocks(classDecl: ts.ClassDeclaration): void { - let staticBlocksCntr = 0; - const staticBlockNodes: ts.Node[] = []; - for (const element of classDecl.members) { - if (ts.isClassStaticBlockDeclaration(element)) { - staticBlockNodes[staticBlocksCntr] = element; - staticBlocksCntr++; + private isValidTypeForUnaryArithmeticOperator(type: ts.Type): boolean { + const typeFlags = type.getFlags(); + const numberLiteralFlags = ts.TypeFlags.BigIntLiteral | ts.TypeFlags.NumberLiteral; + const numberLikeFlags = ts.TypeFlags.BigIntLike | ts.TypeFlags.NumberLike; + const isNumberLike = !!(typeFlags & (numberLiteralFlags | numberLikeFlags)); + + const isAllowedNumericType = this.tsUtils.isStdBigIntType(type) || this.tsUtils.isStdNumberType(type); + + return isNumberLike || isAllowedNumericType; + } + + private handleInteropOperand(tsUnaryArithm: ts.PrefixUnaryExpression): void { + const processPropertyAccess = (expr: ts.PropertyAccessExpression | ts.ParenthesizedExpression): void => { + const propertyAccess = ts.isParenthesizedExpression(expr) ? expr.expression : expr; + + if (ts.isPropertyAccessExpression(propertyAccess)) { + const exprSym = this.tsUtils.trueSymbolAtLocation(propertyAccess); + const declaration = exprSym?.declarations?.[0]; + this.checkAndProcessDeclaration(declaration, tsUnaryArithm); } + }; + + if (ts.isPropertyAccessExpression(tsUnaryArithm.operand) || ts.isParenthesizedExpression(tsUnaryArithm.operand)) { + processPropertyAccess(tsUnaryArithm.operand); } - if (staticBlocksCntr > 1) { - const autofix = this.autofixer?.fixMultipleStaticBlocks(staticBlockNodes); - // autofixes for all additional static blocks are the same - for (let i = 1; i < staticBlocksCntr; i++) { - this.incrementCounters(staticBlockNodes[i], FaultID.MultipleStaticBlocks, autofix); + } + + private checkAndProcessDeclaration( + declaration: ts.Declaration | undefined, + tsUnaryArithm: ts.PrefixUnaryExpression + ): void { + if (declaration?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { + if ( + [ + ts.SyntaxKind.PlusToken, + ts.SyntaxKind.ExclamationToken, + ts.SyntaxKind.TildeToken, + ts.SyntaxKind.MinusToken + ].includes(tsUnaryArithm.operator) + ) { + const autofix = this.autofixer?.fixInteropInterfaceConvertNum(tsUnaryArithm); + this.incrementCounters(tsUnaryArithm, FaultID.InteropNoHaveNum, autofix); } } } - private handleModuleDeclaration(node: ts.Node): void { - // early exit via exception if cancellation was requested - this.options.cancellationToken?.throwIfCancellationRequested(); + private handlePostfixUnaryExpression(node: ts.Node): void { + const unaryExpr = node as ts.PostfixUnaryExpression; + if (unaryExpr.operator === ts.SyntaxKind.PlusPlusToken || unaryExpr.operator === ts.SyntaxKind.MinusMinusToken) { + this.checkAutoIncrementDecrement(unaryExpr); + } + } - const tsModuleDecl = node as ts.ModuleDeclaration; + private handlePrefixUnaryExpression(node: ts.Node): void { + const tsUnaryArithm = node as ts.PrefixUnaryExpression; + if (this.useStatic && this.options.arkts2) { + const tsUnaryArithm = node as ts.PrefixUnaryExpression; + this.handleInteropOperand(tsUnaryArithm); + } + const tsUnaryOp = tsUnaryArithm.operator; + const tsUnaryOperand = tsUnaryArithm.operand; + if ( + tsUnaryOp === ts.SyntaxKind.PlusToken || + tsUnaryOp === ts.SyntaxKind.MinusToken || + tsUnaryOp === ts.SyntaxKind.TildeToken + ) { + const tsOperatndType = this.tsTypeChecker.getTypeAtLocation(tsUnaryOperand); + const isTilde = tsUnaryOp === ts.SyntaxKind.TildeToken; + const isInvalidTilde = + isTilde && ts.isNumericLiteral(tsUnaryOperand) && !this.tsUtils.isIntegerConstantValue(tsUnaryOperand); + if (!this.isValidTypeForUnaryArithmeticOperator(tsOperatndType) || isInvalidTilde) { + this.incrementCounters(node, FaultID.UnaryArithmNotNumber); + } + } + if ( + tsUnaryArithm.operator === ts.SyntaxKind.PlusPlusToken || + tsUnaryArithm.operator === ts.SyntaxKind.MinusMinusToken + ) { + this.checkAutoIncrementDecrement(tsUnaryArithm); + } + } - this.countDeclarationsWithDuplicateName(tsModuleDecl.name, tsModuleDecl); + private handleBinaryExpression(node: ts.Node): void { + const tsBinaryExpr = node as ts.BinaryExpression; + const tsLhsExpr = tsBinaryExpr.left; + const tsRhsExpr = tsBinaryExpr.right; + if (isAssignmentOperator(tsBinaryExpr.operatorToken)) { + this.processBinaryAssignment(tsBinaryExpr, tsLhsExpr, tsRhsExpr); + } + const leftOperandType = this.tsTypeChecker.getTypeAtLocation(tsLhsExpr); + const typeNode = this.tsUtils.getVariableDeclarationTypeNode(tsLhsExpr); + switch (tsBinaryExpr.operatorToken.kind) { + // FaultID.BitOpWithWrongType - removed as rule #61 + case ts.SyntaxKind.CommaToken: + this.processBinaryComma(tsBinaryExpr); + break; + case ts.SyntaxKind.InstanceOfKeyword: + this.processBinaryInstanceOf(node, tsLhsExpr, leftOperandType); + this.handleInstanceOfExpression(tsBinaryExpr); + break; + case ts.SyntaxKind.InKeyword: + this.incrementCounters(tsBinaryExpr.operatorToken, FaultID.InOperator); + break; + case ts.SyntaxKind.EqualsToken: + this.handleTsInterop(tsLhsExpr, () => { + this.checkUsageOfTsTypes(leftOperandType, tsBinaryExpr); + }); + this.checkAssignmentMatching(tsBinaryExpr, leftOperandType, tsRhsExpr); + this.checkFunctionTypeCompatible(typeNode, tsRhsExpr); + this.handleEsObjectAssignment(tsBinaryExpr, typeNode, tsRhsExpr); + this.handleSdkDuplicateDeclName(tsBinaryExpr); + this.checkArrayTypeImmutable(tsBinaryExpr); + break; + case ts.SyntaxKind.AmpersandAmpersandEqualsToken: + case ts.SyntaxKind.QuestionQuestionEqualsToken: + case ts.SyntaxKind.BarBarEqualsToken: + if (this.options.arkts2) { + this.incrementCounters(tsBinaryExpr.operatorToken, FaultID.UnsupportOperator); + } + break; + default: + } + this.checkInterOpImportJsDataCompare(tsBinaryExpr); + this.checkInteropEqualityJudgment(tsBinaryExpr); + this.handleNumericBigintCompare(tsBinaryExpr); + this.handleArkTSPropertyAccess(tsBinaryExpr); + this.handleObjectLiteralAssignmentToClass(tsBinaryExpr); + } - const tsModuleBody = tsModuleDecl.body; - const tsModifiers = ts.getModifiers(tsModuleDecl); - if (tsModuleBody) { - if (ts.isModuleBlock(tsModuleBody)) { - this.handleModuleBlock(tsModuleBody); + private checkInterOpImportJsDataCompare(expr: ts.BinaryExpression): void { + if (!this.useStatic || !this.options.arkts2 || !TypeScriptLinter.isComparisonOperator(expr.operatorToken.kind)) { + return; + } + + const processExpression = (expr: ts.Expression): void => { + const symbol = this.tsUtils.trueSymbolAtLocation(expr); + if (this.isJsFileSymbol(symbol) || this.isJsFileExpression(expr)) { + this.incrementCounters(expr, FaultID.InterOpImportJsDataCompare); } + }; + + processExpression(expr.left); + processExpression(expr.right); + } + + private static isComparisonOperator(kind: ts.SyntaxKind): boolean { + return [ + ts.SyntaxKind.GreaterThanToken, + ts.SyntaxKind.LessThanToken, + ts.SyntaxKind.GreaterThanEqualsToken, + ts.SyntaxKind.LessThanEqualsToken + ].includes(kind); + } + + private isJsFileSymbol(symbol: ts.Symbol | undefined): boolean { + if (!symbol) { + return false; } - if ( - this.options.arkts2 && + const declaration = symbol.declarations?.[0]; + if (!declaration || !ts.isVariableDeclaration(declaration)) { + return false; + } + + const initializer = declaration.initializer; + return initializer ? this.isJsFileExpression(initializer) : false; + } + + private isJsFileExpression(expr: ts.Expression): boolean { + if (ts.isPropertyAccessExpression(expr)) { + const initializerSym = this.tsUtils.trueSymbolAtLocation(expr.expression); + return initializerSym?.declarations?.[0]?.getSourceFile()?.fileName.endsWith(EXTNAME_JS) ?? false; + } + return expr.getSourceFile()?.fileName.endsWith(EXTNAME_JS) ?? false; + } + + private checkInteropEqualityJudgment(tsBinaryExpr: ts.BinaryExpression): void { + if (this.useStatic && this.options.arkts2) { + switch (tsBinaryExpr.operatorToken.kind) { + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + if (this.tsUtils.isJsImport(tsBinaryExpr.left) || this.tsUtils.isJsImport(tsBinaryExpr.right)) { + const autofix = this.autofixer?.fixInteropEqualityOperator(tsBinaryExpr, tsBinaryExpr.operatorToken.kind); + this.incrementCounters(tsBinaryExpr, FaultID.InteropEqualityJudgment, autofix); + } + break; + default: + } + } + } + + private handleTsInterop(nodeToCheck: ts.Node, handler: { (): void }): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + const declarationNode = this.tsUtils.getDeclarationNode(nodeToCheck); + if (!declarationNode) { + return; + } + + const fileName = declarationNode.getSourceFile().fileName; + if (fileName.includes(ARKTS_IGNORE_DIRS_OH_MODULES)) { + return; + } + if (!fileName.endsWith(EXTNAME_TS)) { + return; + } + + if (fileName.endsWith(EXTNAME_D_TS)) { + return; + } + + handler(); + } + + private handleJsInterop(nodeToCheck: ts.Node, handler: { (): void }): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + const declarationNode = this.tsUtils.getDeclarationNode(nodeToCheck); + if (!declarationNode) { + return; + } + + const fileName = declarationNode.getSourceFile().fileName; + if (fileName.includes(ARKTS_IGNORE_DIRS_OH_MODULES)) { + return; + } + if (!fileName.endsWith(EXTNAME_JS)) { + return; + } + + if (fileName.endsWith(EXTNAME_D_TS)) { + return; + } + + handler(); + } + + private processBinaryAssignment( + binaryExpr: ts.BinaryExpression, + tsLhsExpr: ts.Expression, + tsRhsExpr: ts.Expression + ): void { + this.handleDestructuringAssignment(binaryExpr, tsLhsExpr, tsRhsExpr); + + if (ts.isPropertyAccessExpression(tsLhsExpr)) { + const tsLhsSymbol = this.tsUtils.trueSymbolAtLocation(tsLhsExpr); + const tsLhsBaseSymbol = this.tsUtils.trueSymbolAtLocation(tsLhsExpr.expression); + if (tsLhsSymbol && tsLhsSymbol.flags & ts.SymbolFlags.Method) { + this.incrementCounters(tsLhsExpr, FaultID.MethodReassignment); + } + if ( + !this.options.arkts2 && + TsUtils.isMethodAssignment(tsLhsSymbol) && + tsLhsBaseSymbol && + (tsLhsBaseSymbol.flags & ts.SymbolFlags.Function) !== 0 + ) { + this.incrementCounters(tsLhsExpr, FaultID.PropertyDeclOnFunction); + } + } + } + + private checkAssignmentNumericSemanticsly(node: ts.VariableDeclaration): void { + if (!this.options.arkts2) { + return; + } + const initializer = node.initializer; + const name = node.name; + if (node.type || !initializer || !ts.isIdentifier(name)) { + return; + } + + // Early return if the variable is imported from JS + if (this.tsUtils.isPossiblyImportedFromJS(name) || this.tsUtils.isPossiblyImportedFromJS(initializer)) { + return; + } + + if ( + ts.isBinaryExpression(initializer) && + ts.isCallExpression(initializer.left) && + TsUtils.isAppStorageAccess(initializer.left) + ) { + return; + } + + const sym = this.tsTypeChecker.getSymbolAtLocation(name); + if (!sym) { + return; + } + + const type = this.tsTypeChecker.getTypeOfSymbolAtLocation(sym, name); + const typeText = this.tsTypeChecker.typeToString(type); + const isEnum = this.isNumericEnumType(type); + if (TsUtils.isNumberLike(type, typeText, isEnum)) { + const autofix = this.autofixer?.fixVariableDeclaration(node, isEnum); + this.incrementCounters(node, FaultID.NumericSemantics, autofix); + } + } + + private isEnumType(type: ts.Type): boolean { + if (type.flags & ts.TypeFlags.Enum) { + return true; + } + + if (type.symbol?.flags & ts.SymbolFlags.Enum) { + return true; + } + + if (type.flags & ts.TypeFlags.EnumLiteral) { + return true; + } + + if (type.isUnion()) { + return type.types.some((t) => { + return this.isEnumType(t); + }); + } + return false; + } + + private isNumericEnumType(type: ts.Type): boolean { + if (!this.isEnumType(type)) { + return false; + } + const declarations = type.symbol?.getDeclarations() || []; + const enumMemberDecl = declarations.find(ts.isEnumMember); + if (enumMemberDecl) { + const value = this.tsTypeChecker.getConstantValue(enumMemberDecl); + return typeof value === STRINGLITERAL_NUMBER; + } + + const enumDecl = declarations.find(ts.isEnumDeclaration); + if (enumDecl) { + return enumDecl.members.every((member) => { + const memberType = this.tsTypeChecker.getTypeAtLocation(member.name); + return (memberType.flags & ts.TypeFlags.NumberLike) !== 0; + }); + } + return false; + } + + private checkAssignmentNumericSemanticsFuntion(node: ts.FunctionDeclaration): void { + if (!this.options.arkts2) { + return; + } + for (const param of node.parameters) { + if (param.type) { + continue; + } + const sym = this.tsTypeChecker.getSymbolAtLocation(param.name); + if (!sym) { + continue; + } + + const type = this.tsTypeChecker.getTypeOfSymbolAtLocation(sym, param.name); + const typeText = this.tsTypeChecker.typeToString(type); + if (typeText === STRINGLITERAL_NUMBER) { + const autofix = this.autofixer?.fixParameter(param); + if (autofix) { + this.incrementCounters(node, FaultID.NumericSemantics, autofix); + } + } + } + if (!node.type) { + const signature = this.tsTypeChecker.getSignatureFromDeclaration(node); + if (!signature) { + return; + } + const retType = this.tsTypeChecker.getReturnTypeOfSignature(signature); + if ((retType.getFlags() & ts.TypeFlags.Number) !== 0) { + const returnTypeNode = this.tsTypeChecker.typeToTypeNode(retType, node, ts.NodeBuilderFlags.None); + if (!returnTypeNode) { + return; + } + const autofix = this.autofixer?.fixMissingReturnType(node, returnTypeNode); + this.incrementCounters(node, FaultID.NumericSemantics, autofix); + } + } + } + + private checkAssignmentNumericSemanticslyPro(node: ts.PropertyDeclaration): void { + if (!this.options.arkts2) { + return; + } + + const initializer = node.initializer; + const name = node.name; + if (node.type || !initializer || !ts.isIdentifier(name)) { + return; + } + + const isNumberArray = ts.isArrayLiteralExpression(initializer) && TypeScriptLinter.isNumberArray(initializer); + const isNumber = !isNumberArray && TypeScriptLinter.isNumericInitializer(initializer); + + const sym = this.tsTypeChecker.getSymbolAtLocation(name); + if (!sym) { + return; + } + + if (!isNumber && !isNumberArray) { + return; + } + const type = this.tsTypeChecker.getTypeOfSymbolAtLocation(sym, name); + const typeText = this.tsTypeChecker.typeToString(type); + const typeFlags = type.flags; + if (isNumber && (typeText === STRINGLITERAL_NUMBER || (typeFlags & ts.TypeFlags.NumberLiteral) !== 0)) { + const autofix = this.autofixer?.fixPropertyDeclaration(node); + this.incrementCounters(node, FaultID.NumericSemantics, autofix); + } + this.checkAssignmentNumericSemanticsArray(node, isNumberArray); + } + + checkAssignmentNumericSemanticsArray(node: ts.PropertyDeclaration, isNumberArray: boolean): void { + if (isNumberArray) { + const autofix = this.autofixer?.fixPropertyDeclarationNumericSemanticsArray(node); + this.incrementCounters(node, FaultID.NumericSemantics, autofix); + } + } + + private static isNumericInitializer(node: ts.Node): boolean { + if (ts.isNumericLiteral(node)) { + return true; + } + if ( + ts.isPrefixUnaryExpression(node) && + node.operator === ts.SyntaxKind.MinusToken && + ts.isNumericLiteral(node.operand) + ) { + return true; + } + return false; + } + + private static isNumberArray(arrayLiteral: ts.ArrayLiteralExpression): boolean { + return arrayLiteral.elements.every((element) => { + if (ts.isSpreadElement(element)) { + return false; + } + return TypeScriptLinter.isNumericInitializer(element); + }); + } + + private handleDestructuringAssignment(node: ts.Node, tsLhsExpr: ts.Expression, tsRhsExpr: ts.Expression): void { + if (ts.isObjectLiteralExpression(tsLhsExpr)) { + const autofix = this.autofixer?.fixObjectLiteralExpressionDestructAssignment(node as ts.BinaryExpression); + this.incrementCounters(node, FaultID.DestructuringAssignment, autofix); + } else if (ts.isArrayLiteralExpression(tsLhsExpr)) { + const rhsType = this.tsTypeChecker.getTypeAtLocation(tsRhsExpr); + const isArrayOrTuple = + this.tsUtils.isOrDerivedFrom(rhsType, this.tsUtils.isArray) || + this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple); + const hasNestedObjectDestructuring = TsUtils.hasNestedObjectDestructuring(tsLhsExpr); + + if ( + !this.options.useRelaxedRules || + !isArrayOrTuple || + hasNestedObjectDestructuring || + TsUtils.destructuringAssignmentHasSpreadOperator(tsLhsExpr) + ) { + const autofix = this.autofixer?.fixArrayBindingPatternAssignment(node as ts.BinaryExpression, isArrayOrTuple); + this.incrementCounters(node, FaultID.DestructuringAssignment, autofix); + } + } + } + + private processBinaryComma(tsBinaryExpr: ts.BinaryExpression): void { + // CommaOpertor is allowed in 'for' statement initalizer and incrementor + let tsExprNode: ts.Node = tsBinaryExpr; + let tsParentNode = tsExprNode.parent; + while (tsParentNode && tsParentNode.kind === ts.SyntaxKind.BinaryExpression) { + tsExprNode = tsParentNode; + tsParentNode = tsExprNode.parent; + if ((tsExprNode as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken) { + // Need to return if one comma enclosed in expression with another comma to avoid multiple reports on one line + return; + } + } + if (tsParentNode && tsParentNode.kind === ts.SyntaxKind.ForStatement) { + const tsForNode = tsParentNode as ts.ForStatement; + if (tsExprNode === tsForNode.initializer || tsExprNode === tsForNode.incrementor) { + return; + } + } + if (tsParentNode && tsParentNode.kind === ts.SyntaxKind.ExpressionStatement) { + const autofix = this.autofixer?.fixCommaOperator(tsExprNode); + this.incrementCounters(tsExprNode, FaultID.CommaOperator, autofix); + return; + } + + this.incrementCounters(tsBinaryExpr as ts.Node, FaultID.CommaOperator); + } + + private processBinaryInstanceOf(node: ts.Node, tsLhsExpr: ts.Expression, leftOperandType: ts.Type): void { + const leftExpr = TsUtils.unwrapParenthesized(tsLhsExpr); + const leftSymbol = this.tsUtils.trueSymbolAtLocation(leftExpr); + + /* + * In ETS, the left-hand side expression may be of any reference type, otherwise + * a compile-time error occurs. In addition, the left operand in ETS cannot be a type. + */ + if (tsLhsExpr.kind === ts.SyntaxKind.ThisKeyword) { + return; + } + + if (TsUtils.isPrimitiveType(leftOperandType) || ts.isTypeNode(leftExpr) || TsUtils.isTypeSymbol(leftSymbol)) { + this.incrementCounters(node, FaultID.InstanceofUnsupported); + } + } + + private handleVariableDeclarationList(node: ts.Node): void { + const varDeclFlags = ts.getCombinedNodeFlags(node); + if (!(varDeclFlags & (ts.NodeFlags.Let | ts.NodeFlags.Const))) { + const autofix = this.autofixer?.fixVarDeclaration(node as ts.VariableDeclarationList); + this.incrementCounters(node, FaultID.VarDeclaration, autofix); + } + } + + private handleVariableDeclaration(node: ts.Node): void { + const tsVarDecl = node as ts.VariableDeclaration; + this.handleVariableDeclarationForProp(tsVarDecl); + if ( + !this.options.useRtLogic || + ts.isVariableDeclarationList(tsVarDecl.parent) && ts.isVariableStatement(tsVarDecl.parent.parent) + ) { + this.handleDeclarationDestructuring(tsVarDecl); + } + + // Check variable declaration for duplicate name. + this.checkVarDeclForDuplicateNames(tsVarDecl.name); + + if (tsVarDecl.type && tsVarDecl.initializer) { + this.checkAssignmentMatching( + tsVarDecl, + this.tsTypeChecker.getTypeAtLocation(tsVarDecl.type), + tsVarDecl.initializer + ); + this.checkFunctionTypeCompatible(tsVarDecl.type, tsVarDecl.initializer); + } + this.handleEsValueDeclaration(tsVarDecl); + this.handleDeclarationInferredType(tsVarDecl); + this.handleDefiniteAssignmentAssertion(tsVarDecl); + this.handleLimitedVoidType(tsVarDecl); + this.handleInvalidIdentifier(tsVarDecl); + this.checkAssignmentNumericSemanticsly(tsVarDecl); + this.checkTypeFromSdk(tsVarDecl.type); + this.handleNoStructuralTyping(tsVarDecl); + this.handleObjectLiteralforUnionTypeInterop(tsVarDecl); + this.handleObjectLiteralAssignmentToClass(tsVarDecl); + this.handleObjectLiteralAssignment(tsVarDecl); + this.handlePropertyDescriptorInScenarios(tsVarDecl); + this.handleSdkDuplicateDeclName(tsVarDecl); + this.checkArrayTypeImmutable(tsVarDecl); + } + + private checkArrayTypeImmutable(node: ts.VariableDeclaration | ts.BinaryExpression): void { + if (!this.options.arkts2) { + return; + } + if (ts.isVariableDeclaration(node)) { + if (!node.initializer || ts.isArrayLiteralExpression(node.initializer)) { + return; + } + if (node.type && ts.isArrayTypeNode(node.type)) { + const varDeclType = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(node.name)); + const initializerType = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(node.initializer)); + if (varDeclType !== initializerType) { + this.incrementCounters(node, FaultID.ArrayTypeImmutable); + } + } + } else { + this.checkArrayTypeImmutableForBinaryExpression(node); + } + } + + private checkArrayTypeImmutableForBinaryExpression(node: ts.BinaryExpression): void { + const sym = this.tsTypeChecker.getSymbolAtLocation(node.left); + const declaration = sym?.declarations?.[0]; + if ( + declaration && + (ts.isVariableDeclaration(declaration) || ts.isParameter(declaration) || ts.isPropertyDeclaration(declaration)) + ) { + if (declaration.type && ts.isArrayTypeNode(declaration.type) && !ts.isArrayLiteralExpression(node.right)) { + const leftType = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(node.left)); + const rightType = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(node.right)); + if (leftType !== rightType) { + this.incrementCounters(node, FaultID.ArrayTypeImmutable); + } + } + } + } + + private checkTypeFromSdk(type: ts.TypeNode | undefined): void { + if (!this.options.arkts2 || !type) { + return; + } + + const fullTypeName = type.getText(); + const nameArr = fullTypeName.split('.'); + const sdkInfos = this.interfaceMap.get(nameArr[0]); + if (!sdkInfos || sdkInfos.size === 0) { + return; + } + + for (const sdkInfo of sdkInfos) { + if (sdkInfo.api_name && nameArr.includes(sdkInfo.api_name)) { + this.incrementCounters(type, FaultID.LimitedVoidTypeFromSdk); + return; + } + } + } + + 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)) { + const autofix = ts.isVariableDeclaration(decl) ? + this.autofixer?.fixObjectBindingPatternDeclarations(decl) : + undefined; + this.incrementCounters(decl, faultId, autofix); + } else if (ts.isArrayBindingPattern(decl.name)) { + // Array destructuring is allowed only for Arrays/Tuples and without spread operator. + const rhsType = this.tsTypeChecker.getTypeAtLocation(decl.initializer ?? decl.name); + const isArrayOrTuple = + rhsType && + (this.tsUtils.isOrDerivedFrom(rhsType, this.tsUtils.isArray) || + this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple)); + const hasNestedObjectDestructuring = TsUtils.hasNestedObjectDestructuring(decl.name); + + if ( + !this.options.useRelaxedRules || + !isArrayOrTuple || + hasNestedObjectDestructuring || + TsUtils.destructuringDeclarationHasSpreadOperator(decl.name) + ) { + const autofix = ts.isVariableDeclaration(decl) ? + this.autofixer?.fixArrayBindingPatternDeclarations(decl, isArrayOrTuple) : + undefined; + this.incrementCounters(decl, faultId, autofix); + } + } + } + + private checkVarDeclForDuplicateNames(tsBindingName: ts.BindingName): void { + if (ts.isIdentifier(tsBindingName)) { + // The syntax kind of the declaration is defined here by the parent of 'BindingName' node. + this.countDeclarationsWithDuplicateName(tsBindingName, tsBindingName, tsBindingName.parent.kind); + return; + } + for (const tsBindingElem of tsBindingName.elements) { + if (ts.isOmittedExpression(tsBindingElem)) { + continue; + } + + this.checkVarDeclForDuplicateNames(tsBindingElem.name); + } + } + + private handleEsValueDeclaration(node: ts.VariableDeclaration): void { + const isDeclaredESValue = !!node.type && TsUtils.isEsValueType(node.type); + const initalizerTypeNode = node.initializer && this.tsUtils.getVariableDeclarationTypeNode(node.initializer); + const isInitializedWithESValue = !!initalizerTypeNode && TsUtils.isEsValueType(initalizerTypeNode); + const isLocal = TsUtils.isInsideBlock(node); + if ((isDeclaredESValue || isInitializedWithESValue) && !isLocal) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(node, faultId); + return; + } + + if (node.initializer) { + this.handleEsObjectAssignment(node, node.type, node.initializer); + } + } + + private handleEsObjectAssignment(node: ts.Node, nodeDeclType: ts.TypeNode | undefined, initializer: ts.Node): void { + const isTypeAnnotated = !!nodeDeclType; + const isDeclaredESValue = isTypeAnnotated && TsUtils.isEsValueType(nodeDeclType); + const initalizerTypeNode = this.tsUtils.getVariableDeclarationTypeNode(initializer); + const isInitializedWithESValue = !!initalizerTypeNode && TsUtils.isEsValueType(initalizerTypeNode); + if (isTypeAnnotated && !isDeclaredESValue && isInitializedWithESValue) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(node, faultId); + return; + } + + if (isDeclaredESValue && !this.tsUtils.isValueAssignableToESValue(initializer)) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(node, faultId); + } + } + + private handleCatchClause(node: ts.Node): void { + const tsCatch = node as ts.CatchClause; + + /* + * In TS catch clause doesn't permit specification of the exception varible type except 'any' or 'unknown'. + * It is not compatible with ETS 'catch' where the exception variable has to be of type + * Error or derived from it. + * So each 'catch' which has explicit type for the exception object goes to problems. + */ + if (tsCatch.variableDeclaration?.type) { + const autofix = this.autofixer?.dropTypeOnVarDecl(tsCatch.variableDeclaration); + this.incrementCounters(node, FaultID.CatchWithUnsupportedType, autofix); + } + + if ( + this.options.arkts2 && + tsCatch.variableDeclaration && + TsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(tsCatch.variableDeclaration)) + ) { + this.incrementCounters(node, FaultID.TsLikeCatchType); + } + } + + private handleClassExtends(tsClassDecl: ts.ClassDeclaration): void { + if (!this.options.arkts2) { + return; + } + const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile); + const classMap = new Map(); + allClasses.forEach((classDecl) => { + if (classDecl.name && !classDecl.heritageClauses) { + classMap.set(classDecl.name.getText(), classDecl); + } + }); + if (!tsClassDecl.heritageClauses) { + return; + } + tsClassDecl.heritageClauses.forEach((clause) => { + clause.types.forEach((type) => { + const baseClassName = type.expression.getText(); + const baseClass = classMap.get(baseClassName); + if (baseClass && ts.isClassDeclaration(baseClass)) { + this.checkMembersConsistency(tsClassDecl, baseClass); + } + }); + }); + } + + private checkMembersConsistency(derivedClass: ts.ClassDeclaration, baseClass: ts.ClassDeclaration): void { + const baseMethods = new Set(); + baseClass.members.forEach((member) => { + if (ts.isMethodDeclaration(member)) { + baseMethods.add(member.name.getText()); + } + }); + derivedClass.members.forEach((member) => { + const memberName = member.name?.getText(); + if (memberName && baseMethods.has(memberName)) { + if (ts.isPropertyDeclaration(member)) { + this.incrementCounters(member, FaultID.MethodOverridingField); + } + } + }); + } + + private handleClassDeclaration(node: ts.Node): void { + // early exit via exception if cancellation was requested + this.options.cancellationToken?.throwIfCancellationRequested(); + + const tsClassDecl = node as ts.ClassDeclaration; + this.handleClassExtends(tsClassDecl); + if (tsClassDecl.name) { + this.countDeclarationsWithDuplicateName(tsClassDecl.name, tsClassDecl); + } + this.countClassMembersWithDuplicateName(tsClassDecl); + + const isSendableClass = TsUtils.hasSendableDecorator(tsClassDecl); + if (isSendableClass) { + TsUtils.getNonSendableDecorators(tsClassDecl)?.forEach((decorator) => { + this.incrementCounters(decorator, FaultID.SendableClassDecorator); + }); + tsClassDecl.typeParameters?.forEach((typeParamDecl) => { + this.checkSendableTypeParameter(typeParamDecl); + }); + } + + if (tsClassDecl.heritageClauses) { + for (const hClause of tsClassDecl.heritageClauses) { + if (!hClause) { + continue; + } + this.checkClassDeclarationHeritageClause(hClause, isSendableClass); + } + } + + // Check captured variables for sendable class + if (isSendableClass) { + tsClassDecl.members.forEach((classMember) => { + this.scanCapturedVarsInSendableScope(classMember, tsClassDecl, FaultID.SendableCapturedVars); + }); + } + + this.processClassStaticBlocks(tsClassDecl); + this.handleInvalidIdentifier(tsClassDecl); + this.handleSdkMethod(tsClassDecl); + this.handleNotsLikeSmartType(tsClassDecl); + } + + private static findFinalExpression(typeNode: ts.TypeNode): ts.Node { + let currentNode = typeNode; + + /* + * CC-OFFNXT(no_explicit_any) std lib + * Handle comment directive '@ts-nocheck' + */ + while ((currentNode as any).expression) { + + /* + * CC-OFFNXT(no_explicit_any) std lib + * Handle comment directive '@ts-nocheck' + */ + currentNode = (currentNode as any).expression; + } + return currentNode; + } + + private processSdkMethodClauseTypes( + tsClassDecl: ts.ClassDeclaration, + heritageClause: ts.HeritageClause, + methodName?: string + ): boolean { + return heritageClause.types.some((type) => { + const fullTypeName = TypeScriptLinter.findFinalExpression(type).getText(); + const sdkInfos = this.interfaceMap.get(fullTypeName); + if (!sdkInfos || sdkInfos.size === 0) { + return false; + } + + return Array.from(sdkInfos).some((sdkInfo) => { + if (sdkInfo.api_type !== METHOD_SIGNATURE && sdkInfo.api_type !== METHOD_DECLARATION) { + return false; + } + + if (!methodName) { + this.processSdkInfoWithMembers(sdkInfo, tsClassDecl.members, tsClassDecl); + return false; + } + + const symbol = this.tsTypeChecker.getSymbolAtLocation(type.expression); + return TypeScriptLinter.isHeritageClauseisThirdPartyBySymbol(symbol) && sdkInfo.api_name === methodName; + }); + }); + } + + private handleSdkMethod(tsClassDecl: ts.ClassDeclaration): void { + if ( + !this.options.arkts2 || + !tsClassDecl.heritageClauses || + tsClassDecl.heritageClauses.length === 0 || + !tsClassDecl.members || + tsClassDecl.members.length === 0 + ) { + return; + } + + for (const heritageClause of tsClassDecl.heritageClauses) { + if (!heritageClause.types || heritageClause.types.length === 0) { + continue; + } + this.processSdkMethodClauseTypes(tsClassDecl, heritageClause); + } + } + + private processSdkInfoWithMembers( + sdkInfo: ApiInfo, + members: ts.NodeArray, + tsClassDecl: ts.ClassDeclaration + ): void { + for (const member of members) { + if (!ts.isMethodDeclaration(member)) { + continue; + } + + const memberName = member.name?.getText(); + if (sdkInfo.api_name === memberName) { + if ( + !TypeScriptLinter.areParametersEqual(sdkInfo.api_func_args ?? [], member.parameters) && + !TypeScriptLinter.areGenericsParametersEqual(sdkInfo.api_func_args ?? [], tsClassDecl) + ) { + return; + } + this.incrementCounters( + member, + sdkInfo.problem === OPTIONAL_METHOD ? FaultID.OptionalMethodFromSdk : FaultID.LimitedVoidTypeFromSdk + ); + } + } + } + + private static areParametersEqual( + sdkFuncArgs: { name: string; type: string }[], + memberParams: ts.NodeArray + ): boolean { + const apiParamCout = sdkFuncArgs.length; + const memberParamCout = memberParams.length; + if (apiParamCout > memberParamCout && sdkFuncArgs[memberParamCout + 1]) { + return false; + } + + for (let i = 0; i < apiParamCout; i++) { + const typeName = memberParams[i].type?.getText(); + if (!typeName?.match(sdkFuncArgs[i].type)) { + return false; + } + } + return true; + } + + private processLimitedVoidTypeFromSdkOnClassDeclaration( + tsClassDecl: ts.ClassDeclaration, + methodName?: string + ): boolean { + if ( + !this.options.arkts2 || + !tsClassDecl.heritageClauses || + tsClassDecl.heritageClauses.length === 0 || + !tsClassDecl.members || + tsClassDecl.members.length === 0 + ) { + return false; + } + let res: boolean = false; + for (const heritageClause of tsClassDecl.heritageClauses) { + if (heritageClause.types?.length) { + res = this.processSdkMethodClauseTypes(tsClassDecl, heritageClause, methodName); + break; + } + } + return res; + } + + private static isHeritageClauseisThirdPartyBySymbol(symbol: ts.Symbol | undefined): boolean { + if (!symbol) { + return false; + } + const declarations = symbol.getDeclarations(); + if (declarations && declarations.length > 0) { + const firstDeclaration = declarations[0]; + if (ts.isImportSpecifier(firstDeclaration)) { + return true; + } + } + return false; + } + + private handleLimitedVoidTypeFromSdkOnPropertyAccessExpression(node: ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { + return; + } + const sym = this.getOriginalSymbol(node.name); + if (!sym) { + return; + } + const methodName = node.name.getText(); + const declaration = sym.declarations?.[0]; + if (declaration && ts.isClassDeclaration(declaration.parent)) { + if (this.processLimitedVoidTypeFromSdkOnClassDeclaration(declaration.parent, methodName)) { + this.incrementCounters(node, FaultID.LimitedVoidTypeFromSdk); + } + } + } + + private static areGenericsParametersEqual( + sdkFuncArgs: { name: string; type: string }[], + node: ts.ClassDeclaration + ): boolean { + if (!ts.isClassDeclaration(node)) { + return false; + } + const apiParamCout = sdkFuncArgs.length; + const typeParameters = node.typeParameters; + if (!typeParameters) { + return false; + } + typeParameters.forEach((typeParam) => { + if (!typeParam.constraint) { + return false; + } + for (let i = 0; i < apiParamCout; i++) { + if (!typeParam.constraint.getText().match(sdkFuncArgs[i].type)) { + return false; + } + } + return true; + }); + return true; + } + + private handleNotSupportCustomDecorators(decorator: ts.Decorator): void { + if (!this.options.arkts2) { + return; + } + + let decoratorName; + if (ts.isCallExpression(decorator.expression)) { + decoratorName = decorator.expression.expression.getText(this.sourceFile); + } else { + decoratorName = decorator.expression.getText(this.sourceFile); + } + if (!DEFAULT_DECORATOR_WHITE_LIST.includes(decoratorName)) { + this.incrementCounters(decorator, FaultID.DecoratorsNotSupported); + } + } + + private checkClassDeclarationHeritageClause(hClause: ts.HeritageClause, isSendableClass: boolean): void { + for (const tsTypeExpr of hClause.types) { + + /* + * Always resolve type from 'tsTypeExpr' node, not from 'tsTypeExpr.expression' node, + * as for the latter, type checker will return incorrect type result for classes in + * 'extends' clause. Additionally, reduce reference, as mostly type checker returns + * the TypeReference type objects for classes and interfaces. + */ + const tsExprType = TsUtils.reduceReference(this.tsTypeChecker.getTypeAtLocation(tsTypeExpr)); + const isSendableBaseType = this.tsUtils.isSendableClassOrInterface(tsExprType); + if (tsExprType.isClass() && hClause.token === ts.SyntaxKind.ImplementsKeyword) { + this.incrementCounters(tsTypeExpr, FaultID.ImplementsClass); + } + if (!isSendableClass) { + // Non-Sendable class can not implements sendable interface / extends sendable class + if (isSendableBaseType) { + const autofix = this.autofixer?.addClassSendableDecorator(hClause, tsTypeExpr); + this.incrementCounters(tsTypeExpr, FaultID.SendableClassInheritance, autofix); + } + continue; + } + + /* + * Sendable class can implements any interface / extends only sendable class + * Sendable class can not extends sendable class variable(local / import) + */ + if (hClause.token === ts.SyntaxKind.ExtendsKeyword) { + if (!isSendableBaseType) { + this.incrementCounters(tsTypeExpr, FaultID.SendableClassInheritance); + continue; + } + if (!this.tsUtils.isValidSendableClassExtends(tsTypeExpr)) { + this.incrementCounters(tsTypeExpr, FaultID.SendableClassInheritance); + } + } + } + } + + private checkSendableTypeParameter(typeParamDecl: ts.TypeParameterDeclaration): void { + const defaultTypeNode = typeParamDecl.default; + if (defaultTypeNode) { + if (!this.tsUtils.isSendableTypeNode(defaultTypeNode)) { + this.incrementCounters(defaultTypeNode, FaultID.SendableGenericTypes); + } + } + } + + private processClassStaticBlocks(classDecl: ts.ClassDeclaration): void { + let staticBlocksCntr = 0; + const staticBlockNodes: ts.Node[] = []; + for (const element of classDecl.members) { + if (ts.isClassStaticBlockDeclaration(element)) { + if (this.options.arkts2 && this.useStatic) { + this.incrementCounters(element, FaultID.NoStaticOnClass); + } + staticBlockNodes[staticBlocksCntr] = element; + staticBlocksCntr++; + } + } + if (staticBlocksCntr > 1) { + const autofix = this.autofixer?.fixMultipleStaticBlocks(staticBlockNodes); + // autofixes for all additional static blocks are the same + for (let i = 1; i < staticBlocksCntr; i++) { + this.incrementCounters(staticBlockNodes[i], FaultID.MultipleStaticBlocks, autofix); + } + } + } + + private handleModuleDeclaration(node: ts.Node): void { + // early exit via exception if cancellation was requested + this.options.cancellationToken?.throwIfCancellationRequested(); + + const tsModuleDecl = node as ts.ModuleDeclaration; + + this.countDeclarationsWithDuplicateName(tsModuleDecl.name, tsModuleDecl); + + if (this.options.arkts2) { + this.handleInvalidIdentifier(tsModuleDecl); + } + + const tsModuleBody = tsModuleDecl.body; + const tsModifiers = ts.getModifiers(tsModuleDecl); + if (tsModuleBody) { + if (ts.isModuleBlock(tsModuleBody)) { + this.handleModuleBlock(tsModuleBody); + } + } + + if ( + this.options.arkts2 && tsModuleBody && ts.isModuleBlock(tsModuleBody) && tsModuleDecl.flags & ts.NodeFlags.Namespace ) { - this.handleNameSpaceModuleBlock(tsModuleBody, (tsModuleDecl.name as ts.Identifier).escapedText.toString()); + this.handleNameSpaceModuleBlock(tsModuleBody, (tsModuleDecl.name as ts.Identifier).escapedText.toString()); + } + + if ( + !(tsModuleDecl.flags & ts.NodeFlags.Namespace) && + TsUtils.hasModifier(tsModifiers, ts.SyntaxKind.DeclareKeyword) + ) { + this.incrementCounters(tsModuleDecl, FaultID.ShorthandAmbientModuleDecl); + } + + if (ts.isStringLiteral(tsModuleDecl.name) && tsModuleDecl.name.text.includes('*')) { + this.incrementCounters(tsModuleDecl, FaultID.WildcardsInModuleName); + } + } + + private handleNameSpaceModuleBlock(moduleBlock: ts.ModuleBlock, nameSpace: string): void { + if (!TypeScriptLinter.nameSpaceFunctionCache.has(nameSpace)) { + TypeScriptLinter.nameSpaceFunctionCache.set(nameSpace, new Set()); + } + + const nameSet = TypeScriptLinter.nameSpaceFunctionCache.get(nameSpace)!; + + for (const statement of moduleBlock.statements) { + const names = TypeScriptLinter.getDeclarationNames(statement); + for (const name of names) { + if (nameSet.has(name)) { + this.incrementCounters(statement, FaultID.NoDuplicateFunctionName); + } else { + nameSet.add(name); + } + } + } + } + + private static getDeclarationNames(statement: ts.Statement): Set { + const names = new Set(); + + if ( + ts.isFunctionDeclaration(statement) && statement.name && statement.body || + ts.isClassDeclaration(statement) && statement.name || + ts.isInterfaceDeclaration(statement) && statement.name || + ts.isEnumDeclaration(statement) && statement.name + ) { + names.add(statement.name.text); + return names; + } + + if (ts.isVariableStatement(statement)) { + for (const decl of statement.declarationList.declarations) { + if (ts.isIdentifier(decl.name)) { + names.add(decl.name.text); + } + } + } + + return names; + } + + private handleModuleBlock(moduleBlock: ts.ModuleBlock): void { + for (const tsModuleStmt of moduleBlock.statements) { + switch (tsModuleStmt.kind) { + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.ExportDeclaration: + break; + + /* + * Nested namespace declarations are prohibited + * but there is no cookbook recipe for it! + */ + case ts.SyntaxKind.ModuleDeclaration: + break; + default: + this.incrementCounters(tsModuleStmt, FaultID.NonDeclarationInNamespace); + break; + } + } + } + + private handleTypeAliasDeclaration(node: ts.Node): void { + const tsTypeAlias = node as ts.TypeAliasDeclaration; + this.countDeclarationsWithDuplicateName(tsTypeAlias.name, tsTypeAlias); + this.handleInvalidIdentifier(tsTypeAlias); + if (TsUtils.hasSendableDecorator(tsTypeAlias)) { + if (!this.isSendableDecoratorValid(tsTypeAlias)) { + return; + } + TsUtils.getNonSendableDecorators(tsTypeAlias)?.forEach((decorator) => { + this.incrementCounters(decorator, FaultID.SendableTypeAliasDecorator); + }); + if (!ts.isFunctionTypeNode(tsTypeAlias.type)) { + this.incrementCounters(tsTypeAlias.type, FaultID.SendableTypeAliasDeclaration); + } + } + if (this.options.arkts2 && tsTypeAlias.type.kind === ts.SyntaxKind.VoidKeyword) { + this.incrementCounters(tsTypeAlias.type, FaultID.LimitedVoidType); + } + } + + private handleTupleType(node: ts.TupleTypeNode): void { + if (!this.options.arkts2) { + return; + } + + node.elements.forEach((elementType) => { + if (elementType.kind === ts.SyntaxKind.VoidKeyword) { + this.incrementCounters(elementType, FaultID.LimitedVoidType); + } + }); + } + + private handleImportClause(node: ts.Node): void { + const tsImportClause = node as ts.ImportClause; + if (this.options.arkts2 && tsImportClause.isLazy) { + const autofix = this.autofixer?.fixImportClause(tsImportClause); + this.incrementCounters(node, FaultID.ImportLazyIdentifier, autofix); + } + if (tsImportClause.name) { + this.countDeclarationsWithDuplicateName(tsImportClause.name, tsImportClause); + } + } + + private handleImportSpecifier(node: ts.Node): void { + const importSpec = node as ts.ImportSpecifier; + this.countDeclarationsWithDuplicateName(importSpec.name, importSpec); + } + + private handleNamespaceImport(node: ts.Node): void { + const tsNamespaceImport = node as ts.NamespaceImport; + this.countDeclarationsWithDuplicateName(tsNamespaceImport.name, tsNamespaceImport); + } + + private handleTypeAssertionExpression(node: ts.Node): void { + const tsTypeAssertion = node as ts.TypeAssertion; + if (tsTypeAssertion.type.getText() === 'const') { + this.incrementCounters(tsTypeAssertion, FaultID.ConstAssertion); + } else { + const autofix = this.autofixer?.fixTypeAssertion(tsTypeAssertion); + this.incrementCounters(node, FaultID.TypeAssertion, autofix); + } + } + + private handleMethodDeclaration(node: ts.Node): void { + const tsMethodDecl = node as ts.MethodDeclaration; + TsUtils.getDecoratorsIfInSendableClass(tsMethodDecl)?.forEach((decorator) => { + this.incrementCounters(decorator, FaultID.SendableClassDecorator); + }); + let isStatic = false; + if (tsMethodDecl.modifiers) { + for (const mod of tsMethodDecl.modifiers) { + if (mod.kind === ts.SyntaxKind.StaticKeyword) { + isStatic = true; + break; + } + } + } + if (tsMethodDecl.body && isStatic) { + this.reportThisKeywordsInScope(tsMethodDecl.body); + } + if (!tsMethodDecl.type) { + this.handleMissingReturnType(tsMethodDecl); + } + if (tsMethodDecl.asteriskToken) { + this.incrementCounters(node, FaultID.GeneratorFunction); + } + this.filterOutDecoratorsDiagnostics( + ts.getDecorators(tsMethodDecl), + NON_RETURN_FUNCTION_DECORATORS, + { begin: tsMethodDecl.parameters.end, end: tsMethodDecl.body?.getStart() ?? tsMethodDecl.parameters.end }, + FUNCTION_HAS_NO_RETURN_ERROR_CODE + ); + if (this.options.arkts2 && tsMethodDecl.questionToken) { + this.incrementCounters(tsMethodDecl.questionToken, FaultID.OptionalMethod); + } + this.handleInvalidIdentifier(tsMethodDecl); + if (!this.tsUtils.isAbstractMethodInAbstractClass(node)) { + this.handleTSOverload(tsMethodDecl); + } + this.checkDefaultParamBeforeRequired(tsMethodDecl); + this.handleMethodInherit(tsMethodDecl); + } + + private checkDefaultParamBeforeRequired(node: ts.FunctionLikeDeclarationBase): void { + if (!this.options.arkts2) { + return; + } + + const params = node.parameters; + let seenRequired = false; + + for (let i = params.length - 1; i >= 0; i--) { + const param = params[i]; + + const isOptional = !!param.initializer || !!param.questionToken; + + if (!isOptional) { + seenRequired = true; + continue; + } + + if (seenRequired && param.initializer) { + this.incrementCounters(param.name, FaultID.DefaultArgsBehindRequiredArgs); + } + } + } + + private handleMethodInherit(node: ts.MethodDeclaration): void { + if (!this.options.arkts2 || !node.name || !ts.isIdentifier(node.name)) { + return; + } + + const classDecl = node.parent; + if (!ts.isClassDeclaration(classDecl)) { + return; + } + + const classType = this.tsTypeChecker.getTypeAtLocation(classDecl); + const baseTypes = classType.getBaseTypes(); + if (!baseTypes || baseTypes.length === 0) { + return; + } + + const methodName = node.name.text; + + for (const baseType of baseTypes) { + const baseMethod = baseType.getProperty(methodName); + if (!baseMethod) { + continue; + } + + const baseMethodDecl = baseMethod.declarations?.find(ts.isMethodDeclaration); + if (!baseMethodDecl) { + continue; + } + + // Check parameter compatibility + this.checkMethodParameters(node, baseMethodDecl); + + // Check return type compatibility + this.checkMethodReturnType(node, baseMethodDecl); + + break; + } + } + + /** + * Checks if child parameters accept at least as many types as parent parameters. + * (Child parameter type should be same or wider than parent.) + */ + private checkMethodParameters(derivedMethod: ts.MethodDeclaration, baseMethod: ts.MethodDeclaration): void { + const derivedParams = derivedMethod.parameters; + const baseParams = baseMethod.parameters; + + const paramCount = Math.min(derivedParams.length, baseParams.length); + + for (let i = 0; i < paramCount; i++) { + const baseParamType = this.tsTypeChecker.getTypeAtLocation(baseParams[i]); + const derivedParamType = this.tsTypeChecker.getTypeAtLocation(derivedParams[i]); + + if (!this.isTypeSameOrWider(baseParamType, derivedParamType)) { + this.incrementCounters(derivedParams[i], FaultID.MethodInheritRule); + } + } + } + + /** + * Checks return type covariance between base and derived methods. + * (Derived return type must be assignable to base return type.) + */ + private checkMethodReturnType(derivedMethod: ts.MethodDeclaration, baseMethod: ts.MethodDeclaration): void { + if (!baseMethod.type || !derivedMethod.type) { + return; + } + + const baseReturnType = this.tsTypeChecker.getTypeAtLocation(baseMethod.type); + const derivedReturnType = this.tsTypeChecker.getTypeAtLocation(derivedMethod.type); + + if (!this.isTypeAssignable(derivedReturnType, baseReturnType)) { + this.incrementCounters(derivedMethod.type, FaultID.MethodInheritRule); + } + } + + /** + * Child type should include all types of parent type (be same or wider). + * Returns true if every type in baseType is also included in derivedType. + */ + private isTypeSameOrWider(baseType: ts.Type, derivedType: ts.Type): boolean { + const baseTypeSet = new Set(this.flattenUnionTypes(baseType)); + const derivedTypeSet = new Set(this.flattenUnionTypes(derivedType)); + + // Check if every type in baseType is also present in derivedType + for (const typeStr of baseTypeSet) { + if (!derivedTypeSet.has(typeStr)) { + return false; + } + } + + return true; + } + + // Checks structural assignability between two types. + private isTypeAssignable(fromType: ts.Type, toType: ts.Type): boolean { + const fromTypes = this.flattenUnionTypes(fromType); + const toTypes = new Set(this.flattenUnionTypes(toType)); + + // All types in `fromTypes` should exist in `toTypes` for assignability. + return fromTypes.every((typeStr) => { + return toTypes.has(typeStr); + }); + } + + // 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)]; + } + + private checkClassImplementsMethod(classDecl: ts.ClassDeclaration, methodName: string): boolean { + for (const member of classDecl.members) { + if (member.name?.getText() === methodName) { + if (ts.isPropertyDeclaration(member)) { + this.incrementCounters(member, FaultID.MethodOverridingField); + } + } + } + return false; + } + + private handleMethodSignature(node: ts.MethodSignature): void { + const tsMethodSign = node; + if (this.options.arkts2 && ts.isInterfaceDeclaration(node.parent)) { + const methodName = node.name.getText(); + const interfaceName = node.parent.name.getText(); + const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile); + const allInterfaces = TypeScriptLinter.getAllInterfaceFromSourceFile(this.sourceFile); + allClasses.forEach((classDecl) => { + if (this.classImplementsInterface(classDecl, interfaceName)) { + this.checkClassImplementsMethod(classDecl, methodName); + } + }); + allInterfaces.forEach((interDecl) => { + if (this.interfaceExtendsInterface(interDecl, interfaceName)) { + this.checkInterfaceExtendsMethod(interDecl, methodName); + } + }); + } + if (!tsMethodSign.type) { + this.handleMissingReturnType(tsMethodSign); + } + if (this.options.arkts2 && tsMethodSign.questionToken) { + this.incrementCounters(tsMethodSign.questionToken, FaultID.OptionalMethod); + } + this.handleInvalidIdentifier(tsMethodSign); + } + + private interfaceExtendsInterface(interDecl: ts.InterfaceDeclaration, interfaceName: string): boolean { + void this; + if (!interDecl.heritageClauses) { + return false; + } + return interDecl.heritageClauses.some((clause) => { + return clause.types.some((type) => { + return ( + ts.isExpressionWithTypeArguments(type) && + ts.isIdentifier(type.expression) && + type.expression.text === interfaceName + ); + }); + }); + } + + private checkInterfaceExtendsMethod(interDecl: ts.InterfaceDeclaration, methodName: string): void { + for (const member of interDecl.members) { + if (member.name?.getText() === methodName) { + if (ts.isPropertySignature(member)) { + this.incrementCounters(member, FaultID.MethodOverridingField); + } + } + } + } + + private classImplementsInterface(classDecl: ts.ClassDeclaration, interfaceName: string): boolean { + void this; + if (!classDecl.heritageClauses) { + return false; + } + return classDecl.heritageClauses.some((clause) => { + return clause.types.some((type) => { + return ( + ts.isExpressionWithTypeArguments(type) && + ts.isIdentifier(type.expression) && + type.expression.text === interfaceName + ); + }); + }); + } + + private handleClassStaticBlockDeclaration(node: ts.Node): void { + const classStaticBlockDecl = node as ts.ClassStaticBlockDeclaration; + if (!ts.isClassDeclaration(classStaticBlockDecl.parent)) { + return; + } + this.reportThisKeywordsInScope(classStaticBlockDecl.body); + } + + private handleIdentifier(node: ts.Node): void { + if (!ts.isIdentifier(node)) { + return; + } + this.handleInterfaceImport(node); + this.checkAsonSymbol(node); + const tsIdentifier = node; + this.handleTsInterop(tsIdentifier, () => { + const parent = tsIdentifier.parent; + if (ts.isPropertyAccessExpression(parent) || ts.isImportSpecifier(parent)) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(tsIdentifier); + this.checkUsageOfTsTypes(type, tsIdentifier); + }); + + const tsIdentSym = this.tsUtils.trueSymbolAtLocation(tsIdentifier); + if (!tsIdentSym) { + return; + } + + const isArkTs2 = this.options.arkts2; + const isGlobalThis = tsIdentifier.text === 'globalThis'; + + if ( + isGlobalThis && + (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && + (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 + ) { + this.handleGlobalThisCase(tsIdentifier, isArkTs2); + } else { + if (isArkTs2) { + this.checkLimitedStdlibApi(tsIdentifier, tsIdentSym); + } + this.handleRestrictedValues(tsIdentifier, tsIdentSym); + } + + if (isArkTs2 && this.tsTypeChecker.isArgumentsSymbol(tsIdentSym)) { + this.incrementCounters(node, FaultID.ArgumentsObject); + } + + if (isArkTs2) { + this.checkWorkerSymbol(tsIdentSym, node); + this.checkCollectionsSymbol(tsIdentSym, node); + } + } + + private handlePropertyDescriptorInScenarios(node: ts.Node): void { + if (ts.isVariableDeclaration(node)) { + const name = node.name; + this.handlePropertyDescriptor(name); + + const type = node.type; + if (!type || !ts.isTypeReferenceNode(type)) { + return; + } + const typeName = type.typeName; + this.handlePropertyDescriptor(typeName); + } + + if (ts.isParameter(node)) { + const name = node.name; + this.handlePropertyDescriptor(name); + + const type = node.type; + if (!type || !ts.isTypeReferenceNode(type)) { + return; + } + const typeName = type.typeName; + this.handlePropertyDescriptor(typeName); + } + + if (ts.isPropertyAccessExpression(node)) { + const name = node.name; + this.handlePropertyDescriptor(name); + + const expression = node.expression; + this.handlePropertyDescriptor(expression); + } + } + + private handlePropertyDescriptor(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + + const symbol = this.tsUtils.trueSymbolAtLocation(node); + if (!symbol || !ts.isIdentifier(node)) { + return; + } + const tsIdentifier = node; + const type = this.tsTypeChecker.getTypeOfSymbolAtLocation(symbol, tsIdentifier); + + const typeSymbol = type.getSymbol(); + const typeName = typeSymbol ? typeSymbol.getName() : symbol.getName(); + + const noPropertyDescriptorSet = TypeScriptLinter.globalApiInfo.get(BuiltinProblem.BuiltinNoPropertyDescriptor); + if (!noPropertyDescriptorSet) { + return; + } + + const matchedApi = [...noPropertyDescriptorSet].some((apiInfoItem) => { + if (apiInfoItem.api_info.parent_api?.length <= 0) { + return false; + } + const apiInfoParentName = apiInfoItem.api_info.parent_api[0].api_name; + const apiTypeName = apiInfoItem.api_info.method_return_type; + const isSameApi = apiInfoParentName === typeName || apiTypeName === typeName; + const decl = TsUtils.getDeclaration(typeSymbol ? typeSymbol : symbol); + const sourceFileName = path.normalize(decl?.getSourceFile().fileName || ''); + const isSameFile = sourceFileName.endsWith(path.normalize(apiInfoItem.file_path)); + return isSameFile && isSameApi; + }); + + if (matchedApi) { + this.incrementCounters(tsIdentifier, FaultID.NoPropertyDescriptor); + } + } + + private handleGlobalThisCase(node: ts.Identifier, isArkTs2: boolean | undefined): void { + let faultId = FaultID.GlobalThis; + let autofix: Autofix[] | undefined; + let targetNode: ts.Node = node; + + if (!isArkTs2) { + this.incrementCounters(targetNode, faultId); + return; + } + faultId = FaultID.GlobalThisError; + + if (ts.isPropertyAccessExpression(node.parent)) { + const parentExpression = node.parent.parent; + if ( + parentExpression && + ts.isBinaryExpression(parentExpression) && + parentExpression.operatorToken.kind === ts.SyntaxKind.EqualsToken + ) { + targetNode = parentExpression; + autofix = this.autofixer?.fixGlobalThisSet(targetNode as ts.BinaryExpression); + } else { + targetNode = node.parent; + autofix = this.autofixer?.fixGlobalThisGet(targetNode as ts.PropertyAccessExpression); + } + } + + this.incrementCounters(targetNode, faultId, autofix); + } + + // hard-coded alternative to TypeScriptLinter.advancedClassChecks + private isAllowedClassValueContext(tsIdentifier: ts.Identifier): boolean { + let ctx: ts.Node = tsIdentifier; + while (ts.isPropertyAccessExpression(ctx.parent) || ts.isQualifiedName(ctx.parent)) { + ctx = ctx.parent; + } + if (ts.isPropertyAssignment(ctx.parent) && ts.isObjectLiteralExpression(ctx.parent.parent)) { + ctx = ctx.parent.parent; + } + if (ts.isArrowFunction(ctx.parent) && ctx.parent.body === ctx) { + ctx = ctx.parent; + } + + if (ts.isCallExpression(ctx.parent) || ts.isNewExpression(ctx.parent)) { + const callee = ctx.parent.expression; + const isAny = TsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)); + const isDynamic = isAny || this.tsUtils.hasLibraryType(callee); + if (callee !== ctx && isDynamic) { + return true; + } + } + return false; + } + + private isStdlibClassVarDecl(ident: ts.Identifier, sym: ts.Symbol): boolean { + + /* + * Most standard JS classes are defined in TS stdlib as ambient global + * variables with interface constructor type and require special check + * when they are being referenced in code. + */ + + if ( + !isStdLibrarySymbol(sym) || + !sym.valueDeclaration || + !ts.isVariableDeclaration(sym.valueDeclaration) || + !TsUtils.isAmbientNode(sym.valueDeclaration) + ) { + return false; + } + + /* + * issue 24075: TS supports calling the constructor of built-in types + * as function (without 'new' keyword): `const a = Number('10')` + * Such cases need to be filtered out. + */ + if (ts.isCallExpression(ident.parent) && ident.parent.expression === ident) { + return false; + } + + const classVarDeclType = StdClassVarDecls.get(sym.name); + if (!classVarDeclType) { + return false; + } + const declType = this.tsTypeChecker.getTypeAtLocation(ident); + return declType.symbol && declType.symbol.name === classVarDeclType; + } + + private handleRestrictedValues(tsIdentifier: ts.Identifier, tsIdentSym: ts.Symbol): void { + const illegalValues = + ts.SymbolFlags.ConstEnum | + ts.SymbolFlags.RegularEnum | + ts.SymbolFlags.ValueModule | + (this.options.advancedClassChecks ? 0 : ts.SymbolFlags.Class); + + /* + * If module name is duplicated by another declaration, this increases the possibility + * of finding a lot of false positives. Thus, do not check further in that case. + */ + if ((tsIdentSym.flags & ts.SymbolFlags.ValueModule) !== 0) { + if (!!tsIdentSym && TsUtils.symbolHasDuplicateName(tsIdentSym, ts.SyntaxKind.ModuleDeclaration)) { + return; + } + } + + if ( + (tsIdentSym.flags & illegalValues) === 0 && !this.isStdlibClassVarDecl(tsIdentifier, tsIdentSym) || + isStruct(tsIdentSym) || + !identiferUseInValueContext(tsIdentifier, tsIdentSym) + ) { + return; + } + + if ((tsIdentSym.flags & ts.SymbolFlags.Class) !== 0) { + if (!this.options.advancedClassChecks && this.isAllowedClassValueContext(tsIdentifier)) { + return; + } + } + + if (tsIdentSym.flags & ts.SymbolFlags.ValueModule) { + this.incrementCounters(tsIdentifier, FaultID.NamespaceAsObject); + } else { + // missing EnumAsObject + const faultId = this.options.arkts2 ? FaultID.ClassAsObjectError : FaultID.ClassAsObject; + this.incrementCounters(tsIdentifier, faultId); + } + } + + private isElementAcessAllowed(type: ts.Type, argType: ts.Type): boolean { + if (type.isUnion()) { + for (const t of type.types) { + if (!this.isElementAcessAllowed(t, argType)) { + return false; + } + } + return true; + } + + const typeNode = this.tsTypeChecker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.None); + + if (this.tsUtils.isArkTSCollectionsArrayLikeType(type)) { + return this.tsUtils.isNumberLikeType(argType); + } + + return ( + this.tsUtils.isLibraryType(type) || + TsUtils.isAnyType(type) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isIndexableArray) || + this.tsUtils.isOrDerivedFrom(type, TsUtils.isTuple) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdRecordType) || + this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStringType) || + !this.options.arkts2 && + (this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdMapType) || TsUtils.isIntrinsicObjectType(type)) || + TsUtils.isEnumType(type) || + // we allow EsObject here beacuse it is reported later using FaultId.EsObjectType + TsUtils.isEsValueType(typeNode) + ); + } + + private handleElementAccessExpression(node: ts.Node): void { + const tsElementAccessExpr = node as ts.ElementAccessExpression; + const tsElementAccessExprSymbol = this.tsUtils.trueSymbolAtLocation(tsElementAccessExpr.expression); + const tsElemAccessBaseExprType = this.tsUtils.getNonNullableType( + this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression) + ); + const tsElemAccessArgType = this.tsTypeChecker.getTypeAtLocation(tsElementAccessExpr.argumentExpression); + + const isSet = TsUtils.isSetExpression(tsElementAccessExpr); + const isSetIndexable = + isSet && + this.tsUtils.isSetIndexableType( + tsElemAccessBaseExprType, + tsElemAccessArgType, + this.tsTypeChecker.getTypeAtLocation((tsElementAccessExpr.parent as ts.BinaryExpression).right) + ); + + const isGet = !isSet; + const isGetIndexable = isGet && this.tsUtils.isGetIndexableType(tsElemAccessBaseExprType, tsElemAccessArgType); + + if ( + // unnamed types do not have symbol, so need to check that explicitly + !this.tsUtils.isLibrarySymbol(tsElementAccessExprSymbol) && + !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && + !this.isElementAcessAllowed(tsElemAccessBaseExprType, tsElemAccessArgType) && + !(this.options.arkts2 && isGetIndexable) && + !(this.options.arkts2 && isSetIndexable) + ) { + const autofix = this.autofixer?.fixPropertyAccessByIndex(tsElementAccessExpr); + this.incrementCounters(node, FaultID.PropertyAccessByIndex, autofix); + } + + if (this.tsUtils.hasEsObjectType(tsElementAccessExpr.expression)) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(node, faultId); + } + if (this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isIndexableArray)) { + this.handleIndexNegative(node); + } + this.checkArrayUsageWithoutBound(tsElementAccessExpr); + this.checkArrayIndexType(tsElemAccessBaseExprType, tsElemAccessArgType, tsElementAccessExpr); + this.fixJsImportElementAccessExpression(tsElementAccessExpr); + this.checkInterOpImportJsIndex(tsElementAccessExpr); + this.checkEnumGetMemberValue(tsElementAccessExpr); + } + + private checkInterOpImportJsIndex(expr: ts.ElementAccessExpression): void { + if (!this.useStatic || !this.options.arkts2) { + return; + } + + const exprSym = this.tsUtils.trueSymbolAtLocation(expr.expression); + if (!exprSym) { + return; + } + + const exprDecl = TsUtils.getDeclaration(exprSym); + if (!exprDecl || !ts.isVariableDeclaration(exprDecl)) { + return; + } + + const initializer = exprDecl.initializer; + if (!initializer || !ts.isPropertyAccessExpression(initializer)) { + return; + } + + const initSym = this.tsUtils.trueSymbolAtLocation(initializer.expression); + if (!initSym) { + return; + } + + const initDecl = TsUtils.getDeclaration(initSym); + if (!initDecl?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { + return; + } + + if (ts.isBinaryExpression(expr.parent) && expr.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { + const autofix = this.autofixer?.fixInteropArrayBinaryExpression(expr.parent); + this.incrementCounters(expr.parent, FaultID.InterOpImportJsIndex, autofix); + } else { + const autofix = this.autofixer?.fixInteropArrayElementAccessExpression(expr); + this.incrementCounters(expr, FaultID.InterOpImportJsIndex, autofix); + } + } + + private checkArrayIndexType(exprType: ts.Type, argType: ts.Type, expr: ts.ElementAccessExpression): void { + if (!this.options.arkts2 || !this.tsUtils.isOrDerivedFrom(exprType, this.tsUtils.isIndexableArray)) { + return; + } + + const argExpr = TypeScriptLinter.getUnwrappedArgumentExpression(expr.argumentExpression); + const validStringLiteralTypes = [ + STRINGLITERAL_INT, + STRINGLITERAL_BYTE, + STRINGLITERAL_SHORT, + STRINGLITERAL_LONG, + STRINGLITERAL_CHAR + ]; + const argTypeString = this.tsTypeChecker.typeToString(argType); + + if (this.tsUtils.isNumberLikeType(argType)) { + this.handleNumericArgument(argExpr, expr.argumentExpression, argType); + } else if (!validStringLiteralTypes.includes(argTypeString)) { + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); + } + } + + private static getUnwrappedArgumentExpression(argExpr: ts.Expression): ts.Expression { + return argExpr.kind === ts.SyntaxKind.AsExpression ? (argExpr as ts.AsExpression).expression : argExpr; + } + + private handleNumericArgument(argExpr: ts.Expression, asExpr: ts.Expression, argType: ts.Type): void { + const isNumericLiteral = ts.isNumericLiteral(argExpr); + const isAsExpression = asExpr.kind === ts.SyntaxKind.AsExpression; + const argText = argExpr.getText(); + const argValue = Number(argText); + + if (isNumericLiteral) { + const isInteger = Number.isInteger(argValue); + const containsDot = argText.includes('.'); + + if (!isInteger || containsDot) { + const autofix = this.autofixer?.fixArrayIndexExprType(isAsExpression ? asExpr : argExpr); + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); + } + } else if (this.tsTypeChecker.typeToString(argType) === 'number') { + if (this.isArrayIndexValidNumber(argExpr)) { + return; + } + const autofix = this.autofixer?.fixArrayIndexExprType(argExpr); + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); + } else { + this.checkNumericArgumentDeclaration(argExpr); + } + + if (ts.isConditionalExpression(argExpr)) { + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); + } + } + + private checkNumericArgumentDeclaration(argExpr: ts.Expression): void { + const symbol = this.tsTypeChecker.getSymbolAtLocation(argExpr); + + if (!symbol) { + return; + } + + const declarations = symbol.getDeclarations(); + if (!declarations || declarations.length === 0) { + return; + } + + const firstDeclaration = declarations[0] as ts.VariableDeclaration; + const initializer = firstDeclaration.initializer; + const initializerText = initializer ? initializer.getText() : 'undefined'; + const isNumericInitializer = initializer && ts.isNumericLiteral(initializer); + const initializerNumber = isNumericInitializer ? Number(initializerText) : NaN; + const isUnsafeNumber = isNumericInitializer && !Number.isInteger(initializerNumber); + + if (isUnsafeNumber) { + const autofix = this.autofixer?.fixArrayIndexExprType(argExpr); + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); + } + + if (initializerText === 'undefined') { + this.handleUndefinedInitializer(argExpr, firstDeclaration); + } + } + + private evaluateValueFromDeclaration(argExpr: ts.Expression): number | null | 'skip' { + const declaration = this.tsUtils.getDeclarationNode(argExpr); + if (!declaration) { + return null; + } + + if (!ts.isVariableDeclaration(declaration)) { + return null; + } + + if (declaration.type !== undefined) { + return 'skip'; + } + + const initializer = declaration.initializer; + if (!initializer) { + return null; + } + + if (!ts.isNumericLiteral(initializer)) { + return null; + } + + const numericValue = Number(initializer.text); + if (!Number.isInteger(numericValue)) { + return null; + } + + return numericValue; + } + + private isArrayIndexValidNumber(argExpr: ts.Expression): boolean { + let evaluatedValue: number | null = null; + if (ts.isParenthesizedExpression(argExpr)) { + return this.isArrayIndexValidNumber(argExpr.expression); + } + + if (ts.isBinaryExpression(argExpr)) { + evaluatedValue = this.evaluateNumericValueFromBinaryExpression(argExpr); + } else { + const evalResult = this.evaluateValueFromDeclaration(argExpr); + if (evalResult === 'skip') { + return false; + } + evaluatedValue = evalResult; + } + + if (evaluatedValue === null) { + return false; + } + + const valueString = String(evaluatedValue); + + if (!Number.isInteger(evaluatedValue)) { + return false; + } + if (valueString.includes('.')) { + return false; + } + + return evaluatedValue >= 0; + } + + private handleUndefinedInitializer(argExpr: ts.Expression, declaration: ts.VariableDeclaration): void { + if (ts.isParameter(declaration)) { + const autofix = this.autofixer?.fixArrayIndexExprType(argExpr); + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType, autofix); + } else { + this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); + } + } + + private handleEnumMember(node: ts.Node): void { + const tsEnumMember = node as ts.EnumMember; + const tsEnumMemberType = this.tsTypeChecker.getTypeAtLocation(tsEnumMember); + const constVal = this.tsTypeChecker.getConstantValue(tsEnumMember); + const tsEnumMemberName = tsEnumMember.name; + if (this.options.arkts2) { + this.handleInvalidIdentifier(tsEnumMember); + if (ts.isStringLiteral(tsEnumMemberName)) { + this.handleStringLiteralEnumMember(tsEnumMember, tsEnumMemberName, node); + } + } + + if (tsEnumMember.initializer && !this.tsUtils.isValidEnumMemberInit(tsEnumMember.initializer)) { + this.incrementCounters(node, FaultID.EnumMemberNonConstInit); + } + // check for type - all members should be of same type + const enumDecl = tsEnumMember.parent; + const firstEnumMember = enumDecl.members[0]; + const firstEnumMemberType = this.tsTypeChecker.getTypeAtLocation(firstEnumMember); + const firstElewmVal = this.tsTypeChecker.getConstantValue(firstEnumMember); + this.handleEnumNotSupportFloat(tsEnumMember); + + /* + * each string enum member has its own type + * so check that value type is string + */ + if ( + constVal !== undefined && + typeof constVal === STRINGLITERAL_STRING && + firstElewmVal !== undefined && + typeof firstElewmVal === STRINGLITERAL_STRING + ) { + return; + } + if ( + constVal !== undefined && + typeof constVal === STRINGLITERAL_NUMBER && + firstElewmVal !== undefined && + typeof firstElewmVal === STRINGLITERAL_NUMBER + ) { + return; + } + if (firstEnumMemberType !== tsEnumMemberType) { + this.incrementCounters(node, FaultID.EnumMemberNonConstInit); + } + } + + private handleStringLiteralEnumMember( + tsEnumMember: ts.EnumMember, + tsEnumMemberName: ts.StringLiteral, + node: ts.Node + ): void { + const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyName(tsEnumMemberName, tsEnumMember); + this.incrementCounters(node, FaultID.LiteralAsPropertyName, autofix); + } + + private handleEnumNotSupportFloat(enumMember: ts.EnumMember): void { + if (!this.options.arkts2) { + return; + } + const initializer = enumMember.initializer; + if (!initializer) { + return; + } + let value; + if (ts.isNumericLiteral(initializer)) { + value = parseFloat(initializer.text); + } else if (ts.isPrefixUnaryExpression(initializer)) { + const operand = initializer.operand; + value = ts.isNumericLiteral(operand) ? parseFloat(operand.text) : value; + } else { + return; + } + + if (!Number.isInteger(value)) { + this.incrementCounters(enumMember, FaultID.EnumMemberNonConstInit); + } + } + + private handleExportAssignment(node: ts.Node): void { + const exportAssignment = node as ts.ExportAssignment; + if (exportAssignment.isExportEquals) { + this.incrementCounters(node, FaultID.ExportAssignment); + } + + if (!TypeScriptLinter.inSharedModule(node)) { + return; + } + + if (!this.tsUtils.isShareableEntity(exportAssignment.expression)) { + this.incrementCounters(exportAssignment.expression, FaultID.SharedModuleExports); + } + } + + private processCalleeSym(calleeSym: ts.Symbol, tsCallExpr: ts.CallExpression): void { + const name = calleeSym.getName(); + const parName = this.tsUtils.getParentSymbolName(calleeSym); + if (!this.options.arkts2) { + this.handleStdlibAPICall(tsCallExpr, calleeSym, name, parName); + this.handleFunctionApplyBindPropCall(tsCallExpr, calleeSym); + } else { + this.handleBuiltinThisArgs(tsCallExpr, calleeSym, name, parName); + } + if (TsUtils.symbolHasEsObjectType(calleeSym)) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(tsCallExpr, faultId); + } + // Need to process Symbol call separately in order to not report two times when using Symbol API + if (this.options.arkts2 && this.tsUtils.isStdSymbol(calleeSym)) { + this.incrementCounters(tsCallExpr, FaultID.SymbolType); + } + + if (this.options.arkts2 && calleeSym.getEscapedName() === 'pow' && isStdLibrarySymbol(calleeSym)) { + this.incrementCounters(tsCallExpr, FaultID.MathPow); + } + + if (this.options.arkts2 && calleeSym.getEscapedName() === 'RegExp' && isStdLibrarySymbol(calleeSym)) { + const autofix = this.autofixer?.fixRegularExpressionLiteral(tsCallExpr); + this.incrementCounters(tsCallExpr, FaultID.RegularExpressionLiteral, autofix); + } + } + + private handleSdkPropertyAccessByIndex(tsCallExpr: ts.CallExpression): void { + const propertyAccessNode = tsCallExpr.expression as ts.PropertyAccessExpression; + if (!ts.isPropertyAccessExpression(propertyAccessNode)) { + return; + } + + const funcName = propertyAccessNode.name; + const indexedTypeSdkInfos = Array.from(TypeScriptLinter.indexedTypeSet); + const isCallInDeprecatedApi = indexedTypeSdkInfos.some((indexedTypeSdkInfo) => { + const isApiNameMismatch = funcName?.getText() !== indexedTypeSdkInfo.api_info.api_name; + if (isApiNameMismatch) { + return false; + } + + const funcDecls = this.tsTypeChecker.getTypeAtLocation(funcName).symbol?.declarations; + return funcDecls?.some((declaration) => { + const interfaceDecl = declaration.parent as ts.InterfaceDeclaration; + if (!(ts.isMethodSignature(declaration) && ts.isInterfaceDeclaration(interfaceDecl))) { + return false; + } + const declFileFromJson = path.normalize(interfaceDecl.getSourceFile().fileName); + const declFileFromSdk = path.normalize(indexedTypeSdkInfo.file_path); + const isSameSdkFilePath = declFileFromJson.endsWith(declFileFromSdk); + const interfaceNameData = indexedTypeSdkInfo.api_info.parent_api[0].api_name; + const isSameInterfaceName = interfaceDecl.name.getText() === interfaceNameData; + return isSameSdkFilePath && isSameInterfaceName; + }); + }); + if (isCallInDeprecatedApi) { + this.incrementCounters(tsCallExpr.expression, FaultID.PropertyAccessByIndexFromSdk); + } + } + + private handleBuiltinCtorCallSignature(tsCallExpr: ts.CallExpression | ts.TypeReferenceNode): void { + if (!this.options.arkts2) { + return; + } + const node = ts.isCallExpression(tsCallExpr) ? tsCallExpr.expression : tsCallExpr.typeName; + const constructorType = this.tsTypeChecker.getTypeAtLocation(node); + const callSignatures = constructorType.getCallSignatures(); + if (callSignatures.length === 0 || BUILTIN_DISABLE_CALLSIGNATURE.includes(node.getText())) { + return; + } + const isSameApi = callSignatures.some((callSignature) => { + const callSignatureDecl = callSignature.getDeclaration(); + if (!ts.isCallSignatureDeclaration(callSignatureDecl)) { + return false; + } + const parentDecl = callSignatureDecl.parent; + const parentName = ts.isInterfaceDeclaration(parentDecl) ? parentDecl.name.getText() : ''; + const BultinNoCtorFuncApiInfoSet = TypeScriptLinter.globalApiInfo.get(BuiltinProblem.BuiltinNoCtorFunc); + if (!BultinNoCtorFuncApiInfoSet) { + return false; + } + const isSameApi = [...BultinNoCtorFuncApiInfoSet].some((apiInfoItem) => { + if (apiInfoItem.api_info.parent_api?.length <= 0) { + return false; + } + const apiInfoParentName = apiInfoItem.api_info.parent_api[0].api_name; + return apiInfoParentName === parentName; + }); + return isSameApi; + }); + if (isSameApi) { + this.incrementCounters(node, FaultID.BuiltinNoCtorFunc); + } + } + + private handleCallExpression(node: ts.Node): void { + const tsCallExpr = node as ts.CallExpression; + this.handleStateStyles(tsCallExpr); + this.handleBuiltinCtorCallSignature(tsCallExpr); + + if (this.options.arkts2 && tsCallExpr.typeArguments !== undefined) { + this.handleSdkPropertyAccessByIndex(tsCallExpr); + } + const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); + const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); + this.handleImportCall(tsCallExpr); + this.handleRequireCall(tsCallExpr); + if (calleeSym !== undefined) { + this.processCalleeSym(calleeSym, tsCallExpr); + } + if (callSignature !== undefined) { + if (!this.tsUtils.isLibrarySymbol(calleeSym)) { + this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); + this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); + } else if (this.options.arkts2) { + this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); + } + } + this.handleInteropForCallExpression(tsCallExpr); + this.handleLibraryTypeCall(tsCallExpr); + if ( + ts.isPropertyAccessExpression(tsCallExpr.expression) && + this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression) + ) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(node, faultId); + } + if ( + !ts.isExpressionStatement(tsCallExpr.parent) && + !ts.isVoidExpression(tsCallExpr.parent) && + !ts.isArrowFunction(tsCallExpr.parent) && + !(ts.isConditionalExpression(tsCallExpr.parent) && ts.isExpressionStatement(tsCallExpr.parent.parent)) + ) { + this.handleLimitedVoidWithCall(tsCallExpr); + } + this.handleAppStorageCallExpression(tsCallExpr); + this.fixJsImportCallExpression(tsCallExpr); + this.handleInteropForCallJSExpression(tsCallExpr, calleeSym, callSignature); + this.handleNoTsLikeFunctionCall(tsCallExpr); + this.handleObjectLiteralInFunctionArgs(tsCallExpr); + this.handleTaskPoolDeprecatedUsages(tsCallExpr); + this.handleSdkDuplicateDeclName(tsCallExpr); + this.handleObjectLiteralAssignmentToClass(tsCallExpr); + } + + handleNoTsLikeFunctionCall(callExpr: ts.CallExpression): void { + if (!this.options.arkts2) { + return; + } + + const expression = callExpr.expression; + const type = this.tsTypeChecker.getTypeAtLocation(expression); + const typeText = this.tsTypeChecker.typeToString(type); + if (typeText === LIKE_FUNCTION) { + const autofix = this.autofixer?.fixNoTsLikeFunctionCall(expression); + this.incrementCounters(expression, FaultID.ExplicitFunctionType, autofix); + } + } + + private handleAppStorageCallExpression(tsCallExpr: ts.CallExpression): void { + if (!this.options.arkts2 || !tsCallExpr) { + return; + } + + if (!TsUtils.isAppStorageAccess(tsCallExpr)) { + return; + } + + let varDecl: ts.VariableDeclaration | undefined; + let parent = tsCallExpr.parent; + + while (parent) { + if (ts.isVariableDeclaration(parent)) { + varDecl = parent; + break; + } + parent = parent.parent; + } + + if (!varDecl || varDecl.type) { + return; + } + const callReturnType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr); + const isNumberReturnType = callReturnType.flags & ts.TypeFlags.Number; + const isNumberGeneric = ((): boolean => { + if (tsCallExpr.typeArguments?.length !== 1) { + return false; + } + const callText = tsCallExpr.getText(); + if (callText.startsWith('Array<') || callText.startsWith('Set<') || callText.startsWith('Map<')) { + return false; + } + const typeArg = tsCallExpr.typeArguments[0]; + if (typeArg.kind === ts.SyntaxKind.NumberKeyword) { + return true; + } + + if (ts.isTypeReferenceNode(typeArg)) { + return ts.isIdentifier(typeArg.typeName) && typeArg.typeName.text === STRINGLITERAL_NUMBER; + } + return typeArg.getText().trim() === STRINGLITERAL_NUMBER; + })(); + + if (isNumberGeneric && !isNumberReturnType) { + const autofix = this.autofixer?.fixAppStorageCallExpression(tsCallExpr); + this.incrementCounters(tsCallExpr, FaultID.NumericSemantics, autofix); + } + } + + handleInteropForCallJSExpression( + tsCallExpr: ts.CallExpression, + sym: ts.Symbol | undefined, + callSignature: ts.Signature | undefined + ): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + // Typeof expressions is handled by a different rule, early return if parent is a typeof expression + if (ts.isTypeOfExpression(tsCallExpr.parent)) { + return; + } + + if (!callSignature || TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { + return; + } + + if (!sym?.declarations?.[0]?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { + return; + } + + const autofix = this.autofixer?.fixInteropInvokeExpression(tsCallExpr); + + this.incrementCounters( + tsCallExpr, + ts.isPropertyAccessExpression(tsCallExpr.expression) ? FaultID.InteropCallObjectMethods : FaultID.CallJSFunction, + autofix + ); + } + + private handleInteropForCallExpression(tsCallExpr: ts.CallExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); + if (!callSignature) { + return; + } + + if (!TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { + return; + } + + this.checkForForbiddenAPIs(callSignature, tsCallExpr); + } + + private isExportedEntityDeclaredInJs(exportDecl: ts.ExportDeclaration): boolean { + if (!this.options.arkts2 || !this.useStatic) { + return false; + } + + // For named exports with braces { ... } + if (exportDecl.exportClause && ts.isNamedExports(exportDecl.exportClause)) { + for (const exportSpecifier of exportDecl.exportClause.elements) { + const identifier = exportSpecifier.name; + if (this.tsUtils.isImportedFromJS(identifier)) { + return true; + } + } + } + + // For namespace exports (export * as namespace from ...) + if (exportDecl.exportClause && ts.isNamespaceExport(exportDecl.exportClause)) { + const namespaceIdentifier = exportDecl.exportClause.name; + if (this.tsUtils.isImportedFromJS(namespaceIdentifier)) { + return true; + } + } + + return false; + } + + private isExportedEntityDeclaredInArkTs1(exportDecl: ts.ExportDeclaration): boolean | undefined { + if (!this.options.arkts2 || !this.useStatic) { + return false; + } + + // For named exports with braces { ... } + if (exportDecl.exportClause && ts.isNamedExports(exportDecl.exportClause)) { + for (const exportSpecifier of exportDecl.exportClause.elements) { + const identifier = exportSpecifier.name; + if (this.tsUtils.isExportImportedFromArkTs1(identifier, exportDecl)) { + return true; + } + } + } + + // For namespace exports (export * as namespace from ...) + if (exportDecl.exportClause && ts.isNamespaceExport(exportDecl.exportClause)) { + const namespaceIdentifier = exportDecl.exportClause.name; + if (this.tsUtils.isExportImportedFromArkTs1(namespaceIdentifier, exportDecl)) { + return true; + } + } + + return false; + } + + private static isDeclaredInArkTs2(callSignature: ts.Signature): boolean | undefined { + const declarationSourceFile = callSignature?.declaration?.getSourceFile(); + if (!declarationSourceFile) { + return undefined; + } + if (!declarationSourceFile.statements) { + return undefined; + } + // check for 'use static' at the start of the file this function declared at + if (declarationSourceFile.statements[0].getText() === USE_STATIC) { + return true; + } + return false; + } + + private checkForForbiddenAPIs(callSignature: ts.Signature, tsCallExpr: ts.CallExpression): void { + if (!callSignature.declaration) { + return; + } + + const functionSymbol = this.getFunctionSymbol(callSignature.declaration); + const functionDeclaration = functionSymbol?.valueDeclaration; + if (!functionDeclaration) { + return; + } + + if (!TypeScriptLinter.isFunctionLike(functionDeclaration)) { + return; + } + switch (TypeScriptLinter.containsForbiddenAPI(functionDeclaration)) { + case REFLECT_LITERAL: + this.incrementCounters(tsCallExpr.parent, FaultID.InteropCallReflect); + break; + case OBJECT_LITERAL: + this.incrementCounters(tsCallExpr.parent, FaultID.InteropCallObjectParam); + break; + default: + break; + } + } + + private handleEtsComponentExpression(node: ts.Node): void { + // for all the checks we make EtsComponentExpression is compatible with the CallExpression + const etsComponentExpression = node as ts.CallExpression; + this.handleLibraryTypeCall(etsComponentExpression); + } + + private handleImportCall(tsCallExpr: ts.CallExpression): void { + if (tsCallExpr.expression.kind !== ts.SyntaxKind.ImportKeyword) { + return; + } else if (this.options.arkts2) { + this.incrementCounters(tsCallExpr, FaultID.DynamicImport); + } + + // relax rule#133 "arkts-no-runtime-import" + const tsArgs = tsCallExpr.arguments; + if (tsArgs.length <= 1 || !ts.isObjectLiteralExpression(tsArgs[1])) { + return; + } + + for (const tsProp of tsArgs[1].properties) { + if ( + (ts.isPropertyAssignment(tsProp) || ts.isShorthandPropertyAssignment(tsProp)) && + tsProp.name.getText() === 'assert' + ) { + this.incrementCounters(tsProp, FaultID.ImportAssertion); + break; + } + } + } + + private handleRequireCall(tsCallExpr: ts.CallExpression): void { + if ( + ts.isIdentifier(tsCallExpr.expression) && + tsCallExpr.expression.text === 'require' && + ts.isVariableDeclaration(tsCallExpr.parent) + ) { + const tsType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); + if (TsUtils.isInterfaceType(tsType) && tsType.symbol.name === 'NodeRequire') { + this.incrementCounters(tsCallExpr.parent, FaultID.ImportAssignment); + } + } + } + + private handleGenericCallWithNoTypeArgs( + callLikeExpr: ts.CallExpression | ts.NewExpression, + callSignature: ts.Signature + ): void { + + /* + * Note: The PR!716 has led to a significant performance degradation. + * Since initial problem was fixed in a more general way, this change + * became redundant. Therefore, it was reverted. See #13721 comments + * for a detailed analysis. + */ + if (this.options.arkts2 && TypeScriptLinter.isInvalidBuiltinGenericConstructorCall(callLikeExpr)) { + const autofix = this.autofixer?.fixGenericCallNoTypeArgs(callLikeExpr as ts.NewExpression); + this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs, autofix); + return; + } + this.checkTypeArgumentsForGenericCallWithNoTypeArgs(callLikeExpr, callSignature); + } + + private static isInvalidBuiltinGenericConstructorCall(newExpression: ts.CallExpression | ts.NewExpression): boolean { + if (!ts.isNewExpression(newExpression)) { + return false; + } + 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, + callSignature: ts.Signature + ): void { + if (ts.isNewExpression(callLikeExpr) && this.isNonGenericClass(callLikeExpr)) { + return; + } + const tsSyntaxKind = ts.isNewExpression(callLikeExpr) ? + ts.SyntaxKind.Constructor : + ts.SyntaxKind.FunctionDeclaration; + const signFlags = ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature | ts.NodeBuilderFlags.IgnoreErrors; + const signDecl = this.tsTypeChecker.signatureToSignatureDeclaration( + callSignature, + tsSyntaxKind, + undefined, + signFlags + ); + if (!signDecl?.typeArguments) { + return; + } + const resolvedTypeArgs = signDecl.typeArguments; + const startTypeArg = callLikeExpr.typeArguments?.length ?? 0; + if (this.options.arkts2 && callLikeExpr.kind === ts.SyntaxKind.NewExpression) { + if (startTypeArg !== resolvedTypeArgs.length) { + const autofix = this.autofixer?.fixGenericCallNoTypeArgs(callLikeExpr); + this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs, autofix); + } + } else { + for (let i = startTypeArg; i < resolvedTypeArgs.length; ++i) { + const typeNode = resolvedTypeArgs[i]; + + /* + * if compiler infers 'unknown' type there are 2 possible cases: + * 1. Compiler unable to infer type from arguments and use 'unknown' + * 2. Compiler infer 'unknown' from arguments + * We report error in both cases. It is ok because we cannot use 'unknown' + * in ArkTS and already have separate check for it. + */ + if (typeNode.kind === ts.SyntaxKind.UnknownKeyword) { + this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs); + break; + } + } + } + } + + private isNonGenericClass(expression: ts.NewExpression): boolean { + const declaration = this.tsUtils.getDeclarationNode(expression.expression); + return !!declaration && ts.isClassDeclaration(declaration) && !declaration.typeParameters; + } + + static isArrayFromCall(callLikeExpr: ts.CallExpression | ts.NewExpression): boolean { + return ( + ts.isCallExpression(callLikeExpr) && + ts.isPropertyAccessExpression(callLikeExpr.expression) && + callLikeExpr.expression.name.text === STRINGLITERAL_FROM && + ts.isIdentifier(callLikeExpr.expression.expression) && + callLikeExpr.expression.expression.text === STRINGLITERAL_ARRAY + ); + } + + private static readonly listFunctionApplyCallApis = [ + 'Function.apply', + 'Function.call', + 'CallableFunction.apply', + 'CallableFunction.call' + ]; + + private static readonly listFunctionBindApis = ['Function.bind', 'CallableFunction.bind']; + + private handleFunctionApplyBindPropCall(tsCallExpr: ts.CallExpression, calleeSym: ts.Symbol): void { + const exprName = this.tsTypeChecker.getFullyQualifiedName(calleeSym); + if (TypeScriptLinter.listFunctionApplyCallApis.includes(exprName)) { + this.incrementCounters(tsCallExpr, FaultID.FunctionApplyCall); + } + if (TypeScriptLinter.listFunctionBindApis.includes(exprName)) { + const faultId = this.options.arkts2 ? FaultID.FunctionBindError : FaultID.FunctionBind; + this.incrementCounters(tsCallExpr, faultId); + } + } + + private handleStructIdentAndUndefinedInArgs( + tsCallOrNewExpr: ts.CallExpression | ts.NewExpression, + callSignature: ts.Signature + ): void { + if (!tsCallOrNewExpr.arguments) { + return; + } + for (let argIndex = 0; argIndex < tsCallOrNewExpr.arguments.length; ++argIndex) { + const tsArg = tsCallOrNewExpr.arguments[argIndex]; + const tsArgType = this.tsTypeChecker.getTypeAtLocation(tsArg); + if (!tsArgType) { + continue; + } + const paramIndex = argIndex < callSignature.parameters.length ? argIndex : callSignature.parameters.length - 1; + const tsParamSym = callSignature.parameters[paramIndex]; + if (!tsParamSym) { + continue; + } + const tsParamDecl = tsParamSym.valueDeclaration; + if (tsParamDecl && ts.isParameter(tsParamDecl)) { + let tsParamType = this.tsTypeChecker.getTypeOfSymbolAtLocation(tsParamSym, tsParamDecl); + if (tsParamDecl.dotDotDotToken && this.tsUtils.isGenericArrayType(tsParamType) && tsParamType.typeArguments) { + tsParamType = tsParamType.typeArguments[0]; + } + if (!tsParamType) { + continue; + } + this.checkAssignmentMatching(tsArg, tsParamType, tsArg); + } + } + } + + private static readonly LimitedApis = new Map | null; fault: FaultID }>([ + ['global', { arr: LIMITED_STD_GLOBAL_API, fault: FaultID.LimitedStdLibApi }], + ['Object', { arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi }], + ['ObjectConstructor', { arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi }], + ['Reflect', { arr: LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi }], + ['ProxyHandler', { arr: LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi }], + [SYMBOL, { arr: null, fault: FaultID.SymbolType }], + [SYMBOL_CONSTRUCTOR, { arr: null, fault: FaultID.SymbolType }] + ]); + + private handleStdlibAPICall( + callExpr: ts.CallExpression, + calleeSym: ts.Symbol, + name: string, + parName: string | undefined + ): void { + if (parName === undefined) { + if (LIMITED_STD_GLOBAL_API.includes(name)) { + this.incrementCounters(callExpr, FaultID.LimitedStdLibApi); + return; + } + const escapedName = calleeSym.escapedName; + if (escapedName === 'Symbol' || escapedName === 'SymbolConstructor') { + this.incrementCounters(callExpr, FaultID.SymbolType); + } + return; + } + const lookup = TypeScriptLinter.LimitedApis.get(parName); + if ( + lookup !== undefined && + (lookup.arr === null || lookup.arr.includes(name)) && + (!this.options.useRelaxedRules || !this.supportedStdCallApiChecker.isSupportedStdCallAPI(callExpr, parName, name)) + ) { + this.incrementCounters(callExpr, lookup.fault); + } + } + + private handleBuiltinThisArgs( + callExpr: ts.CallExpression, + calleeSym: ts.Symbol, + name: string, + parName: string | undefined + ): void { + if (parName === undefined) { + return; + } + + const builtinThisArgsInfos = TypeScriptLinter.funcMap.get(name); + if (!builtinThisArgsInfos) { + return; + } + + const sourceFile = calleeSym?.declarations?.[0]?.getSourceFile(); + if (!sourceFile) { + return; + } + + const fileName = path.basename(sourceFile.fileName); + const builtinInfos = builtinThisArgsInfos.get(fileName); + if (!(builtinInfos && builtinInfos.size > 0)) { + return; + } + for (const info of builtinInfos) { + const needReport = + info.parent_api.length > 0 && + info.parent_api[0].api_name === parName && + info?.api_func_args?.length === callExpr.arguments.length; + if (needReport) { + this.incrementCounters(callExpr, FaultID.BuiltinThisArgs); + return; + } + } + } + + private checkLimitedStdlibApi(node: ts.Identifier, symbol: ts.Symbol): void { + const parName = this.tsUtils.getParentSymbolName(symbol); + const entries = LIMITED_STD_API.get(parName); + if (!entries) { + return; + } + for (const entry of entries) { + if ( + entry.api.includes(symbol.name) && + !this.supportedStdCallApiChecker.isSupportedStdCallAPI(node, parName, symbol.name) + ) { + this.incrementCounters(node, entry.faultId); + return; + } + } + } + + private handleLibraryTypeCall(expr: ts.CallExpression | ts.NewExpression): void { + if (!expr.arguments || !this.tscStrictDiagnostics || !this.sourceFile) { + return; + } + + const file = path.normalize(this.sourceFile.fileName); + const tscDiagnostics: readonly ts.Diagnostic[] | undefined = this.tscStrictDiagnostics.get(file); + if (!tscDiagnostics?.length) { + return; + } + + const isOhModulesEts = TsUtils.isOhModulesEtsSymbol(this.tsUtils.trueSymbolAtLocation(expr.expression)); + const deleteDiagnostics: Set = new Set(); + LibraryTypeCallDiagnosticChecker.instance.filterDiagnostics( + tscDiagnostics, + expr, + this.tsUtils.isLibraryType(this.tsTypeChecker.getTypeAtLocation(expr.expression)), + (diagnostic, errorType) => { + + /* + * When a diagnostic meets the filter criteria, If it happens in an ets file in the 'oh_modules' directory. + * the diagnostic is downgraded to warning. For other files, downgraded to nothing. + */ + if (isOhModulesEts && errorType !== DiagnosticCheckerErrorType.UNKNOW) { + diagnostic.category = ts.DiagnosticCategory.Warning; + return false; + } + deleteDiagnostics.add(diagnostic); + return true; + } + ); + + if (!deleteDiagnostics.size) { + return; + } + + this.tscStrictDiagnostics.set( + file, + tscDiagnostics.filter((item) => { + return !deleteDiagnostics.has(item); + }) + ); + } + + private checkConstrutorAccess(newExpr: ts.NewExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + if (!ts.isPropertyAccessExpression(newExpr.parent)) { + return; + } + + if (newExpr.parent.name.text === 'constructor') { + this.incrementCounters(newExpr.parent, FaultID.NoConstructorOnClass); + } + } + + private checkForInterfaceInitialization(newExpression: ts.NewExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + if (!ts.isReturnStatement(newExpression.parent)) { + return; + } + + const calleeExpr = newExpression.expression; + if (!ts.isIdentifier(calleeExpr)) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(calleeExpr); + if (type.isClassOrInterface()) { + this.incrementCounters(calleeExpr, FaultID.ConstructorIfaceFromSdk); + } + } + + private handleNewExpression(node: ts.Node): void { + const tsNewExpr = node as ts.NewExpression; + + this.checkForInterfaceInitialization(tsNewExpr); + this.handleSharedArrayBuffer(tsNewExpr); + this.handleSdkDuplicateDeclName(tsNewExpr); + this.checkConstrutorAccess(tsNewExpr); + this.checkCreatingPrimitiveTypes(tsNewExpr); + + if (this.options.advancedClassChecks || this.options.arkts2) { + const calleeExpr = tsNewExpr.expression; + const calleeType = this.tsTypeChecker.getTypeAtLocation(calleeExpr); + if ( + !this.tsUtils.isClassTypeExpression(calleeExpr) && + !isStdLibraryType(calleeType) && + !this.tsUtils.isLibraryType(calleeType) && + !this.tsUtils.hasEsObjectType(calleeExpr) + ) { + // missing exact rule + const faultId = this.options.arkts2 ? FaultID.DynamicCtorCall : FaultID.ClassAsObject; + this.incrementCounters(calleeExpr, faultId); + } + } + const sym = this.tsUtils.trueSymbolAtLocation(tsNewExpr.expression); + const callSignature = this.tsTypeChecker.getResolvedSignature(tsNewExpr); + if (callSignature !== undefined) { + if (!this.tsUtils.isLibrarySymbol(sym)) { + this.handleStructIdentAndUndefinedInArgs(tsNewExpr, callSignature); + this.handleGenericCallWithNoTypeArgs(tsNewExpr, callSignature); + } else if (this.options.arkts2) { + this.handleGenericCallWithNoTypeArgs(tsNewExpr, callSignature); + } + } + this.handleSendableGenericTypes(tsNewExpr); + this.handleInstantiatedJsObject(tsNewExpr, sym); + } + + private checkCreatingPrimitiveTypes(tsNewExpr: ts.NewExpression): void { + if (!this.options.arkts2) { + return; + } + const typeStr = this.tsTypeChecker.typeToString(this.tsTypeChecker.getTypeAtLocation(tsNewExpr)); + const primitiveTypes = ['Number', 'String', 'Boolean']; + if (primitiveTypes.includes(typeStr)) { + this.incrementCounters(tsNewExpr, FaultID.CreatingPrimitiveTypes); + } + } + + handleInstantiatedJsObject(tsNewExpr: ts.NewExpression, sym: ts.Symbol | undefined): void { + if (this.useStatic && this.options.arkts2) { + if (sym?.declarations?.[0]?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { + const args = tsNewExpr.arguments; + const autofix = this.autofixer?.fixInteropInstantiateExpression(tsNewExpr, args); + this.incrementCounters(tsNewExpr, FaultID.InstantiatedJsOjbect, autofix); + } + } + } + + private handleSendableGenericTypes(node: ts.NewExpression): void { + const type = this.tsTypeChecker.getTypeAtLocation(node); + if (!this.tsUtils.isSendableClassOrInterface(type)) { + return; + } + + const typeArgs = node.typeArguments; + if (!typeArgs || typeArgs.length === 0) { + return; + } + + for (const arg of typeArgs) { + if (!this.tsUtils.isSendableTypeNode(arg)) { + this.incrementCounters(arg, FaultID.SendableGenericTypes); + } + } + } + + private handleAsExpression(node: ts.Node): void { + const tsAsExpr = node as ts.AsExpression; + if (tsAsExpr.type.getText() === 'const') { + this.incrementCounters(node, FaultID.ConstAssertion); + } + const targetType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.type).getNonNullableType(); + const exprType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.expression).getNonNullableType(); + // check for rule#65: 'number as Number' and 'boolean as Boolean' are disabled + if ( + this.tsUtils.isNumberLikeType(exprType) && this.tsUtils.isStdNumberType(targetType) || + TsUtils.isBooleanLikeType(exprType) && this.tsUtils.isStdBooleanType(targetType) + ) { + this.incrementCounters(node, FaultID.TypeAssertion); + } + if ( + !this.tsUtils.isSendableClassOrInterface(exprType) && + !this.tsUtils.isObject(exprType) && + !TsUtils.isAnyType(exprType) && + this.tsUtils.isSendableClassOrInterface(targetType) + ) { + this.incrementCounters(tsAsExpr, FaultID.SendableAsExpr); + } + if (this.tsUtils.isWrongSendableFunctionAssignment(targetType, exprType)) { + this.incrementCounters(tsAsExpr, FaultID.SendableFunctionAsExpr); + } + if ( + this.options.arkts2 && + this.tsUtils.needToDeduceStructuralIdentity(targetType, exprType, tsAsExpr.expression, true) + ) { + if (!this.tsUtils.isObject(exprType)) { + this.incrementCounters(node, FaultID.StructuralIdentity); + } + } + this.handleAsExpressionImport(tsAsExpr); + this.handleNoTuplesArrays(node, targetType, exprType); + this.handleObjectLiteralAssignmentToClass(tsAsExpr); + } + + private handleAsExpressionImport(tsAsExpr: ts.AsExpression): void { + if (!this.useStatic || !this.options.arkts2) { + return; + } + + const type = tsAsExpr.type; + const expression = tsAsExpr.expression; + const restrictedPrimitiveTypes = [ + ts.SyntaxKind.NumberKeyword, + ts.SyntaxKind.BooleanKeyword, + ts.SyntaxKind.StringKeyword, + ts.SyntaxKind.BigIntKeyword, + ts.SyntaxKind.UndefinedKeyword + ]; + this.handleAsExpressionImportNull(tsAsExpr); + const isRestrictedPrimitive = restrictedPrimitiveTypes.includes(type.kind); + const isRestrictedArrayType = + type.kind === ts.SyntaxKind.ArrayType || + ts.isTypeReferenceNode(type) && ts.isIdentifier(type.typeName) && type.typeName.text === 'Array'; + + if (!isRestrictedPrimitive && !isRestrictedArrayType) { + return; + } + + let identifier: ts.Identifier | undefined; + if (ts.isIdentifier(expression)) { + identifier = expression; + } else if (ts.isPropertyAccessExpression(expression)) { + identifier = ts.isIdentifier(expression.expression) ? expression.expression : undefined; + } + + if (identifier) { + const sym = this.tsUtils.trueSymbolAtLocation(identifier); + const decl = TsUtils.getDeclaration(sym); + if (decl?.getSourceFile().fileName.endsWith(EXTNAME_JS)) { + const autofix = this.autofixer?.fixInteropAsExpression(tsAsExpr); + this.incrementCounters(tsAsExpr, FaultID.InterOpConvertImport, autofix); + } + } + } + + private handleAsExpressionImportNull(tsAsExpr: ts.AsExpression): void { + const type = tsAsExpr.type; + const isNullAssertion = + type.kind === ts.SyntaxKind.NullKeyword || + ts.isLiteralTypeNode(type) && type.literal.kind === ts.SyntaxKind.NullKeyword || + type.getText() === 'null'; + if (isNullAssertion) { + this.incrementCounters(tsAsExpr, FaultID.InterOpConvertImport); + } + } + + private handleSdkConstructorIface(typeRef: ts.TypeReferenceNode): void { + if (!this.options.arkts2 && typeRef?.typeName === undefined && !ts.isQualifiedName(typeRef.typeName)) { + return; + } + const qualifiedName = typeRef.typeName as ts.QualifiedName; + // tsc version diff + const topName = qualifiedName.left?.getText(); + const sdkInfos = this.interfaceMap.get(topName); + if (!sdkInfos) { + return; + } + for (const sdkInfo of sdkInfos) { + if (sdkInfo.api_type !== 'ConstructSignature') { + continue; + } + // sdk api from json has 3 overload. need consider these case. + if (sdkInfo.parent_api[0].api_name === qualifiedName.right.getText()) { + this.incrementCounters(typeRef, FaultID.ConstructorIfaceFromSdk); + break; + } + } + } + + private handleSharedArrayBuffer(node: ts.TypeReferenceNode | ts.NewExpression): void { + if (!this.options.arkts2) { + return; + } + + const typeNameIdentifier = ts.isTypeReferenceNode(node) ? node.typeName : node.expression; + if (!ts.isIdentifier(typeNameIdentifier) || typeNameIdentifier.getText() !== ESLIB_SHAREDARRAYBUFFER) { + return; + } + + const decls = this.tsUtils.trueSymbolAtLocation(typeNameIdentifier)?.getDeclarations(); + const isSharedMemoryEsLib = decls?.some((decl) => { + const srcFileName = decl.getSourceFile().fileName; + return srcFileName.endsWith(ESLIB_SHAREDMEMORY_FILENAME); + }); + if (!isSharedMemoryEsLib || this.hasLocalSharedArrayBufferClass()) { + return; + } + if (ts.isNewExpression(node)) { + const autofix = this.autofixer?.fixSharedArrayBufferConstructor(node); + this.incrementCounters(node.expression, FaultID.SharedArrayBufferDeprecated, autofix); + } else { + const autofix = this.autofixer?.fixSharedArrayBufferTypeReference(node); + this.incrementCounters(node, FaultID.SharedArrayBufferDeprecated, autofix); + } + } + + private hasLocalSharedArrayBufferClass(): boolean { + return this.sourceFile.statements.some((stmt) => { + return ts.isClassDeclaration(stmt) && stmt.name?.text === ESLIB_SHAREDARRAYBUFFER; + }); + } + + private handleTypeReference(node: ts.Node): void { + const typeRef = node as ts.TypeReferenceNode; + + this.handleBuiltinCtorCallSignature(typeRef); + this.handleSharedArrayBuffer(typeRef); + this.handleSdkDuplicateDeclName(typeRef); + + this.handleSdkConstructorIface(typeRef); + + const isESValue = TsUtils.isEsValueType(typeRef); + const isPossiblyValidContext = TsUtils.isEsValuePossiblyAllowed(typeRef); + if (isESValue && !isPossiblyValidContext) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(node, faultId); + return; + } + + const typeName = this.tsUtils.entityNameToString(typeRef.typeName); + const isStdUtilityType = LIMITED_STANDARD_UTILITY_TYPES.includes(typeName); + if (isStdUtilityType) { + this.incrementCounters(node, FaultID.UtilityType); + return; + } + + this.checkPartialType(node); + + const typeNameType = this.tsTypeChecker.getTypeAtLocation(typeRef.typeName); + if (this.options.arkts2 && (typeNameType.flags & ts.TypeFlags.Void) !== 0) { + this.incrementCounters(typeRef, FaultID.LimitedVoidType); + } + if (this.tsUtils.isSendableClassOrInterface(typeNameType)) { + this.checkSendableTypeArguments(typeRef); + } + + this.checkNoEnumProp(typeRef); + } + + private checkNoEnumProp(typeRef: ts.TypeReferenceNode): void { + if (!this.options.arkts2) { + return; + } + if (ts.isQualifiedName(typeRef.typeName)) { + const symbol = this.tsTypeChecker.getSymbolAtLocation(typeRef.typeName.right); + + if (!symbol) { + return; + } + + const declarations = symbol.getDeclarations(); + if (!declarations || declarations.length === 0) { + return; + } + + if (ts.isEnumMember(declarations[0])) { + this.incrementCounters(typeRef, FaultID.NoEnumPropAsType); + } + } + } + + private checkPartialType(node: ts.Node): void { + const typeRef = node as ts.TypeReferenceNode; + // Using Partial type is allowed only when its argument type is either Class or Interface. + const isStdPartial = this.tsUtils.entityNameToString(typeRef.typeName) === 'Partial'; + if (!isStdPartial) { + return; + } + + const hasSingleTypeArgument = !!typeRef.typeArguments && typeRef.typeArguments.length === 1; + let argType; + if (!this.options.useRtLogic) { + const firstTypeArg = !!typeRef.typeArguments && hasSingleTypeArgument && typeRef.typeArguments[0]; + argType = firstTypeArg && this.tsTypeChecker.getTypeFromTypeNode(firstTypeArg); + } else { + argType = hasSingleTypeArgument && this.tsTypeChecker.getTypeFromTypeNode(typeRef.typeArguments[0]); + } + + if (argType && !argType.isClassOrInterface()) { + this.incrementCounters(node, FaultID.UtilityType); + } + } + + private checkSendableTypeArguments(typeRef: ts.TypeReferenceNode): void { + if (typeRef.typeArguments) { + for (const typeArg of typeRef.typeArguments) { + if (!this.tsUtils.isSendableTypeNode(typeArg)) { + this.incrementCounters(typeArg, FaultID.SendableGenericTypes); + } + } + } + } + + private handleMetaProperty(node: ts.Node): void { + const tsMetaProperty = node as ts.MetaProperty; + if (tsMetaProperty.name.text === 'target') { + this.incrementCounters(node, FaultID.NewTarget); + } + } + + private handleSpreadOp(node: ts.Node): void { + + /* + * spread assignment is disabled + * spread element is allowed only for arrays as rest parameter + */ + if (ts.isSpreadElement(node)) { + const spreadExprType = this.tsUtils.getTypeOrTypeConstraintAtLocation(node.expression); + if ( + spreadExprType && + (this.options.useRtLogic || ts.isCallLikeExpression(node.parent) || ts.isArrayLiteralExpression(node.parent)) && + (this.tsUtils.isOrDerivedFrom(spreadExprType, this.tsUtils.isArray) || + this.tsUtils.isOrDerivedFrom(spreadExprType, this.tsUtils.isCollectionArrayType)) + ) { + return; + } + } + this.incrementCounters(node, FaultID.SpreadOperator); + } + + private handleConstructSignature(node: ts.Node): void { + switch (node.parent.kind) { + case ts.SyntaxKind.TypeLiteral: + this.incrementCounters(node, FaultID.ConstructorType); + break; + case ts.SyntaxKind.InterfaceDeclaration: + this.incrementCounters(node, FaultID.ConstructorIface); + break; + default: + } + } + + private handleExpressionWithTypeArguments(node: ts.Node): void { + const tsTypeExpr = node as ts.ExpressionWithTypeArguments; + const symbol = this.tsUtils.trueSymbolAtLocation(tsTypeExpr.expression); + + if (!!symbol && TsUtils.isEsObjectSymbol(symbol)) { + const faultId = this.options.arkts2 ? FaultID.EsValueTypeError : FaultID.EsValueType; + this.incrementCounters(tsTypeExpr, faultId); + } + this.handleSdkDuplicateDeclName(tsTypeExpr); + } + + private handleComputedPropertyName(node: ts.Node): void { + const computedProperty = node as ts.ComputedPropertyName; + if (this.isSendableCompPropName(computedProperty)) { + // cancel the '[Symbol.iterface]' restriction of 'sendable class/interface' in the 'collections.d.ts' file + if (this.tsUtils.isSymbolIteratorExpression(computedProperty.expression)) { + const declNode = computedProperty.parent?.parent; + if (declNode && TsUtils.isArkTSCollectionsClassOrInterfaceDeclaration(declNode)) { + return; + } + } + this.incrementCounters(node, FaultID.SendableComputedPropName); + } else if (!this.tsUtils.isValidComputedPropertyName(computedProperty, false)) { + this.incrementCounters(node, FaultID.ComputedPropertyName); + } + } + + private isSendableCompPropName(compProp: ts.ComputedPropertyName): boolean { + const declNode = compProp.parent?.parent; + if (declNode && ts.isClassDeclaration(declNode) && TsUtils.hasSendableDecorator(declNode)) { + return true; + } else if (declNode && ts.isInterfaceDeclaration(declNode)) { + const declNodeType = this.tsTypeChecker.getTypeAtLocation(declNode); + if (this.tsUtils.isSendableClassOrInterface(declNodeType)) { + return true; + } + } + return false; + } + + private handleGetAccessor(node: ts.GetAccessorDeclaration): void { + TsUtils.getDecoratorsIfInSendableClass(node)?.forEach((decorator) => { + this.incrementCounters(decorator, FaultID.SendableClassDecorator); + }); + } + + private handleSetAccessor(node: ts.SetAccessorDeclaration): void { + TsUtils.getDecoratorsIfInSendableClass(node)?.forEach((decorator) => { + this.incrementCounters(decorator, FaultID.SendableClassDecorator); + }); + } + + /* + * issue 13987: + * When variable have no type annotation and no initial value, and 'noImplicitAny' + * option is enabled, compiler attempts to infer type from variable references: + * see https://github.com/microsoft/TypeScript/pull/11263. + * In this case, we still want to report the error, since ArkTS doesn't allow + * to omit both type annotation and initializer. + */ + private proceedVarPropDeclaration( + decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration + ): boolean | undefined { + if ( + (ts.isVariableDeclaration(decl) && ts.isVariableStatement(decl.parent.parent) || + ts.isPropertyDeclaration(decl)) && + !decl.initializer + ) { + if ( + ts.isPropertyDeclaration(decl) && + this.tsUtils.skipPropertyInferredTypeCheck(decl, this.sourceFile, this.options.isEtsFileCb) + ) { + return true; + } + + this.incrementCounters(decl, FaultID.AnyType); + return true; + } + return undefined; + } + + private handleDeclarationInferredType( + decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration + ): void { + // The type is explicitly specified, no need to check inferred type. + if (decl.type) { + return; + } + + /* + * issue 13161: + * In TypeScript, the catch clause variable must be 'any' or 'unknown' type. Since + * ArkTS doesn't support these types, the type for such variable is simply omitted, + * and we don't report it as an error. See TypeScriptLinter.handleCatchClause() + * for reference. + */ + if (ts.isCatchClause(decl.parent)) { + return; + } + // Destructuring declarations are not supported, do not process them. + if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) { + return; + } + + if (this.proceedVarPropDeclaration(decl)) { + return; + } + + const type = this.tsTypeChecker.getTypeAtLocation(decl); + if (type) { + this.validateDeclInferredType(type, decl); + } + } + + private handleDefiniteAssignmentAssertion(decl: ts.VariableDeclaration | ts.PropertyDeclaration): void { + if (decl.exclamationToken === undefined) { + return; + } + + if (decl.kind === ts.SyntaxKind.PropertyDeclaration) { + const parentDecl = decl.parent; + if (parentDecl.kind === ts.SyntaxKind.ClassDeclaration && TsUtils.hasSendableDecorator(parentDecl)) { + this.incrementCounters(decl, FaultID.SendableDefiniteAssignment); + return; + } + } + const faultId = this.options.arkts2 ? FaultID.DefiniteAssignmentError : FaultID.DefiniteAssignment; + this.incrementCounters(decl, faultId); + } + + private readonly validatedTypesSet = new Set(); + + private checkAnyOrUnknownChildNode(node: ts.Node): boolean { + if (node.kind === ts.SyntaxKind.AnyKeyword || node.kind === ts.SyntaxKind.UnknownKeyword) { + return true; + } + for (const child of node.getChildren()) { + if (this.checkAnyOrUnknownChildNode(child)) { + return true; + } + } + return false; + } + + private handleInferredObjectreference( + type: ts.Type, + decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration + ): void { + const typeArgs = this.tsTypeChecker.getTypeArguments(type as ts.TypeReference); + if (typeArgs) { + const haveAnyOrUnknownNodes = this.checkAnyOrUnknownChildNode(decl); + if (!haveAnyOrUnknownNodes) { + for (const typeArg of typeArgs) { + this.validateDeclInferredType(typeArg, decl); + } + } + } + } + + private validateDeclInferredType( + type: ts.Type, + decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration + ): void { + if (type.aliasSymbol !== undefined) { + return; + } + if (TsUtils.isObjectType(type) && !!(type.objectFlags & ts.ObjectFlags.Reference)) { + this.handleInferredObjectreference(type, decl); + return; + } + if (this.validatedTypesSet.has(type)) { + return; + } + if (type.isUnion()) { + this.validatedTypesSet.add(type); + for (const unionElem of type.types) { + this.validateDeclInferredType(unionElem, decl); + } + } + if (TsUtils.isAnyType(type)) { + this.incrementCounters(decl, FaultID.AnyType); + } else if (TsUtils.isUnknownType(type)) { + this.incrementCounters(decl, FaultID.UnknownType); + } + } + + private handleCommentDirectives(sourceFile: ts.SourceFile): void { + + /* + * We use a dirty hack to retrieve list of parsed comment directives by accessing + * internal properties of SourceFile node. + */ + /* CC-OFFNXT(no_explicit_any) std lib */ + // Handle comment directive '@ts-nocheck' + const pragmas = (sourceFile as any).pragmas; + if (pragmas && pragmas instanceof Map) { + const noCheckPragma = pragmas.get('ts-nocheck'); + if (noCheckPragma) { + + /* + * The value is either a single entry or an array of entries. + * Wrap up single entry with array to simplify processing. + */ + /* CC-OFFNXT(no_explicit_any) std lib */ + const noCheckEntries: any[] = Array.isArray(noCheckPragma) ? noCheckPragma : [noCheckPragma]; + for (const entry of noCheckEntries) { + this.processNoCheckEntry(entry); + } + } + } + + /* CC-OFFNXT(no_explicit_any) std lib */ + // Handle comment directives '@ts-ignore' and '@ts-expect-error' + const commentDirectives = (sourceFile as any).commentDirectives; + if (commentDirectives && Array.isArray(commentDirectives)) { + for (const directive of commentDirectives) { + if (directive.range?.pos === undefined || directive.range?.end === undefined) { + continue; + } + + const range = directive.range as ts.TextRange; + const kind: ts.SyntaxKind = + sourceFile.text.slice(range.pos, range.pos + 2) === '/*' ? + ts.SyntaxKind.MultiLineCommentTrivia : + ts.SyntaxKind.SingleLineCommentTrivia; + const commentRange: ts.CommentRange = { + pos: range.pos, + end: range.end, + kind + }; + + this.incrementCounters(commentRange, FaultID.ErrorSuppression); + } + } + } + + /* CC-OFFNXT(no_explicit_any) std lib */ + private processNoCheckEntry(entry: any): void { + if (entry.range?.kind === undefined || entry.range?.pos === undefined || entry.range?.end === undefined) { + return; + } + + this.incrementCounters(entry.range as ts.CommentRange, FaultID.ErrorSuppression); + } + + private reportThisKeywordsInScope(scope: ts.Block | ts.Expression): void { + const callback = (node: ts.Node): void => { + if (node.kind === ts.SyntaxKind.ThisKeyword) { + this.incrementCounters(node, FaultID.FunctionContainsThis); + } + }; + const stopCondition = (node: ts.Node): boolean => { + const isClassLike = ts.isClassDeclaration(node) || ts.isClassExpression(node); + const isFunctionLike = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node); + const isModuleDecl = ts.isModuleDeclaration(node); + return isClassLike || isFunctionLike || isModuleDecl; + }; + forEachNodeInSubtree(scope, callback, stopCondition); + } + + private handleConstructorDeclaration(node: ts.Node): void { + const ctorDecl = node as ts.ConstructorDeclaration; + this.handleTSOverload(ctorDecl); + const paramProperties = ctorDecl.parameters.filter((x) => { + return this.tsUtils.hasAccessModifier(x); + }); + if (paramProperties.length === 0) { + return; + } + let paramTypes: ts.TypeNode[] | undefined; + if (ctorDecl.body) { + paramTypes = this.collectCtorParamTypes(ctorDecl); + } + const autofix = this.autofixer?.fixCtorParameterProperties(ctorDecl, paramTypes); + for (const param of paramProperties) { + this.incrementCounters(param, FaultID.ParameterProperties, autofix); + } + } + + private collectCtorParamTypes(ctorDecl: ts.ConstructorDeclaration): ts.TypeNode[] | undefined { + const paramTypes: ts.TypeNode[] = []; + + for (const param of ctorDecl.parameters) { + let paramTypeNode = param.type; + if (!paramTypeNode) { + const paramType = this.tsTypeChecker.getTypeAtLocation(param); + paramTypeNode = this.tsTypeChecker.typeToTypeNode(paramType, param, ts.NodeBuilderFlags.None); + } + if (!paramTypeNode || !this.tsUtils.isSupportedType(paramTypeNode)) { + return undefined; + } + paramTypes.push(paramTypeNode); + } + + return paramTypes; + } + + private handlePrivateIdentifier(node: ts.Node): void { + const ident = node as ts.PrivateIdentifier; + const autofix = this.autofixer?.fixPrivateIdentifier(ident); + this.incrementCounters(node, FaultID.PrivateIdentifier, autofix); + } + + private handleIndexSignature(node: ts.Node): void { + if (!this.tsUtils.isAllowedIndexSignature(node as ts.IndexSignatureDeclaration)) { + this.incrementCounters(node, FaultID.IndexMember); + } + } + + private handleTypeLiteral(node: ts.Node): void { + const typeLiteral = node as ts.TypeLiteralNode; + const autofix = this.autofixer?.fixTypeliteral(typeLiteral); + this.incrementCounters(node, FaultID.ObjectTypeLiteral, autofix); + } + + private scanCapturedVarsInSendableScope(startNode: ts.Node, scope: ts.Node, faultId: FaultID): void { + const callback = (node: ts.Node): void => { + // Namespace import will introduce closure in the es2abc compiler stage + if (!ts.isIdentifier(node) || this.checkNamespaceImportVar(node)) { + return; + } + + // The "b" of "A.b" should not be checked since it's load from object "A" + const parent: ts.Node = node.parent; + if (ts.isPropertyAccessExpression(parent) && parent.name === node) { + return; + } + // When overloading function, will misreport + if (ts.isFunctionDeclaration(startNode) && startNode.name === node) { + return; + } + + this.checkLocalDecl(node, scope, faultId); + }; + // Type nodes should not checked because no closure will be introduced + const stopCondition = (node: ts.Node): boolean => { + // already existed 'arkts-sendable-class-decoratos' error + if (ts.isDecorator(node) && node.parent === startNode) { + return true; + } + return ts.isTypeReferenceNode(node); + }; + forEachNodeInSubtree(startNode, callback, stopCondition); + } + + private checkLocalDecl(node: ts.Identifier, scope: ts.Node, faultId: FaultID): void { + const trueSym = this.tsUtils.trueSymbolAtLocation(node); + // Sendable decorator should be used in method of Sendable classes + if (trueSym === undefined) { + return; + } + + // Const enum member will be replaced by the exact value of it, no closure will be introduced + if (TsUtils.isConstEnum(trueSym)) { + return; + } + + const declarations = trueSym.getDeclarations(); + if (declarations?.length) { + this.checkLocalDeclWithSendableClosure(node, scope, declarations[0], faultId); + } + } + + private checkLocalDeclWithSendableClosure( + node: ts.Identifier, + scope: ts.Node, + decl: ts.Declaration, + faultId: FaultID + ): void { + const declPosition = decl.getStart(); + if ( + decl.getSourceFile().fileName !== node.getSourceFile().fileName || + declPosition !== undefined && declPosition >= scope.getStart() && declPosition < scope.getEnd() + ) { + return; + } + + if (this.isFileExportDecl(decl)) { + return; + } + + if (this.isTopSendableClosure(decl)) { + return; + } + + /** + * The cases in condition will introduce closure if defined in the same file as the Sendable class. The following + * cases are excluded because they are not allowed in ArkTS: + * 1. ImportEqualDecalration + * 2. BindingElement + */ + if ( + ts.isVariableDeclaration(decl) || + ts.isFunctionDeclaration(decl) || + ts.isClassDeclaration(decl) || + ts.isInterfaceDeclaration(decl) || + ts.isEnumDeclaration(decl) || + ts.isModuleDeclaration(decl) || + ts.isParameter(decl) + ) { + this.incrementCounters(node, faultId); + } + } + + private isTopSendableClosure(decl: ts.Declaration): boolean { + if (!ts.isSourceFile(decl.parent)) { + return false; + } + if ( + ts.isClassDeclaration(decl) && + this.tsUtils.isSendableClassOrInterface(this.tsTypeChecker.getTypeAtLocation(decl)) + ) { + return true; + } + if (ts.isFunctionDeclaration(decl) && TsUtils.hasSendableDecoratorFunctionOverload(decl)) { + return true; + } + return false; + } + + private checkNamespaceImportVar(node: ts.Node): boolean { + // Namespace import cannot be determined by the true symbol + const sym = this.tsTypeChecker.getSymbolAtLocation(node); + const decls = sym?.getDeclarations(); + if (decls?.length) { + if (ts.isNamespaceImport(decls[0])) { + this.incrementCounters(node, FaultID.SendableCapturedVars); + return true; + } + } + return false; + } + + private isFileExportDecl(decl: ts.Declaration): boolean { + const sourceFile = decl.getSourceFile(); + if (!this.fileExportDeclCaches) { + this.fileExportDeclCaches = this.tsUtils.searchFileExportDecl(sourceFile); + } + return this.fileExportDeclCaches.has(decl); + } + + private handleExportKeyword(node: ts.Node): void { + const parentNode = node.parent; + if (!TypeScriptLinter.inSharedModule(node) || ts.isModuleBlock(parentNode.parent)) { + return; + } + + switch (parentNode.kind) { + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: + if (!this.tsUtils.isShareableType(this.tsTypeChecker.getTypeAtLocation(parentNode))) { + this.incrementCounters((parentNode as ts.NamedDeclaration).name ?? parentNode, FaultID.SharedModuleExports); + } + return; + case ts.SyntaxKind.VariableStatement: + for (const variableDeclaration of (parentNode as ts.VariableStatement).declarationList.declarations) { + if (!this.tsUtils.isShareableEntity(variableDeclaration.name)) { + this.incrementCounters(variableDeclaration.name, FaultID.SharedModuleExports); + } + } + return; + case ts.SyntaxKind.TypeAliasDeclaration: + if (!this.tsUtils.isShareableEntity(parentNode)) { + this.incrementCounters(parentNode, FaultID.SharedModuleExportsWarning); + } + return; + default: + this.incrementCounters(parentNode, FaultID.SharedModuleExports); + } + } + + private handleExportDeclaration(node: ts.Node): void { + const exportDecl = node as ts.ExportDeclaration; + + if (this.isExportedEntityDeclaredInJs(exportDecl)) { + this.incrementCounters(node, FaultID.InteropJsObjectExport); + return; } - if ( - !(tsModuleDecl.flags & ts.NodeFlags.Namespace) && - TsUtils.hasModifier(tsModifiers, ts.SyntaxKind.DeclareKeyword) - ) { - this.incrementCounters(tsModuleDecl, FaultID.ShorthandAmbientModuleDecl); + if (this.isExportedEntityDeclaredInArkTs1(exportDecl)) { + this.incrementCounters(node, FaultID.InteropArkTs1ObjectExport); + return; } - if (ts.isStringLiteral(tsModuleDecl.name) && tsModuleDecl.name.text.includes('*')) { - this.incrementCounters(tsModuleDecl, FaultID.WildcardsInModuleName); + if (!TypeScriptLinter.inSharedModule(node) || ts.isModuleBlock(node.parent)) { + return; } - } - private handleNameSpaceModuleBlock(moduleBlock: ts.ModuleBlock, nameSpace: string): void { - if (!TypeScriptLinter.nameSpaceFunctionCache.has(nameSpace)) { - TypeScriptLinter.nameSpaceFunctionCache.set(nameSpace, new Set()); + if (exportDecl.exportClause === undefined) { + this.incrementCounters(exportDecl, FaultID.SharedModuleNoWildcardExport); + return; } - const nameSet = TypeScriptLinter.nameSpaceFunctionCache.get(nameSpace)!; + if (ts.isNamespaceExport(exportDecl.exportClause)) { + if (!this.tsUtils.isShareableType(this.tsTypeChecker.getTypeAtLocation(exportDecl.exportClause.name))) { + this.incrementCounters(exportDecl.exportClause.name, FaultID.SharedModuleExports); + } + return; + } - for (const statement of moduleBlock.statements) { - const names = TypeScriptLinter.getDeclarationNames(statement); - for (const name of names) { - if (nameSet.has(name)) { - this.incrementCounters(statement, FaultID.NoDuplicateFunctionName); - } else { - nameSet.add(name); - } + for (const exportSpecifier of exportDecl.exportClause.elements) { + if (!this.tsUtils.isShareableEntity(exportSpecifier.name)) { + this.incrementCounters(exportSpecifier.name, FaultID.SharedModuleExports); } } } - private static getDeclarationNames(statement: ts.Statement): Set { - const names = new Set(); - - if ( - ts.isFunctionDeclaration(statement) && statement.name && statement.body || - ts.isClassDeclaration(statement) && statement.name || - ts.isInterfaceDeclaration(statement) && statement.name || - ts.isEnumDeclaration(statement) && statement.name - ) { - names.add(statement.name.text); - return names; + private handleReturnStatement(node: ts.Node): void { + // The return value must match the return type of the 'function' + const returnStat = node as ts.ReturnStatement; + const expr = returnStat.expression; + if (!expr) { + return; } - - if (ts.isVariableStatement(statement)) { - for (const decl of statement.declarationList.declarations) { - if (ts.isIdentifier(decl.name)) { - names.add(decl.name.text); - } - } + const lhsType = this.tsTypeChecker.getContextualType(expr); + if (!lhsType) { + return; } - - return names; + this.checkAssignmentMatching(node, lhsType, expr, true); + this.handleObjectLiteralInReturn(returnStat); + this.handleObjectLiteralAssignmentToClass(returnStat); } - private handleModuleBlock(moduleBlock: ts.ModuleBlock): void { - for (const tsModuleStmt of moduleBlock.statements) { - switch (tsModuleStmt.kind) { - case ts.SyntaxKind.VariableStatement: - case ts.SyntaxKind.FunctionDeclaration: - case ts.SyntaxKind.ClassDeclaration: - case ts.SyntaxKind.InterfaceDeclaration: - case ts.SyntaxKind.TypeAliasDeclaration: - case ts.SyntaxKind.EnumDeclaration: - case ts.SyntaxKind.ExportDeclaration: - break; - - /* - * Nested namespace declarations are prohibited - * but there is no cookbook recipe for it! - */ - case ts.SyntaxKind.ModuleDeclaration: - break; - default: - this.incrementCounters(tsModuleStmt, FaultID.NonDeclarationInNamespace); - break; - } + /** + * 'arkts-no-structural-typing' check was missing in some scenarios, + * in order not to cause incompatibility, + * only need to strictly match the type of filling the check again + */ + private checkAssignmentMatching( + field: ts.Node, + lhsType: ts.Type, + rhsExpr: ts.Expression, + isNewStructuralCheck: boolean = false + ): void { + const rhsType = this.tsTypeChecker.getTypeAtLocation(rhsExpr); + this.handleNoTuplesArrays(field, lhsType, rhsType); + // check that 'sendable typeAlias' is assigned correctly + if (this.tsUtils.isWrongSendableFunctionAssignment(lhsType, rhsType)) { + this.incrementCounters(field, 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; + } + if (this.tsUtils.needToDeduceStructuralIdentity(lhsType, rhsType, rhsExpr, isStrict)) { + this.incrementCounters(field, FaultID.StructuralIdentity); } } - private handleTypeAliasDeclaration(node: ts.Node): void { - const tsTypeAlias = node as ts.TypeAliasDeclaration; - this.countDeclarationsWithDuplicateName(tsTypeAlias.name, tsTypeAlias); - this.handleInvalidIdentifier(tsTypeAlias); - if (TsUtils.hasSendableDecorator(tsTypeAlias)) { - if (!this.isSendableDecoratorValid(tsTypeAlias)) { - return; - } - TsUtils.getNonSendableDecorators(tsTypeAlias)?.forEach((decorator) => { - this.incrementCounters(decorator, FaultID.SendableTypeAliasDecorator); - }); - if (!ts.isFunctionTypeNode(tsTypeAlias.type)) { - this.incrementCounters(tsTypeAlias.type, FaultID.SendableTypeAliasDeclaration); + private handleDecorator(node: ts.Node): void { + this.handleExtendDecorator(node); + this.handleEntryDecorator(node); + this.handleProvideDecorator(node); + this.handleLocalBuilderDecorator(node); + + const decorator: ts.Decorator = node as ts.Decorator; + this.checkSendableAndConcurrentDecorator(decorator); + this.handleStylesDecorator(decorator); + if (TsUtils.getDecoratorName(decorator) === SENDABLE_DECORATOR) { + const parent: ts.Node = decorator.parent; + if (!parent || !SENDABLE_DECORATOR_NODES.includes(parent.kind)) { + const autofix = this.autofixer?.removeNode(decorator); + this.incrementCounters(decorator, FaultID.SendableDecoratorLimited, autofix); } } - if (this.options.arkts2 && tsTypeAlias.type.kind === ts.SyntaxKind.VoidKeyword) { - this.incrementCounters(tsTypeAlias.type, FaultID.LimitedVoidType); - } + this.handleNotSupportCustomDecorators(decorator); } - private handleTupleType(node: ts.TupleTypeNode): void { + private handleProvideDecorator(node: ts.Node): void { if (!this.options.arkts2) { return; } - node.elements.forEach((elementType) => { - if (elementType.kind === ts.SyntaxKind.VoidKeyword) { - this.incrementCounters(elementType, FaultID.LimitedVoidType); + if (!ts.isDecorator(node)) { + return; + } + + if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { + if (node.expression.expression.text !== PROVIDE_DECORATOR_NAME || node.expression.arguments.length !== 1) { + return; } - }); + const arg = node.expression.arguments[0]; + if (!ts.isStringLiteral(arg) && !ts.isObjectLiteralExpression(arg)) { + return; + } + if (ts.isObjectLiteralExpression(arg)) { + const properties = arg.properties; + if (properties.length !== 1) { + return; + } + const property = properties[0] as ts.PropertyAssignment; + if (!ts.isIdentifier(property.name) || !ts.isStringLiteral(property.initializer)) { + return; + } + if (property.name.escapedText !== PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME) { + return; + } + } + const autofix = this.autofixer?.fixProvideDecorator(node); + this.incrementCounters(node.parent, FaultID.ProvideAnnotation, autofix); + } } - private handleImportClause(node: ts.Node): void { - const tsImportClause = node as ts.ImportClause; - if (this.options.arkts2 && tsImportClause.isLazy) { - this.incrementCounters(node, FaultID.ImportLazyIdentifier); + private isSendableDecoratorValid(decl: ts.FunctionDeclaration | ts.TypeAliasDeclaration): boolean { + if ( + this.compatibleSdkVersion > SENDBALE_FUNCTION_START_VERSION || + this.compatibleSdkVersion === SENDBALE_FUNCTION_START_VERSION && + !SENDABLE_FUNCTION_UNSUPPORTED_STAGES_IN_API12.includes(this.compatibleSdkVersionStage) + ) { + return true; } - if (tsImportClause.name) { - this.countDeclarationsWithDuplicateName(tsImportClause.name, tsImportClause); + const curDecorator = TsUtils.getSendableDecorator(decl); + if (curDecorator) { + this.incrementCounters(curDecorator, FaultID.SendableBetaCompatible); } + return false; } - private handleImportSpecifier(node: ts.Node): void { - const importSpec = node as ts.ImportSpecifier; - this.countDeclarationsWithDuplicateName(importSpec.name, importSpec); + private handleImportType(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + this.incrementCounters(node, FaultID.ImportType); + this.incrementCounters(node, FaultID.DynamicImport); } - private handleNamespaceImport(node: ts.Node): void { - const tsNamespaceImport = node as ts.NamespaceImport; - this.countDeclarationsWithDuplicateName(tsNamespaceImport.name, tsNamespaceImport); + private handleVoidExpression(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + const autofix = this.autofixer?.fixVoidOperator(node as ts.VoidExpression); + this.incrementCounters(node, FaultID.VoidOperator, autofix); } - private handleTypeAssertionExpression(node: ts.Node): void { - const tsTypeAssertion = node as ts.TypeAssertion; - if (tsTypeAssertion.type.getText() === 'const') { - this.incrementCounters(tsTypeAssertion, FaultID.ConstAssertion); - } else { - const autofix = this.autofixer?.fixTypeAssertion(tsTypeAssertion); - this.incrementCounters(node, FaultID.TypeAssertion, autofix); + private handleRegularExpressionLiteral(node: ts.Node): void { + if (!this.options.arkts2) { + return; } + const autofix = this.autofixer?.fixRegularExpressionLiteral(node as ts.RegularExpressionLiteral); + this.incrementCounters(node, FaultID.RegularExpressionLiteral, autofix); } - private handleMethodDeclaration(node: ts.Node): void { - const tsMethodDecl = node as ts.MethodDeclaration; - TsUtils.getDecoratorsIfInSendableClass(tsMethodDecl)?.forEach((decorator) => { - this.incrementCounters(decorator, FaultID.SendableClassDecorator); - }); - let isStatic = false; - if (tsMethodDecl.modifiers) { - for (const mod of tsMethodDecl.modifiers) { - if (mod.kind === ts.SyntaxKind.StaticKeyword) { - isStatic = true; - break; - } - } - } - if (tsMethodDecl.body && isStatic) { - this.reportThisKeywordsInScope(tsMethodDecl.body); - } - if (!tsMethodDecl.type) { - this.handleMissingReturnType(tsMethodDecl); + private handleLimitedVoidType(node: ts.VariableDeclaration): void { + if (!this.options.arkts2) { + return; } - if (tsMethodDecl.asteriskToken) { - this.incrementCounters(node, FaultID.GeneratorFunction); + + const typeNode = node.type; + if (typeNode && typeNode.kind === ts.SyntaxKind.VoidKeyword) { + this.incrementCounters(typeNode, FaultID.LimitedVoidType); } - this.filterOutDecoratorsDiagnostics( - ts.getDecorators(tsMethodDecl), - NON_RETURN_FUNCTION_DECORATORS, - { begin: tsMethodDecl.parameters.end, end: tsMethodDecl.body?.getStart() ?? tsMethodDecl.parameters.end }, - FUNCTION_HAS_NO_RETURN_ERROR_CODE - ); - if (this.options.arkts2 && tsMethodDecl.questionToken) { - this.incrementCounters(tsMethodDecl.questionToken, FaultID.OptionalMethod); + } + + private handleLimitedVoidWithCall(node: ts.CallExpression): void { + if (!this.options.arkts2) { + return; } - this.handleInvalidIdentifier(tsMethodDecl); - if (!this.tsUtils.isAbstractMethodInAbstractClass(node)) { - this.handleTSOverload(tsMethodDecl); + + if (ts.isPropertyAccessExpression(node.parent)) { + return; } - } - private checkClassImplementsMethod(classDecl: ts.ClassDeclaration, methodName: string): boolean { - for (const member of classDecl.members) { - if (member.name?.getText() === methodName) { - if (ts.isPropertyDeclaration(member)) { - this.incrementCounters(member, FaultID.MethodOverridingField); - } + const signature = this.tsTypeChecker.getResolvedSignature(node); + if (signature) { + const returnType = this.tsTypeChecker.getReturnTypeOfSignature(signature); + if (this.tsTypeChecker.typeToString(returnType) === 'void') { + this.incrementCounters(node, FaultID.LimitedVoidType); } } - return false; } - private handleMethodSignature(node: ts.MethodSignature): void { - const tsMethodSign = node; - if (this.options.arkts2 && ts.isInterfaceDeclaration(node.parent)) { - const methodName = node.name.getText(); - const interfaceName = node.parent.name.getText(); - const allClasses = TypeScriptLinter.getAllClassesFromSourceFile(this.sourceFile!); - const allInterfaces = TypeScriptLinter.getAllInterfaceFromSourceFile(this.sourceFile!); - allClasses.forEach((classDecl) => { - if (this.classImplementsInterface(classDecl, interfaceName)) { - this.checkClassImplementsMethod(classDecl, methodName); - } - }); - allInterfaces.forEach((interDecl) => { - if (this.interfaceExtendsInterface(interDecl, interfaceName)) { - this.checkInterfaceExtendsMethod(interDecl, methodName); - } - }); + private handleArrayType(arrayType: ts.Node): void { + if (!this.options.arkts2) { + return; } - if (!tsMethodSign.type) { - this.handleMissingReturnType(tsMethodSign); + + if (!arrayType || !ts.isArrayTypeNode(arrayType)) { + return; } - if (this.options.arkts2 && tsMethodSign.questionToken) { - this.incrementCounters(tsMethodSign.questionToken, FaultID.OptionalMethod); + + if (arrayType.elementType.kind === ts.SyntaxKind.VoidKeyword) { + this.incrementCounters(arrayType.elementType, FaultID.LimitedVoidType); } - this.handleInvalidIdentifier(tsMethodSign); } - private interfaceExtendsInterface(interDecl: ts.InterfaceDeclaration, interfaceName: string): boolean { - void this; - if (!interDecl.heritageClauses) { - return false; + private handleUnionType(unionType: ts.Node): void { + if (!this.options.arkts2) { + return; } - return interDecl.heritageClauses.some((clause) => { - return clause.types.some((type) => { - return ( - ts.isExpressionWithTypeArguments(type) && - ts.isIdentifier(type.expression) && - type.expression.text === interfaceName - ); - }); - }); - } - private checkInterfaceExtendsMethod(interDecl: ts.InterfaceDeclaration, methodName: string): void { - for (const member of interDecl.members) { - if (member.name?.getText() === methodName) { - if (ts.isPropertySignature(member)) { - this.incrementCounters(member, FaultID.MethodOverridingField); - } + if (!unionType || !ts.isUnionTypeNode(unionType)) { + return; + } + + const types = unionType.types; + for (const type of types) { + if (type.kind === ts.SyntaxKind.VoidKeyword) { + this.incrementCounters(type, FaultID.LimitedVoidType); } } } - private classImplementsInterface(classDecl: ts.ClassDeclaration, interfaceName: string): boolean { - void this; - if (!classDecl.heritageClauses) { - return false; + private handleDebuggerStatement(node: ts.Node): void { + if (!this.options.arkts2) { + return; } - return classDecl.heritageClauses.some((clause) => { - return clause.types.some((type) => { - return ( - ts.isExpressionWithTypeArguments(type) && - ts.isIdentifier(type.expression) && - type.expression.text === interfaceName - ); - }); - }); + const autofix = this.autofixer?.fixDebuggerStatement(node as ts.DebuggerStatement); + this.incrementCounters(node, FaultID.DebuggerStatement, autofix); } - private handleClassStaticBlockDeclaration(node: ts.Node): void { - const classStaticBlockDecl = node as ts.ClassStaticBlockDeclaration; - if (!ts.isClassDeclaration(classStaticBlockDecl.parent)) { + private handleTSOverload(decl: ts.FunctionDeclaration | ts.MethodDeclaration | ts.ConstructorDeclaration): void { + if (!this.options.arkts2) { return; } - this.reportThisKeywordsInScope(classStaticBlockDecl.body); + if (decl.name) { + const symbol = this.tsTypeChecker.getSymbolAtLocation(decl.name); + if (!symbol) { + return; + } + const declarations = symbol.getDeclarations(); + if (!declarations) { + return; + } + const filterDecl = declarations.filter((name) => { + return ts.isFunctionDeclaration(name) || ts.isMethodDeclaration(name); + }); + const isInternalFunction = decl.name && ts.isIdentifier(decl.name) && interanlFunction.includes(decl.name.text); + if (isInternalFunction && filterDecl.length > 2 || !isInternalFunction && filterDecl.length > 1) { + this.incrementCounters(decl, FaultID.TsOverload); + } + } else if (ts.isConstructorDeclaration(decl) && decl.getText()) { + this.handleTSOverloadUnderConstructorDeclaration(decl); + } } - private handleIdentifier(node: ts.Node): void { - if (!ts.isIdentifier(node)) { - return; + private handleTSOverloadUnderConstructorDeclaration(decl: ts.ConstructorDeclaration): void { + const parent = decl.parent; + const constructors = parent.members.filter(ts.isConstructorDeclaration); + const isStruct = decl.getText() && ts.isStructDeclaration(parent); + if ((isStruct ? --constructors.length : constructors.length) > 1) { + this.incrementCounters(decl, FaultID.TsOverload); } - this.handleInterfaceImport(node); - const tsIdentifier = node; - const tsIdentSym = this.tsUtils.trueSymbolAtLocation(tsIdentifier); - if (!tsIdentSym) { + } + + private handleSwitchStatement(node: ts.Node): void { + if (!this.options.arkts2) { return; } + const switchStatement = node as ts.SwitchStatement; - const isArkTs2 = this.options.arkts2; - const isGlobalThis = tsIdentifier.text === 'globalThis'; + this.validateSwitchExpression(switchStatement); - if ( - isGlobalThis && - (tsIdentSym.flags & ts.SymbolFlags.Module) !== 0 && - (tsIdentSym.flags & ts.SymbolFlags.Transient) !== 0 - ) { - this.handleGlobalThisCase(tsIdentifier, isArkTs2); - } else { - if (isArkTs2) { - this.checkLimitedStdlibApi(tsIdentifier, tsIdentSym); + const duplicateCases = this.findDuplicateCases(switchStatement); + if (duplicateCases.length > 0) { + for (const duplicateCase of duplicateCases) { + this.incrementCounters(duplicateCase.expression, FaultID.CaseExpression); } - this.handleRestrictedValues(tsIdentifier, tsIdentSym); } + } - if (isArkTs2 && this.tsTypeChecker.isArgumentsSymbol(tsIdentSym)) { - this.incrementCounters(node, FaultID.ArgumentsObject); + private validateSwitchExpression(switchStatement: ts.SwitchStatement): void { + const expr = switchStatement.expression; + const nodeType = this.tsTypeChecker.getTypeAtLocation(expr); + const { isLiteralInitialized, isFloatLiteral, hasExplicitTypeAnnotation } = this.getDeclarationInfo(expr); + + const isUnionType = (nodeType.flags & ts.TypeFlags.Union) !== 0; + + const isTypeAllowed = (t: ts.Type): boolean => { + const typeText = this.tsTypeChecker.typeToString(t); + return Boolean( + t.flags & ts.TypeFlags.StringLike || + typeText === 'String' || + t.flags & ts.TypeFlags.NumberLike && (/^\d+$/).test(typeText) || + isLiteralInitialized && !hasExplicitTypeAnnotation && !isFloatLiteral || + t.flags & ts.TypeFlags.EnumLike + ); + }; + + let isAllowed = !isUnionType && isTypeAllowed(nodeType); + + if (isUnionType) { + const unionType = nodeType as ts.UnionType; + isAllowed = unionType.types.every(isTypeAllowed); } - if (isArkTs2) { - this.checkWorkerSymbol(tsIdentSym, node); + if (!isAllowed) { + this.incrementCounters(expr, FaultID.SwitchExpression); } - if (isArkTs2 && tsIdentifier.text === LIKE_FUNCTION && isStdLibrarySymbol(tsIdentSym)) { - this.incrementCounters(node, FaultID.ExplicitFunctionType); + } + + private getDeclarationInfo(expression: ts.Expression): { + isLiteralInitialized: boolean; + isFloatLiteral: boolean; + hasExplicitTypeAnnotation: boolean; + } { + const symbol = this.tsTypeChecker.getSymbolAtLocation(expression); + const declaration = symbol?.valueDeclaration; + + if (!declaration || !ts.isVariableDeclaration(declaration)) { + return { isLiteralInitialized: false, isFloatLiteral: false, hasExplicitTypeAnnotation: false }; } + + const hasExplicitTypeAnnotation = !!declaration.type; + const initializerInfo = TypeScriptLinter.getInitializerInfo(declaration.initializer); + + return { + isLiteralInitialized: initializerInfo.isLiteralInitialized, + isFloatLiteral: initializerInfo.isFloatLiteral, + hasExplicitTypeAnnotation + }; } - private handleGlobalThisCase(node: ts.Identifier, isArkTs2: boolean | undefined): void { - let faultId = FaultID.GlobalThis; - let autofix: Autofix[] | undefined; - let targetNode: ts.Node = node; + private static getInitializerInfo(initializer?: ts.Expression): { + isLiteralInitialized: boolean; + isFloatLiteral: boolean; + } { + if (!initializer) { + return { isLiteralInitialized: false, isFloatLiteral: false }; + } - if (!isArkTs2) { - this.incrementCounters(targetNode, faultId); - return; + const isLiteralInitialized = ts.isNumericLiteral(initializer) || ts.isStringLiteral(initializer); + + let isFloatLiteral = false; + if (ts.isNumericLiteral(initializer)) { + const literalText = initializer.getText(); + if (!(/^0[xX]/).test(literalText)) { + isFloatLiteral = (/\.|e[-+]|\dE[-+]/i).test(literalText); + } } - faultId = FaultID.GlobalThisError; - if (ts.isPropertyAccessExpression(node.parent)) { - const parentExpression = node.parent.parent; - if ( - parentExpression && - ts.isBinaryExpression(parentExpression) && - parentExpression.operatorToken.kind === ts.SyntaxKind.EqualsToken - ) { - targetNode = parentExpression; - autofix = this.autofixer?.fixGlobalThisSet(targetNode as ts.BinaryExpression); - } else { - targetNode = node.parent; - autofix = this.autofixer?.fixGlobalThisGet(targetNode as ts.PropertyAccessExpression); + return { isLiteralInitialized, isFloatLiteral }; + } + + private findDuplicateCases(switchStatement: ts.SwitchStatement): ts.CaseClause[] { + const seenValues = new Map(); + const duplicates: ts.CaseClause[] = []; + + for (const clause of switchStatement.caseBlock.clauses) { + if (ts.isCaseClause(clause) && clause.expression) { + const value = this.getConstantValue(clause.expression); + const key = value !== undefined ? value : clause.expression.getText(); + if (seenValues.has(key)) { + duplicates.push(clause); + } else { + seenValues.set(key, clause); + } } } + return duplicates; + } + + private getConstantValue(expression: ts.Expression): string | number | boolean | undefined { + if (ts.isLiteralExpression(expression)) { + return ts.isNumericLiteral(expression) ? Number(expression.text) : expression.text; + } - this.incrementCounters(targetNode, faultId, autofix); + switch (expression.kind) { + case ts.SyntaxKind.TrueKeyword: + return true; + case ts.SyntaxKind.FalseKeyword: + return false; + default: + if (ts.isElementAccessExpression(expression) || ts.isPropertyAccessExpression(expression)) { + const constantValue = this.tsTypeChecker.getConstantValue(expression); + if (constantValue !== undefined) { + return constantValue; + } + } + return undefined; + } } - // hard-coded alternative to TypeScriptLinter.advancedClassChecks - private isAllowedClassValueContext(tsIdentifier: ts.Identifier): boolean { - let ctx: ts.Node = tsIdentifier; - while (ts.isPropertyAccessExpression(ctx.parent) || ts.isQualifiedName(ctx.parent)) { - ctx = ctx.parent; + private handleLimitedLiteralType(literalTypeNode: ts.LiteralTypeNode): void { + if (!this.options.arkts2 || !literalTypeNode) { + return; } - if (ts.isPropertyAssignment(ctx.parent) && ts.isObjectLiteralExpression(ctx.parent.parent)) { - ctx = ctx.parent.parent; + const literal = literalTypeNode.literal; + if ( + !( + literal.kind === ts.SyntaxKind.StringLiteral || + literal.kind === ts.SyntaxKind.NullKeyword || + literal.kind === ts.SyntaxKind.UndefinedKeyword + ) + ) { + this.incrementCounters(literalTypeNode, FaultID.LimitedLiteralType); } - if (ts.isArrowFunction(ctx.parent) && ctx.parent.body === ctx) { - ctx = ctx.parent; + } + + private findVariableInitializationValue(identifier: ts.Identifier): number | null { + const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); + if (!symbol) { + return null; + } + if (this.constVariableInitCache.has(symbol)) { + return this.constVariableInitCache.get(symbol)!; + } + const declarations = symbol.getDeclarations(); + if (declarations && declarations.length > 0) { + const declaration = declarations[0]; + + const isConditionOnEnumMember = ts.isEnumMember(declaration) && declaration.initializer; + const isConditionOnVariableDecl = + ts.isVariableDeclaration(declaration) && + declaration.initializer && + (declaration.parent as ts.VariableDeclarationList).flags & ts.NodeFlags.Const; + if (isConditionOnEnumMember || isConditionOnVariableDecl) { + const res = this.evaluateNumericValue(declaration.initializer); + this.constVariableInitCache.set(symbol, res); + return res; + } } - if (ts.isCallExpression(ctx.parent) || ts.isNewExpression(ctx.parent)) { - const callee = ctx.parent.expression; - const isAny = TsUtils.isAnyType(this.tsTypeChecker.getTypeAtLocation(callee)); - const isDynamic = isAny || this.tsUtils.hasLibraryType(callee); - if (callee !== ctx && isDynamic) { - return true; + return null; + } + + private evaluateNumericValueFromPrefixUnaryExpression(node: ts.PrefixUnaryExpression): number | null { + if (node.operator === ts.SyntaxKind.MinusToken) { + if (ts.isNumericLiteral(node.operand) || ts.isIdentifier(node.operand) && node.operand.text === 'Infinity') { + return node.operand.text === 'Infinity' ? Number.NEGATIVE_INFINITY : -Number(node.operand.text); + } + const operandValue = this.evaluateNumericValue(node.operand); + if (operandValue !== null) { + return -operandValue; } } - return false; + return null; } - private isStdlibClassVarDecl(ident: ts.Identifier, sym: ts.Symbol): boolean { - - /* - * Most standard JS classes are defined in TS stdlib as ambient global - * variables with interface constructor type and require special check - * when they are being referenced in code. - */ - + private evaluateNumericValueFromAsExpression(node: ts.AsExpression): number | null { + const typeNode = node.type; if ( - !isStdLibrarySymbol(sym) || - !sym.valueDeclaration || - !ts.isVariableDeclaration(sym.valueDeclaration) || - !TsUtils.isAmbientNode(sym.valueDeclaration) + typeNode.kind === ts.SyntaxKind.NumberKeyword || + ts.isTypeReferenceNode(typeNode) && typeNode.typeName.getText() === 'Number' ) { - return false; - } - - /* - * issue 24075: TS supports calling the constructor of built-in types - * as function (without 'new' keyword): `const a = Number('10')` - * Such cases need to be filtered out. - */ - if (ts.isCallExpression(ident.parent) && ident.parent.expression === ident) { - return false; + return this.evaluateNumericValue(node.expression); } + return null; + } - const classVarDeclType = StdClassVarDecls.get(sym.name); - if (!classVarDeclType) { - return false; + private evaluateNumericValue(node: ts.Expression): number | null { + let result: number | null = null; + if (ts.isNumericLiteral(node)) { + result = Number(node.text); + } else if (ts.isPrefixUnaryExpression(node)) { + result = this.evaluateNumericValueFromPrefixUnaryExpression(node); + } else if (ts.isBinaryExpression(node)) { + result = this.evaluateNumericValueFromBinaryExpression(node); + } else if (ts.isPropertyAccessExpression(node)) { + result = this.evaluateNumericValueFromPropertyAccess(node); + } else if (ts.isParenthesizedExpression(node)) { + result = this.evaluateNumericValue(node.expression); + } else if (ts.isAsExpression(node)) { + result = this.evaluateNumericValueFromAsExpression(node); + } else if (ts.isIdentifier(node)) { + if (node.text === 'Infinity') { + return Number.POSITIVE_INFINITY; + } else if (node.text === 'NaN') { + return Number.NaN; + } + const symbol = this.tsTypeChecker.getSymbolAtLocation(node); + return symbol ? this.constVariableInitCache.get(symbol) || null : null; } - const declType = this.tsTypeChecker.getTypeAtLocation(ident); - return declType.symbol && declType.symbol.name === classVarDeclType; + return result; } - private handleRestrictedValues(tsIdentifier: ts.Identifier, tsIdentSym: ts.Symbol): void { - const illegalValues = - ts.SymbolFlags.ConstEnum | - ts.SymbolFlags.RegularEnum | - ts.SymbolFlags.ValueModule | - (this.options.advancedClassChecks ? 0 : ts.SymbolFlags.Class); - - /* - * If module name is duplicated by another declaration, this increases the possibility - * of finding a lot of false positives. Thus, do not check further in that case. - */ - if ((tsIdentSym.flags & ts.SymbolFlags.ValueModule) !== 0) { - if (!!tsIdentSym && TsUtils.symbolHasDuplicateName(tsIdentSym, ts.SyntaxKind.ModuleDeclaration)) { - return; + private evaluateNumericValueFromBinaryExpression(node: ts.BinaryExpression): number | null { + const leftValue = this.evaluateNumericValue(node.left); + const rightValue = this.evaluateNumericValue(node.right); + if (leftValue !== null && rightValue !== null) { + switch (node.operatorToken.kind) { + case ts.SyntaxKind.PlusToken: + return leftValue + rightValue; + case ts.SyntaxKind.MinusToken: + return leftValue - rightValue; + case ts.SyntaxKind.AsteriskToken: + return leftValue * rightValue; + case ts.SyntaxKind.SlashToken: + return leftValue / rightValue; + case ts.SyntaxKind.PercentToken: + return leftValue % rightValue; + case ts.SyntaxKind.AsteriskAsteriskToken: + return Math.pow(leftValue, rightValue); + default: + return null; } } + return null; + } + private evaluateNumericValueFromPropertyAccess(node: ts.PropertyAccessExpression): number | null { + const numberProperties = ['MIN_SAFE_INTEGER', 'MAX_SAFE_INTEGER', 'NaN', 'NEGATIVE_INFINITY', 'POSITIVE_INFINITY']; if ( - (tsIdentSym.flags & illegalValues) === 0 && - !(this.options.arkts2 && this.isStdlibClassVarDecl(tsIdentifier, tsIdentSym)) || - isStruct(tsIdentSym) || - !identiferUseInValueContext(tsIdentifier, tsIdentSym) + ts.isIdentifier(node.expression) && + node.expression.text === 'Number' && + numberProperties.includes(node.name.text) ) { - return; + switch (node.name.text) { + case 'MIN_SAFE_INTEGER': + return Number.MIN_SAFE_INTEGER; + case 'MAX_SAFE_INTEGER': + return Number.MAX_SAFE_INTEGER; + case 'NaN': + return Number.NaN; + case 'NEGATIVE_INFINITY': + return Number.NEGATIVE_INFINITY; + case 'POSITIVE_INFINITY': + return Number.POSITIVE_INFINITY; + default: + return null; + } } + return this.evaluateNumericValue(node.name); + } - if ((tsIdentSym.flags & ts.SymbolFlags.Class) !== 0) { - if (!this.options.advancedClassChecks && this.isAllowedClassValueContext(tsIdentifier)) { - return; + private collectVariableNamesAndCache(node: ts.Node): void { + if (ts.isIdentifier(node)) { + const value = this.findVariableInitializationValue(node); + const symbol = this.tsTypeChecker.getSymbolAtLocation(node); + if (value && symbol) { + this.constVariableInitCache.set(symbol, value); } } + ts.forEachChild(node, this.collectVariableNamesAndCache.bind(this)); + } - if (tsIdentSym.flags & ts.SymbolFlags.ValueModule) { - this.incrementCounters(tsIdentifier, FaultID.NamespaceAsObject); - } else { - // missing EnumAsObject - const faultId = this.options.arkts2 ? FaultID.ClassAsObjectError : FaultID.ClassAsObject; - this.incrementCounters(tsIdentifier, faultId); + private handleIndexNegative(node: ts.Node): void { + if (!this.options.arkts2 || !ts.isElementAccessExpression(node)) { + return; } - } + const indexNode = node.argumentExpression; + if (indexNode) { + this.collectVariableNamesAndCache(indexNode); + const indexValue = this.evaluateNumericValue(indexNode); - private isElementAcessAllowed(type: ts.Type, argType: ts.Type): boolean { - if (type.isUnion()) { - for (const t of type.types) { - if (!this.isElementAcessAllowed(t, argType)) { - return false; - } + if (indexValue !== null && (indexValue < 0 || isNaN(indexValue))) { + this.incrementCounters(node, FaultID.IndexNegative); } - return true; } + } - const typeNode = this.tsTypeChecker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.None); - - if (this.tsUtils.isArkTSCollectionsArrayLikeType(type)) { - return this.tsUtils.isNumberLikeType(argType); + private handleNoTuplesArrays(node: ts.Node, lhsType: ts.Type, rhsType: ts.Type): void { + if (!this.options.arkts2) { + return; + } + if ( + this.tsUtils.isOrDerivedFrom(lhsType, this.tsUtils.isArray) && + this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple) || + this.tsUtils.isOrDerivedFrom(rhsType, this.tsUtils.isArray) && + this.tsUtils.isOrDerivedFrom(lhsType, TsUtils.isTuple) + ) { + this.incrementCounters(node, FaultID.NoTuplesArrays); } - - return ( - this.tsUtils.isLibraryType(type) || - TsUtils.isAnyType(type) || - this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isIndexableArray) || - this.tsUtils.isOrDerivedFrom(type, TsUtils.isTuple) || - this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdRecordType) || - this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStringType) || - !this.options.arkts2 && - (this.tsUtils.isOrDerivedFrom(type, this.tsUtils.isStdMapType) || TsUtils.isIntrinsicObjectType(type)) || - TsUtils.isEnumType(type) || - // we allow EsObject here beacuse it is reported later using FaultId.EsObjectType - TsUtils.isEsObjectType(typeNode) - ); } - private handleElementAccessExpression(node: ts.Node): void { - const tsElementAccessExpr = node as ts.ElementAccessExpression; - const tsElementAccessExprSymbol = this.tsUtils.trueSymbolAtLocation(tsElementAccessExpr.expression); - const tsElemAccessBaseExprType = this.tsUtils.getNonNullableType( - this.tsUtils.getTypeOrTypeConstraintAtLocation(tsElementAccessExpr.expression) - ); - const tsElemAccessArgType = this.tsTypeChecker.getTypeAtLocation(tsElementAccessExpr.argumentExpression); - - const isSet = TsUtils.isSetExpression(tsElementAccessExpr); - const isSetIndexable = - isSet && - this.tsUtils.isSetIndexableType( - tsElemAccessBaseExprType, - tsElemAccessArgType, - this.tsTypeChecker.getTypeAtLocation((tsElementAccessExpr.parent as ts.BinaryExpression).right) - ); + private handleExponentOperation(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + const autofix = this.autofixer?.fixExponent(node.parent); + this.incrementCounters(node, FaultID.ExponentOp, autofix); + } - const isGet = !isSet; - const isGetIndexable = isGet && this.tsUtils.isGetIndexableType(tsElemAccessBaseExprType, tsElemAccessArgType); + private handleNonNullExpression(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } if ( - // unnamed types do not have symbol, so need to check that explicitly - !this.tsUtils.isLibrarySymbol(tsElementAccessExprSymbol) && - !ts.isArrayLiteralExpression(tsElementAccessExpr.expression) && - !this.isElementAcessAllowed(tsElemAccessBaseExprType, tsElemAccessArgType) && - !(this.options.arkts2 && isGetIndexable) && - !(this.options.arkts2 && isSetIndexable) + !ts.isNonNullExpression(node) || + !ts.isNonNullExpression(node.expression) || + ts.isNonNullExpression(node.parent) || + ts.isNonNullExpression(node.expression.expression) ) { - const autofix = this.autofixer?.fixPropertyAccessByIndex(tsElementAccessExpr); - this.incrementCounters(node, FaultID.PropertyAccessByIndex, autofix); + return; } - if (this.tsUtils.hasEsObjectType(tsElementAccessExpr.expression)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(node, faultId); - } - if (this.tsUtils.isOrDerivedFrom(tsElemAccessBaseExprType, this.tsUtils.isIndexableArray)) { - this.handleIndexNegative(node); + const statement = ts.findAncestor(node, ts.isExpressionStatement); + if (statement && this.isCustomComponent(statement)) { + let currentParam: ts.Identifier | undefined; + if (ts.isPropertyAccessExpression(node.expression.expression)) { + currentParam = node.expression.expression.name as ts.Identifier; + } + + let customParam: ts.Identifier | undefined; + if (ts.isPropertyAssignment(node.parent)) { + customParam = node.parent.name as ts.Identifier; + } + + if (!currentParam || !customParam) { + return; + } + + const originalExpr = node.parent.parent; + if (!ts.isObjectLiteralExpression(originalExpr)) { + return; + } + const autofix = this.autofixer?.fixCustomBidirectionalBinding(originalExpr, currentParam, customParam); + this.incrementCounters(node, FaultID.DoubleExclaBindingNotSupported, autofix); + } else { + const autofix = this.autofixer?.fixNativeBidirectionalBinding(node, this.interfacesNeedToImport); + this.incrementCounters(node, FaultID.DoubleExclaBindingNotSupported, autofix); } - this.checkArrayIndexType(tsElemAccessBaseExprType, tsElemAccessArgType, tsElementAccessExpr); } - private checkArrayIndexType(exprType: ts.Type, argType: ts.Type, expr: ts.ElementAccessExpression): void { - if (!this.options.arkts2 || !this.tsUtils.isOrDerivedFrom(exprType, this.tsUtils.isIndexableArray)) { - return; + private isCustomComponent(statement: ts.ExpressionStatement): boolean { + const callExpr = statement.expression; + if (!ts.isCallExpression(callExpr)) { + return false; } - const argExpr = TypeScriptLinter.getUnwrappedArgumentExpression(expr.argumentExpression); + const identifier = callExpr.expression; + if (!ts.isIdentifier(identifier)) { + return false; + } - if (this.tsUtils.isNumberLikeType(argType)) { - this.handleNumericArgument(argExpr); - } else if (this.tsTypeChecker.typeToString(argType) !== STRINGLITERAL_INT) { - this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); + const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); + if (symbol) { + const decl = this.tsUtils.getDeclarationNode(identifier); + if (decl?.getSourceFile() === statement.getSourceFile()) { + return true; + } } - } - private static getUnwrappedArgumentExpression(argExpr: ts.Expression): ts.Expression { - return argExpr.kind === ts.SyntaxKind.AsExpression ? (argExpr as ts.AsExpression).expression : argExpr; + return this.interfacesAlreadyImported.has(callExpr.expression.getText()); } - private handleNumericArgument(argExpr: ts.Expression): void { + private handleDoubleDollar(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } + if ( - ts.isNumericLiteral(argExpr) && !Number.isInteger(Number(argExpr.text)) || - argExpr.kind === ts.SyntaxKind.CallExpression + ts.isPropertyAccessExpression(node) && + ts.isIdentifier(node.expression) && + node.expression.escapedText === DOUBLE_DOLLAR_IDENTIFIER + THIS_IDENTIFIER ) { - this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); + const autofix = this.autofixer?.fixDoubleDollar(node, this.interfacesNeedToImport); + this.incrementCounters(node, FaultID.DoubleDollarBindingNotSupported, autofix); } - - this.checkNumericArgumentDeclaration(argExpr); } - private checkNumericArgumentDeclaration(argExpr: ts.Expression): void { - const symbol = this.tsTypeChecker.getSymbolAtLocation(argExpr); + private handleDollarBind(node: ts.Node): void { + if (!this.options.arkts2) { + return; + } - if (!symbol) { + if (!ts.isPropertyAssignment(node) || !ts.isIdentifier(node.initializer)) { return; } - const declarations = symbol.getDeclarations(); - if (!declarations || declarations.length === 0) { + const text = node.initializer.getText(); + if (!(/^\$.+$/).test(text)) { return; } - const firstDeclaration = declarations[0] as ts.VariableDeclaration; - const initializer = firstDeclaration.initializer; - const initializerText = initializer ? initializer.getText() : 'undefined'; - const isNumericInitializer = initializer && ts.isNumericLiteral(initializer); - const initializerNumber = isNumericInitializer ? Number(initializerText) : NaN; - const isUnsafeNumber = isNumericInitializer && !Number.isInteger(initializerNumber); - const isConstDeclaration = firstDeclaration.parent.flags === ts.NodeFlags.Let; - const isUndefinedButNotMaxSafeInteger = - initializerText === 'undefined' && argExpr.getText() !== 'Number.MAX_SAFE_INTEGER'; + const autofix = this.autofixer?.fixDollarBind(node); + this.incrementCounters(node, FaultID.DollarBindingNotSupported, autofix); + } - if ( - isUnsafeNumber || - firstDeclaration.parent.flags === ts.NodeFlags.Const && isUnsafeNumber || - isConstDeclaration || - isUndefinedButNotMaxSafeInteger - ) { - this.incrementCounters(argExpr, FaultID.ArrayIndexExprType); + private handleExtendDecorator(node: ts.Node): void { + if (!this.options.arkts2) { + return; } - } - private handleEnumMember(node: ts.Node): void { - const tsEnumMember = node as ts.EnumMember; - const tsEnumMemberType = this.tsTypeChecker.getTypeAtLocation(tsEnumMember); - const constVal = this.tsTypeChecker.getConstantValue(tsEnumMember); - const tsEnumMemberName = tsEnumMember.name; - if (this.options.arkts2 && ts.isStringLiteral(tsEnumMemberName)) { - this.handleStringLiteralEnumMember(tsEnumMember, tsEnumMemberName, node); + if (!ts.isFunctionDeclaration(node.parent) || !ts.isDecorator(node)) { + return; } - if (tsEnumMember.initializer && !this.tsUtils.isValidEnumMemberInit(tsEnumMember.initializer)) { - this.incrementCounters(node, FaultID.EnumMemberNonConstInit); + if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { + if (node.expression.expression.text === CustomDecoratorName.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) { + const autofix = this.autofixer?.fixExtendDecorator(node, true, this.interfacesNeedToImport); + this.incrementCounters(node.parent, FaultID.AnimatableExtendDecoratorTransform, autofix); + } } - // check for type - all members should be of same type - const enumDecl = tsEnumMember.parent; - const firstEnumMember = enumDecl.members[0]; - const firstEnumMemberType = this.tsTypeChecker.getTypeAtLocation(firstEnumMember); - const firstElewmVal = this.tsTypeChecker.getConstantValue(firstEnumMember); - this.handleEnumNotSupportFloat(tsEnumMember); + } - /* - * each string enum member has its own type - * so check that value type is string - */ - if ( - constVal !== undefined && - typeof constVal === STRINGLITERAL_STRING && - firstElewmVal !== undefined && - typeof firstElewmVal === STRINGLITERAL_STRING - ) { + private handleEntryDecorator(node: ts.Node): void { + if (!this.options.arkts2) { return; } - if ( - constVal !== undefined && - typeof constVal === STRINGLITERAL_NUMBER && - firstElewmVal !== undefined && - typeof firstElewmVal === STRINGLITERAL_NUMBER - ) { + + if (!ts.isDecorator(node)) { return; } - if (firstEnumMemberType !== tsEnumMemberType) { - this.incrementCounters(node, FaultID.EnumMemberNonConstInit); - } - } - private handleStringLiteralEnumMember( - tsEnumMember: ts.EnumMember, - tsEnumMemberName: ts.StringLiteral, - node: ts.Node - ): void { - const autofix = this.autofixer?.fixLiteralAsPropertyNamePropertyName(tsEnumMemberName); - this.autofixer?.checkEnumMemberNameConflict(tsEnumMember, autofix); - this.incrementCounters(node, FaultID.LiteralAsPropertyName, autofix); + if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { + if (node.expression.expression.escapedText !== ENTRY_DECORATOR_NAME || node.expression.arguments.length !== 1) { + return; + } + const arg = node.expression.arguments[0]; + if (ts.isObjectLiteralExpression(arg)) { + const properties = arg.properties; + if (properties.length !== 1) { + return; + } + if (!ts.isPropertyAssignment(properties[0])) { + return; + } + const property = properties[0]; + if (ts.isStringLiteral(property.initializer)) { + return; + } + } + const autofix = this.autofixer?.fixEntryDecorator(node); + this.incrementCounters(node, FaultID.EntryAnnotation, autofix); + } } - private handleEnumNotSupportFloat(enumMember: ts.EnumMember): void { + private handleStructPropertyDecl(propDecl: ts.PropertyDeclaration): void { if (!this.options.arkts2) { return; } - const initializer = enumMember.initializer; - if (!initializer) { - return; - } - let value; - if (ts.isNumericLiteral(initializer)) { - value = parseFloat(initializer.text); - } else if (ts.isPrefixUnaryExpression(initializer)) { - const operand = initializer.operand; - value = ts.isNumericLiteral(operand) ? parseFloat(operand.text) : value; - } else { - return; - } + const isStatic = TsUtils.hasModifier(propDecl.modifiers, ts.SyntaxKind.StaticKeyword); + const hasNoInitializer = !propDecl.initializer; + const isOptional = !!propDecl.questionToken; - if (!Number.isInteger(value)) { - this.incrementCounters(enumMember, FaultID.EnumMemberNonConstInit); - } - } + const defaultSkipTypeCheck = (typeNode: ts.TypeNode | undefined): boolean => { + if (!typeNode) { + return false; + } - private handleExportAssignment(node: ts.Node): void { - const exportAssignment = node as ts.ExportAssignment; - if (exportAssignment.isExportEquals) { - this.incrementCounters(node, FaultID.ExportAssignment); + const typeText = typeNode.getText(); + if (ts.isLiteralTypeNode(typeNode) || ['boolean', 'number', 'null', 'undefined'].includes(typeText)) { + return true; + } + + if (ts.isUnionTypeNode(typeNode)) { + return typeNode.types.some((t) => { + const tText = t.getText(); + return tText === 'undefined'; + }); + } + + return false; + }; + + const shouldSkipCheck = isOptional || defaultSkipTypeCheck(propDecl.type); + + if (isStatic && hasNoInitializer && !shouldSkipCheck) { + this.incrementCounters(propDecl, FaultID.ClassstaticInitialization); } + } - if (!TypeScriptLinter.inSharedModule(node)) { + private handleTaggedTemplatesExpression(node: ts.Node): void { + if (!this.options.arkts2) { return; } + this.incrementCounters(node, FaultID.TaggedTemplates); + } - if (!this.tsUtils.isShareableEntity(exportAssignment.expression)) { - this.incrementCounters(exportAssignment.expression, FaultID.SharedModuleExports); + private checkFunctionTypeCompatible(lhsTypeNode: ts.TypeNode | undefined, rhsExpr: ts.Expression): void { + if (this.options.arkts2 && lhsTypeNode && this.tsUtils.isIncompatibleFunctionals(lhsTypeNode, rhsExpr)) { + this.incrementCounters(rhsExpr, FaultID.IncompationbleFunctionType); } } - private processCalleeSym(calleeSym: ts.Symbol, tsCallExpr: ts.CallExpression): void { + private handleInvalidIdentifier( + decl: + | ts.TypeAliasDeclaration + | ts.StructDeclaration + | ts.VariableDeclaration + | ts.FunctionDeclaration + | ts.MethodSignature + | ts.ClassDeclaration + | ts.PropertyDeclaration + | ts.MethodDeclaration + | ts.ParameterDeclaration + | ts.PropertySignature + | ts.ImportDeclaration + | ts.EnumDeclaration + | ts.EnumMember + | ts.ModuleDeclaration + | ts.InterfaceDeclaration + ): void { if (!this.options.arkts2) { - this.handleStdlibAPICall(tsCallExpr, calleeSym); - this.handleFunctionApplyBindPropCall(tsCallExpr, calleeSym); - } - if (TsUtils.symbolHasEsObjectType(calleeSym)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(tsCallExpr, faultId); - } - // Need to process Symbol call separately in order to not report two times when using Symbol API - if (this.options.arkts2 && this.tsUtils.isStdSymbol(calleeSym)) { - this.incrementCounters(tsCallExpr, FaultID.SymbolType); + return; } - if (this.options.arkts2 && calleeSym.getEscapedName() === 'pow' && isStdLibrarySymbol(calleeSym)) { - this.incrementCounters(tsCallExpr, FaultID.MathPow); - } + const checkIdentifier = (identifier: ts.Identifier | undefined): void => { + const text = identifier && ts.isIdentifier(identifier) ? identifier.text : ''; + if (identifier && text && INVALID_IDENTIFIER_KEYWORDS.includes(text)) { + this.incrementCounters(identifier, FaultID.InvalidIdentifier); + } + }; - if (this.options.arkts2 && calleeSym.getEscapedName() === 'RegExp' && isStdLibrarySymbol(calleeSym)) { - const autofix = this.autofixer?.fixRegularExpressionLiteral(tsCallExpr); - this.incrementCounters(tsCallExpr, FaultID.RegularExpressionLiteral, autofix); + if (ts.isImportDeclaration(decl)) { + const importClause = decl.importClause; + if (importClause?.namedBindings && ts.isNamedImports(importClause?.namedBindings)) { + importClause.namedBindings.elements.forEach((importSpecifier) => { + checkIdentifier(importSpecifier.name); + }); + } + checkIdentifier(importClause?.name); + } else if (isStructDeclaration(decl)) { + checkIdentifier((decl as ts.StructDeclaration).name); + } else { + checkIdentifier(decl.name as ts.Identifier); } } - private handleCallExpression(node: ts.Node): void { - const tsCallExpr = node as ts.CallExpression; - this.handleStateStyles(tsCallExpr); - - const calleeSym = this.tsUtils.trueSymbolAtLocation(tsCallExpr.expression); - const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); - this.handleImportCall(tsCallExpr); - this.handleRequireCall(tsCallExpr); - if (calleeSym !== undefined) { - this.processCalleeSym(calleeSym, tsCallExpr); + private handleHeritageClause(node: ts.HeritageClause): void { + this.checkEWTArgumentsForSdkDuplicateDeclName(node); + if (!this.options.arkts2 || !this.useStatic) { + return; } - if (callSignature !== undefined && !this.tsUtils.isLibrarySymbol(calleeSym)) { - this.handleGenericCallWithNoTypeArgs(tsCallExpr, callSignature); - this.handleStructIdentAndUndefinedInArgs(tsCallExpr, callSignature); + if (node.token === ts.SyntaxKind.ExtendsKeyword || node.token === ts.SyntaxKind.ImplementsKeyword) { + node.types.forEach((type) => { + const expr = type.expression; + if (ts.isCallExpression(expr)) { + this.incrementCounters(expr, FaultID.ExtendsExpression); + return; + } + if ( + ts.isIdentifier(expr) && + this.isVariableReference(expr) && + this.tsUtils.isBuiltinClassHeritageClause(node) + ) { + this.incrementCounters(expr, FaultID.ExtendsExpression); + } else if (ts.isIdentifier(expr)) { + this.fixJsImportExtendsClass(node.parent, expr); + } + }); + + this.handleMissingSuperCallInExtendedClass(node); } - this.handleInteropForCallExpression(tsCallExpr); - this.handleLibraryTypeCall(tsCallExpr); + } - if ( - ts.isPropertyAccessExpression(tsCallExpr.expression) && - this.tsUtils.hasEsObjectType(tsCallExpr.expression.expression) - ) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(node, faultId); + private isVariableReference(identifier: ts.Identifier): boolean { + const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); + return !!symbol && (symbol.flags & ts.SymbolFlags.Variable) !== 0; + } + + private checkSendableAndConcurrentDecorator(decorator: ts.Decorator): void { + if (!this.options.arkts2 || !this.useStatic) { + return; } - if ( - !ts.isExpressionStatement(tsCallExpr.parent) && - !ts.isVoidExpression(tsCallExpr.parent) && - !ts.isArrowFunction(tsCallExpr.parent) - ) { - this.handleLimitedVoidWithCall(tsCallExpr); + const decoratorName = TsUtils.getDecoratorName(decorator); + const autofix = this.autofixer?.removeNode(decorator); + if (decoratorName === SENDABLE_DECORATOR) { + this.incrementCounters(decorator, FaultID.LimitedStdLibNoSendableDecorator, autofix); } - this.handleInteropForCallExpression(tsCallExpr); + if (decoratorName === CONCURRENT_DECORATOR) { + this.incrementCounters(decorator, FaultID.LimitedStdLibNoDoncurrentDecorator, autofix); + } } - private handleInteropForCallExpression(tsCallExpr: ts.CallExpression): void { - const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); - if (!callSignature) { + private checkAsonSymbol(node: ts.Identifier): void { + if (!this.options.arkts2) { return; } - if (TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { + if (node.text !== ASON_TEXT) { return; } - this.checkInteropFunctionParameters(callSignature, tsCallExpr); - this.checkForReflectAPIUse(callSignature, tsCallExpr); + const parent = node.parent; + switch (parent.kind) { + case ts.SyntaxKind.QualifiedName: + if (!ts.isQualifiedName(parent)) { + return; + } + if (parent.right.text !== node.text) { + return; + } + this.checkAsonUsage(parent.left); + + break; + case ts.SyntaxKind.PropertyAccessExpression: + if (!ts.isPropertyAccessExpression(parent)) { + return; + } + if (parent.name.text !== node.text) { + return; + } + this.checkAsonUsage(parent.expression); + + break; + default: + } } - private static isDeclaredInArkTs2(callSignature: ts.Signature): boolean | undefined { - const declarationSourceFile = callSignature?.declaration?.getSourceFile(); - if (!declarationSourceFile) { - return undefined; + private checkAsonUsage(nodeToCheck: ts.Node): void { + if (!ts.isIdentifier(nodeToCheck)) { + return; } - if (!declarationSourceFile.statements) { - return undefined; + const declaration = this.tsUtils.getDeclarationNode(nodeToCheck); + if (!declaration && nodeToCheck.text === ARKTS_UTILS_TEXT) { + this.incrementCounters(nodeToCheck, FaultID.LimitedStdLibNoASON); + return; } - // check for 'use static' at the start of the file this function declared at - if (declarationSourceFile.statements[0].getText() !== USE_STATIC) { - return true; + + if (!declaration) { + return; + } + + const sourceFile = declaration.getSourceFile(); + const fileName = path.basename(sourceFile.fileName); + + if ( + ASON_MODULES.some((moduleName) => { + return fileName.startsWith(moduleName); + }) + ) { + this.incrementCounters(nodeToCheck, FaultID.LimitedStdLibNoASON); } - return false; } - private checkInteropFunctionParameters(callSignature: ts.Signature, tsCallExpr: ts.CallExpression): void { - // checking if the we are invoking the function with the type Object from ArkTS 1.2 with the type Class from ArkTS 1.0 - for (const [index, param] of callSignature.parameters.entries()) { - const paramType = this.tsTypeChecker.getTypeOfSymbolAtLocation(param, tsCallExpr); - if (!this.tsUtils.isObject(paramType)) { + private checkCollectionsSymbol(symbol: ts.Symbol, node: ts.Node): void { + const cb = (): void => { + const parent = node.parent; + if (!parent) { return; } + if (ts.isPropertyAccessExpression(parent)) { + const autofix = this.autofixer?.replaceNode(parent, parent.name.text); + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + } - const argument = tsCallExpr.arguments[index]; - if (!argument) { - return; + if (ts.isQualifiedName(parent)) { + const autofix = this.autofixer?.replaceNode(parent, parent.right.text); + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); } - if (this.tsTypeChecker.getTypeAtLocation(argument).isClass()) { - // return error - this.incrementCounters(tsCallExpr, FaultID.InteropCallObjectParam); + if (ts.isImportSpecifier(parent) && ts.isIdentifier(node)) { + const autofix = this.autofixer?.removeImport(node, parent); + this.incrementCounters(node, FaultID.NoNeedStdLibSendableContainer, autofix); + } + }; + + this.checkSymbolAndExecute(symbol, COLLECTIONS_TEXT, COLLECTIONS_MODULES, cb); + } + + private checkWorkerSymbol(symbol: ts.Symbol, node: ts.Node): void { + const cb = (): void => { + this.incrementCounters(node, FaultID.NoNeedStdlibWorker); + }; + + this.checkSymbolAndExecute(symbol, WORKER_TEXT, WORKER_MODULES, cb); + } + + private checkSymbolAndExecute(symbol: ts.Symbol, symbolName: string, modules: string[], cb: () => void): void { + void this; + if (symbol.name === symbolName) { + const decl = TsUtils.getDeclaration(symbol); + + if (!decl) { return; } + + const sourceFile = decl.getSourceFile(); + const fileName = path.basename(sourceFile.fileName); + + if ( + modules.some((moduleName) => { + return fileName.startsWith(moduleName); + }) + ) { + cb(); + } } } - private checkForReflectAPIUse(callSignature: ts.Signature, tsCallExpr: ts.CallExpression): void { - if (!callSignature.declaration) { + interfacesNeedToAlarm: ts.Identifier[] = []; + interfacesNeedToImport: Set = new Set(); + interfacesAlreadyImported: Set = new Set(); + + private handleInterfaceImport(identifier: ts.Identifier): void { + if (!this.options.arkts2) { return; } - const functionSymbol = this.getFunctionSymbol(callSignature.declaration); - const functionDeclaration = functionSymbol?.valueDeclaration; - if (!functionDeclaration) { + if (this.shouldSkipIdentifier(identifier)) { return; } - if ( - TypeScriptLinter.isFunctionLike(functionDeclaration) && - TypeScriptLinter.containsReflectAPI(functionDeclaration) - ) { - this.incrementCounters(tsCallExpr.parent, FaultID.InteropCallReflect); + const name = identifier.getText(); + if (!this.interfacesNeedToImport.has(name)) { + this.interfacesNeedToImport.add(name); } - } - private handleEtsComponentExpression(node: ts.Node): void { - // for all the checks we make EtsComponentExpression is compatible with the CallExpression - const etsComponentExpression = node as ts.CallExpression; - this.handleLibraryTypeCall(etsComponentExpression); + this.interfacesNeedToAlarm.push(identifier); } - private handleImportCall(tsCallExpr: ts.CallExpression): void { - if (tsCallExpr.expression.kind !== ts.SyntaxKind.ImportKeyword) { - return; - } else if (this.options.arkts2) { - this.incrementCounters(tsCallExpr, FaultID.DynamicImport); + private shouldSkipIdentifier(identifier: ts.Identifier): boolean { + const name = identifier.getText(); + if (!arkuiImportList.has(name)) { + return true; } - // relax rule#133 "arkts-no-runtime-import" - const tsArgs = tsCallExpr.arguments; - if (tsArgs.length <= 1 || !ts.isObjectLiteralExpression(tsArgs[1])) { - return; + if (skipImportDecoratorName.has(name)) { + return true; } - for (const tsProp of tsArgs[1].properties) { - if ( - (ts.isPropertyAssignment(tsProp) || ts.isShorthandPropertyAssignment(tsProp)) && - tsProp.name.getText() === 'assert' - ) { - this.incrementCounters(tsProp, FaultID.ImportAssertion); - break; + const targetPropertyAccess = TypeScriptLinter.findTargetPropertyAccess(identifier.parent); + if (targetPropertyAccess) { + const expr = targetPropertyAccess.expression; + if (this.isDeclarationInSameFile(expr)) { + return true; } } - } - private handleRequireCall(tsCallExpr: ts.CallExpression): void { - if ( - ts.isIdentifier(tsCallExpr.expression) && - tsCallExpr.expression.text === 'require' && - ts.isVariableDeclaration(tsCallExpr.parent) - ) { - const tsType = this.tsTypeChecker.getTypeAtLocation(tsCallExpr.expression); - if (TsUtils.isInterfaceType(tsType) && tsType.symbol.name === 'NodeRequire') { - this.incrementCounters(tsCallExpr.parent, FaultID.ImportAssignment); + const parent = identifier.parent; + const wrappedSkipComponents = new Set([CustomDecoratorName.AnimatableExtend, CustomDecoratorName.Extend]); + if (ts.isCallExpression(parent)) { + const expr = parent.expression; + if (wrappedSkipComponents.has(expr.getText()) && name !== CustomDecoratorName.AnimatableExtend) { + return true; } } - } - private handleGenericCallWithNoTypeArgs( - callLikeExpr: ts.CallExpression | ts.NewExpression, - callSignature: ts.Signature - ): void { + if (this.isDeclarationInSameFile(identifier)) { + return true; + } - /* - * Note: The PR!716 has led to a significant performance degradation. - * Since initial problem was fixed in a more general way, this change - * became redundant. Therefore, it was reverted. See #13721 comments - * for a detailed analysis. - */ - if (this.options.arkts2 && TypeScriptLinter.isInvalidBuiltinGenericConstructorCall(callLikeExpr)) { - this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs); - return; + return this.interfacesAlreadyImported.has(name); + } + + private static findTargetPropertyAccess(node: ts.Node): ts.PropertyAccessExpression | undefined { + while (ts.isPropertyAccessExpression(node)) { + const expr = node.expression; + if (!ts.isPropertyAccessExpression(expr)) { + return node; + } + node = expr; } - this.checkTypeArgumentsForGenericCallWithNoTypeArgs(callLikeExpr, callSignature); - this.checkTypeArgumentsForGenericCallWithNoTypeArgsNumber(callLikeExpr, callSignature); + return undefined; } - private static isInvalidBuiltinGenericConstructorCall(newExpression: ts.CallExpression | ts.NewExpression): boolean { - if (!ts.isNewExpression(newExpression)) { - return false; + private isDeclarationInSameFile(node: ts.Node): boolean { + const symbol = this.tsTypeChecker.getSymbolAtLocation(node); + const decl = TsUtils.getDeclaration(symbol); + if (decl?.getSourceFile() === node.getSourceFile()) { + return true; } - const isBuiltin = BUILTIN_GENERIC_CONSTRUCTORS.has(newExpression.expression.getText().replace(/Constructor$/, '')); - return isBuiltin && (!newExpression.typeArguments || newExpression.typeArguments.length === 0); + + return false; } - private checkTypeArgumentsForGenericCallWithNoTypeArgs( - callLikeExpr: ts.CallExpression | ts.NewExpression, - callSignature: ts.Signature - ): void { - const tsSyntaxKind = ts.isNewExpression(callLikeExpr) ? - ts.SyntaxKind.Constructor : - ts.SyntaxKind.FunctionDeclaration; - const signFlags = ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature | ts.NodeBuilderFlags.IgnoreErrors; - const signDecl = this.tsTypeChecker.signatureToSignatureDeclaration( - callSignature, - tsSyntaxKind, - undefined, - signFlags - ); - if (!signDecl?.typeArguments) { + private processInterfacesToImport(sourceFile: ts.SourceFile): void { + if (!this.options.arkts2) { return; } - const resolvedTypeArgs = signDecl.typeArguments; - const startTypeArg = callLikeExpr.typeArguments?.length ?? 0; - if (this.options.arkts2 && callLikeExpr.kind === ts.SyntaxKind.NewExpression) { - if (startTypeArg !== resolvedTypeArgs.length) { - this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs); - } - } else { - for (let i = startTypeArg; i < resolvedTypeArgs.length; ++i) { - const typeNode = resolvedTypeArgs[i]; - /* - * if compiler infers 'unknown' type there are 2 possible cases: - * 1. Compiler unable to infer type from arguments and use 'unknown' - * 2. Compiler infer 'unknown' from arguments - * We report error in both cases. It is ok because we cannot use 'unknown' - * in ArkTS and already have separate check for it. - */ - if (typeNode.kind === ts.SyntaxKind.UnknownKeyword) { - this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs); - break; - } - } - } + const autofix = this.autofixer?.fixInterfaceImport( + this.interfacesNeedToImport, + this.interfacesAlreadyImported, + sourceFile + ); + + this.interfacesNeedToAlarm.forEach((identifier) => { + this.incrementCounters(identifier, FaultID.UIInterfaceImport, autofix); + }); + + this.interfacesNeedToAlarm = []; + this.interfacesNeedToImport.clear(); + this.interfacesAlreadyImported.clear(); } - checkTypeArgumentsForGenericCallWithNoTypeArgsNumber( - callLikeExpr: ts.CallExpression | ts.NewExpression, - callSignature: ts.Signature - ): void { - const tsSyntaxKind = ts.isNewExpression(callLikeExpr) ? - ts.SyntaxKind.Constructor : - ts.SyntaxKind.FunctionDeclaration; - const signFlags = ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature | ts.NodeBuilderFlags.IgnoreErrors; - const signDecl = this.tsTypeChecker.signatureToSignatureDeclaration( - callSignature, - tsSyntaxKind, - undefined, - signFlags - ); - if (!signDecl?.typeArguments) { + private extractImportedNames(sourceFile: ts.SourceFile): void { + if (!this.options.arkts2) { return; } - let hasNumberType = false; - const resolvedTypeArgs = signDecl.typeArguments; - const startTypeArg = callLikeExpr.typeArguments?.length ?? 0; - for (let i = startTypeArg; i < resolvedTypeArgs.length; ++i) { - const typeNode = resolvedTypeArgs[i]; - if ( - typeNode.kind === ts.SyntaxKind.NumberKeyword || - ts.isLiteralTypeNode(typeNode) && ts.isNumericLiteral(typeNode.literal) - ) { - hasNumberType = true; - break; + for (const statement of sourceFile.statements) { + if (!ts.isImportDeclaration(statement)) { + continue; + } + + const importClause = statement.importClause; + if (!importClause) { + continue; + } + + const namedBindings = importClause.namedBindings; + if (!namedBindings || !ts.isNamedImports(namedBindings)) { + continue; + } + + for (const specifier of namedBindings.elements) { + const importedName = specifier.name.getText(sourceFile); + this.interfacesAlreadyImported.add(importedName); } } - if (this.options.arkts2 && hasNumberType && ts.isCallExpression(callLikeExpr)) { - const resolvedTypeArgs = signDecl.typeArguments.map((typeNode) => { - if (ts.isLiteralTypeNode(typeNode) && ts.isNumericLiteral(typeNode.literal)) { - return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword); - } - return typeNode; - }); - const resolvedTypeArgsNodeArray = ts.factory.createNodeArray(resolvedTypeArgs); - const autofix = this.autofixer?.fixFunctionDeclarationly(callLikeExpr, resolvedTypeArgsNodeArray); - this.incrementCounters(callLikeExpr, FaultID.NumericSemantics, autofix); + } + + private handleStylesDecorator(node: ts.Decorator): void { + if (!this.options.arkts2) { + return; } - } - private static readonly listFunctionApplyCallApis = [ - 'Function.apply', - 'Function.call', - 'CallableFunction.apply', - 'CallableFunction.call' - ]; + if (!ts.isFunctionDeclaration(node.parent) && !ts.isMethodDeclaration(node.parent)) { + return; + } - private static readonly listFunctionBindApis = ['Function.bind', 'CallableFunction.bind']; + if (!ts.isIdentifier(node.expression) || node.expression.text !== CustomDecoratorName.Styles) { + return; + } - private handleFunctionApplyBindPropCall(tsCallExpr: ts.CallExpression, calleeSym: ts.Symbol): void { - const exprName = this.tsTypeChecker.getFullyQualifiedName(calleeSym); - if (TypeScriptLinter.listFunctionApplyCallApis.includes(exprName)) { - this.incrementCounters(tsCallExpr, FaultID.FunctionApplyCall); + const decl = node.parent; + const declName = decl.name?.getText(); + if (ts.isFunctionDeclaration(decl)) { + const functionCalls = TypeScriptLinter.findDeclarationCalls(this.sourceFile, declName as string); + const autofix = this.autofixer?.fixStylesDecoratorGlobal(decl, functionCalls, this.interfacesNeedToImport); + this.incrementCounters(decl, FaultID.StylesDecoratorNotSupported, autofix); } - if (TypeScriptLinter.listFunctionBindApis.includes(exprName)) { - const faultId = this.options.arkts2 ? FaultID.FunctionBindError : FaultID.FunctionBind; - this.incrementCounters(tsCallExpr, faultId); + + if (ts.isMethodDeclaration(decl)) { + const methodCalls = TypeScriptLinter.findDeclarationCalls(this.sourceFile, declName as string); + const autofix = this.autofixer?.fixStylesDecoratorStruct(decl, methodCalls, this.interfacesNeedToImport); + this.incrementCounters(decl, FaultID.StylesDecoratorNotSupported, autofix); } } - private handleStructIdentAndUndefinedInArgs( - tsCallOrNewExpr: ts.CallExpression | ts.NewExpression, - callSignature: ts.Signature - ): void { - if (!tsCallOrNewExpr.arguments) { + private handleStateStyles(node: ts.CallExpression | ts.PropertyAccessExpression): void { + if (!this.options.arkts2) { return; } - for (let argIndex = 0; argIndex < tsCallOrNewExpr.arguments.length; ++argIndex) { - const tsArg = tsCallOrNewExpr.arguments[argIndex]; - const tsArgType = this.tsTypeChecker.getTypeAtLocation(tsArg); - if (!tsArgType) { - continue; - } - const paramIndex = argIndex < callSignature.parameters.length ? argIndex : callSignature.parameters.length - 1; - const tsParamSym = callSignature.parameters[paramIndex]; - if (!tsParamSym) { - continue; - } - const tsParamDecl = tsParamSym.valueDeclaration; - if (tsParamDecl && ts.isParameter(tsParamDecl)) { - let tsParamType = this.tsTypeChecker.getTypeOfSymbolAtLocation(tsParamSym, tsParamDecl); - if (tsParamDecl.dotDotDotToken && this.tsUtils.isGenericArrayType(tsParamType) && tsParamType.typeArguments) { - tsParamType = tsParamType.typeArguments[0]; - } - if (!tsParamType) { - continue; - } - this.checkAssignmentMatching(tsArg, tsParamType, tsArg); + + let args: ts.Expression[] = []; + let startNode: ts.Node | undefined; + if (ts.isCallExpression(node)) { + if (node.expression.getText() !== STATE_STYLES) { + return; } + startNode = node.expression; + args = Array.from(node.arguments); } - } - - private static readonly LimitedApis = new Map | null; fault: FaultID }>([ - ['global', { arr: LIMITED_STD_GLOBAL_API, fault: FaultID.LimitedStdLibApi }], - ['Object', { arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi }], - ['ObjectConstructor', { arr: LIMITED_STD_OBJECT_API, fault: FaultID.LimitedStdLibApi }], - ['Reflect', { arr: LIMITED_STD_REFLECT_API, fault: FaultID.LimitedStdLibApi }], - ['ProxyHandler', { arr: LIMITED_STD_PROXYHANDLER_API, fault: FaultID.LimitedStdLibApi }], - [SYMBOL, { arr: null, fault: FaultID.SymbolType }], - [SYMBOL_CONSTRUCTOR, { arr: null, fault: FaultID.SymbolType }] - ]); - private handleStdlibAPICall(callExpr: ts.CallExpression, calleeSym: ts.Symbol): void { - const name = calleeSym.getName(); - const parName = this.tsUtils.getParentSymbolName(calleeSym); - if (parName === undefined) { - if (LIMITED_STD_GLOBAL_API.includes(name)) { - this.incrementCounters(callExpr, FaultID.LimitedStdLibApi); + if (ts.isPropertyAccessExpression(node)) { + if (node.name.getText() !== STATE_STYLES) { return; } - const escapedName = calleeSym.escapedName; - if (escapedName === 'Symbol' || escapedName === 'SymbolConstructor') { - this.incrementCounters(callExpr, FaultID.SymbolType); + if (!ts.isCallExpression(node.parent)) { + return; } + startNode = node.name; + args = Array.from(node.parent.arguments); + } + + if (args.length === 0 || !startNode) { return; } - const lookup = TypeScriptLinter.LimitedApis.get(parName); - if ( - lookup !== undefined && - (lookup.arr === null || lookup.arr.includes(name)) && - (!this.options.useRelaxedRules || !this.supportedStdCallApiChecker.isSupportedStdCallAPI(callExpr, parName, name)) - ) { - this.incrementCounters(callExpr, lookup.fault); + + const object = args[0]; + if (!object || !ts.isObjectLiteralExpression(object)) { + return; } - } - private checkLimitedStdlibApi(node: ts.Identifier, symbol: ts.Symbol): void { - const parName = this.tsUtils.getParentSymbolName(symbol); - const entries = LIMITED_STD_API.get(parName); - if (!entries) { + const properties = object.properties; + if (properties.length === 0) { return; } - for (const entry of entries) { - if ( - entry.api.includes(symbol.name) && - !this.supportedStdCallApiChecker.isSupportedStdCallAPI(node, parName, symbol.name) - ) { - this.incrementCounters(node, entry.faultId); - return; + + if (!TypeScriptLinter.hasAnonBlock(properties)) { + return; + } + + const autofix = this.autofixer?.fixStateStyles(object, startNode, this.interfacesNeedToImport); + this.incrementCounters(object, FaultID.StylesDecoratorNotSupported, autofix); + } + + private static hasAnonBlock(properties: ts.NodeArray): boolean { + let anonBlockCount = 0; + + properties.forEach((property) => { + if (ts.isPropertyAssignment(property) && ts.isObjectLiteralExpression(property.initializer)) { + anonBlockCount++; } + }); + + return anonBlockCount !== 0; + } + + private handleStringLiteral(node: ts.StringLiteral): void { + if (!this.options.arkts2) { + return; } + + this.checkForConcurrentExpressions(node); } - private handleLibraryTypeCall(expr: ts.CallExpression | ts.NewExpression): void { - if (!expr.arguments || !this.tscStrictDiagnostics || !this.sourceFile) { + private checkForConcurrentExpressions(stringLiteral: ts.StringLiteral): void { + if (!stringLiteral.parent) { return; } - const file = path.normalize(this.sourceFile.fileName); - const tscDiagnostics: readonly ts.Diagnostic[] | undefined = this.tscStrictDiagnostics.get(file); - if (!tscDiagnostics?.length) { + if (!ts.isExpressionStatement(stringLiteral.parent)) { return; } - const isOhModulesEts = TsUtils.isOhModulesEtsSymbol(this.tsUtils.trueSymbolAtLocation(expr.expression)); - const deleteDiagnostics: Set = new Set(); - LibraryTypeCallDiagnosticChecker.instance.filterDiagnostics( - tscDiagnostics, - expr, - this.tsUtils.isLibraryType(this.tsTypeChecker.getTypeAtLocation(expr.expression)), - (diagnostic, errorType) => { + const text = stringLiteral.text; + const autofix = this.autofixer?.removeNode(stringLiteral); - /* - * When a diagnostic meets the filter criteria, If it happens in an ets file in the 'oh_modules' directory. - * the diagnostic is downgraded to warning. For other files, downgraded to nothing. - */ - if (isOhModulesEts && errorType !== DiagnosticCheckerErrorType.UNKNOW) { - diagnostic.category = ts.DiagnosticCategory.Warning; - return false; + if (text === USE_CONCURRENT) { + this.incrementCounters(stringLiteral, FaultID.UseConcurrentDeprecated, autofix); + } + + if (text === USE_SHARED) { + this.incrementCounters(stringLiteral, FaultID.UseSharedDeprecated, autofix); + } + } + + private static findDeclarationCalls(sourceFile: ts.SourceFile, declName: string): ts.Identifier[] { + const functionCalls: ts.Identifier[] = []; + + function traverse(node: ts.Node): void { + const identifier = getIdentifierFromNode(node); + if (identifier && identifier.getText() === declName) { + functionCalls.push(identifier); + } + + ts.forEachChild(node, traverse); + } + + function getIdentifierFromNode(node: ts.Node): ts.Identifier | undefined { + if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) { + return node.expression; + } + if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name)) { + if (node.expression.getText() === THIS_IDENTIFIER) { + return undefined; } - deleteDiagnostics.add(diagnostic); - return true; + return node.name; } - ); + return undefined; + } - if (!deleteDiagnostics.size) { + traverse(sourceFile); + return functionCalls; + } + + addObservedDecorator: Set = new Set(); + + private handleDataObservation(node: ts.PropertyDeclaration): void { + if (!this.options.arkts2) { return; } - this.tscStrictDiagnostics.set( - file, - tscDiagnostics.filter((item) => { - return !deleteDiagnostics.has(item); - }) - ); - } + const decorators = ts.getDecorators(node); + if (!decorators || decorators.length === 0) { + return; + } + const decorator = decorators[0]; + let decoratorName = ''; + if (ts.isIdentifier(decorator.expression)) { + decoratorName = decorator.expression.getText(); + } else if (ts.isCallExpression(decorator.expression)) { + decoratorName = decorator.expression.expression.getText(); + } + if (!observedDecoratorName.has(decoratorName)) { + return; + } - private handleNewExpression(node: ts.Node): void { - const tsNewExpr = node as ts.NewExpression; + let firstClassDecls: ts.ClassDeclaration[] | undefined; + const expr = node.initializer; + if (expr && ts.isNewExpression(expr)) { + firstClassDecls = this.addFromNewExpression(expr); + } - if (this.options.advancedClassChecks || this.options.arkts2) { - const calleeExpr = tsNewExpr.expression; - const calleeType = this.tsTypeChecker.getTypeAtLocation(calleeExpr); - if ( - !this.tsUtils.isClassTypeExpression(calleeExpr) && - !isStdLibraryType(calleeType) && - !this.tsUtils.isLibraryType(calleeType) && - !this.tsUtils.hasEsObjectType(calleeExpr) - ) { - // missing exact rule - const faultId = this.options.arkts2 ? FaultID.DynamicCtorCall : FaultID.ClassAsObject; - this.incrementCounters(calleeExpr, faultId); + let secondClassDecls: ts.ClassDeclaration[] | undefined; + const type = node.type; + if (type) { + secondClassDecls = this.addFromTypeNode(type); + } + + const classDecls = (firstClassDecls || []).concat(secondClassDecls || []); + if (classDecls.length === 0) { + return; + } + + const filteredClassDecls = classDecls.filter((classDecl) => { + if (this.addObservedDecorator.has(classDecl)) { + return false; } + this.addObservedDecorator.add(classDecl); + return true; + }); + if (filteredClassDecls.length !== 0) { + this.interfacesNeedToImport.add(CustomDecoratorName.Observed); } - const sym = this.tsUtils.trueSymbolAtLocation(tsNewExpr.expression); - const callSignature = this.tsTypeChecker.getResolvedSignature(tsNewExpr); - if (callSignature !== undefined && !this.tsUtils.isLibrarySymbol(sym)) { - this.handleStructIdentAndUndefinedInArgs(tsNewExpr, callSignature); - this.handleGenericCallWithNoTypeArgs(tsNewExpr, callSignature); + const autofix = this.autofixer?.fixDataObservation(filteredClassDecls); + this.incrementCounters(node, FaultID.DataObservation, autofix); + } + + private addFromNewExpression(expr: ts.NewExpression): ts.ClassDeclaration[] | undefined { + const identifier = expr.expression; + if (!ts.isIdentifier(identifier)) { + return undefined; } - this.handleSendableGenericTypes(tsNewExpr); + + const decl: ts.ClassDeclaration | undefined = this.getClassDeclaration(identifier); + if (!decl) { + return undefined; + } + + const classDecls: ts.ClassDeclaration[] = this.getClassHierarchy(decl); + const filteredClassDecls = classDecls.filter((classDecl) => { + if (TypeScriptLinter.hasObservedDecorator(classDecl)) { + return false; + } + return true; + }); + return filteredClassDecls; + } + + private addFromTypeNode(type: ts.TypeNode): ts.ClassDeclaration[] | undefined { + const targets: ts.Node[] = []; + if (ts.isUnionTypeNode(type)) { + const types = type.types; + types.forEach((typeNode) => { + if (ts.isTypeReferenceNode(typeNode)) { + targets.push(typeNode.typeName); + } + }); + } else if (ts.isTypeReferenceNode(type)) { + targets.push(type.typeName); + } + + const classDecls: ts.ClassDeclaration[] = []; + targets.forEach((target) => { + const decl: ts.ClassDeclaration | undefined = this.getClassDeclaration(target); + if (!decl) { + return; + } + + const decls: ts.ClassDeclaration[] = this.getClassHierarchy(decl); + classDecls.push(...decls); + }); + const filteredClassDecls = classDecls.filter((classDecl) => { + if (TypeScriptLinter.hasObservedDecorator(classDecl)) { + return false; + } + return true; + }); + return filteredClassDecls; + } + + private static hasObservedDecorator(classDecl: ts.ClassDeclaration): boolean { + return ( + ts.getDecorators(classDecl)?.some((decorator) => { + return decorator.getText() === '@' + CustomDecoratorName.Observed; + }) ?? false + ); } - private handleSendableGenericTypes(node: ts.NewExpression): void { - const type = this.tsTypeChecker.getTypeAtLocation(node); - if (!this.tsUtils.isSendableClassOrInterface(type)) { - return; + private getClassDeclaration(node: ts.Node): ts.ClassDeclaration | undefined { + const symbol = this.tsTypeChecker.getSymbolAtLocation(node); + let decl: ts.Declaration | undefined; + if (symbol) { + decl = this.tsUtils.getDeclarationNode(node); + if (decl?.getSourceFile() !== node.getSourceFile()) { + return undefined; + } } - const typeArgs = node.typeArguments; - if (!typeArgs || typeArgs.length === 0) { - return; + if (!decl || !ts.isClassDeclaration(decl)) { + return undefined; } - for (const arg of typeArgs) { - if (!this.tsUtils.isSendableTypeNode(arg)) { - this.incrementCounters(arg, FaultID.SendableGenericTypes); - } - } + return decl; } - private handleAsExpression(node: ts.Node): void { - const tsAsExpr = node as ts.AsExpression; - if (tsAsExpr.type.getText() === 'const') { - this.incrementCounters(node, FaultID.ConstAssertion); - } - const targetType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.type).getNonNullableType(); - const exprType = this.tsTypeChecker.getTypeAtLocation(tsAsExpr.expression).getNonNullableType(); - // check for rule#65: 'number as Number' and 'boolean as Boolean' are disabled - if ( - this.tsUtils.isNumberLikeType(exprType) && this.tsUtils.isStdNumberType(targetType) || - TsUtils.isBooleanLikeType(exprType) && this.tsUtils.isStdBooleanType(targetType) - ) { - this.incrementCounters(node, FaultID.TypeAssertion); - } - if ( - !this.tsUtils.isSendableClassOrInterface(exprType) && - !this.tsUtils.isObject(exprType) && - !TsUtils.isAnyType(exprType) && - this.tsUtils.isSendableClassOrInterface(targetType) - ) { - this.incrementCounters(tsAsExpr, FaultID.SendableAsExpr); - } - if (this.tsUtils.isWrongSendableFunctionAssignment(targetType, exprType)) { - this.incrementCounters(tsAsExpr, FaultID.SendableFunctionAsExpr); - } - if ( - this.options.arkts2 && - this.tsUtils.needToDeduceStructuralIdentity(targetType, exprType, tsAsExpr.expression, true) - ) { - if (!this.tsUtils.isObject(exprType)) { - this.incrementCounters(node, FaultID.StructuralIdentity); + private getClassHierarchy(classDecl: ts.ClassDeclaration): ts.ClassDeclaration[] { + const hierarchy: ts.ClassDeclaration[] = []; + let currentClass: ts.ClassDeclaration | undefined = classDecl; + + while (currentClass) { + hierarchy.push(currentClass); + const heritageClause = currentClass.heritageClauses?.find((clause) => { + return clause.token === ts.SyntaxKind.ExtendsKeyword; + }); + const identifier = heritageClause?.types[0]?.expression as ts.Identifier | undefined; + if (!identifier) { + break; } + currentClass = this.getClassDeclaration(identifier); } - } - private handleTypeReference(node: ts.Node): void { - const typeRef = node as ts.TypeReferenceNode; + return hierarchy; + } - const isESObject = TsUtils.isEsObjectType(typeRef); - const isPossiblyValidContext = TsUtils.isEsObjectPossiblyAllowed(typeRef); - if (isESObject && !isPossiblyValidContext) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(node, faultId); + private checkArkTSObjectInterop(tsCallExpr: ts.CallExpression): void { + const callSignature = this.tsTypeChecker.getResolvedSignature(tsCallExpr); + if (!callSignature?.declaration) { return; } - const typeName = this.tsUtils.entityNameToString(typeRef.typeName); - const isStdUtilityType = LIMITED_STANDARD_UTILITY_TYPES.includes(typeName); - if (isStdUtilityType) { - this.incrementCounters(node, FaultID.UtilityType); + if (!TypeScriptLinter.isDeclaredInArkTs2(callSignature)) { return; } - this.checkPartialType(node); - - const typeNameType = this.tsTypeChecker.getTypeAtLocation(typeRef.typeName); - if (this.options.arkts2 && (typeNameType.flags & ts.TypeFlags.Void) !== 0) { - this.incrementCounters(typeRef, FaultID.LimitedVoidType); - } - if (this.tsUtils.isSendableClassOrInterface(typeNameType)) { - this.checkSendableTypeArguments(typeRef); - } - } - - private checkPartialType(node: ts.Node): void { - const typeRef = node as ts.TypeReferenceNode; - // Using Partial type is allowed only when its argument type is either Class or Interface. - const isStdPartial = this.tsUtils.entityNameToString(typeRef.typeName) === 'Partial'; - if (!isStdPartial) { + if (!this.hasObjectParameter(callSignature, tsCallExpr)) { return; } - const hasSingleTypeArgument = !!typeRef.typeArguments && typeRef.typeArguments.length === 1; - let argType; - if (!this.options.useRtLogic) { - const firstTypeArg = !!typeRef.typeArguments && hasSingleTypeArgument && typeRef.typeArguments[0]; - argType = firstTypeArg && this.tsTypeChecker.getTypeFromTypeNode(firstTypeArg); - } else { - argType = hasSingleTypeArgument && this.tsTypeChecker.getTypeFromTypeNode(typeRef.typeArguments[0]); + const functionSymbol = this.getFunctionSymbol(callSignature.declaration); + const functionDeclaration = functionSymbol?.valueDeclaration; + if (!functionDeclaration) { + return; } - if (argType && !argType.isClassOrInterface()) { - this.incrementCounters(node, FaultID.UtilityType); + if ( + TypeScriptLinter.isFunctionLike(functionDeclaration) && + TypeScriptLinter.containsForbiddenAPI(functionDeclaration) + ) { + this.incrementCounters(tsCallExpr.parent, FaultID.InteropCallReflect); } } - private checkSendableTypeArguments(typeRef: ts.TypeReferenceNode): void { - if (typeRef.typeArguments) { - for (const typeArg of typeRef.typeArguments) { - if (!this.tsUtils.isSendableTypeNode(typeArg)) { - this.incrementCounters(typeArg, FaultID.SendableGenericTypes); - } + private hasObjectParameter(callSignature: ts.Signature, tsCallExpr: ts.CallExpression): boolean { + for (const [index, param] of callSignature.parameters.entries()) { + const paramType = this.tsTypeChecker.getTypeOfSymbolAtLocation(param, tsCallExpr); + + if (!this.tsUtils.isObject(paramType)) { + continue; + } + + const argument = tsCallExpr.arguments[index]; + if (!argument) { + continue; + } + + if (this.tsTypeChecker.getTypeAtLocation(argument).isClass()) { + return true; } } + + return false; } - private handleMetaProperty(node: ts.Node): void { - const tsMetaProperty = node as ts.MetaProperty; - if (tsMetaProperty.name.text === 'target') { - this.incrementCounters(node, FaultID.NewTarget); + private static containsForbiddenAPI( + node: ts.FunctionDeclaration | ts.MethodDeclaration | ts.FunctionExpression + ): ForbidenAPICheckResult { + if (!node.body) { + return NONE; } + return TypeScriptLinter.isForbiddenUsed(node.body); } - private handleSpreadOp(node: ts.Node): void { + private static isForbiddenUsed(currentNode: ts.Node): ForbidenAPICheckResult { + if (!ts.isCallExpression(currentNode)) { + let found: ForbidenAPICheckResult = NONE; + ts.forEachChild(currentNode, (child) => { + if (found === NONE) { + found = TypeScriptLinter.isForbiddenUsed(child); + } + }); - /* - * spread assignment is disabled - * spread element is allowed only for arrays as rest parameter - */ - if (ts.isSpreadElement(node)) { - const spreadExprType = this.tsUtils.getTypeOrTypeConstraintAtLocation(node.expression); - if ( - spreadExprType && - (this.options.useRtLogic || ts.isCallLikeExpression(node.parent) || ts.isArrayLiteralExpression(node.parent)) && - (this.tsUtils.isOrDerivedFrom(spreadExprType, this.tsUtils.isArray) || - this.tsUtils.isOrDerivedFrom(spreadExprType, this.tsUtils.isCollectionArrayType)) - ) { - return; - } + return found; } - this.incrementCounters(node, FaultID.SpreadOperator); - } - private handleConstructSignature(node: ts.Node): void { - switch (node.parent.kind) { - case ts.SyntaxKind.TypeLiteral: - this.incrementCounters(node, FaultID.ConstructorType); - break; - case ts.SyntaxKind.InterfaceDeclaration: - this.incrementCounters(node, FaultID.ConstructorIface); - break; - default: + const expr = currentNode.expression; + if (!ts.isPropertyAccessExpression(expr)) { + return NONE; } - } - - private handleExpressionWithTypeArguments(node: ts.Node): void { - const tsTypeExpr = node as ts.ExpressionWithTypeArguments; - const symbol = this.tsUtils.trueSymbolAtLocation(tsTypeExpr.expression); - if (!!symbol && TsUtils.isEsObjectSymbol(symbol)) { - const faultId = this.options.arkts2 ? FaultID.EsObjectTypeError : FaultID.EsObjectType; - this.incrementCounters(tsTypeExpr, faultId); + const obj = expr.expression; + const method = expr.name; + if (!ts.isIdentifier(obj)) { + return NONE; } - } - private handleComputedPropertyName(node: ts.Node): void { - const computedProperty = node as ts.ComputedPropertyName; - if (this.isSendableCompPropName(computedProperty)) { - // cancel the '[Symbol.iterface]' restriction of 'sendable class/interface' in the 'collections.d.ts' file - if (this.tsUtils.isSymbolIteratorExpression(computedProperty.expression)) { - const declNode = computedProperty.parent?.parent; - if (declNode && TsUtils.isArkTSCollectionsClassOrInterfaceDeclaration(declNode)) { - return; - } + if (obj.text === REFLECT_LITERAL) { + if (REFLECT_PROPERTIES.includes(method.text)) { + return REFLECT_LITERAL; } - this.incrementCounters(node, FaultID.SendableComputedPropName); - } else if (!this.tsUtils.isValidComputedPropertyName(computedProperty, false)) { - this.incrementCounters(node, FaultID.ComputedPropertyName); } - } - private isSendableCompPropName(compProp: ts.ComputedPropertyName): boolean { - const declNode = compProp.parent?.parent; - if (declNode && ts.isClassDeclaration(declNode) && TsUtils.hasSendableDecorator(declNode)) { - return true; - } else if (declNode && ts.isInterfaceDeclaration(declNode)) { - const declNodeType = this.tsTypeChecker.getTypeAtLocation(declNode); - if (this.tsUtils.isSendableClassOrInterface(declNodeType)) { - return true; + if (obj.text === OBJECT_LITERAL) { + if (OBJECT_PROPERTIES.includes(method.text)) { + return OBJECT_LITERAL; } } - return false; + return NONE; } - private handleGetAccessor(node: ts.GetAccessorDeclaration): void { - TsUtils.getDecoratorsIfInSendableClass(node)?.forEach((decorator) => { - this.incrementCounters(decorator, FaultID.SendableClassDecorator); - }); + private getFunctionSymbol(declaration: ts.Declaration): ts.Symbol | undefined { + if (TypeScriptLinter.isFunctionLike(declaration)) { + return declaration.name ? this.tsTypeChecker.getSymbolAtLocation(declaration.name) : undefined; + } + return undefined; } - private handleSetAccessor(node: ts.SetAccessorDeclaration): void { - TsUtils.getDecoratorsIfInSendableClass(node)?.forEach((decorator) => { - this.incrementCounters(decorator, FaultID.SendableClassDecorator); - }); + private static isFunctionLike( + node: ts.Node + ): node is ts.FunctionDeclaration | ts.MethodDeclaration | ts.FunctionExpression { + return ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || ts.isFunctionExpression(node); } - /* - * issue 13987: - * When variable have no type annotation and no initial value, and 'noImplicitAny' - * option is enabled, compiler attempts to infer type from variable references: - * see https://github.com/microsoft/TypeScript/pull/11263. - * In this case, we still want to report the error, since ArkTS doesn't allow - * to omit both type annotation and initializer. - */ - private proceedVarPropDeclaration( - decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration - ): boolean | undefined { - if ( - (ts.isVariableDeclaration(decl) && ts.isVariableStatement(decl.parent.parent) || - ts.isPropertyDeclaration(decl)) && - !decl.initializer - ) { - if ( - ts.isPropertyDeclaration(decl) && - this.tsUtils.skipPropertyInferredTypeCheck(decl, this.sourceFile, this.options.isEtsFileCb) - ) { - return true; - } - - this.incrementCounters(decl, FaultID.AnyType); - return true; + private handleSdkForConstructorFuncs(node: ts.PropertyAccessExpression): void { + if (!this.options.arkts2 || !node) { + return; } - return undefined; - } - - private handleDeclarationInferredType( - decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration - ): void { - // The type is explicitly specified, no need to check inferred type. - if (decl.type) { + const sdkInfos = this.interfaceMap.get(node.expression.getText()); + if (!sdkInfos || sdkInfos.size === 0) { return; } - /* - * issue 13161: - * In TypeScript, the catch clause variable must be 'any' or 'unknown' type. Since - * ArkTS doesn't support these types, the type for such variable is simply omitted, - * and we don't report it as an error. See TypeScriptLinter.handleCatchClause() - * for reference. - */ - if (ts.isCatchClause(decl.parent)) { - return; + for (const sdkInfo of sdkInfos) { + const propertyName = node.name.getText(); + if (propertyName === sdkInfo.api_name) { + this.incrementCounters(node.name, FaultID.ConstructorTypesDeprecated); + } } - // Destructuring declarations are not supported, do not process them. - if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) { + } + + private handleQuotedHyphenPropsDeprecated(node: ts.PropertyAccessExpression | ts.PropertyAssignment): void { + if (!this.options.arkts2 || !node) { return; } + const literalAsPropertyNameInfos = Array.from(TypeScriptLinter.literalAsPropertyNameTypeSet); + literalAsPropertyNameInfos.some((literalAsPropertyNameInfo) => { + this.localApiListItem = literalAsPropertyNameInfo; + const api_name = literalAsPropertyNameInfo.api_info.api_name; + if (api_name !== (ts.isPropertyAccessExpression(node) ? node.name.text : node.name.getText())) { + return false; + } + const parentSym = this.getFinalSymOnQuotedHyphenPropsDeprecated( + ts.isPropertyAccessExpression(node) ? node.expression : node + ); + if (parentSym && this.shouldWarn(parentSym)) { + this.incrementCounters(node, FaultID.QuotedHyphenPropsDeprecated); + return true; + } + return false; + }); + } - if (this.proceedVarPropDeclaration(decl)) { - return; - } + private shouldWarn(symbol: ts.Symbol): boolean { + const parentApiName = this.getLocalApiListItemByKey(SdkNameInfo.ParentApiName); + return symbol && this.isHeritageClauseisThirdPartyBySymbol(symbol) || symbol.name === parentApiName; + } - const type = this.tsTypeChecker.getTypeAtLocation(decl); - if (type) { - this.validateDeclInferredType(type, decl); + private getFinalSymOnQuotedHyphenPropsDeprecated(node: ts.Node): ts.Symbol | undefined { + let currentNode = node; + while (currentNode) { + const symbol = this.checkNodeTypeOnQuotedHyphenPropsDeprecated(currentNode); + if (symbol) { + return symbol; + } + currentNode = currentNode.parent; } + return undefined; } - private handleDefiniteAssignmentAssertion(decl: ts.VariableDeclaration | ts.PropertyDeclaration): void { - if (decl.exclamationToken === undefined) { - return; + private checkNodeTypeOnQuotedHyphenPropsDeprecated(node: ts.Node): ts.Symbol | undefined { + if (ts.isVariableDeclaration(node)) { + return this.getTypeOfVariable(node); } - if (decl.kind === ts.SyntaxKind.PropertyDeclaration) { - const parentDecl = decl.parent; - if (parentDecl.kind === ts.SyntaxKind.ClassDeclaration && TsUtils.hasSendableDecorator(parentDecl)) { - this.incrementCounters(decl, FaultID.SendableDefiniteAssignment); - return; - } + if (ts.isPropertySignature(node)) { + return this.tsTypeChecker.getTypeAtLocation(node.type!).getSymbol(); } - const faultId = this.options.arkts2 ? FaultID.DefiniteAssignmentError : FaultID.DefiniteAssignment; - this.incrementCounters(decl, faultId); - } - private readonly validatedTypesSet = new Set(); + const nodesWithResolvableType = [ + ts.isFunctionDeclaration(node) && node.type, + ts.isMethodDeclaration(node) && node.type, + ts.isTypeReferenceNode(node) && node, + ts.isParameter(node) && node.type + ].filter(Boolean); - private checkAnyOrUnknownChildNode(node: ts.Node): boolean { - if (node.kind === ts.SyntaxKind.AnyKeyword || node.kind === ts.SyntaxKind.UnknownKeyword) { - return true; + for (const typeNode of nodesWithResolvableType) { + return typeNode ? this.resolveTypeNodeSymbol(typeNode) : undefined; } - for (const child of node.getChildren()) { - if (this.checkAnyOrUnknownChildNode(child)) { - return true; + + if (ts.isIdentifier(node)) { + const symbol = this.tsTypeChecker.getSymbolAtLocation(node); + const declaration = symbol?.getDeclarations()?.[0]; + if (declaration) { + return this.getFinalSymOnQuotedHyphenPropsDeprecated(declaration); } } - return false; + + return undefined; } - private handleInferredObjectreference( - type: ts.Type, - decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration - ): void { - const typeArgs = this.tsTypeChecker.getTypeArguments(type as ts.TypeReference); - if (typeArgs) { - const haveAnyOrUnknownNodes = this.checkAnyOrUnknownChildNode(decl); - if (!haveAnyOrUnknownNodes) { - for (const typeArg of typeArgs) { - this.validateDeclInferredType(typeArg, decl); - } - } + private getTypeOfVariable(variable: ts.VariableDeclaration): ts.Symbol | undefined { + if (variable.type) { + return ts.isArrayTypeNode(variable.type) ? + this.resolveTypeNodeSymbol(variable.type.elementType) : + this.resolveTypeNodeSymbol(variable.type); } + return variable.initializer ? this.tsTypeChecker.getTypeAtLocation(variable.initializer).getSymbol() : undefined; } - private validateDeclInferredType( - type: ts.Type, - decl: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration - ): void { - if (type.aliasSymbol !== undefined) { - return; - } - if (TsUtils.isObjectType(type) && !!(type.objectFlags & ts.ObjectFlags.Reference)) { - this.handleInferredObjectreference(type, decl); - return; + private resolveTypeNodeSymbol(typeNode: ts.TypeNode): ts.Symbol | undefined { + if (!ts.isTypeReferenceNode(typeNode)) { + return undefined; } - if (this.validatedTypesSet.has(type)) { - return; + const symbol = this.tsTypeChecker.getTypeAtLocation(typeNode).getSymbol(); + if (!symbol) { + return this.resolveTypeNoSymbol(typeNode); } - if (type.isUnion()) { - this.validatedTypesSet.add(type); - for (const unionElem of type.types) { - this.validateDeclInferredType(unionElem, decl); + const declarations = symbol.getDeclarations(); + if (declarations && declarations.length > 0) { + const declaration = declarations[0]; + if (ts.isTypeAliasDeclaration(declaration)) { + return this.resolveTypeNodeSymbol(declaration.type); + } else if (ts.isInterfaceDeclaration(declaration)) { + const heritageSymbol = this.processQuotedHyphenPropsDeprecatedOnInterfaceDeclaration(declaration); + return heritageSymbol; } } - if (TsUtils.isAnyType(type)) { - this.incrementCounters(decl, FaultID.AnyType); - } else if (TsUtils.isUnknownType(type)) { - this.incrementCounters(decl, FaultID.UnknownType); - } + return this.tsTypeChecker.getTypeAtLocation(typeNode).getSymbol(); } - private handleCommentDirectives(sourceFile: ts.SourceFile): void { + private resolveTypeNoSymbol(typeNode: ts.TypeReferenceNode): ts.Symbol | undefined { + if (!typeNode.typeName) { + return undefined; + } + if (ts.isQualifiedName(typeNode.typeName)) { + return this.tsTypeChecker.getSymbolAtLocation(typeNode.typeName.right); + } + const sym = this.tsUtils.trueSymbolAtLocation(typeNode.typeName); + if (sym) { + const globalDeclaration = sym.getDeclarations()?.[0]; + if (globalDeclaration && ts.isTypeAliasDeclaration(globalDeclaration)) { + return this.resolveTypeNodeSymbol(globalDeclaration.type); + } + } - /* - * We use a dirty hack to retrieve list of parsed comment directives by accessing - * internal properties of SourceFile node. - */ - /* CC-OFFNXT(no_explicit_any) std lib */ - // Handle comment directive '@ts-nocheck' - const pragmas = (sourceFile as any).pragmas; - if (pragmas && pragmas instanceof Map) { - const noCheckPragma = pragmas.get('ts-nocheck'); - if (noCheckPragma) { + return this.tsTypeChecker.getTypeAtLocation(typeNode).getSymbol(); + } - /* - * The value is either a single entry or an array of entries. - * Wrap up single entry with array to simplify processing. - */ - /* CC-OFFNXT(no_explicit_any) std lib */ - const noCheckEntries: any[] = Array.isArray(noCheckPragma) ? noCheckPragma : [noCheckPragma]; - for (const entry of noCheckEntries) { - this.processNoCheckEntry(entry); + private isHeritageClauseisThirdPartyBySymbol(symbol: ts.Symbol): boolean { + const declarations = symbol.getDeclarations(); + if (declarations && declarations.length > 0) { + const firstDeclaration = declarations[0]; + if (ts.isImportSpecifier(firstDeclaration)) { + const importDecl = firstDeclaration.parent.parent.parent; + const importPath = importDecl.moduleSpecifier.getText(); + const import_path = this.getLocalApiListItemByKey(SdkNameInfo.ImportPath); + if (import_path && JSON.stringify(import_path).includes(importPath)) { + return true; } } } + return false; + } - /* CC-OFFNXT(no_explicit_any) std lib */ - // Handle comment directives '@ts-ignore' and '@ts-expect-error' - const commentDirectives = (sourceFile as any).commentDirectives; - if (commentDirectives && Array.isArray(commentDirectives)) { - for (const directive of commentDirectives) { - if (directive.range?.pos === undefined || directive.range?.end === undefined) { - continue; - } + private getLocalApiListItemByKey(key: string): string | string[] { + if (!this.localApiListItem) { + return ''; + } + if (SdkNameInfo.ParentApiName === key) { + return this.localApiListItem.api_info.parent_api[0].api_name; + } else if (SdkNameInfo.ImportPath === key) { + return this.localApiListItem.import_path; + } + return ''; + } - const range = directive.range as ts.TextRange; - const kind: ts.SyntaxKind = - sourceFile.text.slice(range.pos, range.pos + 2) === '/*' ? - ts.SyntaxKind.MultiLineCommentTrivia : - ts.SyntaxKind.SingleLineCommentTrivia; - const commentRange: ts.CommentRange = { - pos: range.pos, - end: range.end, - kind - }; + private processQuotedHyphenPropsDeprecatedOnInterfaceDeclaration( + node: ts.InterfaceDeclaration + ): ts.Symbol | undefined { + const heritageSymbol = this.processHeritageClauses(node); + if (heritageSymbol) { + return heritageSymbol; + } + return this.processMembers(node); + } - this.incrementCounters(commentRange, FaultID.ErrorSuppression); - } + private processHeritageClauses(node: ts.InterfaceDeclaration): ts.Symbol | undefined { + if (!node.heritageClauses) { + return undefined; + } + for (const heritageClause of node.heritageClauses) { + return this.processHeritageClause(heritageClause); } + + return undefined; } - /* CC-OFFNXT(no_explicit_any) std lib */ - private processNoCheckEntry(entry: any): void { - if (entry.range?.kind === undefined || entry.range?.pos === undefined || entry.range?.end === undefined) { - return; + private processHeritageClause(heritageClause: ts.HeritageClause): ts.Symbol | undefined { + for (const type of heritageClause.types) { + if (!type.expression) { + return undefined; + } + if (ts.isPropertyAccessExpression(type.expression)) { + return this.processPropertyAccessExpression(type.expression); + } } + return undefined; + } - this.incrementCounters(entry.range as ts.CommentRange, FaultID.ErrorSuppression); + private processPropertyAccessExpression(expression: ts.PropertyAccessExpression): ts.Symbol | undefined { + const heritageSymbol = this.tsTypeChecker.getSymbolAtLocation(expression.expression); + if (heritageSymbol && expression.name.text === this.getLocalApiListItemByKey(SdkNameInfo.ParentApiName)) { + return heritageSymbol; + } + return undefined; } - private reportThisKeywordsInScope(scope: ts.Block | ts.Expression): void { - const callback = (node: ts.Node): void => { - if (node.kind === ts.SyntaxKind.ThisKeyword) { - this.incrementCounters(node, FaultID.FunctionContainsThis); + private processMembers(node: ts.InterfaceDeclaration): ts.Symbol | undefined { + if (!node.members) { + return undefined; + } + for (const member of node.members) { + if (ts.isPropertySignature(member) && member.type) { + return this.resolveTypeNodeSymbol(member.type); } - }; - const stopCondition = (node: ts.Node): boolean => { - const isClassLike = ts.isClassDeclaration(node) || ts.isClassExpression(node); - const isFunctionLike = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node); - const isModuleDecl = ts.isModuleDeclaration(node); - return isClassLike || isFunctionLike || isModuleDecl; - }; - forEachNodeInSubtree(scope, callback, stopCondition); + } + return undefined; } - private handleConstructorDeclaration(node: ts.Node): void { - const ctorDecl = node as ts.ConstructorDeclaration; - this.handleTSOverload(ctorDecl); - const paramProperties = ctorDecl.parameters.filter((x) => { - return this.tsUtils.hasAccessModifier(x); + private processApiNodeSdkDuplicateDeclName(apiName: string, errorNode: ts.Node): void { + const setApiListItem = TypeScriptLinter.globalApiInfo.get(SdkProblem.DeclWithDuplicateName); + if (!setApiListItem) { + return; + } + const apiNamesArr = [...setApiListItem]; + const hasSameApiName = apiNamesArr.some((apilistItem) => { + return apilistItem.api_info.api_name === errorNode.getText(); }); - if (paramProperties.length === 0) { + if (!hasSameApiName) { return; } - let paramTypes: ts.TypeNode[] | undefined; - if (ctorDecl.body) { - paramTypes = this.collectCtorParamTypes(ctorDecl); + + if (ts.isTypeReferenceNode(errorNode)) { + errorNode = errorNode.typeName; } - const autofix = this.autofixer?.fixCtorParameterProperties(ctorDecl, paramTypes); - for (const param of paramProperties) { - this.incrementCounters(param, FaultID.ParameterProperties, autofix); + + const matchedApi = apiNamesArr.some((sdkInfo) => { + const isSameName = sdkInfo.api_info.api_name === apiName; + const isGlobal = sdkInfo.is_global; + return isSameName && isGlobal; + }); + + if (matchedApi) { + this.incrementCounters(errorNode, FaultID.DuplicateDeclNameFromSdk); } } - private collectCtorParamTypes(ctorDecl: ts.ConstructorDeclaration): ts.TypeNode[] | undefined { - const paramTypes: ts.TypeNode[] = []; - - for (const param of ctorDecl.parameters) { - let paramTypeNode = param.type; - if (!paramTypeNode) { - const paramType = this.tsTypeChecker.getTypeAtLocation(param); - paramTypeNode = this.tsTypeChecker.typeToTypeNode(paramType, param, ts.NodeBuilderFlags.None); - } - if (!paramTypeNode || !this.tsUtils.isSupportedType(paramTypeNode)) { - return undefined; - } - paramTypes.push(paramTypeNode); + private handleSdkDuplicateDeclName( + node: + | ts.TypeReferenceNode + | ts.NewExpression + | ts.VariableDeclaration + | ts.PropertyDeclaration + | ts.ParameterDeclaration + | ts.CallExpression + | ts.BinaryExpression + | ts.ExpressionWithTypeArguments + | ts.Identifier + ): void { + if (!this.options.arkts2) { + return; + } + switch (node.kind) { + case ts.SyntaxKind.TypeReference: + this.checkTypeReferenceForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.NewExpression: + this.checkNewExpressionForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.Identifier: + this.checkHeritageClauseForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.Parameter: + this.checkDeclarationForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.CallExpression: + this.checkCallExpressionForSdkDuplicateDeclName(node); + break; + case ts.SyntaxKind.BinaryExpression: + this.checkBinaryExpressionForSdkDuplicateDeclName(node); + break; + default: } + } - return paramTypes; + private checkTypeReferenceForSdkDuplicateDeclName(node: ts.TypeReferenceNode): void { + const typeName = node.typeName; + if (ts.isIdentifier(typeName)) { + this.processApiNodeSdkDuplicateDeclName(typeName.text, node); + } } - private handlePrivateIdentifier(node: ts.Node): void { - const ident = node as ts.PrivateIdentifier; - const autofix = this.autofixer?.fixPrivateIdentifier(ident); - this.incrementCounters(node, FaultID.PrivateIdentifier, autofix); + private checkNewExpressionForSdkDuplicateDeclName(node: ts.NewExpression): void { + const expression = node.expression; + if (ts.isIdentifier(expression)) { + this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + } } - private handleIndexSignature(node: ts.Node): void { - if (!this.tsUtils.isAllowedIndexSignature(node as ts.IndexSignatureDeclaration)) { - this.incrementCounters(node, FaultID.IndexMember); + private checkHeritageClauseForSdkDuplicateDeclName(node: ts.Identifier): void { + if (ts.isIdentifier(node)) { + this.processApiNodeSdkDuplicateDeclName(node.text, node); } } - private handleTypeLiteral(node: ts.Node): void { - const typeLiteral = node as ts.TypeLiteralNode; - const autofix = this.autofixer?.fixTypeliteral(typeLiteral); - this.incrementCounters(node, FaultID.ObjectTypeLiteral, autofix); + private checkDeclarationForSdkDuplicateDeclName( + node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration + ): void { + const expression = node.initializer; + if (expression && ts.isIdentifier(expression)) { + this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + } } - private scanCapturedVarsInSendableScope(startNode: ts.Node, scope: ts.Node, faultId: FaultID): void { - const callback = (node: ts.Node): void => { - // Namespace import will introduce closure in the es2abc compiler stage - if (!ts.isIdentifier(node) || this.checkNamespaceImportVar(node)) { - return; - } + private checkCallExpressionForSdkDuplicateDeclName(node: ts.CallExpression): void { + if (ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { + const expression = node.expression.expression; + this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + } + } - // The "b" of "A.b" should not be checked since it's load from object "A" - const parent: ts.Node = node.parent; - if (ts.isPropertyAccessExpression(parent) && parent.name === node) { - return; - } - // When overloading function, will misreport - if (ts.isFunctionDeclaration(startNode) && startNode.name === node) { - return; - } + private checkBinaryExpressionForSdkDuplicateDeclName(node: ts.BinaryExpression): void { + const expression = node.right; + if (ts.isIdentifier(expression)) { + this.processApiNodeSdkDuplicateDeclName(expression.text, expression); + } + } - this.checkLocalDecl(node, scope, faultId); - }; - // Type nodes should not checked because no closure will be introduced - const stopCondition = (node: ts.Node): boolean => { - // already existed 'arkts-sendable-class-decoratos' error - if (ts.isDecorator(node) && node.parent === startNode) { - return true; + private checkEWTArgumentsForSdkDuplicateDeclName(node: ts.HeritageClause): void { + if (!this.options.arkts2) { + return; + } + if (node.token === ts.SyntaxKind.ExtendsKeyword || node.token === ts.SyntaxKind.ImplementsKeyword) { + node.types.forEach((type) => { + const expr = type.expression; + if (ts.isIdentifier(expr)) { + this.processApiNodeSdkDuplicateDeclName(expr.text, expr); + } + }); + } + } + + private getOriginalSymbol(node: ts.Node): ts.Symbol | undefined { + if (ts.isIdentifier(node)) { + const variableDeclaration = this.findVariableDeclaration(node); + if (variableDeclaration?.initializer) { + return this.getOriginalSymbol(variableDeclaration.initializer); + } + } else if (ts.isNewExpression(node)) { + const constructor = node.expression; + if (ts.isIdentifier(constructor)) { + return this.tsUtils.trueSymbolAtLocation(constructor); + } + } else if (ts.isCallExpression(node)) { + const callee = node.expression; + if (ts.isIdentifier(callee)) { + return this.tsUtils.trueSymbolAtLocation(callee); + } else if (ts.isPropertyAccessExpression(callee)) { + return this.getOriginalSymbol(callee.expression); } - return ts.isTypeReferenceNode(node); - }; - forEachNodeInSubtree(startNode, callback, stopCondition); + } else if (ts.isPropertyAccessExpression(node)) { + return this.getOriginalSymbol(node.expression); + } + return this.tsUtils.trueSymbolAtLocation(node); } - private checkLocalDecl(node: ts.Identifier, scope: ts.Node, faultId: FaultID): void { - const trueSym = this.tsUtils.trueSymbolAtLocation(node); - // Sendable decorator should be used in method of Sendable classes - if (trueSym === undefined) { - return; + private static isFromJsImport(symbol: ts.Symbol): boolean { + const declaration = symbol.declarations?.[0]; + if (declaration) { + const sourceFile = declaration.getSourceFile(); + return sourceFile.fileName.endsWith(EXTNAME_JS); } + return false; + } - // Const enum member will be replaced by the exact value of it, no closure will be introduced - if (TsUtils.isConstEnum(trueSym)) { - return; + private hasLocalAssignment(node: ts.Node): boolean { + if (ts.isIdentifier(node)) { + const variableDeclaration = this.findVariableDeclaration(node); + return !!variableDeclaration?.initializer; } + return false; + } - const declarations = trueSym.getDeclarations(); - if (declarations?.length) { - this.checkLocalDeclWithSendableClosure(node, scope, declarations[0], faultId); + private isLocalCall(node: ts.Node): boolean { + if (ts.isCallExpression(node)) { + const callee = node.expression; + if (ts.isIdentifier(callee)) { + return this.hasLocalAssignment(callee); + } else if (ts.isPropertyAccessExpression(callee)) { + const objectNode = callee.expression; + return this.hasLocalAssignment(objectNode); + } } + return false; } - private checkLocalDeclWithSendableClosure( - node: ts.Identifier, - scope: ts.Node, - decl: ts.Declaration, - faultId: FaultID - ): void { - const declPosition = decl.getStart(); - if ( - decl.getSourceFile().fileName !== node.getSourceFile().fileName || - declPosition !== undefined && declPosition >= scope.getStart() && declPosition < scope.getEnd() - ) { + private handleInterOpImportJsOnTypeOfNode(typeofExpress: ts.TypeOfExpression): void { + if (!this.options.arkts2 || !typeofExpress || !this.useStatic) { + return; + } + const targetNode = typeofExpress.expression; + if (this.hasLocalAssignment(targetNode) || this.isLocalCall(targetNode)) { return; } + const targetSymbol = this.getOriginalSymbol(targetNode); + if (targetSymbol && TypeScriptLinter.isFromJsImport(targetSymbol)) { + const autofix = this.autofixer?.fixInterOpImportJsOnTypeOf(typeofExpress); + this.incrementCounters(typeofExpress, FaultID.InterOpImportJsForTypeOf, autofix); + } + } - if (this.isFileExportDecl(decl)) { + private handleSdkTypeQuery(decl: ts.PropertyAccessExpression): void { + if (!this.options.arkts2 || !ts.isPropertyAccessExpression(decl)) { return; } - if (this.isTopSendableClosure(decl)) { + if (this.handleSelfPropertyAccess(decl)) { return; } - /** - * The cases in condition will introduce closure if defined in the same file as the Sendable class. The following - * cases are excluded because they are not allowed in ArkTS: - * 1. ImportEqualDecalration - * 2. BindingElement - */ - if ( - ts.isVariableDeclaration(decl) || - ts.isFunctionDeclaration(decl) || - ts.isClassDeclaration(decl) || - ts.isInterfaceDeclaration(decl) || - ts.isEnumDeclaration(decl) || - ts.isModuleDeclaration(decl) || - ts.isParameter(decl) - ) { - this.incrementCounters(node, faultId); + if (ts.isPropertyAccessExpression(decl)) { + const deprecatedProperties = [ + 'position', + 'subtype', + 'movingPhotoEffectMode', + 'dynamicRangeType', + 'thumbnailVisible' + ]; + + const propertyName = ts.isIdentifier(decl.name) ? decl.name.text : ''; + if (deprecatedProperties.includes(propertyName)) { + this.incrementCounters(decl.name, FaultID.SdkTypeQuery); + return; + } } + + this.handleImportApiPropertyAccess(decl); } - private isTopSendableClosure(decl: ts.Declaration): boolean { - if (!ts.isSourceFile(decl.parent)) { + private handleSelfPropertyAccess(decl: ts.PropertyAccessExpression): boolean { + if (!ts.isPropertyAccessExpression(decl.expression)) { return false; } - if ( - ts.isClassDeclaration(decl) && - this.tsUtils.isSendableClassOrInterface(this.tsTypeChecker.getTypeAtLocation(decl)) - ) { - return true; + + const propertyName = ts.isIdentifier(decl.expression.name) && decl.expression.name.text || ''; + if (propertyName !== 'self') { + return false; } - if (ts.isFunctionDeclaration(decl) && TsUtils.hasSendableDecoratorFunctionOverload(decl)) { - return true; + + this.incrementCounters(decl.name, FaultID.SdkTypeQuery); + return true; + } + + private handleImportApiPropertyAccess(decl: ts.PropertyAccessExpression): void { + if (!ts.isPropertyAccessExpression(decl.expression)) { + return; + } + + const importApiName = ts.isIdentifier(decl.expression.expression) && decl.expression.expression.text || ''; + const sdkInfos = importApiName && this.interfaceMap.get(importApiName); + if (!sdkInfos) { + return; + } + + const apiName = ts.isIdentifier(decl.name) && decl.name.text || ''; + const matchedApi = [...sdkInfos].find((sdkInfo) => { + return sdkInfo.api_name === apiName; + }); + + if (matchedApi) { + this.incrementCounters(decl.name, FaultID.SdkTypeQuery); } - return false; } - private checkNamespaceImportVar(node: ts.Node): boolean { - // Namespace import cannot be determined by the true symbol - const sym = this.tsTypeChecker.getSymbolAtLocation(node); - const decls = sym?.getDeclarations(); - if (decls?.length) { - if (ts.isNamespaceImport(decls[0])) { - this.incrementCounters(node, FaultID.SendableCapturedVars); - return true; - } + private handleGetOwnPropertyNames(decl: ts.PropertyAccessExpression): void { + if (this.checkPropertyAccessExpression(decl, GET_OWN_PROPERTY_NAMES_TEXT, TypeScriptLinter.missingAttributeSet)) { + const autofix = this.autofixer?.fixMissingAttribute(decl); + this.incrementCounters(decl, FaultID.BuiltinGetOwnPropertyNames, autofix); } - return false; } - private isFileExportDecl(decl: ts.Declaration): boolean { - const sourceFile = decl.getSourceFile(); - if (!this.fileExportDeclCaches) { - this.fileExportDeclCaches = this.tsUtils.searchFileExportDecl(sourceFile); + private handleSymbolIterator(decl: ts.PropertyAccessExpression): void { + if (this.checkPropertyAccessExpression(decl, SYMBOL_ITERATOR, TypeScriptLinter.symbotIterSet)) { + this.incrementCounters(decl, FaultID.BuiltinSymbolIterator); } - return this.fileExportDeclCaches.has(decl); } - lint(sourceFile: ts.SourceFile): void { - if (this.options.enableAutofix) { - this.autofixer = new Autofixer(this.tsTypeChecker, this.tsUtils, sourceFile, this.options.cancellationToken); + private checkPropertyAccessExpression(decl: ts.PropertyAccessExpression, name: string, set: Set): boolean { + if (set.size === 0 || decl.getText() !== name) { + return false; } - this.sourceFile = sourceFile; - this.fileExportDeclCaches = undefined; - this.extractImportedNames(this.sourceFile); - this.visitSourceFile(this.sourceFile); - this.handleCommentDirectives(this.sourceFile); - this.processInterfacesToImport(); + const symbol = this.tsUtils.trueSymbolAtLocation(decl); + const sourceFile = symbol?.declarations?.[0]?.getSourceFile(); + if (!sourceFile) { + return false; + } + + const fileName = path.basename(sourceFile.fileName); + return set.has(fileName); } - private handleExportKeyword(node: ts.Node): void { - const parentNode = node.parent; - if (!TypeScriptLinter.inSharedModule(node) || ts.isModuleBlock(parentNode.parent)) { + private fixJsImportCallExpression(callExpr: ts.CallExpression): void { + if (!this.options.arkts2 || !this.useStatic) { return; } - switch (parentNode.kind) { - case ts.SyntaxKind.EnumDeclaration: - case ts.SyntaxKind.InterfaceDeclaration: - case ts.SyntaxKind.FunctionDeclaration: - case ts.SyntaxKind.ClassDeclaration: - if (!this.tsUtils.isShareableType(this.tsTypeChecker.getTypeAtLocation(parentNode))) { - this.incrementCounters((parentNode as ts.NamedDeclaration).name ?? parentNode, FaultID.SharedModuleExports); - } - return; - case ts.SyntaxKind.VariableStatement: - for (const variableDeclaration of (parentNode as ts.VariableStatement).declarationList.declarations) { - if (!this.tsUtils.isShareableEntity(variableDeclaration.name)) { - this.incrementCounters(variableDeclaration.name, FaultID.SharedModuleExports); - } + const identifier = this.tsUtils.findIdentifierInExpression(callExpr); + if (!identifier) { + return; + } + + if (!this.tsUtils.isImportedFromJS(identifier)) { + return; + } + + callExpr.arguments.forEach((arg) => { + const type = this.tsTypeChecker.getTypeAtLocation(arg); + if (ts.isArrowFunction(arg)) { + this.incrementCounters(arg, FaultID.InteropJsObjectCallStaticFunc); + } else if (ts.isIdentifier(arg)) { + const sym = this.tsTypeChecker.getSymbolAtLocation(arg); + const decl = sym?.declarations?.[0]; + if ( + decl && + (ts.isFunctionDeclaration(decl) || + ts.isVariableDeclaration(decl) && decl.initializer && ts.isArrowFunction(decl.initializer)) + ) { + this.incrementCounters(arg, FaultID.InteropJsObjectCallStaticFunc); } - return; - case ts.SyntaxKind.TypeAliasDeclaration: - if (!this.tsUtils.isShareableEntity(parentNode)) { - this.incrementCounters(parentNode, FaultID.SharedModuleExportsWarning); + if (type?.isClassOrInterface()) { + this.incrementCounters(arg, FaultID.InteropJsObjectExpandStaticInstance); } - return; - default: - this.incrementCounters(parentNode, FaultID.SharedModuleExports); - } + } else if (ts.isObjectLiteralExpression(arg) || type?.isClassOrInterface()) { + this.incrementCounters(arg, FaultID.InteropJsObjectExpandStaticInstance); + } + }); } - private handleExportDeclaration(node: ts.Node): void { - if (!TypeScriptLinter.inSharedModule(node) || ts.isModuleBlock(node.parent)) { + private fixJsImportExtendsClass( + node: ts.ClassLikeDeclaration | ts.InterfaceDeclaration, + identifier: ts.Identifier + ): void { + if (!this.options.arkts2) { return; } - const exportDecl = node as ts.ExportDeclaration; - if (exportDecl.exportClause === undefined) { - this.incrementCounters(exportDecl, FaultID.SharedModuleNoWildcardExport); + if (!this.tsUtils.isImportedFromJS(identifier)) { return; } - if (ts.isNamespaceExport(exportDecl.exportClause)) { - if (!this.tsUtils.isShareableType(this.tsTypeChecker.getTypeAtLocation(exportDecl.exportClause.name))) { - this.incrementCounters(exportDecl.exportClause.name, FaultID.SharedModuleExports); - } + const className = node.name?.text; + if (!className) { return; } + this.incrementCounters(node, FaultID.InteropJsObjectInheritance); + } - for (const exportSpecifier of exportDecl.exportClause.elements) { - if (!this.tsUtils.isShareableEntity(exportSpecifier.name)) { - this.incrementCounters(exportSpecifier.name, FaultID.SharedModuleExports); - } + private fixJsImportPropertyAccessExpression(node: ts.Node): void { + if (!this.options.arkts2 || !this.useStatic) { + return; } - } - private handleReturnStatement(node: ts.Node): void { - // The return value must match the return type of the 'function' - const returnStat = node as ts.ReturnStatement; - const expr = returnStat.expression; - if (!expr) { + const identifier = this.tsUtils.findIdentifierInExpression(node); + if (!identifier) { return; } - const lhsType = this.tsTypeChecker.getContextualType(expr); - if (!lhsType) { + + // Try direct check first + if (this.tsUtils.isImportedFromJS(identifier)) { + const autofix = this.autofixer?.createReplacementForJsImportPropertyAccessExpression( + node as ts.PropertyAccessExpression + ); + + this.incrementCounters( + node, + TsUtils.isInsideIfCondition(node) ? FaultID.InteropJsObjectConditionJudgment : FaultID.InteropJsObjectUsage, + autofix + ); return; } - this.checkAssignmentMatching(node, lhsType, expr, true); + + // Try indirect reference (e.g., const foo = importedObj;) + const originalIdentifier = this.tsUtils.findOriginalIdentifier(identifier); + if (originalIdentifier && this.tsUtils.isImportedFromJS(originalIdentifier)) { + const autofix = this.autofixer?.createReplacementForJsIndirectImportPropertyAccessExpression( + node as ts.PropertyAccessExpression + ); + this.incrementCounters(node, FaultID.InteropJsObjectUsage, autofix); + } } - /** - * 'arkts-no-structural-typing' check was missing in some scenarios, - * in order not to cause incompatibility, - * only need to strictly match the type of filling the check again - */ - private checkAssignmentMatching( - field: ts.Node, - lhsType: ts.Type, - rhsExpr: ts.Expression, - isNewStructuralCheck: boolean = false - ): void { - const rhsType = this.tsTypeChecker.getTypeAtLocation(rhsExpr); - this.handleNoTuplesArrays(field, lhsType, rhsType); - // check that 'sendable typeAlias' is assigned correctly - if (this.tsUtils.isWrongSendableFunctionAssignment(lhsType, rhsType)) { - this.incrementCounters(field, FaultID.SendableFunctionAssignment); + private fixJsImportElementAccessExpression(elementAccessExpr: ts.ElementAccessExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; } - 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) { + + const variableDeclaration = ts.isIdentifier(elementAccessExpr.expression) ? + this.tsUtils.findVariableDeclaration(elementAccessExpr.expression) : + undefined; + if (!variableDeclaration?.initializer) { return; } - if (this.tsUtils.needToDeduceStructuralIdentity(lhsType, rhsType, rhsExpr, isStrict)) { - this.incrementCounters(field, FaultID.StructuralIdentity); + + const identifier = ts.isPropertyAccessExpression(variableDeclaration.initializer) ? + (variableDeclaration.initializer.expression as ts.Identifier) : + undefined; + if (!identifier) { + return; + } + + if (!this.tsUtils.isImportedFromJS(identifier)) { + return; } + + const autofix = this.autofixer?.createReplacementJsImportElementAccessExpression( + elementAccessExpr, + elementAccessExpr.expression as ts.Identifier + ); + + this.incrementCounters(elementAccessExpr, FaultID.InteropJsObjectTraverseJsInstance, autofix); } - private handleDecorator(node: ts.Node): void { - this.handleExtendDecorator(node); + private handleTaskPoolDeprecatedUsages(node: ts.CallExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } - const decorator: ts.Decorator = node as ts.Decorator; - this.handleSendableDecorator(decorator); - this.handleConcurrentDecorator(decorator); - this.handleStylesDecorator(decorator); - this.handleTypescriptDecorators(decorator); - if (TsUtils.getDecoratorName(decorator) === SENDABLE_DECORATOR) { - const parent: ts.Node = decorator.parent; - if (!parent || !SENDABLE_DECORATOR_NODES.includes(parent.kind)) { - const autofix = this.autofixer?.removeDecorator(decorator); - this.incrementCounters(decorator, FaultID.SendableDecoratorLimited, autofix); - } + if (!ts.isPropertyAccessExpression(node.expression)) { + return; } - this.handleNotSupportCustomDecorators(decorator); - } - private isSendableDecoratorValid(decl: ts.FunctionDeclaration | ts.TypeAliasDeclaration): boolean { - if ( - this.compatibleSdkVersion > SENDBALE_FUNCTION_START_VERSION || - this.compatibleSdkVersion === SENDBALE_FUNCTION_START_VERSION && - !SENDABLE_FUNCTION_UNSUPPORTED_STAGES_IN_API12.includes(this.compatibleSdkVersionStage) - ) { - return true; + const propertyAccess = node.expression; + const objectExpr = propertyAccess.expression; + + // Step 1: Must be either setCloneList or setTransferList + if (!TypeScriptLinter.isDeprecatedTaskPoolMethodCall(propertyAccess)) { + return; } - const curDecorator = TsUtils.getSendableDecorator(decl); - if (curDecorator) { - this.incrementCounters(curDecorator, FaultID.SendableBetaCompatible); + + if (!ts.isIdentifier(objectExpr)) { + return; } - return false; - } - private handleImportType(node: ts.Node): void { - if (!this.options.arkts2) { + // Step 2: Resolve declaration of task + const variableDecl = this.tsUtils.findVariableDeclaration(objectExpr); + if (!variableDecl?.initializer || !ts.isNewExpression(variableDecl.initializer)) { return; } - this.incrementCounters(node, FaultID.ImportType); - this.incrementCounters(node, FaultID.DynamicImport); + + // Step 3: Check new taskpool.Task() + const taskpoolExpr = variableDecl.initializer.expression; + if (!TypeScriptLinter.isTaskPoolTaskCreation(taskpoolExpr)) { + return; + } + + const faultId = + propertyAccess.name.text === DEPRECATED_TASKPOOL_METHOD_SETCLONELIST ? + FaultID.SetCloneListDeprecated : + FaultID.SetTransferListDeprecated; + this.incrementCounters(node.parent, faultId); + } + + private static isDeprecatedTaskPoolMethodCall(propertyAccess: ts.PropertyAccessExpression): boolean { + if (!ts.isIdentifier(propertyAccess.expression)) { + return false; + } + const methodName = propertyAccess.name.text; + return ( + methodName === DEPRECATED_TASKPOOL_METHOD_SETCLONELIST || + methodName === DEPRECATED_TASKPOOL_METHOD_SETTRANSFERLIST + ); + } + + private static isTaskPoolTaskCreation(taskpoolExpr: ts.Expression): boolean { + return ( + ts.isPropertyAccessExpression(taskpoolExpr) && + ts.isIdentifier(taskpoolExpr.expression) && + taskpoolExpr.expression.text === STDLIB_TASKPOOL_OBJECT_NAME && + taskpoolExpr.name.text === STDLIB_TASK_CLASS_NAME + ); } - private handleVoidExpression(node: ts.Node): void { + private checkStdLibConcurrencyImport(importDeclaration: ts.ImportDeclaration): void { if (!this.options.arkts2) { return; } - const autofix = this.autofixer?.fixVoidOperator(node as ts.VoidExpression); - this.incrementCounters(node, FaultID.VoidOperator, autofix); - } - private handleRegularExpressionLiteral(node: ts.Node): void { - if (!this.options.arkts2) { + const importClause = importDeclaration.importClause; + if (!importClause) { return; } - const autofix = this.autofixer?.fixRegularExpressionLiteral(node as ts.RegularExpressionLiteral); - this.incrementCounters(node, FaultID.RegularExpressionLiteral, autofix); - } - private handleLimitedVoidType(node: ts.VariableDeclaration): void { - if (!this.options.arkts2) { + const moduleName = (importDeclaration.moduleSpecifier as ts.StringLiteral).text; + const expectedImports = MODULE_IMPORTS[moduleName]; + if (!expectedImports) { return; } - const typeNode = node.type; - if (typeNode && typeNode.kind === ts.SyntaxKind.VoidKeyword) { - this.incrementCounters(typeNode, FaultID.LimitedVoidType); - } - } + const defaultImport = importClause.name; + const namedBindings = importClause.namedBindings; - private handleLimitedVoidWithCall(node: ts.CallExpression): void { - if (!this.options.arkts2) { + const namedImports = namedBindings && ts.isNamedImports(namedBindings) ? namedBindings.elements : []; + + const defaultIsForbidden = defaultImport && expectedImports.includes(defaultImport.getText()); + const forbiddenNamed = namedImports.filter((spec) => { + const name = spec.propertyName ? spec.propertyName.getText() : spec.name.getText(); + return expectedImports.includes(name); + }); + + if ( + TypeScriptLinter.shouldRemoveWholeImport( + defaultIsForbidden, + forbiddenNamed.length, + namedImports.length, + defaultImport + ) + ) { + const autofix = this.autofixer?.removeNode(importDeclaration); + this.incrementCounters(importDeclaration, FaultID.LimitedStdLibNoImportConcurrency, autofix); return; } - const signature = this.tsTypeChecker.getResolvedSignature(node); - if (signature) { - const returnType = this.tsTypeChecker.getReturnTypeOfSignature(signature); - if (this.tsTypeChecker.typeToString(returnType) === 'void') { - this.incrementCounters(node, FaultID.LimitedVoidType); - } + if (defaultIsForbidden) { + const autofix = this.autofixer?.removeDefaultImport(importDeclaration, defaultImport); + this.incrementCounters(defaultImport, FaultID.LimitedStdLibNoImportConcurrency, autofix); + } + + for (const spec of forbiddenNamed) { + const autofix = this.autofixer?.removeImportSpecifier(spec, importDeclaration); + this.incrementCounters(spec, FaultID.LimitedStdLibNoImportConcurrency, autofix); } } - private handleArrayType(arrayType: ts.Node): void { - if (!this.options.arkts2) { + private static shouldRemoveWholeImport( + defaultIsForbidden: boolean | undefined, + forbiddenNamedCount: number, + namedImportsCount: number, + defaultImport: ts.Identifier | undefined + ): boolean { + return ( + defaultIsForbidden && forbiddenNamedCount === namedImportsCount || + defaultIsForbidden && namedImportsCount === 0 || + !defaultImport && forbiddenNamedCount === namedImportsCount && namedImportsCount > 0 + ); + } + + /** + * Checks for missing super() call in child classes that extend a parent class + * with parameterized constructors. If parent class only has parameterized constructors + * and the child class does not call super() in its constructor, report a fault. + * + * This ensures safe and correct subclassing behavior. + * + * @param node The HeritageClause node (extends clause) to analyze. + */ + private handleMissingSuperCallInExtendedClass(node: ts.HeritageClause): void { + if (!this.options.arkts2 || !this.useStatic) { return; } - if (!arrayType || !ts.isArrayTypeNode(arrayType)) { + // We are only interested in 'extends' clauses + if (node.token !== ts.SyntaxKind.ExtendsKeyword) { return; } - if (arrayType.elementType.kind === ts.SyntaxKind.VoidKeyword) { - this.incrementCounters(arrayType.elementType, FaultID.LimitedVoidType); + // Get the parent class declaration (what the child class extends) + const parentClass = this.getParentClassDeclaration(node); + if (!parentClass) { + return; } - } - private handleUnionType(unionType: ts.Node): void { - if (!this.options.arkts2) { + // If parent class has a parameterless constructor (or no constructor at all), child is fine + if (TypeScriptLinter.parentHasParameterlessConstructor(parentClass)) { return; } - if (!unionType || !ts.isUnionTypeNode(unionType)) { + // The child class node (the one extending) + const childClass = node.parent; + if (!ts.isClassDeclaration(childClass)) { return; } - const types = unionType.types; - for (const type of types) { - if (type.kind === ts.SyntaxKind.VoidKeyword) { - this.incrementCounters(type, FaultID.LimitedVoidType); - } + // Look for child class constructor + const childConstructor = childClass.members.find(ts.isConstructorDeclaration); + + /* + * If child has no constructor → error (super() cannot be called) + * If child constructor exists but does not contain super() → error + */ + if (!childConstructor?.body || !TypeScriptLinter.childHasSuperCall(childConstructor)) { + this.incrementCounters(node, FaultID.MissingSuperCall); } } - private handleDebuggerStatement(node: ts.Node): void { - if (!this.options.arkts2) { - return; + /** + * Retrieves the parent class declaration node from an extends heritage clause. + */ + private getParentClassDeclaration(node: ts.HeritageClause): ts.ClassDeclaration | undefined { + const parentExpr = node.types[0]?.expression; + if (!parentExpr) { + return undefined; } - const autofix = this.autofixer?.fixDebuggerStatement(node as ts.DebuggerStatement); - this.incrementCounters(node, FaultID.DebuggerStatement, autofix); + const parentSymbol = this.tsUtils.trueSymbolAtLocation(parentExpr); + return parentSymbol?.declarations?.find(ts.isClassDeclaration); } - private handleTSOverload(decl: ts.FunctionDeclaration | ts.MethodDeclaration | ts.ConstructorDeclaration): void { - if (!this.options.arkts2) { - return; + /** + * Determines if a parent class has a parameterless constructor. + * If it has no constructor at all, that counts as parameterless. + */ + private static parentHasParameterlessConstructor(parentClass: ts.ClassDeclaration): boolean { + const constructors = parentClass.members.filter(ts.isConstructorDeclaration); + return ( + constructors.length === 0 || + constructors.some((ctor) => { + return ctor.parameters.length === 0; + }) + ); + } + + private static childHasSuperCall(constructor: ts.ConstructorDeclaration): boolean { + let superCalled = false; + + if (!constructor.body) { + return false; } - if (decl.name) { - const symbol = this.tsTypeChecker.getSymbolAtLocation(decl.name); - if (symbol) { - const declarations = symbol.getDeclarations(); - if (declarations && declarations.length > 1) { - this.incrementCounters(decl, FaultID.TsOverload); - } - } - } else if (ts.isConstructorDeclaration(decl)) { - const parent = decl.parent; - const constructors = parent.members.filter(ts.isConstructorDeclaration); - if (constructors.length > 1) { - this.incrementCounters(decl, FaultID.TsOverload); + + ts.forEachChild(constructor.body, (stmt) => { + if ( + ts.isExpressionStatement(stmt) && + ts.isCallExpression(stmt.expression) && + stmt.expression.expression.kind === ts.SyntaxKind.SuperKeyword + ) { + superCalled = true; } - } + }); + return superCalled; } - private handleSwitchStatement(node: ts.Node): void { - if (!this.options.arkts2) { + private handleInterOpImportJs(importDecl: ts.ImportDeclaration): void { + if (!this.options.arkts2 || !importDecl || !this.useStatic) { return; } - const switchStatement = node as ts.SwitchStatement; - if (!this.isValidSwitchExpr(switchStatement)) { - this.incrementCounters(switchStatement.expression, FaultID.SwitchExpression); + const importClause = importDecl.importClause; + if (!importClause) { + return; } - const duplicateCases = this.findDuplicateCases(switchStatement); - if (duplicateCases.length > 0) { - for (const duplicateCase of duplicateCases) { - this.incrementCounters(duplicateCase.expression, FaultID.CaseExpression); + const namedBindings = importClause.namedBindings; + let symbol: ts.Symbol | undefined; + let defaultSymbol: ts.Symbol | undefined; + if (importClause.name) { + defaultSymbol = this.tsUtils.trueSymbolAtLocation(importClause.name); + } + if (namedBindings) { + if (ts.isNamedImports(namedBindings)) { + symbol = this.tsUtils.trueSymbolAtLocation(namedBindings.elements[0].name); + } else if (ts.isNamespaceImport(namedBindings)) { + symbol = this.tsUtils.trueSymbolAtLocation(namedBindings.name); } } + const symbolToUse = defaultSymbol || symbol; + if (symbolToUse) { + this.tryAutoFixInterOpImportJs(importDecl, importClause, symbolToUse, defaultSymbol); + } } - private findDuplicateCases(switchStatement: ts.SwitchStatement): ts.CaseClause[] { - const seenValues = new Map(); - const duplicates: ts.CaseClause[] = []; - - for (const clause of switchStatement.caseBlock.clauses) { - if (ts.isCaseClause(clause) && clause.expression) { - const value = this.getConstantValue(clause.expression); - const key = value !== undefined ? value : clause.expression.getText(); - if (seenValues.has(key)) { - duplicates.push(clause); - } else { - seenValues.set(key, clause); - } + private tryAutoFixInterOpImportJs( + importDecl: ts.ImportDeclaration, + importClause: ts.ImportClause, + symbolToUse: ts.Symbol, + defaultSymbol?: ts.Symbol + ): void { + const declaration = symbolToUse.declarations?.[0]; + if (declaration) { + const sourceFile = declaration.getSourceFile(); + if (sourceFile.fileName.endsWith(EXTNAME_JS)) { + const autofix = this.autofixer?.fixInterOpImportJs( + importDecl, + importClause, + TsUtils.removeOrReplaceQuotes(importDecl.moduleSpecifier.getText(this.sourceFile), false), + defaultSymbol + ); + this.incrementCounters(importDecl, FaultID.InterOpImportJs, autofix); } } - return duplicates; } - private getConstantValue(expression: ts.Expression): string | number | boolean | undefined { - if (ts.isLiteralExpression(expression)) { - return ts.isNumericLiteral(expression) ? Number(expression.text) : expression.text; + private findVariableDeclaration(identifier: ts.Identifier): ts.VariableDeclaration | undefined { + const sym = this.tsUtils.trueSymbolAtLocation(identifier); + const decl = TsUtils.getDeclaration(sym); + if ( + decl && + ts.isVariableDeclaration(decl) && + decl.getSourceFile().fileName === identifier.getSourceFile().fileName + ) { + return decl; } + return undefined; + } - switch (expression.kind) { - case ts.SyntaxKind.TrueKeyword: - return true; - case ts.SyntaxKind.FalseKeyword: - return false; - default: - if (ts.isElementAccessExpression(expression) || ts.isPropertyAccessExpression(expression)) { - const constantValue = this.tsTypeChecker.getConstantValue(expression); - if (constantValue !== undefined) { - return constantValue; - } - } - return undefined; + private isFromJSModule(node: ts.Node): boolean { + const symbol = this.tsUtils.trueSymbolAtLocation(node); + if (symbol?.declarations?.[0]) { + const sourceFile = symbol.declarations[0].getSourceFile(); + return sourceFile.fileName.endsWith(EXTNAME_JS); } + return false; } - private isValidSwitchExpr(switchStatement: ts.SwitchStatement): boolean { - const expressionType = this.tsTypeChecker.getTypeAtLocation(switchStatement.expression); - if (!expressionType) { - return false; + handleInstanceOfExpression(node: ts.BinaryExpression): void { + if (!this.options.arkts2 || !this.useStatic) { + return; } - if (this.isSwitchAllowedType(expressionType)) { - return true; + const left = node.left; + const right = node.right; + const getNode = (expr: ts.Expression): ts.Node => { + return ts.isPropertyAccessExpression(expr) || ts.isCallExpression(expr) ? expr.expression : expr; + }; + const leftExpr = getNode(left); + const rightExpr = getNode(right); + if (this.tsUtils.isJsImport(leftExpr) || this.tsUtils.isJsImport(rightExpr)) { + this.incrementCounters(node, FaultID.InteropJsInstanceof); } - if (expressionType.isUnion()) { - const unionTypes = expressionType.types; - return unionTypes.every(this.isSwitchAllowedType); + } + + private checkAutoIncrementDecrement(unaryExpr: ts.PostfixUnaryExpression | ts.PrefixUnaryExpression): void { + if (ts.isPropertyAccessExpression(unaryExpr.operand)) { + const propertyAccess = unaryExpr.operand; + if (this.useStatic && this.options.arkts2) { + if (this.isFromJSModule(propertyAccess.expression)) { + this.incrementCounters(unaryExpr, FaultID.InteropIncrementDecrement); + } + } } - return false; } - private isSwitchAllowedType(type: ts.Type): boolean { - if (type.flags & (ts.TypeFlags.StringLike | ts.TypeFlags.EnumLike)) { - return true; + private handleObjectLiteralforUnionTypeInterop(node: ts.VariableDeclaration): void { + if (!this.options.arkts2 || !this.useStatic) { + return; + } + + if (!node.type || !ts.isUnionTypeNode(node.type)) { + return; } - if (type.flags & ts.TypeFlags.NumberLiteral) { - const value = (type as ts.NumberLiteralType).value; - return Number.isInteger(value); + if (!node.initializer || node.initializer.kind !== ts.SyntaxKind.ObjectLiteralExpression) { + return; } - return this.tsTypeChecker.typeToString(type) === 'int'; + const typeNodes = node.type.types; + + const isDefected = typeNodes.some((tNode) => { + if (!ts.isTypeReferenceNode(tNode)) { + return false; + } + const type = this.tsTypeChecker.getTypeAtLocation(tNode); + const symbol = type.getSymbol(); + if (!symbol) { + return false; + } + for (const declaration of symbol.declarations ?? []) { + if (!TsUtils.isArkts12File(declaration.getSourceFile())) { + return true; + } + } + return false; + }); + + if (isDefected) { + this.incrementCounters(node, FaultID.InteropObjectLiteralAmbiguity); + } } - private handleLimitedLiteralType(literalTypeNode: ts.LiteralTypeNode): void { - if (!this.options.arkts2 || !literalTypeNode) { + private handleObjectLiteralAssignmentToClass( + node: + | ts.VariableDeclaration + | ts.CallExpression + | ts.ReturnStatement + | ts.ArrayLiteralExpression + | ts.PropertyDeclaration + | ts.AsExpression + | ts.BinaryExpression + ): void { + if (!this.options.arkts2 || !this.useStatic) { return; } - const literal = literalTypeNode.literal; - if ( - !( - literal.kind === ts.SyntaxKind.StringLiteral || - literal.kind === ts.SyntaxKind.NullKeyword || - literal.kind === ts.SyntaxKind.UndefinedKeyword - ) - ) { - this.incrementCounters(literalTypeNode, FaultID.LimitedLiteralType); + + switch (node.kind) { + case ts.SyntaxKind.VariableDeclaration: + this.checkVariableDeclarationForObjectLiteral(node); + break; + case ts.SyntaxKind.CallExpression: + this.checkCallExpressionForObjectLiteral(node); + break; + case ts.SyntaxKind.ReturnStatement: + this.checkReturnStatementForObjectLiteral(node); + break; + case ts.SyntaxKind.ArrayLiteralExpression: + this.checkArrayLiteralExpressionForObjectLiteral(node); + break; + case ts.SyntaxKind.PropertyDeclaration: + this.checkPropertyDeclarationForObjectLiteral(node); + break; + case ts.SyntaxKind.AsExpression: + this.checkAsExpressionForObjectLiteral(node); + break; + case ts.SyntaxKind.BinaryExpression: + this.checkBinaryExpressionForObjectLiteral(node); + break; + default: } } - private findVariableInitializationValue(identifier: ts.Identifier): number | null { - const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); + private reportIfAssignedToNonArkts2Class(type: ts.Type, expr: ts.ObjectLiteralExpression): void { + const symbol = type.getSymbol(); if (!symbol) { - return null; - } - if (this.constVariableInitCache.has(symbol)) { - return this.constVariableInitCache.get(symbol)!; + return; } - const declarations = symbol.getDeclarations(); - if (declarations && declarations.length > 0) { - const declaration = declarations[0]; - const isConditionOnEnumMember = ts.isEnumMember(declaration) && declaration.initializer; - const isConditionOnVariableDecl = - ts.isVariableDeclaration(declaration) && - declaration.initializer && - (declaration.parent as ts.VariableDeclarationList).flags & ts.NodeFlags.Const; - if (isConditionOnEnumMember || isConditionOnVariableDecl) { - const res = this.evaluateNumericValue(declaration.initializer); - this.constVariableInitCache.set(symbol, res); - return res; - } + const declarations = symbol.declarations ?? []; + const isClass = declarations.some(ts.isClassDeclaration); + if (!isClass) { + return; } - return null; - } + const isFromArkTs2 = declarations.some((decl) => { + return TsUtils.isArkts12File(decl.getSourceFile()); + }); - private evaluateNumericValueFromPrefixUnaryExpression(node: ts.PrefixUnaryExpression): number | null { - if (node.operator === ts.SyntaxKind.MinusToken) { - if (ts.isNumericLiteral(node.operand) || ts.isIdentifier(node.operand) && node.operand.text === 'Infinity') { - return node.operand.text === 'Infinity' ? Number.NEGATIVE_INFINITY : -Number(node.operand.text); - } - const operandValue = this.evaluateNumericValue(node.operand); - if (operandValue !== null) { - return -operandValue; - } + if (isFromArkTs2) { + return; } - return null; - } - private evaluateNumericValueFromAsExpression(node: ts.AsExpression): number | null { - const typeNode = node.type; - if ( - typeNode.kind === ts.SyntaxKind.NumberKeyword || - ts.isTypeReferenceNode(typeNode) && typeNode.typeName.getText() === 'Number' - ) { - return this.evaluateNumericValue(node.expression); - } - return null; - } + const hasConstructor = declarations.some((decl) => { + return ts.isClassDeclaration(decl) && decl.members.some(ts.isConstructorDeclaration); + }); - private evaluateNumericValue(node: ts.Expression): number | null { - let result: number | null = null; - if (ts.isNumericLiteral(node)) { - result = Number(node.text); - } else if (ts.isPrefixUnaryExpression(node)) { - result = this.evaluateNumericValueFromPrefixUnaryExpression(node); - } else if (ts.isBinaryExpression(node)) { - result = this.evaluateNumericValueFromBinaryExpression(node); - } else if (ts.isPropertyAccessExpression(node)) { - result = this.evaluateNumericValueFromPropertyAccess(node); - } else if (ts.isParenthesizedExpression(node)) { - result = this.evaluateNumericValue(node.expression); - } else if (ts.isAsExpression(node)) { - result = this.evaluateNumericValueFromAsExpression(node); - } else if (ts.isIdentifier(node)) { - if (node.text === 'Infinity') { - return Number.POSITIVE_INFINITY; - } else if (node.text === 'NaN') { - return Number.NaN; - } - const symbol = this.tsTypeChecker.getSymbolAtLocation(node); - return symbol ? this.constVariableInitCache.get(symbol) || null : null; + if (hasConstructor) { + this.incrementCounters(expr, FaultID.InteropObjectLiteralClass); } - return result; } - private evaluateNumericValueFromBinaryExpression(node: ts.BinaryExpression): number | null { - const leftValue = this.evaluateNumericValue(node.left); - const rightValue = this.evaluateNumericValue(node.right); - if (leftValue !== null && rightValue !== null) { - switch (node.operatorToken.kind) { - case ts.SyntaxKind.PlusToken: - return leftValue + rightValue; - case ts.SyntaxKind.MinusToken: - return leftValue - rightValue; - case ts.SyntaxKind.AsteriskToken: - return leftValue * rightValue; - case ts.SyntaxKind.SlashToken: - return leftValue / rightValue; - case ts.SyntaxKind.PercentToken: - return leftValue % rightValue; - case ts.SyntaxKind.AsteriskAsteriskToken: - return Math.pow(leftValue, rightValue); - default: - return null; - } + private checkVariableDeclarationForObjectLiteral(node: ts.VariableDeclaration): void { + if (!node.initializer || !node.type) { + return; } - return null; - } - private evaluateNumericValueFromPropertyAccess(node: ts.PropertyAccessExpression): number | null { - const numberProperties = ['MIN_SAFE_INTEGER', 'MAX_SAFE_INTEGER', 'NaN', 'NEGATIVE_INFINITY', 'POSITIVE_INFINITY']; - if ( - ts.isIdentifier(node.expression) && - node.expression.text === 'Number' && - numberProperties.includes(node.name.text) - ) { - switch (node.name.text) { - case 'MIN_SAFE_INTEGER': - return Number.MIN_SAFE_INTEGER; - case 'MAX_SAFE_INTEGER': - return Number.MAX_SAFE_INTEGER; - case 'NaN': - return Number.NaN; - case 'NEGATIVE_INFINITY': - return Number.NEGATIVE_INFINITY; - case 'POSITIVE_INFINITY': - return Number.POSITIVE_INFINITY; - default: - return null; + const type = this.tsTypeChecker.getTypeAtLocation(node.type); + + const checkObjectLiteral = (expr: ts.Expression): void => { + if (ts.isObjectLiteralExpression(expr)) { + this.reportIfAssignedToNonArkts2Class(type, expr); } + }; + + if (ts.isObjectLiteralExpression(node.initializer)) { + checkObjectLiteral(node.initializer); + } else if (ts.isConditionalExpression(node.initializer)) { + checkObjectLiteral(node.initializer.whenTrue); + checkObjectLiteral(node.initializer.whenFalse); } - return this.evaluateNumericValue(node.name); } - private collectVariableNamesAndCache(node: ts.Node): void { - if (ts.isIdentifier(node)) { - const value = this.findVariableInitializationValue(node); - const symbol = this.tsTypeChecker.getSymbolAtLocation(node); - if (value && symbol) { - this.constVariableInitCache.set(symbol, value); + private checkCallExpressionForObjectLiteral(node: ts.CallExpression): void { + for (const arg of node.arguments) { + if (ts.isObjectLiteralExpression(arg)) { + const signature = this.tsTypeChecker.getResolvedSignature(node); + const params = signature?.getParameters() ?? []; + const index = node.arguments.indexOf(arg); + const paramSymbol = params[index]; + if (!paramSymbol) { + continue; + } + + const paramDecl = paramSymbol.declarations?.[0]; + if (!paramDecl || !ts.isParameter(paramDecl) || !paramDecl.type) { + continue; + } + + const type = this.tsTypeChecker.getTypeAtLocation(paramDecl.type); + this.reportIfAssignedToNonArkts2Class(type, arg); } } - ts.forEachChild(node, this.collectVariableNamesAndCache.bind(this)); } - private handleIndexNegative(node: ts.Node): void { - if (!this.options.arkts2 || !ts.isElementAccessExpression(node)) { + private checkReturnStatementForObjectLiteral(node: ts.ReturnStatement): void { + if (!node.expression || !ts.isObjectLiteralExpression(node.expression)) { + return; + } + const func = ts.findAncestor(node, ts.isFunctionLike); + if (!func?.type) { return; } - const indexNode = node.argumentExpression; - if (indexNode) { - this.collectVariableNamesAndCache(indexNode); - const indexValue = this.evaluateNumericValue(indexNode); - if (indexValue !== null && (indexValue < 0 || isNaN(indexValue))) { - this.incrementCounters(node, FaultID.IndexNegative); + const returnType = this.tsTypeChecker.getTypeAtLocation(func.type); + this.reportIfAssignedToNonArkts2Class(returnType, node.expression); + } + + private checkArrayLiteralExpressionForObjectLiteral(node: ts.ArrayLiteralExpression): void { + for (const element of node.elements) { + if (ts.isObjectLiteralExpression(element)) { + const contextualType = this.tsTypeChecker.getContextualType(node); + if (!contextualType) { + continue; + } + + const typeArgs = (contextualType as ts.TypeReference).typeArguments; + const elementType = typeArgs?.[0]; + if (!elementType) { + continue; + } + + this.reportIfAssignedToNonArkts2Class(elementType, element); } } } - private handleNoTuplesArrays(node: ts.Node, lhsType: ts.Type, rhsType: ts.Type): void { - if (!this.options.arkts2) { + private checkPropertyDeclarationForObjectLiteral(node: ts.PropertyDeclaration): void { + if (!node.initializer || !ts.isObjectLiteralExpression(node.initializer) || !node.type) { return; } - if ( - this.tsUtils.isOrDerivedFrom(lhsType, this.tsUtils.isArray) && - this.tsUtils.isOrDerivedFrom(rhsType, TsUtils.isTuple) - ) { - this.incrementCounters(node, FaultID.NoTuplesArrays); - } + + const type = this.tsTypeChecker.getTypeAtLocation(node.type); + this.reportIfAssignedToNonArkts2Class(type, node.initializer); } - private handleExponentOperation(node: ts.Node): void { - if (!this.options.arkts2) { + private checkAsExpressionForObjectLiteral(node: ts.AsExpression): void { + if (!ts.isObjectLiteralExpression(node.expression)) { return; } - const autofix = this.autofixer?.fixExponent(node.parent); - this.incrementCounters(node, FaultID.ExponentOp, autofix); + + const type = this.tsTypeChecker.getTypeAtLocation(node.type); + this.reportIfAssignedToNonArkts2Class(type, node.expression); } - private handleNonNullExpression(node: ts.Node): void { - if (!this.options.arkts2) { + private checkBinaryExpressionForObjectLiteral(node: ts.BinaryExpression): void { + if (node.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { return; } - - if ( - !ts.isNonNullExpression(node) || - !ts.isNonNullExpression(node.expression) || - ts.isNonNullExpression(node.parent) || - ts.isNonNullExpression(node.expression.expression) - ) { + if (!ts.isObjectLiteralExpression(node.right)) { return; } - const statement = ts.findAncestor(node, ts.isExpressionStatement); - if (statement && this.isCustomComponent(statement)) { - let currentParam: ts.Identifier | undefined; - if (ts.isPropertyAccessExpression(node.expression.expression)) { - currentParam = node.expression.expression.name as ts.Identifier; - } - - let customParam: ts.Identifier | undefined; - if (ts.isPropertyAssignment(node.parent)) { - customParam = node.parent.name as ts.Identifier; - } - - if (!currentParam || !customParam) { - return; - } - - const originalExpr = node.parent.parent; - if (!ts.isObjectLiteralExpression(originalExpr)) { - return; - } - const autofix = this.autofixer?.fixCustomBidirectionalBinding(originalExpr, currentParam, customParam); - this.incrementCounters(node, FaultID.DoubleExclaBindingNotSupported, autofix); - } else { - const autofix = this.autofixer?.fixNativeBidirectionalBinding(node, this.interfacesNeedToImport); - this.incrementCounters(node, FaultID.DoubleExclaBindingNotSupported, autofix); - } + const type = this.tsTypeChecker.getTypeAtLocation(node.left); + this.reportIfAssignedToNonArkts2Class(type, node.right); } - private isCustomComponent(statement: ts.ExpressionStatement): boolean { - const callExpr = statement.expression; - if (!ts.isCallExpression(callExpr)) { + private isObjectLiteralAssignedToArkts12Type(node: ts.Expression, expectedTypeNode?: ts.TypeNode): boolean { + if (node.kind !== ts.SyntaxKind.ObjectLiteralExpression) { return false; } - const identifier = callExpr.expression; - if (!ts.isIdentifier(identifier)) { - return false; + let type: ts.Type; + if (expectedTypeNode) { + type = this.tsTypeChecker.getTypeAtLocation(expectedTypeNode); + } else { + type = this.tsTypeChecker.getContextualType(node) ?? this.tsTypeChecker.getTypeAtLocation(node); } - const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); - if (symbol) { - const decl = this.tsUtils.getDeclarationNode(identifier); - if (decl?.getSourceFile() === statement.getSourceFile()) { - return true; - } + if (!type) { + return false; } - return this.importedInterfaces.has(callExpr.expression.getText()); + return TypeScriptLinter.isTypeFromArkts12(type); } - private handleDoubleDollar(node: ts.Node): void { - if (!this.options.arkts2) { - return; + private static isTypeFromArkts12(type: ts.Type): boolean { + const symbol = type?.getSymbol(); + if (!symbol) { + return false; } - if ( - ts.isPropertyAccessExpression(node) && - ts.isIdentifier(node.expression) && - node.expression.escapedText === DOUBLE_DOLLAR_IDENTIFIER + THIS_IDENTIFIER - ) { - const autofix = this.autofixer?.fixDoubleDollar(node, this.interfacesNeedToImport); - this.incrementCounters(node, FaultID.DoubleDollarBindingNotSupported, autofix); + const isFromArkts12 = (symbol.declarations ?? []).some((decl) => { + return TsUtils.isArkts12File(decl.getSourceFile()); + }); + + if (isFromArkts12) { + return true; } + return false; } - private handleDollarBind(node: ts.Node): void { - if (!this.options.arkts2) { + private processNestedObjectLiterals(objLiteral: ts.Expression, parentType?: ts.Type): void { + if (!ts.isObjectLiteralExpression(objLiteral)) { return; } - if (ts.isPropertyAssignment(node)) { - const text = node.initializer.getText(); - if (!(/^\$\w+$/).test(text)) { + objLiteral.properties.forEach((prop) => { + if (!ts.isPropertyAssignment(prop) || !ts.isObjectLiteralExpression(prop.initializer)) { return; } - const autofix = this.autofixer?.fixDollarBind(node); - this.incrementCounters(node, FaultID.DollarBindingNotSupported, autofix); - } + + if (this.isObjectLiteralAssignedToArkts12Type(prop.initializer)) { + this.incrementCounters(prop.initializer, FaultID.InteropStaticObjectLiterals); + return; + } + + this.checkPropertyTypeFromParent(prop, parentType); + this.processNestedObjectLiterals(prop.initializer); + }); } - private handleExtendDecorator(node: ts.Node): void { - if (!this.options.arkts2) { + private checkPropertyTypeFromParent(prop: ts.PropertyAssignment, parentType?: ts.Type): void { + if (!parentType) { return; } - - if (!ts.isFunctionDeclaration(node.parent) || !ts.isDecorator(node)) { + if (!ts.isObjectLiteralExpression(prop.initializer)) { return; } - if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { - if (node.expression.expression.text === CustomDecoratorName.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) { - const autofix = this.autofixer?.fixExtendDecorator(node, true, this.interfacesNeedToImport); - this.incrementCounters(node.parent, FaultID.AnimatableExtendDecoratorTransform, autofix); - } - } - } + const propName = prop.name.getText(); + const property = parentType.getProperty(propName); - private handleStructPropertyDecl(propDecl: ts.PropertyDeclaration): void { - if (!this.options.arkts2) { + if (!property?.valueDeclaration) { return; } - const isStatic = TsUtils.hasModifier(propDecl.modifiers, ts.SyntaxKind.StaticKeyword); - const hasNoInitializer = !propDecl.initializer; - if (isStatic && hasNoInitializer) { - this.incrementCounters(propDecl, FaultID.ClassstaticInitialization); + + const propType = this.tsTypeChecker.getTypeOfSymbolAtLocation(property, property.valueDeclaration); + + if (TypeScriptLinter.isTypeFromArkts12(propType)) { + this.incrementCounters(prop.initializer, FaultID.InteropStaticObjectLiterals); } } - private handleTaggedTemplatesExpression(node: ts.Node): void { - if (!this.options.arkts2) { + private handleObjectLiteralAssignment(node: ts.VariableDeclaration): void { + if (TsUtils.isArkts12File(node.getSourceFile())) { return; } - this.incrementCounters(node, FaultID.TaggedTemplates); - } - private checkFunctionTypeCompatible(lhsTypeNode: ts.TypeNode | undefined, rhsExpr: ts.Expression): void { - if (this.options.arkts2 && lhsTypeNode && this.tsUtils.isIncompatibleFunctionals(lhsTypeNode, rhsExpr)) { - this.incrementCounters(rhsExpr, FaultID.IncompationbleFunctionType); + if (!node.initializer) { + return; } - } - private handleInvalidIdentifier( - decl: - | ts.TypeAliasDeclaration - | ts.StructDeclaration - | ts.VariableDeclaration - | ts.FunctionDeclaration - | ts.MethodSignature - | ts.ClassDeclaration - | ts.PropertyDeclaration - | ts.MethodDeclaration - | ts.ParameterDeclaration - | ts.PropertySignature - | ts.ImportDeclaration - ): void { - if (!this.options.arkts2) { + if ( + ts.isObjectLiteralExpression(node.initializer) && + this.isObjectLiteralAssignedToArkts12Type(node.initializer, node.type) + ) { + this.incrementCounters(node.initializer, FaultID.InteropStaticObjectLiterals); return; } - const checkIdentifier = (identifier: ts.Identifier | undefined): void => { - const text = identifier && ts.isIdentifier(identifier) ? identifier.text : ''; - if (identifier && text && INVALID_IDENTIFIER_KEYWORDS.includes(text)) { - this.incrementCounters(identifier, FaultID.InvalidIdentifier); - } - }; + const parentType = node.type ? + this.tsTypeChecker.getTypeAtLocation(node.type) : + this.tsTypeChecker.getTypeAtLocation(node.initializer); - if (ts.isImportDeclaration(decl)) { - const importClause = decl.importClause; - if (importClause?.namedBindings && ts.isNamedImports(importClause?.namedBindings)) { - importClause.namedBindings.elements.forEach((importSpecifier) => { - checkIdentifier(importSpecifier.name); - }); - } - checkIdentifier(importClause?.name); - } else if (isStructDeclaration(decl)) { - checkIdentifier((decl as ts.StructDeclaration).name); - } else { - checkIdentifier(decl.name as ts.Identifier); - } + this.processNestedObjectLiterals(node.initializer, parentType); } - private checkExtendsExpression(node: ts.HeritageClause): void { - if (!this.options.arkts2) { + private handleObjectLiteralInFunctionArgs(node: ts.CallExpression): void { + if (TsUtils.isArkts12File(node.getSourceFile())) { return; } - if (node.token === ts.SyntaxKind.ExtendsKeyword) { - node.types.forEach((type) => { - const expr = type.expression; - if ( - ts.isIdentifier(expr) && - this.isVariableReference(expr) && - this.tsUtils.isBuiltinClassHeritageClause(node) - ) { - this.incrementCounters(expr, FaultID.ExtendsExpression); - } - }); + const signature = this.tsTypeChecker.getResolvedSignature(node); + if (!signature) { + return; } - } - private isVariableReference(identifier: ts.Identifier): boolean { - const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); - return !!symbol && (symbol.flags & ts.SymbolFlags.Variable) !== 0; + const params = signature.getParameters(); + + node.arguments.forEach((arg, index) => { + if (!ts.isObjectLiteralExpression(arg)) { + return; + } + + if (index < params.length) { + const param = params[index]; + if (!param.valueDeclaration) { + return; + } + + const paramType = this.tsTypeChecker.getTypeOfSymbolAtLocation(param, param.valueDeclaration); + + if (TypeScriptLinter.isTypeFromArkts12(paramType)) { + this.incrementCounters(arg, FaultID.InteropStaticObjectLiterals); + } + } else if (this.isObjectLiteralAssignedToArkts12Type(arg)) { + this.incrementCounters(arg, FaultID.InteropStaticObjectLiterals); + } + }); } - private handleSendableDecorator(decorator: ts.Decorator): void { - if (!this.options.arkts2) { + private handleObjectLiteralInReturn(node: ts.ReturnStatement): void { + if (TsUtils.isArkts12File(node.getSourceFile())) { return; } - if (TsUtils.getDecoratorName(decorator) === SENDABLE_DECORATOR) { - const parent: ts.Node = decorator.parent; - if (parent && parent.kind !== ts.SyntaxKind.ClassDeclaration) { - return; - } - const autofix = this.autofixer?.removeDecorator(decorator); - this.incrementCounters(decorator, FaultID.LimitedStdLibApi, autofix); - } - } - private handleConcurrentDecorator(decorator: ts.Decorator): void { - if (!this.options.arkts2) { + if (!node.expression || !ts.isObjectLiteralExpression(node.expression)) { return; } - if (TsUtils.getDecoratorName(decorator) === CONCURRENT_DECORATOR) { - const parent: ts.Node = decorator.parent; - if (parent && parent.kind !== ts.SyntaxKind.FunctionDeclaration) { - return; + + let current: ts.Node = node; + let functionNode: ts.FunctionLikeDeclaration | undefined; + + while (current && !functionNode) { + current = current.parent; + if ( + current && + (ts.isFunctionDeclaration(current) || + ts.isMethodDeclaration(current) || + ts.isFunctionExpression(current) || + ts.isArrowFunction(current)) + ) { + functionNode = current; + } + } + + if (functionNode?.type) { + const returnType = this.tsTypeChecker.getTypeAtLocation(functionNode.type); + if (TypeScriptLinter.isTypeFromArkts12(returnType)) { + this.incrementCounters(node.expression, FaultID.InteropStaticObjectLiterals); } - const autofix = this.autofixer?.removeDecorator(decorator); - this.incrementCounters(decorator, FaultID.LimitedStdLibApi, autofix); + } else if (this.isObjectLiteralAssignedToArkts12Type(node.expression)) { + this.incrementCounters(node.expression, FaultID.InteropStaticObjectLiterals); } } - private handleTypescriptDecorators(decorator: ts.Decorator): void { + private handleLocalBuilderDecorator(node: ts.Node): void { if (!this.options.arkts2) { return; } - if (!ts.isClassDeclaration(decorator.parent)) { + if (!ts.isDecorator(node) || !ts.isIdentifier(node.expression)) { return; } + const decoratorName = node.expression.getText(); + if (decoratorName === CustomDecoratorName.LocalBuilder) { + const autofix = this.autofixer?.fixBuilderDecorators(node); + this.incrementCounters(node, FaultID.LocalBuilderDecoratorNotSupported, autofix); + } + } - const decoratorExpression = decorator.expression; - const symbol = this.tsUtils.trueSymbolAtLocation(decoratorExpression); - if (!symbol) { + private checkEnumGetMemberValue(node: ts.ElementAccessExpression): void { + if (!this.options.arkts2) { return; } - const decl = TsUtils.getDeclaration(symbol); - if (!decl) { + if (!ts.isIdentifier(node.expression) || !ts.isNumericLiteral(node.argumentExpression)) { return; } - const sourceFile = decl.getSourceFile(); - if (sourceFile.fileName.endsWith(EXTNAME_TS)) { - this.incrementCounters(decorator, FaultID.InteropNoDecorators); + const symbol = this.tsUtils.trueSymbolAtLocation(node.expression); + if (!symbol?.declarations) { + return; } - } - - private checkWorkerSymbol(symbol: ts.Symbol, node: ts.Node): void { - if (symbol.name === WORKER_TEXT) { - const decl = TsUtils.getDeclaration(symbol); - if (!decl) { + for (const decl of symbol.declarations) { + if (ts.isEnumDeclaration(decl)) { + this.incrementCounters(node, FaultID.UnsupportPropNameFromValue); return; } - const sourceFile = decl.getSourceFile(); - if (WORKER_MODULES.includes(path.basename(sourceFile.fileName).toLowerCase())) { - this.incrementCounters(node, FaultID.LimitedStdLibApi); - } } } - interfaceIdentifiers: ts.Identifier[] = []; - interfacesNeedToImport: Set = new Set(); - importedInterfaces: Set = new Set(); - - private handleInterfaceImport(identifier: ts.Identifier): void { + private handleMakeObserved(node: ts.PropertyAccessExpression): void { if (!this.options.arkts2) { return; } - const name = identifier.getText(); - if (this.shouldSkipIdentifier(identifier)) { + const name = node.name; + if (name.getText() !== MAKE_OBSERVED) { return; } - this.interfaceIdentifiers.push(identifier); - this.interfacesNeedToImport.add(name); - } - - private shouldSkipIdentifier(identifier: ts.Identifier): boolean { - const name = identifier.getText(); - if (!arkuiImportList.has(name)) { - return true; + const expr = node.expression; + const symbol = this.tsTypeChecker.getSymbolAtLocation(expr); + const importSpecifier = TsUtils.getDeclaration(symbol); + if (!importSpecifier || !ts.isImportSpecifier(importSpecifier)) { + return; } - if (skipImportDecoratorName.has(name)) { - return true; + const importDecl = ts.findAncestor(importSpecifier, ts.isImportDeclaration); + if (!importDecl) { + return; } - const wrappedSkipComponents = new Set([CustomDecoratorName.AnimatableExtend, CustomDecoratorName.Extend]); - const parent = identifier.parent; - if (ts.isCallExpression(parent)) { - const expr = parent.expression; - if (wrappedSkipComponents.has(expr.getText()) && name !== CustomDecoratorName.AnimatableExtend) { - return true; - } + const moduleSpecifier = importDecl.moduleSpecifier; + if (!ts.isStringLiteral(moduleSpecifier)) { + return; } - - const symbol = this.tsTypeChecker.getSymbolAtLocation(identifier); - if (symbol) { - const decl = this.tsUtils.getDeclarationNode(identifier); - if (decl?.getSourceFile() === identifier.getSourceFile()) { - return true; - } + if (moduleSpecifier.text !== ARKUI_PACKAGE_NAME && moduleSpecifier.text !== ARKUI_STATE_MANAGEMENT) { + return; } - return this.interfacesNeedToImport.has(name) || this.importedInterfaces.has(name); + this.incrementCounters(node, FaultID.MakeObservedIsNotSupported); } - private processInterfacesToImport(): void { + private handlePropertyDeclarationForProp(node: ts.PropertyDeclaration): void { if (!this.options.arkts2) { return; } - this.interfaceIdentifiers.forEach((identifier, index) => { - if (index === this.interfaceIdentifiers.length - 1) { - const autofix = this.autofixer?.fixSingleImport( - this.interfacesNeedToImport, - this.importedInterfaces, - identifier.getSourceFile() - ); - this.incrementCounters(identifier, FaultID.UIInterfaceImport, autofix); - } else { - this.incrementCounters(identifier, FaultID.UIInterfaceImport); - } - }); - - this.interfaceIdentifiers = []; - this.interfacesNeedToImport.clear(); - this.importedInterfaces.clear(); - } - - private extractImportedNames(sourceFile: ts.SourceFile): void { - if (!this.options.arkts2) { + const decorators = ts.getDecorators(node); + if (!decorators || decorators.length === 0) { return; } - for (const statement of sourceFile.statements) { - if (!ts.isImportDeclaration(statement)) { - continue; - } - const importClause = statement.importClause; - if (!importClause) { - continue; - } + let decoratorName: string | undefined; + if (ts.isIdentifier(decorators[0].expression)) { + decoratorName = decorators[0].expression.getText(); + } else if (ts.isCallExpression(decorators[0].expression) && ts.isIdentifier(decorators[0].expression.expression)) { + decoratorName = decorators[0].expression.expression.getText(); + } - const namedBindings = importClause.namedBindings; - if (!namedBindings || !ts.isNamedImports(namedBindings)) { - continue; - } + if (!decoratorName) { + return; + } - for (const specifier of namedBindings.elements) { - const importedName = specifier.name.getText(sourceFile); - this.importedInterfaces.add(importedName); - } + switch (decoratorName) { + case PropDecoratorName.Prop: + this.incrementCounters(node, FaultID.PropDecoratorNotSupported); + break; + case PropDecoratorName.StorageProp: + this.incrementCounters(node, FaultID.StoragePropDecoratorNotSupported); + break; + case PropDecoratorName.LocalStorageProp: + this.incrementCounters(node, FaultID.LocalStoragePropDecoratorNotSupported); + break; + default: } } - private handleStylesDecorator(node: ts.Decorator): void { + private handleVariableDeclarationForProp(node: ts.VariableDeclaration): void { if (!this.options.arkts2) { return; } - if (!ts.isFunctionDeclaration(node.parent) && !ts.isMethodDeclaration(node.parent)) { + const callExpr = node.initializer; + if (!callExpr || !ts.isCallExpression(callExpr)) { return; } - if (!ts.isIdentifier(node.expression) || node.expression.text !== CustomDecoratorName.Styles) { + const propertyAccessExpr = callExpr.expression; + if (!ts.isPropertyAccessExpression(propertyAccessExpr)) { return; } - const decl = node.parent; - const declName = decl.name?.getText(); - if (ts.isFunctionDeclaration(decl)) { - const functionCalls = TypeScriptLinter.findDeclarationCalls(this.sourceFile as ts.SourceFile, declName as string); - const autofix = this.autofixer?.fixStylesDecoratorGlobal(decl, functionCalls, this.interfacesNeedToImport); - this.incrementCounters(decl, FaultID.StylesDecoratorNotSupported, autofix); + const storage = propertyAccessExpr.expression; + if ( + !ts.isIdentifier(storage) || + !this.isTargetStorageType(storage, [StorageTypeName.LocalStorage, StorageTypeName.AppStorage]) + ) { + return; } - if (ts.isMethodDeclaration(decl)) { - const methodCalls = TypeScriptLinter.findDeclarationCalls(this.sourceFile as ts.SourceFile, declName as string); - const autofix = this.autofixer?.fixStylesDecoratorStruct(decl, methodCalls, this.interfacesNeedToImport); - this.incrementCounters(decl, FaultID.StylesDecoratorNotSupported, autofix); + const functionName = propertyAccessExpr.name.getText(); + switch (functionName) { + case PropFunctionName.Prop: + this.incrementCounters(node, FaultID.PropFunctionNotSupported); + break; + case PropFunctionName.SetAndProp: + this.incrementCounters(node, FaultID.SetAndPropFunctionNotSupported); + break; + default: } } - private handleStateStyles(node: ts.CallExpression): void { - if (!this.options.arkts2) { - return; + private isTargetStorageType(storage: ts.Identifier, targetTypes: string[]): boolean { + const decl = this.tsUtils.getDeclarationNode(storage); + if (!decl) { + if (targetTypes.includes(storage.getText())) { + return true; + } + return false; } - if (node.expression.getText() !== STATE_STYLES) { - return; + if (!ts.isVariableDeclaration(decl)) { + return false; } - const args = node.arguments; - if (args.length === 0) { - return; + let storageType: ts.Node | undefined; + if (decl.initializer) { + if (ts.isNewExpression(decl.initializer)) { + storageType = decl.initializer.expression; + } else if (ts.isCallExpression(decl.initializer) && ts.isPropertyAccessExpression(decl.initializer.expression)) { + storageType = decl.initializer.expression.expression; + } } - const object = args[0]; - if (!ts.isObjectLiteralExpression(object)) { - return; + if (!storageType || !ts.isIdentifier(storageType)) { + return false; } - const properties = object.properties; - if (properties.length === 0) { + return targetTypes.includes(storageType.getText()); + } + + private handleAwaitExpression(node: ts.Node): void { + if (!this.options.arkts2 || !this.useStatic) { return; } - const property = properties[0] as ts.PropertyAssignment; - if (!ts.isObjectLiteralExpression(property.initializer)) { - return; + const awaitExpr = node as ts.AwaitExpression; + const checkAndReportJsImportAwait = (targetNode: ts.Node): boolean => { + if (ts.isIdentifier(targetNode) && this.tsUtils.isJsImport(targetNode)) { + this.incrementCounters(node, FaultID.NoAwaitJsPromise); + return true; + } + return false; + }; + const expr = awaitExpr.expression; + checkAndReportJsImportAwait(expr); + if (ts.isCallExpression(expr)) { + checkAndReportJsImportAwait(expr.expression); } + } - const autofix = this.autofixer?.fixStateStyles(object, this.interfacesNeedToImport); - this.incrementCounters(node, FaultID.StylesDecoratorNotSupported, autofix); + private handleNotsLikeSmartType(classDecl: ts.ClassDeclaration): void { + if (!this.options.arkts2) { + return; + } + const className = classDecl.name?.getText(); + classDecl.members.forEach((member) => { + if (ts.isMethodDeclaration(member)) { + this.checkMethod(member, className); + } + }); } - private static findDeclarationCalls(sourceFile: ts.SourceFile, declName: string): ts.CallExpression[] { - const functionCalls: ts.CallExpression[] = []; + private checkMethod(methodNode: ts.MethodDeclaration, className: string | undefined): void { + const variableDeclarations = new Map(); + const returnStatements: ts.ReturnStatement[] = []; + if (methodNode.body) { + ts.forEachChild(methodNode.body, (node) => { + this.visitMethodBody(node, variableDeclarations, returnStatements); + }); + } + + const isStaticPropertyAccess = (node: ts.Expression, className: string): boolean => { + return ( + ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === className + ); + }; + + const isInstancePropertyAccess = (node: ts.Expression): boolean => { + return ts.isPropertyAccessExpression(node) && node.expression.kind === ts.SyntaxKind.ThisKeyword; + }; - function traverse(node: ts.Node): void { - if (ts.isCallExpression(node)) { - const callName = node.expression.getText(); - if (callName === declName) { - functionCalls.push(node); + this.checkReturnStatements(returnStatements, className, isStaticPropertyAccess, isInstancePropertyAccess); + } + + private visitMethodBody( + node: ts.Node, + variableDeclarations: Map, + returnStatements: ts.ReturnStatement[] + ): void { + if (ts.isVariableStatement(node)) { + node.declarationList.declarations.forEach((decl) => { + if (ts.isIdentifier(decl.name)) { + variableDeclarations.set(decl.name.text, decl.type); } - } - ts.forEachChild(node, traverse); + }); } - traverse(sourceFile); - return functionCalls; + if (ts.isReturnStatement(node)) { + returnStatements.push(node); + } + + ts.forEachChild(node, (child) => { + this.visitMethodBody(child, variableDeclarations, returnStatements); + }); } - needObservation: Set = new Set(); + private checkReturnStatements( + returnStatements: ts.ReturnStatement[], + className: string | undefined, + isStaticPropertyAccess: (node: ts.Expression, className: string) => boolean, + isInstancePropertyAccess: (node: ts.Expression) => boolean + ): void { + returnStatements.forEach((returnStmt) => { + if (!returnStmt.expression) { + return; + } + + const returnType = this.tsTypeChecker.getTypeAtLocation(returnStmt.expression); + if (className && isStaticPropertyAccess(returnStmt.expression, className) && returnType.isUnion()) { + this.incrementCounters(returnStmt, FaultID.NoTsLikeSmartType); + } - private handleDataObservation(node: ts.PropertyDeclaration): void { + if (isInstancePropertyAccess(returnStmt.expression) && returnType.isUnion()) { + this.incrementCounters(returnStmt, FaultID.NoTsLikeSmartType); + } + }); + } + + private handleNumericBigintCompare(node: ts.BinaryExpression): void { if (!this.options.arkts2) { return; } + const leftType = this.tsTypeChecker.getTypeAtLocation(node.left); + const rightType = this.tsTypeChecker.getTypeAtLocation(node.right); - const decorators = ts.getDecorators(node); - if (!decorators || decorators.length === 0) { + const isBigInt = (type: ts.Type): boolean => { + return (type.flags & ts.TypeFlags.BigInt) !== 0 || (type.flags & ts.TypeFlags.BigIntLiteral) !== 0; + }; + const isNumber = (type: ts.Type): boolean => { + return (type.flags & ts.TypeFlags.Number) !== 0 || (type.flags & ts.TypeFlags.NumberLiteral) !== 0; + }; + + const isBigIntAndNumberOperand = isNumber(leftType) && isBigInt(rightType) || isBigInt(leftType) && isNumber(rightType); + if (isBigIntAndNumberOperand) { + this.incrementCounters(node, FaultID.NumericBigintCompare); + } + } + + private handleBigIntLiteral(node: ts.BigIntLiteral): void { + if (!this.options.arkts2) { return; } + const literalText = node.getText(); - const decorator = decorators[0]; - let decoratorName = ''; - if (ts.isIdentifier(decorator.expression)) { - decoratorName = decorator.expression.getText(); - } else if (ts.isCallExpression(decorator.expression)) { - decoratorName = decorator.expression.expression.getText(); + if ((/^0[box]/i).test(literalText)) { + this.incrementCounters(node, FaultID.NondecimalBigint); } + } - if (!observedDecoratorName.has(decoratorName)) { + private handleStructDeclarationForLayout(node: ts.StructDeclaration): void { + if (!this.options.arkts2) { return; } - const type = node.type; - if (!type) { + if (!node.name) { return; } - const targets: ts.Node[] = []; - if (ts.isUnionTypeNode(type)) { - const types = type.types; - types.forEach((typeNode) => { - this.processTypeNode(typeNode, targets); - }); - } else { - this.processTypeNode(type, targets); - } + let hasTargetFunc = false; - targets.forEach((target) => { - const targetName = target.getText(); - const classDecl = this.findClassDeclaration(targetName); - if (TypeScriptLinter.hasObservedDecorator(classDecl)) { - return; + const members = node.members; + for (const member of members) { + if (!ts.isMethodDeclaration(member)) { + continue; } - const autofix = this.autofixer?.fixDataObservation(classDecl); - this.incrementCounters(target, FaultID.DataObservation, autofix); - }); - } - private processTypeNode(typeNode: ts.TypeNode, targets: ts.Node[]): void { - if (ts.isTypeReferenceNode(typeNode)) { - const target = typeNode.typeName; - const targetName = target.getText(); - if (!this.needObservation.has(targetName)) { - targets.push(target); - this.needObservation.add(targetName); + if (customLayoutFunctionName.has(member.name.getText())) { + hasTargetFunc = true; + break; } } - } - - private static hasObservedDecorator(classDecl: ts.ClassDeclaration | undefined): boolean { - if (!classDecl || !ts.isClassDeclaration(classDecl)) { - return false; - } - - return ( - ts.getDecorators(classDecl)?.some((decorator) => { - return decorator.getText() === '@' + CustomDecoratorName.Observed; - }) ?? false - ); - } - private findClassDeclaration(targetName: string): ts.ClassDeclaration | undefined { - const sourceFile = this.sourceFile as ts.SourceFile; - const statements = sourceFile.statements; - if (!statements) { - return undefined; + if (!hasTargetFunc) { + return; } - const classDecl = statements.find((statement) => { - return ts.isClassDeclaration(statement) && statement.name?.getText() === targetName; - }); - - if (!classDecl || !ts.isClassDeclaration(classDecl)) { - return undefined; + const decorators = ts.getDecorators(node); + if (decorators) { + for (const decorator of decorators) { + const decoratorName = TsUtils.getDecoratorName(decorator); + if (decoratorName && decoratorName === CustomDecoratorName.Layoutable) { + return; + } + } } - return classDecl; + const autofix = this.autofixer?.fixCustomLayout(node); + this.incrementCounters(node.name, FaultID.CustomLayoutNeedAddDecorator, autofix); } - private static containsReflectAPI( - node: ts.FunctionDeclaration | ts.MethodDeclaration | ts.FunctionExpression - ): boolean { - if (!node.body) { - return false; + private handleArkTSPropertyAccess(expr: ts.BinaryExpression): void { + if (!this.useStatic || !this.options.arkts2 || !TypeScriptLinter.isBinaryOperations(expr.operatorToken.kind)) { + return; } - const checkForReflect = (currentNode: ts.Node): boolean => { - if (ts.isCallExpression(currentNode)) { - const expr = currentNode.expression; - if (ts.isPropertyAccessExpression(expr)) { - const obj = expr.expression; - const method = expr.name; - return ts.isIdentifier(obj) && obj.text === 'Reflect' && REFLECT_PROPERTIES.includes(method.text); - } + const processExpression = (expr: ts.Expression): void => { + const symbol = this.tsUtils.trueSymbolAtLocation(expr); + if (this.isJsFileSymbol(symbol)) { + this.incrementCounters(expr, FaultID.BinaryOperations); } - let found = false; - ts.forEachChild(currentNode, (child) => { - found = found || checkForReflect(child); - }); - return found; }; - return checkForReflect(node.body); + processExpression(expr.left); + processExpression(expr.right); } - private getFunctionSymbol(declaration: ts.Declaration): ts.Symbol | undefined { - if (TypeScriptLinter.isFunctionLike(declaration)) { - return declaration.name ? this.tsTypeChecker.getSymbolAtLocation(declaration.name) : undefined; - } - return undefined; + private static isBinaryOperations(kind: ts.SyntaxKind): boolean { + const binaryOperators: ts.SyntaxKind[] = [ + ts.SyntaxKind.PlusToken, + ts.SyntaxKind.MinusToken, + ts.SyntaxKind.AsteriskToken, + ts.SyntaxKind.SlashToken, + ts.SyntaxKind.PercentToken, + ts.SyntaxKind.AsteriskAsteriskToken + ]; + return binaryOperators.includes(kind); } - private static isFunctionLike( - node: ts.Node - ): node is ts.FunctionDeclaration | ts.MethodDeclaration | ts.FunctionExpression { - return ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || ts.isFunctionExpression(node); + private handleNumericLiteral(node: ts.Node): void { + if (!this.options.arkts2 || !ts.isNumericLiteral(node)) { + return; + } + const isInElementAccessExpression = (node: ts.NumericLiteral): boolean => { + for (let parent = node.parent; parent; parent = parent.parent) { + if (ts.isElementAccessExpression(parent)) { + return true; + } + } + return false; + }; + const isNoNeedFix = + isInElementAccessExpression(node) || + ts.isEnumMember(node.parent) || + 'name' in node.parent && node.parent.name === node; + if (isNoNeedFix) { + return; + } + const value = parseFloat(node.text); + const nodeText = node.getText(); + const hasScientificOrRadixNotation = (/[a-zA-Z]/).test(nodeText); + const isIntegerWithoutZero = Number.isInteger(value) && !nodeText.endsWith('.0'); + if (isIntegerWithoutZero && !hasScientificOrRadixNotation) { + const autofix = this.autofixer?.fixNumericLiteralIntToNumber(node); + this.incrementCounters(node, FaultID.NumericSemantics, autofix); + } } } diff --git a/ets2panda/linter/src/lib/TypeScriptLinterConfig.ts b/ets2panda/linter/src/lib/TypeScriptLinterConfig.ts index ade75c42e55c77eff5c5242c4984c76fd9fd5667..e43ee6219c936a521fe74aa59e2cf1c8fcba2843 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinterConfig.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinterConfig.ts @@ -16,7 +16,7 @@ import * as ts from 'typescript'; import { FaultID } from './Problems'; -export class LinterConfig { +export class TypeScriptLinterConfig { /* * The SyntaxKind enum defines additional elements at the end of the enum @@ -31,7 +31,7 @@ export class LinterConfig { static tsSyntaxKindNames: string[] = []; static { - LinterConfig.initTsSyntaxKindNames(); + TypeScriptLinterConfig.initTsSyntaxKindNames(); } private static initTsSyntaxKindNames(): void { @@ -41,8 +41,8 @@ export class LinterConfig { for (let i = 0; i < values.length; i++) { const val = values[i]; const kindNum = typeof val === 'string' ? parseInt(val) : val; - if (kindNum && !LinterConfig.tsSyntaxKindNames[kindNum]) { - LinterConfig.tsSyntaxKindNames[kindNum] = keys[i]; + if (kindNum && !TypeScriptLinterConfig.tsSyntaxKindNames[kindNum]) { + TypeScriptLinterConfig.tsSyntaxKindNames[kindNum] = keys[i]; } } } diff --git a/ets2panda/linter/src/lib/autofixes/AutofixReportHtmlHelper.ts b/ets2panda/linter/src/lib/autofixes/AutofixReportHtmlHelper.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b6908e29221eef3e7ccba8b4422a593ef0ca6aa --- /dev/null +++ b/ets2panda/linter/src/lib/autofixes/AutofixReportHtmlHelper.ts @@ -0,0 +1,47 @@ +/* + * 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 const AUTOFIX_HTML_TEMPLATE_TEXT = 'this is replace content'; +export const AutofixHtmlTemplate = ` + + + + AutoFixes + + + +
+ + + +`; diff --git a/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts b/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts index 54c5dee7ddfa4fd527cc76cf28ea1dbc609746b2..8b54a99d038efb82dfbb5aa80fcc17f234e91d79 100644 --- a/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts +++ b/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts @@ -21,6 +21,7 @@ export const cookBookRefToFixTitle: Map = new Map([ [16, 'Combine static block statements into one static block'], [25, 'Replace with field declaration'], [29, 'Replace with dot notation'], + [34, 'Add type annotation'], [37, 'Replace with \'new Regexp()\' stdlib API call'], [38, 'Add interface definition'], [40, 'Replace with interface'], @@ -39,6 +40,7 @@ export const cookBookRefToFixTitle: Map = new Map([ [189, 'Add type annotations to numerical variables'], [193, 'Replace with arrow function'], [206, 'Replace with a special library to call'], + [209, 'Transform "number" to "int"'], [251, 'Transform "!!" to "$$()"'], [252, 'Transform "$$" to "$$()"'], [253, '"$value" transform to "this.value"'], @@ -46,5 +48,18 @@ export const cookBookRefToFixTitle: Map = new Map([ [256, '"@Styles" transform to function with receiver'], [257, '"@AnimatableExtend" transform to function with receiver'], [258, 'Add "@Observed" decorator'], - [259, 'Add UI Interface Import'] + [259, 'Add UI Interface Import'], + [260, '"@Entry" annotaion fixed'], + [263, '"@Provide" annotation fixed'], + [275, 'Custom layout need add decorator'], + [300, 'Replace calling method of the TS-like `Function` type'], + [330, 'Convert import named objects from JS to ESValue'], + [332, 'Using the ESValue interface to access properties'], + [334, 'Call typeOf function'], + [335, 'Call toNumber function to convert'], + [338, 'Replace with library function call'], + [339, 'Using \'ESValue\' interface call'], + [341, 'Create JS objects using instantite'], + [358, 'Replace missing attribute'], + [359, '"@LocalBuilder" transform to "@Builder"'] ]); diff --git a/ets2panda/linter/src/lib/autofixes/Autofixer.ts b/ets2panda/linter/src/lib/autofixes/Autofixer.ts index 60d4c961ab2de96f75e791d3975fca7d974a9793..564ebc117d6aab1fc815b6d3331695fdf5f3ac17 100644 --- a/ets2panda/linter/src/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/src/lib/autofixes/Autofixer.ts @@ -15,14 +15,12 @@ import * as ts from 'typescript'; import { TsUtils } from '../utils/TsUtils'; -import { FaultID } from '../Problems'; import { scopeContainsThis } from '../utils/functions/ContainsThis'; -import { forEachNodeInSubtree } from '../utils/functions/ForEachNodeInSubtree'; import { NameGenerator } from '../utils/functions/NameGenerator'; import { isAssignmentOperator } from '../utils/functions/isAssignmentOperator'; import { SymbolCache } from './SymbolCache'; import { SENDABLE_DECORATOR } from '../utils/consts/SendableAPI'; -import { PATH_SEPARATOR, SRC_AND_MAIN } from '../utils/consts/OhmUrl'; +import { DEFAULT_MODULE_NAME, PATH_SEPARATOR, SRC_AND_MAIN } from '../utils/consts/OhmUrl'; import { STRINGLITERAL_NUMBER, STRINGLITERAL_NUMBER_ARRAY } from '../utils/consts/StringLiteral'; import { DOUBLE_DOLLAR_IDENTIFIER, @@ -33,14 +31,49 @@ import { APPLY_STYLES_IDENTIFIER, CustomDecoratorName, ARKUI_PACKAGE_NAME, - VALUE_IDENTIFIER + VALUE_IDENTIFIER, + INDENT_STEP, + ENTRY_DECORATOR_NAME, + ENTRY_STORAGE_PROPERITY, + LOCAL_STORAGE_TYPE_NAME, + GET_LOCAL_STORAGE_FUNC_NAME, + PROVIDE_DECORATOR_NAME, + PROVIDE_ALIAS_PROPERTY_NAME, + PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME } from '../utils/consts/ArkuiConstants'; +import { ES_VALUE } from '../utils/consts/ESObject'; +import { + LOAD, + GET_PROPERTY_BY_NAME, + SET_PROPERTY_BY_NAME, + GET_PROPERTY_BY_INDEX, + SET_PROPERTY_BY_INDEX, + ARE_EQUAL, + ARE_STRICTLY_EQUAL, + WRAP, + INSTANTIATE, + TO_NUMBER, + INVOKE, + INVOKE_METHOD +} from '../utils/consts/InteropAPI'; +import { ESLIB_SHAREDARRAYBUFFER } from '../utils/consts/ConcurrentAPI'; const UNDEFINED_NAME = 'undefined'; +const LINE_FEED = '\n'; +const CARRIAGE_RETURN_LINE_FEED = '\r\n'; + +const NEW_LINE_SEARCH_REGEX = /\r\n|\n|\r/; + const GENERATED_OBJECT_LITERAL_INTERFACE_NAME = 'GeneratedObjectLiteralInterface_'; const GENERATED_OBJECT_LITERAL_INTERFACE_TRESHOLD = 1000; +const GENERATED_OBJECT_LITERAL_CLASS_NAME = 'GeneratedObjectLiteralClass_'; +const GENERATED_OBJECT_LITERAL_CLASS_TRESHOLD = 1000; + +const GENERATED_OBJECT_LITERAL_INIT_INTERFACE_NAME = 'GeneratedObjectLiteralInitInterface_'; +const GENERATED_OBJECT_LITERAL_INIT_INTERFACE_TRESHOLD = 1000; + const GENERATED_TYPE_LITERAL_INTERFACE_NAME = 'GeneratedTypeLiteralInterface_'; const GENERATED_TYPE_LITERAL_INTERFACE_TRESHOLD = 1000; @@ -49,26 +82,38 @@ 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 SPECIAL_LIB_NAME = 'specialAutofixLib'; +const OBJECT_LITERAL_CLASS_CONSTRUCTOR_PARAM_NAME = 'init'; + +const METHOD_KEYS = 'keys'; + +interface CreateClassPropertyForObjectLiteralParams { + prop: ts.PropertyAssignment | ts.ShorthandPropertyAssignment; + enclosingStmt: ts.Node; + classFields: ts.PropertyDeclaration[]; + ctorBodyStmts: ts.Statement[]; + ctorInitProps: ts.PropertyAssignment[]; +} + export interface Autofix { replacementText: string; start: number; end: number; + line?: number; + column?: number; + endLine?: number; + endColumn?: number; } export class Autofixer { - private readonly printer: ts.Printer = ts.createPrinter({ - omitTrailingSemicolon: false, - removeComments: false, - newLine: ts.NewLineKind.LineFeed - }); - - private readonly nonCommentPrinter: ts.Printer = ts.createPrinter({ - omitTrailingSemicolon: false, - removeComments: true, - newLine: ts.NewLineKind.LineFeed - }); + private readonly printer: ts.Printer; + + private readonly nonCommentPrinter: ts.Printer; private readonly typeLiteralInterfaceNameGenerator = new NameGenerator( GENERATED_TYPE_LITERAL_INTERFACE_NAME, @@ -90,6 +135,24 @@ export class Autofixer { GENERATED_OBJECT_LITERAL_INTERFACE_TRESHOLD ); + private readonly objectLiteralClassNameGenerator = new NameGenerator( + GENERATED_OBJECT_LITERAL_CLASS_NAME, + GENERATED_OBJECT_LITERAL_CLASS_TRESHOLD + ); + + private readonly objectLiteralInitInterfaceNameGenerator = new NameGenerator( + GENERATED_OBJECT_LITERAL_INIT_INTERFACE_NAME, + GENERATED_OBJECT_LITERAL_INIT_INTERFACE_TRESHOLD + ); + + private readonly importVarNameGenerator = new NameGenerator( + GENERATED_IMPORT_VARIABLE_NAME, + GENERATED_IMPORT_VARIABLE_TRESHOLD + ); + + private modVarName: string = ''; + private readonly lastImportEndMap = new Map(); + private readonly symbolCache: SymbolCache; private readonly renameSymbolAsIdentifierCache = new Map(); @@ -100,6 +163,8 @@ export class Autofixer { private readonly sendableDecoratorCache = new Map(); + private readonly newLine: string; + constructor( private readonly typeChecker: ts.TypeChecker, private readonly utils: TsUtils, @@ -107,6 +172,29 @@ export class Autofixer { readonly cancellationToken?: ts.CancellationToken ) { this.symbolCache = new SymbolCache(this.typeChecker, this.utils, sourceFile, cancellationToken); + this.newLine = Autofixer.getNewLineCharacterFromSrcFile(sourceFile); + + const tsNewLineKind = + this.newLine === CARRIAGE_RETURN_LINE_FEED ? ts.NewLineKind.CarriageReturnLineFeed : ts.NewLineKind.LineFeed; + this.printer = ts.createPrinter({ + omitTrailingSemicolon: false, + removeComments: false, + newLine: tsNewLineKind + }); + this.nonCommentPrinter = ts.createPrinter({ + omitTrailingSemicolon: false, + removeComments: true, + newLine: tsNewLineKind + }); + } + + private static getNewLineCharacterFromSrcFile(srcFile: ts.SourceFile): string { + const match = srcFile.text.match(NEW_LINE_SEARCH_REGEX); + return match ? match[0] : LINE_FEED; + } + + private getNewLine(srcFile?: ts.SourceFile): string { + return srcFile ? Autofixer.getNewLineCharacterFromSrcFile(srcFile) : this.newLine; } /** @@ -118,7 +206,7 @@ export class Autofixer { * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring text. */ - private static genDestructElementTextForObjDecls( + private genDestructElementTextForObjDecls( variableDeclarationMap: Map, newObjectName: string, declarationFlags: ts.NodeFlags, @@ -150,7 +238,7 @@ export class Autofixer { // Print the variable statement to text and append it const text = printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); - destructElementText += text; + destructElementText += text + this.getNewLine(); }); return destructElementText; @@ -158,13 +246,13 @@ export class Autofixer { /** * Creates autofix suggestions for destructuring assignment. - * @param variableDeclaration - The variable or parameter declaration to fix. + * @param variableDeclaration - The variable declaration to fix. * @param newObjectName - Name of the new object to use for destructuring. * @param destructElementText - Generated text for destructuring elements. * @returns Array of autofix suggestions or undefined. */ - private static genAutofixForObjDecls( - variableDeclaration: ts.VariableDeclaration | ts.ParameterDeclaration, + private genAutofixForObjDecls( + variableDeclaration: ts.VariableDeclaration, newObjectName: string | undefined, destructElementText: string, isIdentifier: boolean @@ -189,7 +277,7 @@ export class Autofixer { end: variableDeclaration.name.getEnd() }; destructElementReplaceText = { - replacementText: destructElementText, + replacementText: this.getNewLine() + destructElementText, start: variableDeclaration.parent.parent.getEnd(), end: variableDeclaration.parent.parent.getEnd() }; @@ -206,13 +294,9 @@ export class Autofixer { * @param variableDeclaration - The variable or parameter declaration to check for boundary conditions. * @returns A boolean indicating if the declaration passes the boundary checks. */ - private static passBoundaryCheckForObjDecls( - faultId: number, - variableDeclaration: ts.VariableDeclaration | ts.ParameterDeclaration - ): boolean { + private static passBoundaryCheckForObjDecls(variableDeclaration: ts.VariableDeclaration): boolean { // Check if the fault ID is for a destructuring parameter or if the declaration has a spread operator if ( - faultId === FaultID.DestructuringParameter || TsUtils.destructuringDeclarationHasSpreadOperator(variableDeclaration.name as ts.BindingPattern) || TsUtils.destructuringDeclarationHasDefaultValue(variableDeclaration.name as ts.BindingPattern) ) { @@ -234,15 +318,12 @@ export class Autofixer { /** ** Fixes object binding pattern declarations by generating appropriate autofix suggestions. - * @param variableDeclaration - The variable or parameter declaration to fix. + * @param variableDeclaration - The variable declaration to fix. * @param faultId - The fault ID indicating the type of check to perform. * @returns Array of autofix suggestions or undefined. */ - fixObjectBindingPatternDeclarations( - variableDeclaration: ts.VariableDeclaration | ts.ParameterDeclaration, - faultId: number - ): Autofix[] | undefined { - if (!Autofixer.passBoundaryCheckForObjDecls(faultId, variableDeclaration)) { + fixObjectBindingPatternDeclarations(variableDeclaration: ts.VariableDeclaration): Autofix[] | undefined { + if (!Autofixer.passBoundaryCheckForObjDecls(variableDeclaration)) { return undefined; } // Map to hold variable names and their corresponding property names @@ -270,7 +351,7 @@ export class Autofixer { return undefined; } const declarationFlags = ts.getCombinedNodeFlags(variableDeclaration); - const destructElementText = Autofixer.genDestructElementTextForObjDecls( + const destructElementText = this.genDestructElementTextForObjDecls( variableDeclarationMap, newObjectName, declarationFlags, @@ -279,7 +360,7 @@ export class Autofixer { ); // Generate and return autofix suggestions for the object declarations - return Autofixer.genAutofixForObjDecls(variableDeclaration, newObjectName, destructElementText, isIdentifier); + return this.genAutofixForObjDecls(variableDeclaration, newObjectName, destructElementText, isIdentifier); } /** @@ -291,7 +372,7 @@ export class Autofixer { * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring text. */ - private static genDestructElementTextForArrayDecls( + private genDestructElementTextForArrayDecls( variableNames: string[], newArrayName: string, declarationFlags: ts.NodeFlags, @@ -327,7 +408,7 @@ export class Autofixer { // Print the variable statement to text and append it const text = printer.printNode(ts.EmitHint.Unspecified, variableStatement, sourceFile); - destructElementText += text; + destructElementText += text + this.getNewLine(); } return destructElementText; @@ -335,13 +416,13 @@ export class Autofixer { /** * Creates autofix suggestions for array destructuring assignment. - * @param variableDeclaration - The variable or parameter declaration to fix. + * @param variableDeclaration - The variable declaration to fix. * @param newArrayName - Name of the new array to use for destructuring. * @param destructElementText - Generated text for destructuring elements. * @returns Array of autofix suggestions. */ - private static genAutofixForArrayDecls( - variableDeclaration: ts.VariableDeclaration | ts.ParameterDeclaration, + private genAutofixForArrayDecls( + variableDeclaration: ts.VariableDeclaration, newArrayName: string | undefined, destructElementText: string, isIdentifierOrElementAccess: boolean @@ -366,7 +447,7 @@ export class Autofixer { end: variableDeclaration.name.getEnd() }; destructElementReplaceText = { - replacementText: destructElementText, + replacementText: this.getNewLine() + destructElementText, start: variableDeclaration.parent.parent.getEnd(), end: variableDeclaration.parent.parent.getEnd() }; @@ -384,7 +465,7 @@ export class Autofixer { * @returns A boolean indicating if the declaration passes the boundary checks. */ private static passBoundaryCheckForArrayDecls( - variableDeclaration: ts.VariableDeclaration | ts.ParameterDeclaration, + variableDeclaration: ts.VariableDeclaration, isArrayOrTuple: boolean ): boolean { // If it's not an array/tuple or the declaration has a spread operator in destructuring @@ -415,12 +496,12 @@ export class Autofixer { /** * Fixes array binding pattern declarations by generating appropriate autofix suggestions. * - * @param variableDeclaration - The variable or parameter declaration to fix. + * @param variableDeclaration - The variable declaration to fix. * @param isArrayOrTuple - Flag indicating if the declaration is for an array or tuple. * @returns Array of autofix suggestions or undefined. */ fixArrayBindingPatternDeclarations( - variableDeclaration: ts.VariableDeclaration | ts.ParameterDeclaration, + variableDeclaration: ts.VariableDeclaration, isArrayOrTuple: boolean ): Autofix[] | undefined { if (!Autofixer.passBoundaryCheckForArrayDecls(variableDeclaration, isArrayOrTuple)) { @@ -453,7 +534,7 @@ export class Autofixer { // Get the combined node flags for the variable declaration const declarationFlags = ts.getCombinedNodeFlags(variableDeclaration); // Generate the destructuring element text for the array declaration - const destructElementText = Autofixer.genDestructElementTextForArrayDecls( + const destructElementText = this.genDestructElementTextForArrayDecls( variableNames, newArrayName, declarationFlags, @@ -462,7 +543,7 @@ export class Autofixer { ); // Generate and return autofix suggestions for the array declarations - return Autofixer.genAutofixForArrayDecls( + return this.genAutofixForArrayDecls( variableDeclaration, newArrayName, destructElementText, @@ -478,7 +559,7 @@ export class Autofixer { * @param sourceFile - Source file from which the nodes are taken. * @returns The generated destructuring assignment text. */ - private static genDestructElementTextForArrayAssignment( + private genDestructElementTextForArrayAssignment( variableNames: string[], newArrayName: string | undefined, printer: ts.Printer, @@ -509,7 +590,7 @@ export class Autofixer { // Print the expression statement to text and append it const text = printer.printNode(ts.EmitHint.Unspecified, expressionStatement, sourceFile); - destructElementText += text; + destructElementText += text + this.getNewLine(); } return destructElementText; @@ -522,7 +603,7 @@ export class Autofixer { * @param destructElementText - Generated text for destructuring assignments. * @returns Array of autofix suggestions. */ - private static genAutofixForArrayAssignment( + private genAutofixForArrayAssignment( assignmentExpr: ts.BinaryExpression, newArrayName: string | undefined, destructElementText: string, @@ -549,7 +630,7 @@ export class Autofixer { end: assignmentExpr.left.getEnd() }; destructElementReplaceText = { - replacementText: destructElementText, + replacementText: this.getNewLine() + destructElementText, start: assignmentExpr.parent.getEnd(), end: assignmentExpr.parent.getEnd() }; @@ -633,14 +714,14 @@ export class Autofixer { } // Generate the text for destructuring assignments - const destructElementText = Autofixer.genDestructElementTextForArrayAssignment( + const destructElementText = this.genDestructElementTextForArrayAssignment( variableNames, newArrayName, this.printer, sourceFile ); - return Autofixer.genAutofixForArrayAssignment( + return this.genAutofixForArrayAssignment( assignmentExpr, newArrayName, destructElementText, @@ -686,7 +767,7 @@ export class Autofixer { * @param printer - TypeScript printer instance for printing nodes. * @returns The generated text for destructuring assignments. */ - private static genDestructElementTextForObjAssignment( + private genDestructElementTextForObjAssignment( tsVarDeclMap: Map, needParentheses: boolean[], newObjName: string, @@ -715,7 +796,8 @@ export class Autofixer { ts.factory.createExpressionStatement(assignmentExpr); // Append the generated text for the destructuring assignment - destructElementText += printer.printNode(ts.EmitHint.Unspecified, statement, binaryExpr.getSourceFile()); + destructElementText += + printer.printNode(ts.EmitHint.Unspecified, statement, binaryExpr.getSourceFile()) + this.getNewLine(); index++; }); @@ -757,7 +839,7 @@ export class Autofixer { * @param destructElementText - Generated text for destructuring assignments. * @returns Array of autofix suggestions or undefined if no fixes are needed. */ - private static createAutofixForObjAssignment( + private createAutofixForObjAssignment( binaryExpr: ts.BinaryExpression, declNameReplaceText: string, destructElementText: string, @@ -782,7 +864,7 @@ export class Autofixer { end: binaryExpr.parent.getEnd() }; destructElementReplaceTextAutofix = { - replacementText: destructElementText, + replacementText: this.getNewLine() + destructElementText, start: binaryExpr.parent.parent.getEnd(), end: binaryExpr.parent.parent.getEnd() }; @@ -842,7 +924,7 @@ export class Autofixer { return undefined; } // Create the text for destructuring elements - const destructElementText = Autofixer.genDestructElementTextForObjAssignment( + const destructElementText = this.genDestructElementTextForObjAssignment( tsVarDeclMap, needParentheses, newObjName, @@ -854,7 +936,7 @@ export class Autofixer { const declNameReplaceText = Autofixer.genDeclNameReplaceTextForObjAssignment(binaryExpr, newObjName, this.printer); // Generate autofix suggestions - return Autofixer.createAutofixForObjAssignment(binaryExpr, declNameReplaceText, destructElementText, isIdentifier); + return this.createAutofixForObjAssignment(binaryExpr, declNameReplaceText, destructElementText, isIdentifier); } fixLiteralAsPropertyNamePropertyAssignment(node: ts.PropertyAssignment): Autofix[] | undefined { @@ -871,13 +953,13 @@ export class Autofixer { return this.renameSymbolAsIdentifier(symbol); } - fixLiteralAsPropertyNamePropertyName(node: ts.PropertyName): Autofix[] | undefined { + fixLiteralAsPropertyNamePropertyName(node: ts.PropertyName, enumMember?: ts.EnumMember): Autofix[] | undefined { const symbol = this.typeChecker.getSymbolAtLocation(node); if (symbol === undefined) { return undefined; } - return this.renameSymbolAsIdentifier(symbol); + return this.renameSymbolAsIdentifier(symbol, enumMember); } fixPropertyAccessByIndex(node: ts.ElementAccessExpression): Autofix[] | undefined { @@ -889,7 +971,7 @@ export class Autofixer { return this.renameSymbolAsIdentifier(symbol); } - private renameSymbolAsIdentifier(symbol: ts.Symbol): Autofix[] | undefined { + private renameSymbolAsIdentifier(symbol: ts.Symbol, enumMember?: ts.EnumMember): Autofix[] | undefined { if (this.renameSymbolAsIdentifierCache.has(symbol)) { return this.renameSymbolAsIdentifierCache.get(symbol); } @@ -899,7 +981,7 @@ export class Autofixer { return undefined; } - const newName = this.utils.findIdentifierNameForSymbol(symbol); + const newName = this.utils.findIdentifierNameForSymbol(symbol, enumMember); if (newName === undefined) { this.renameSymbolAsIdentifierCache.set(symbol, undefined); return undefined; @@ -938,7 +1020,25 @@ export class Autofixer { return result; } - static fixImportPath(parts: string[], index: number, importDeclNode: ts.ImportDeclaration): Autofix[] | undefined { + addDefaultModuleToPath(parts: string[], importDeclNode: ts.ImportDeclaration): Autofix[] | undefined { + void this; + const moduleSpecifier = importDeclNode.moduleSpecifier; + + /* + * check the current file's path + * get the parent directory name of the "src" directory + */ + + const moduleName = TsUtils.getModuleName(importDeclNode); + const newPathParts = [moduleName ?? DEFAULT_MODULE_NAME, SRC_AND_MAIN, ...parts]; + const newPath = newPathParts.join(PATH_SEPARATOR); + const newPathString = '\'' + newPath + '\''; + + return [{ start: moduleSpecifier.getStart(), end: moduleSpecifier.getEnd(), replacementText: newPathString }]; + } + + fixImportPath(parts: string[], index: number, importDeclNode: ts.ImportDeclaration): Autofix[] | undefined { + void this; const moduleSpecifier = importDeclNode.moduleSpecifier; const beforeEts = parts.slice(0, index); @@ -1304,11 +1404,11 @@ export class Autofixer { if (tsExprNode.left.kind === ts.SyntaxKind.BinaryExpression) { text += this.recursiveCommaOperator(tsExprNode.left as ts.BinaryExpression); - text += '\n' + tsExprNode.right.getFullText() + ';'; + text += this.getNewLine() + tsExprNode.right.getFullText() + ';'; } else { const leftText = tsExprNode.left.getFullText(); const rightText = tsExprNode.right.getFullText(); - text = leftText + ';\n' + rightText + ';'; + text = leftText + ';' + this.getNewLine() + rightText + ';'; } return text; @@ -1419,13 +1519,7 @@ export class Autofixer { const autofixes: Autofix[] = [{ start: newFieldPos, end: newFieldPos, replacementText: '' }]; for (let i = 0; i < ctorDecl.parameters.length; i++) { - this.fixCtorParameterPropertiesProcessParam( - ctorDecl.parameters[i], - paramTypes[i], - ctorDecl.getSourceFile(), - fieldInitStmts, - autofixes - ); + this.fixCtorParameterPropertiesProcessParam(ctorDecl.parameters[i], paramTypes[i], fieldInitStmts, autofixes); } // Note: Bodyless ctors can't have parameter properties. @@ -1483,7 +1577,6 @@ export class Autofixer { private fixCtorParameterPropertiesProcessParam( param: ts.ParameterDeclaration, paramType: ts.TypeNode, - sourceFile: ts.SourceFile, fieldInitStmts: ts.Statement[], autofixes: Autofix[] ): void { @@ -1502,11 +1595,12 @@ export class Autofixer { const newFieldNode = ts.factory.createPropertyDeclaration( paramModifiers, propIdent, - undefined, + param.questionToken, paramType, undefined ); - const newFieldText = this.printer.printNode(ts.EmitHint.Unspecified, newFieldNode, sourceFile) + '\n'; + const newFieldText = + this.printer.printNode(ts.EmitHint.Unspecified, newFieldNode, param.getSourceFile()) + this.getNewLine(); autofixes[0].replacementText += newFieldText; const newParamDecl = ts.factory.createParameterDeclaration( @@ -1517,7 +1611,7 @@ export class Autofixer { param.type, param.initializer ); - const newParamText = this.printer.printNode(ts.EmitHint.Unspecified, newParamDecl, sourceFile); + const newParamText = this.printer.printNode(ts.EmitHint.Unspecified, newParamDecl, param.getSourceFile()); autofixes.push({ start: param.getStart(), end: param.getEnd(), replacementText: newParamText }); fieldInitStmts.push( @@ -1753,7 +1847,11 @@ export class Autofixer { return this.fixRecordObjectLiteral(objectLiteralExpr); } - // Can't fix when object literal has a contextual type. + // Here, we only fix object literal that doesn't have a contextual type. + return undefined; + } + + if (Autofixer.hasUnfixableProperty(objectLiteralExpr)) { return undefined; } @@ -1762,6 +1860,28 @@ export class Autofixer { return undefined; } + if (Autofixer.hasMethodsOrAccessors(objectLiteralExpr)) { + return this.fixObjectLiteralAsClass(objectLiteralExpr, undefined, enclosingStmt); + } + return this.fixUntypedObjectLiteralAsInterface(objectLiteralExpr, enclosingStmt); + } + + private static hasUnfixableProperty(objectLiteralExpr: ts.ObjectLiteralExpression): boolean { + return objectLiteralExpr.properties.some((prop) => { + return ts.isSpreadAssignment(prop) || !ts.isIdentifier(prop.name); + }); + } + + private static hasMethodsOrAccessors(objectLiteralExpr: ts.ObjectLiteralExpression): boolean { + return objectLiteralExpr.properties.some((prop) => { + return ts.isMethodDeclaration(prop) || ts.isAccessor(prop); + }); + } + + private fixUntypedObjectLiteralAsInterface( + objectLiteralExpr: ts.ObjectLiteralExpression, + enclosingStmt: ts.Node + ): Autofix[] | undefined { const newInterfaceProps = this.getInterfacePropertiesFromObjectLiteral(objectLiteralExpr, enclosingStmt); if (!newInterfaceProps) { return undefined; @@ -1774,7 +1894,7 @@ export class Autofixer { } return [ - this.createNewInterface(srcFile, newInterfaceName, newInterfaceProps, enclosingStmt.getStart()), + this.createNewInterfaceForObjectLiteral(srcFile, newInterfaceName, newInterfaceProps, enclosingStmt.getStart()), this.fixObjectLiteralExpression(srcFile, newInterfaceName, objectLiteralExpr) ]; } @@ -1810,7 +1930,7 @@ export class Autofixer { return undefined; } - if (Autofixer.propertyTypeIsCapturedFromEnclosingLocalScope(propType, enclosingStmt)) { + if (TsUtils.typeIsCapturedFromEnclosingLocalScope(propType, enclosingStmt)) { return undefined; } @@ -1828,21 +1948,7 @@ export class Autofixer { return newProp; } - private static propertyTypeIsCapturedFromEnclosingLocalScope(type: ts.Type, enclosingStmt: ts.Node): boolean { - const sym = type.getSymbol(); - let symNode: ts.Node | undefined = TsUtils.getDeclaration(sym); - - while (symNode) { - if (symNode === enclosingStmt) { - return true; - } - symNode = symNode.parent; - } - - return false; - } - - private createNewInterface( + private createNewInterfaceForObjectLiteral( srcFile: ts.SourceFile, interfaceName: string, members: ts.TypeElement[], @@ -1855,7 +1961,7 @@ export class Autofixer { undefined, members ); - const text = this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile) + '\n'; + const text = this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile) + this.getNewLine(); return { start: pos, end: pos, replacementText: text }; } @@ -1904,6 +2010,286 @@ export class Autofixer { return (decl.exclamationToken || decl.name).getEnd(); } + private fixObjectLiteralAsClass( + objectLiteralExpr: ts.ObjectLiteralExpression, + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined, + enclosingStmt: ts.Node + ): Autofix[] | undefined { + if (this.utils.nodeCapturesValueFromEnclosingLocalScope(objectLiteralExpr, enclosingStmt)) { + return undefined; + } + + const srcFile = objectLiteralExpr.getSourceFile(); + const newClassName = TsUtils.generateUniqueName(this.objectLiteralClassNameGenerator, srcFile); + if (!newClassName) { + return undefined; + } + const newInitInterfaceName = TsUtils.generateUniqueName(this.objectLiteralInitInterfaceNameGenerator, srcFile); + if (!newInitInterfaceName) { + return undefined; + } + + const classDeclAndCtorInitProps = this.createClassDeclForObjectLiteral( + objectLiteralExpr, + enclosingStmt, + newClassName, + newInitInterfaceName, + typeDecl + ); + if (!classDeclAndCtorInitProps) { + return undefined; + } + const { classDecl, ctorInitProps } = classDeclAndCtorInitProps; + let classDeclText = + this.printer.printNode(ts.EmitHint.Unspecified, classDecl, srcFile) + this.getNewLine() + this.getNewLine(); + + const ctorArgs: ts.Expression[] = []; + if (ctorInitProps.length) { + classDeclText += this.createInitInterfaceForObjectLiteral(srcFile, newInitInterfaceName, classDecl); + classDeclText += this.getNewLine() + this.getNewLine(); + ctorArgs.push(ts.factory.createObjectLiteralExpression(ctorInitProps, ctorInitProps.length > 1)); + } + const newExpr = ts.factory.createNewExpression(ts.factory.createIdentifier(newClassName), undefined, ctorArgs); + const newExprText = this.printer.printNode(ts.EmitHint.Unspecified, newExpr, srcFile); + const ctorCallAutofix = { + start: objectLiteralExpr.getStart(), + end: objectLiteralExpr.getEnd(), + replacementText: newExprText + }; + const classDeclPos = enclosingStmt.getStart(); + return [{ start: classDeclPos, end: classDeclPos, replacementText: classDeclText }, ctorCallAutofix]; + } + + private createClassDeclForObjectLiteral( + objectLiteralExpr: ts.ObjectLiteralExpression, + enclosingStmt: ts.Node, + newClassName: string, + newInitInterfaceName: string, + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): { classDecl: ts.ClassDeclaration; ctorInitProps: ts.PropertyAssignment[] } | undefined { + const classFields: ts.PropertyDeclaration[] = []; + const classMethods: (ts.MethodDeclaration | ts.AccessorDeclaration)[] = []; + const ctorBodyStmts: ts.Statement[] = []; + const ctorInitProps: ts.PropertyAssignment[] = []; + + Autofixer.addSuperCallToObjectLiteralConstructor(typeDecl, ctorBodyStmts); + + for (const prop of objectLiteralExpr.properties) { + if (ts.isSpreadAssignment(prop) || !ts.isIdentifier(prop.name)) { + return undefined; + } + if (ts.isMethodDeclaration(prop) || ts.isAccessor(prop)) { + classMethods.push(prop); + continue; + } + const created = this.createClassPropertyForObjectLiteral({ + prop, + enclosingStmt, + classFields, + ctorBodyStmts, + ctorInitProps + }); + if (!created) { + return undefined; + } + } + + const classElements: ts.ClassElement[] = [...classFields]; + if (ctorInitProps.length) { + classElements.push(Autofixer.createClassConstructorForObjectLiteral(newInitInterfaceName, ctorBodyStmts)); + } + classElements.push(...classMethods); + + const heritageClauses = Autofixer.createHeritageClausesForObjectLiteralClass(typeDecl); + + return { + classDecl: ts.factory.createClassDeclaration(undefined, newClassName, undefined, heritageClauses, classElements), + ctorInitProps + }; + } + + private static addSuperCallToObjectLiteralConstructor( + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined, + ctorBodyStmts: ts.Statement[] + ): void { + if (typeDecl && ts.isClassDeclaration(typeDecl)) { + const superCall = ts.factory.createExpressionStatement( + ts.factory.createCallExpression(ts.factory.createSuper(), undefined, []) + ); + ctorBodyStmts.push(superCall); + } + } + + private createClassPropertyForObjectLiteral( + createClassPropParams: CreateClassPropertyForObjectLiteralParams + ): boolean { + const { prop, enclosingStmt, classFields, ctorBodyStmts, ctorInitProps } = createClassPropParams; + if (!ts.isIdentifier(prop.name)) { + return false; + } + const propType = this.typeChecker.getTypeAtLocation(prop); + + // Can't capture generic type parameters of enclosing declarations. + if (this.utils.hasGenericTypeParameter(propType)) { + return false; + } + + if (TsUtils.typeIsCapturedFromEnclosingLocalScope(propType, enclosingStmt)) { + return false; + } + + const propTypeNode = this.typeChecker.typeToTypeNode(propType, undefined, ts.NodeBuilderFlags.None); + if (!propTypeNode || !this.utils.isSupportedType(propTypeNode)) { + return false; + } + + const propName = ts.factory.createIdentifier(prop.name.text); + classFields.push(ts.factory.createPropertyDeclaration(undefined, propName, undefined, propTypeNode, undefined)); + ctorBodyStmts.push( + ts.factory.createExpressionStatement( + ts.factory.createBinaryExpression( + ts.factory.createPropertyAccessExpression(ts.factory.createThis(), propName), + ts.factory.createToken(ts.SyntaxKind.EqualsToken), + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(OBJECT_LITERAL_CLASS_CONSTRUCTOR_PARAM_NAME), + propName + ) + ) + ) + ); + ctorInitProps.push(ts.isPropertyAssignment(prop) ? prop : ts.factory.createPropertyAssignment(prop.name, propName)); + return true; + } + + private static createHeritageClausesForObjectLiteralClass( + typeDecl: ts.ClassDeclaration | ts.InterfaceDeclaration | undefined + ): ts.HeritageClause[] | undefined { + if (!typeDecl?.name) { + return undefined; + } + + return [ + ts.factory.createHeritageClause( + ts.isClassDeclaration(typeDecl) ? ts.SyntaxKind.ExtendsKeyword : ts.SyntaxKind.ImplementsKeyword, + [ts.factory.createExpressionWithTypeArguments(typeDecl.name, undefined)] + ) + ]; + } + + private static createClassConstructorForObjectLiteral( + newInitInterfaceName: string, + ctorBodyStmts: ts.Statement[] + ): ts.ConstructorDeclaration { + const ctorParams: ts.ParameterDeclaration[] = []; + ctorParams.push( + ts.factory.createParameterDeclaration( + undefined, + undefined, + OBJECT_LITERAL_CLASS_CONSTRUCTOR_PARAM_NAME, + undefined, + ts.factory.createTypeReferenceNode(newInitInterfaceName) + ) + ); + return ts.factory.createConstructorDeclaration(undefined, ctorParams, ts.factory.createBlock(ctorBodyStmts, true)); + } + + private createInitInterfaceForObjectLiteral( + srcFile: ts.SourceFile, + interfaceName: string, + newClassDecl: ts.ClassDeclaration + ): string { + const props: ts.PropertySignature[] = []; + newClassDecl.members.forEach((prop) => { + if (ts.isPropertyDeclaration(prop)) { + props.push(ts.factory.createPropertySignature(undefined, prop.name, undefined, prop.type)); + } + }); + const newInterfaceDecl = ts.factory.createInterfaceDeclaration( + undefined, + interfaceName, + undefined, + undefined, + props + ); + return this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile); + } + + fixTypedObjectLiteral( + objectLiteralExpr: ts.ObjectLiteralExpression, + objectLiteralType: ts.Type | undefined + ): Autofix[] | undefined { + // Here we only try to fix typed object literal. Other case is handled by 'fixUntypedObjectLiteral' method. + + if (!objectLiteralType || !this.utils.validateObjectLiteralType(objectLiteralType)) { + return undefined; + } + + const typeDecl = TsUtils.getDeclaration(objectLiteralType.getSymbol()); + if (!typeDecl || !ts.isClassDeclaration(typeDecl) && !ts.isInterfaceDeclaration(typeDecl) || !typeDecl.name) { + return undefined; + } + + if (Autofixer.hasUnfixableProperty(objectLiteralExpr)) { + return undefined; + } + + if (this.hasMethodOverridingProperty(objectLiteralExpr, objectLiteralType)) { + return undefined; + } + + const enclosingStmt = TsUtils.getEnclosingTopLevelStatement(objectLiteralExpr); + if (!enclosingStmt) { + return undefined; + } + + return this.fixObjectLiteralAsClass(objectLiteralExpr, typeDecl, enclosingStmt); + } + + private hasMethodOverridingProperty( + objectLiteralExpr: ts.ObjectLiteralExpression, + objectLiteralType: ts.Type + ): boolean { + const typeProps = this.typeChecker.getPropertiesOfType(objectLiteralType); + for (const objProp of objectLiteralExpr.properties) { + if ( + ts.isPropertyAssignment(objProp) && + typeProps.some((typeProp) => { + const typePropDecl = TsUtils.getDeclaration(typeProp); + return ( + !!typePropDecl && + (ts.isMethodSignature(typePropDecl) || ts.isMethodDeclaration(typePropDecl)) && + typePropDecl.name === objProp.name + ); + }) + ) { + return true; + } + + if ( + ts.isMethodDeclaration(objProp) && + typeProps.some((typeProp) => { + const typePropDecl = TsUtils.getDeclaration(typeProp); + return ( + !!typePropDecl && + (ts.isPropertyDeclaration(typePropDecl) || ts.isPropertySignature(typePropDecl)) && + typePropDecl.name.getText() === objProp.name.getText() + ); + }) + ) { + return true; + } + } + + return false; + } + + fixShorthandPropertyAssignment(prop: ts.ShorthandPropertyAssignment): Autofix[] { + const newName = ts.factory.createIdentifier(prop.name.text); + const newProp = ts.factory.createPropertyAssignment(newName, newName); + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, newProp, prop.getSourceFile()); + return [{ start: prop.getStart(), end: prop.getEnd(), replacementText }]; + } + /* * In case of type alias initialized with type literal, replace * entire type alias with identical interface declaration. @@ -1940,7 +2326,7 @@ export class Autofixer { return undefined; } - if (this.typeLiteralCapturesTypeFromEnclosingLocalScope(typeLiteral, enclosingStmt)) { + if (this.utils.nodeCapturesValueFromEnclosingLocalScope(typeLiteral, enclosingStmt)) { return undefined; } @@ -1956,7 +2342,8 @@ export class Autofixer { undefined, typeLiteral.members ); - const interfaceText = this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile) + '\n'; + const interfaceText = + this.printer.printNode(ts.EmitHint.Unspecified, newInterfaceDecl, srcFile) + this.getNewLine(); return [ { start: newInterfacePos, end: newInterfacePos, replacementText: interfaceText }, @@ -1964,39 +2351,79 @@ export class Autofixer { ]; } - typeLiteralCapturesTypeFromEnclosingLocalScope(typeLiteral: ts.TypeLiteralNode, enclosingStmt: ts.Node): boolean { - let found = false; + removeNode(node: ts.Node): Autofix[] { + void this; + return [{ start: node.getStart(), end: node.getEnd(), replacementText: '' }]; + } + + replaceNode(node: ts.Node, replacementText: string): Autofix[] { + void this; + return [{ start: node.getStart(), end: node.getEnd(), replacementText }]; + } - const callback = (node: ts.Node): void => { - if (!ts.isIdentifier(node)) { - return; - } - const sym = this.typeChecker.getSymbolAtLocation(node); - let symNode: ts.Node | undefined = TsUtils.getDeclaration(sym); - while (symNode) { - if (symNode === typeLiteral) { - return; - } - if (symNode === enclosingStmt) { - found = true; - return; - } - symNode = symNode.parent; + removeImportSpecifier( + specToRemove: ts.ImportSpecifier, + importDeclaration: ts.ImportDeclaration + ): Autofix[] | undefined { + if (!importDeclaration) { + return undefined; + } + + const importClause = importDeclaration.importClause; + if (!importClause?.namedBindings || !ts.isNamedImports(importClause.namedBindings)) { + return undefined; + } + + const namedBindings = importClause.namedBindings; + const allSpecifiers = namedBindings.elements; + const remainingSpecifiers = allSpecifiers.filter((spec) => { + return spec !== specToRemove; + }); + + // If none are valid, remove all named imports. + if (remainingSpecifiers.length === 0) { + if (importClause.name) { + const start = importClause.name.end; + const end = namedBindings.end; + return [{ start, end, replacementText: '' }]; } - }; + return this.removeNode(importDeclaration); + } - const stopCondition = (node: ts.Node): boolean => { - void node; - return found; - }; + const specIndex = allSpecifiers.findIndex((spec) => { + return spec === specToRemove; + }); + const isLast = specIndex === allSpecifiers.length - 1; + const isFirst = specIndex === 0; + + let start = specToRemove.getStart(); + let end = specToRemove.getEnd(); - forEachNodeInSubtree(typeLiteral, callback, stopCondition); - return found; + if (!isLast) { + end = allSpecifiers[specIndex + 1].getStart(); + } else if (!isFirst) { + const prev = allSpecifiers[specIndex - 1]; + start = prev.getEnd(); + } + + return [{ start, end, replacementText: '' }]; } - removeDecorator(decorator: ts.Decorator): Autofix[] { - void this; - return [{ start: decorator.getStart(), end: decorator.getEnd(), replacementText: '' }]; + removeDefaultImport(importDecl: ts.ImportDeclaration, defaultImport: ts.Identifier): Autofix[] | undefined { + const importClause = importDecl.importClause; + if (!importClause || !defaultImport) { + return undefined; + } + + const namedBindings = importClause.namedBindings; + + if (!namedBindings) { + return this.removeNode(importDecl); + } + const start = defaultImport.getStart(); + const end = namedBindings.getStart(); + + return [{ start, end, replacementText: '' }]; } fixSendableExplicitFieldType(node: ts.PropertyDeclaration): Autofix[] | undefined { @@ -2011,19 +2438,9 @@ export class Autofixer { return undefined; } - const questionOrExclamationToken: ts.ExclamationToken | ts.QuestionToken | undefined = - node.questionToken ?? node.exclamationToken ?? undefined; - - const newPropDecl: ts.PropertyDeclaration = ts.factory.createPropertyDeclaration( - node.modifiers, - node.name, - questionOrExclamationToken, - propTypeNode, - initializer - ); - - const text = this.printer.printNode(ts.EmitHint.Unspecified, newPropDecl, node.getSourceFile()); - return [{ start: node.getFullStart(), end: node.getEnd(), replacementText: text }]; + const pos = (node.questionToken || node.exclamationToken || node.name).getEnd(); + const text = ': ' + this.printer.printNode(ts.EmitHint.Unspecified, propTypeNode, node.getSourceFile()); + return [{ start: pos, end: pos, replacementText: text }]; } addClassSendableDecorator( @@ -2044,7 +2461,7 @@ export class Autofixer { addSendableDecorator(node: ts.Node): Autofix[] { void this; - const text = '@' + SENDABLE_DECORATOR + '\n'; + const text = '@' + SENDABLE_DECORATOR + this.getNewLine(); const pos = node.getStart(); return [{ start: pos, end: pos, replacementText: text }]; } @@ -2112,12 +2529,13 @@ export class Autofixer { fixRegularExpressionLiteral(node: ts.RegularExpressionLiteral | ts.CallExpression): Autofix[] | undefined { const srcFile = node.getSourceFile(); - let pattern: string; + let patternNode: ts.Expression | undefined; let flag: string | undefined; + if (ts.isRegularExpressionLiteral(node)) { const literalText = node.getText(); const parts = Autofixer.extractRegexParts(literalText); - pattern = parts.pattern; + patternNode = ts.factory.createStringLiteral(parts.pattern); flag = parts.flag; } else if (ts.isCallExpression(node)) { const args = node.arguments; @@ -2125,10 +2543,11 @@ export class Autofixer { return undefined; } const patternArg = args[0]; - if (!ts.isStringLiteral(patternArg)) { + if (!this.isStaticStringExpression(patternArg)) { return undefined; } - pattern = patternArg.text; + patternNode = patternArg; + if (args.length > 1) { const flagArg = args[1]; if (ts.isStringLiteral(flagArg)) { @@ -2140,13 +2559,47 @@ export class Autofixer { } else { return undefined; } - const args = [ts.factory.createStringLiteral(pattern)]; - if (flag) { - args.push(ts.factory.createStringLiteral(flag)); + + const newArgs: ts.Expression[] = [patternNode]; + if (flag !== undefined) { + newArgs.push(ts.factory.createStringLiteral(flag)); } - const newExpression = ts.factory.createNewExpression(ts.factory.createIdentifier('RegExp'), undefined, args); + const newExpression = ts.factory.createNewExpression(ts.factory.createIdentifier('RegExp'), undefined, newArgs); + const text = this.printer.printNode(ts.EmitHint.Unspecified, newExpression, srcFile); - return [{ start: node.getStart(), end: node.getEnd(), replacementText: text }]; + return [ + { + start: node.getStart(), + end: node.getEnd(), + replacementText: text + } + ]; + } + + private isStaticStringExpression(node: ts.Node): boolean { + if (ts.isStringLiteral(node)) { + return true; + } + if (ts.isBinaryExpression(node)) { + return ( + node.operatorToken.kind === ts.SyntaxKind.PlusToken && + this.isStaticStringExpression(node.left) && + this.isStaticStringExpression(node.right) + ); + } + if (ts.isCallExpression(node)) { + const expression = node.expression; + if ( + ts.isPropertyAccessExpression(expression) && + expression.name.text === 'concat' && + this.isStaticStringExpression(expression.expression) + ) { + return node.arguments.every((arg) => { + return this.isStaticStringExpression(arg); + }); + } + } + return false; } private static extractRegexParts(literalText: string): { @@ -2168,7 +2621,7 @@ export class Autofixer { fixDebuggerStatement(debuggerStmt: ts.DebuggerStatement): Autofix[] { void this; - const text = SPECIAL_LIB_NAME + '.debugger()'; + const text = SPECIAL_LIB_NAME + '.debugger();'; return [{ start: debuggerStmt.getStart(), end: debuggerStmt.getEnd(), replacementText: text }]; } @@ -2284,7 +2737,9 @@ export class Autofixer { arrowFunc ); const newExpr = ts.factory.createObjectLiteralExpression([assignment1, assignment2], true); - const text = this.printer.printNode(ts.EmitHint.Unspecified, newExpr, originalExpr.getSourceFile()); + let text = this.printer.printNode(ts.EmitHint.Unspecified, newExpr, originalExpr.getSourceFile()); + const startPos = this.sourceFile.getLineAndCharacterOfPosition(originalExpr.parent.getStart()).character; + text = this.adjustIndentation(text, startPos); return [{ start: originalExpr.getStart(), end: originalExpr.getEnd(), replacementText: text }]; } @@ -2328,7 +2783,7 @@ export class Autofixer { const parameters: ts.MemberName[] = []; const values: ts.Expression[][] = []; const statements = block?.statements; - this.getParamsAndValues(statements, parameters, values); + Autofixer.getParamsAndValues(statements, parameters, values); const returnStatement = ts.factory.createReturnStatement(ts.factory.createThis()); const newBlock = Autofixer.createBlock(parameters, values, ts.factory.createThis(), returnStatement); const componentName = extendDecorator.expression.arguments[0]?.getText(); @@ -2337,7 +2792,6 @@ export class Autofixer { } const typeName = componentName + ATTRIBUTE_SUFFIX; interfacesNeedToImport.add(typeName); - interfacesNeedToImport.add(CustomDecoratorName.Memo); const parameDecl = ts.factory.createParameterDeclaration( undefined, undefined, @@ -2348,21 +2802,150 @@ export class Autofixer { ); const returnType = ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(THIS_IDENTIFIER), undefined); const newFuncDecl = Autofixer.createFunctionDeclaration(funcDecl, undefined, parameDecl, returnType, newBlock); - const newDecorators: ts.Decorator[] = []; + let text = this.printer.printNode(ts.EmitHint.Unspecified, newFuncDecl, funcDecl.getSourceFile()); if (preserveDecorator) { - newDecorators.push(ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.AnimatableExtend))); + text = '@' + CustomDecoratorName.AnimatableExtend + this.getNewLine() + text; } - newDecorators.push(ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Memo))); - const text1 = this.printer.printList( - ts.ListFormat.Decorators, - ts.factory.createNodeArray(newDecorators), - funcDecl.getSourceFile() - ); - const text2 = this.printer.printNode(ts.EmitHint.Unspecified, newFuncDecl, funcDecl.getSourceFile()); - const text = text1 + text2; return [{ start: funcDecl.getStart(), end: funcDecl.getEnd(), replacementText: text }]; } + fixEntryDecorator(entryDecorator: ts.Decorator): Autofix[] | undefined { + if (!ts.isCallExpression(entryDecorator.expression)) { + return undefined; + } + + const args = entryDecorator.expression.arguments; + if (args.length !== 1) { + return undefined; + } + + const parentNode = entryDecorator.parent; + const arg = args[0]; + let getLocalStorageStatement: ts.VariableStatement | undefined; + + if (ts.isIdentifier(arg) || ts.isNewExpression(arg) || ts.isCallExpression(arg)) { + getLocalStorageStatement = Autofixer.createGetLocalStorageLambdaStatement(arg); + } else if (ts.isObjectLiteralExpression(arg)) { + getLocalStorageStatement = Autofixer.processEntryAnnotationObjectLiteralExpression(arg); + } + + if (getLocalStorageStatement !== undefined) { + let text = this.printer.printNode(ts.EmitHint.Unspecified, getLocalStorageStatement, parentNode.getSourceFile()); + const fixedEntryDecorator = Autofixer.createFixedEntryDecorator(); + const fixedEntryDecoratorText = this.printer.printNode( + ts.EmitHint.Unspecified, + fixedEntryDecorator, + parentNode.getSourceFile() + ); + text = text + this.getNewLine() + fixedEntryDecoratorText; + return [{ start: entryDecorator.getStart(), end: entryDecorator.getEnd(), replacementText: text }]; + } + return undefined; + } + + private static createFixedEntryDecorator(): ts.Decorator { + const storageProperty = ts.factory.createPropertyAssignment( + ts.factory.createIdentifier(ENTRY_STORAGE_PROPERITY), + ts.factory.createStringLiteral(GET_LOCAL_STORAGE_FUNC_NAME) + ); + const objectLiteralExpr = ts.factory.createObjectLiteralExpression([storageProperty], false); + const callExpr = ts.factory.createCallExpression(ts.factory.createIdentifier(ENTRY_DECORATOR_NAME), undefined, [ + objectLiteralExpr + ]); + return ts.factory.createDecorator(callExpr); + } + + private static processEntryAnnotationObjectLiteralExpression( + expression: ts.ObjectLiteralExpression + ): ts.VariableStatement | undefined { + const objectProperties = expression.properties; + if (objectProperties.length !== 1) { + return undefined; + } + const objectProperty = objectProperties[0]; + if (!ts.isPropertyAssignment(objectProperty)) { + return undefined; + } + if (ts.isIdentifier(objectProperty.name)) { + if (objectProperty.name.escapedText !== ENTRY_STORAGE_PROPERITY) { + return undefined; + } + const properityInitializer = objectProperty.initializer; + if ( + ts.isIdentifier(properityInitializer) || + ts.isNewExpression(properityInitializer) || + ts.isCallExpression(properityInitializer) || + ts.isPropertyAccessExpression(properityInitializer) + ) { + return Autofixer.createGetLocalStorageLambdaStatement(properityInitializer); + } + } + return undefined; + } + + private static createGetLocalStorageLambdaStatement(expression: ts.Expression): ts.VariableStatement { + const variable = ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(GET_LOCAL_STORAGE_FUNC_NAME), + undefined, + undefined, + ts.factory.createArrowFunction( + undefined, + undefined, + [], + ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(LOCAL_STORAGE_TYPE_NAME), undefined), + ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + expression + ) + ); + const declarationList = ts.factory.createVariableDeclarationList([variable], ts.NodeFlags.Const); + return ts.factory.createVariableStatement(undefined, declarationList); + } + + fixProvideDecorator(provideDecorator: ts.Decorator): Autofix[] | undefined { + const callExpr = provideDecorator.expression as ts.CallExpression; + const args = callExpr.arguments; + const parentNode = provideDecorator.parent; + const arg = args[0]; + let provideAnnotationFixed: ts.Decorator | undefined; + if (ts.isStringLiteral(arg)) { + provideAnnotationFixed = Autofixer.createProvideDecorator(arg); + } + if (ts.isObjectLiteralExpression(arg)) { + const properties = arg.properties; + const property = properties[0] as ts.PropertyAssignment; + const propertyInitializer = property.initializer as ts.StringLiteral; + provideAnnotationFixed = Autofixer.createProvideDecorator(propertyInitializer, true); + } + if (provideAnnotationFixed !== undefined) { + const text = this.printer.printNode(ts.EmitHint.Unspecified, provideAnnotationFixed, parentNode.getSourceFile()); + return [{ start: provideDecorator.getStart(), end: provideDecorator.getEnd(), replacementText: text }]; + } + return undefined; + } + + private static createProvideDecorator( + alias: ts.StringLiteral, + allowOverride: boolean | undefined = undefined + ): ts.Decorator { + const properties: ts.PropertyAssignment[] = []; + properties.push( + ts.factory.createPropertyAssignment(ts.factory.createIdentifier(PROVIDE_ALIAS_PROPERTY_NAME), alias) + ); + if (allowOverride !== undefined && allowOverride) { + properties.push( + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier(PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME), + ts.factory.createTrue() + ) + ); + } + const objectLiteralExpr = ts.factory.createObjectLiteralExpression(properties, false); + const callExpr = ts.factory.createCallExpression(ts.factory.createIdentifier(PROVIDE_DECORATOR_NAME), undefined, [ + objectLiteralExpr + ]); + return ts.factory.createDecorator(callExpr); + } + private static createFunctionDeclaration( funcDecl: ts.FunctionDeclaration, typeParameters: ts.TypeParameterDeclaration[] | undefined, @@ -2403,23 +2986,56 @@ export class Autofixer { return block; } - traverseNodes(node: ts.Node, parameters: ts.MemberName[], values: ts.Expression[][]): void { - if (ts.isCallExpression(node)) { - if (ts.isPropertyAccessExpression(node.expression)) { - const propertyAccess = node.expression; + private static traverseNodes(node: ts.Node, parameters: ts.MemberName[], values: ts.Expression[][]): void { + const callExpressions: ts.CallExpression[] = Autofixer.extractCallExpressions(node); + callExpressions.forEach((callExpression) => { + if (ts.isPropertyAccessExpression(callExpression.expression)) { + const propertyAccess = callExpression.expression; parameters.push(propertyAccess.name); - } else if (ts.isIdentifier(node.expression)) { - parameters.push(node.expression); + } else if (ts.isIdentifier(callExpression.expression)) { + parameters.push(callExpression.expression); + } + values.push(Array.from(callExpression.arguments)); + }); + } + + private static extractCallExpressions(node: ts.Node): ts.CallExpression[] { + const callExpressions: ts.CallExpression[] = []; + let current: ts.Node | undefined; + if (ts.isExpressionStatement(node)) { + if (ts.isCallExpression(node.expression)) { + current = node.expression; } - values.push(Array.from(node.arguments)); } - ts.forEachChild(node, (child) => { - this.traverseNodes(child, parameters, values); - }); + if (ts.isPropertyAssignment(node)) { + if (ts.isCallExpression(node.initializer)) { + current = node.initializer; + } + } + + while (current) { + if (ts.isCallExpression(current)) { + if ( + (ts.isPropertyAccessExpression(current.parent) || + ts.isExpressionStatement(current.parent) || + ts.isPropertyAssignment(current.parent)) && + (ts.isPropertyAccessExpression(current.expression) || ts.isIdentifier(current.expression)) + ) { + callExpressions.push(current); + } + } + + if (ts.isCallExpression(current) || ts.isPropertyAccessExpression(current)) { + current = current.expression; + } else { + break; + } + } + return callExpressions; } - getParamsAndValues( + private static getParamsAndValues( statements: ts.NodeArray | undefined, parameters: ts.MemberName[], values: ts.Expression[][] @@ -2431,7 +3047,7 @@ export class Autofixer { const statement = statements[i]; const tempParas: ts.MemberName[] = []; const tempVals: ts.Expression[][] = []; - this.traverseNodes(statement, tempParas, tempVals); + Autofixer.traverseNodes(statement, tempParas, tempVals); if ( ts.isExpressionStatement(statement) && ts.isCallExpression(statement.expression) && @@ -2501,6 +3117,74 @@ export class Autofixer { ]; } + /** + * Transforms a call expression invoking an imported function or method into its interop equivalent. + * - For direct calls like foo() or bar(123), transforms to foo.invoke() or bar.invoke(ESValue.wrap(123)) + * - For property access calls like foo.bar(123), transforms to foo.invokeMethod('bar', ESValue.wrap(123)) + * @param expression The call expression node to transform. + * @returns Autofix array or undefined. + */ + fixInteropInvokeExpression(expression: ts.CallExpression): Autofix[] | undefined { + const callee = expression.expression; + const args = this.createArgs(expression.arguments); + + let replacement: ts.CallExpression; + + if (ts.isPropertyAccessExpression(callee)) { + // For expressions like foo.bar(123) => foo.invokeMethod('bar', ...) + replacement = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(callee.expression, ts.factory.createIdentifier(INVOKE_METHOD)), + undefined, + [ts.factory.createStringLiteral(callee.name.getText()), ...args || []] + ); + } else if (ts.isIdentifier(callee)) { + // For expressions like foo() or bar(123) => foo.invoke(...) or bar.invoke(...) + replacement = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(callee, ts.factory.createIdentifier(INVOKE)), + undefined, + args + ); + } else { + return undefined; + } + + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, replacement, expression.getSourceFile()); + return [{ start: expression.getStart(), end: expression.getEnd(), replacementText }]; + } + + fixInteropInstantiateExpression( + express: ts.NewExpression, + args: ts.NodeArray | undefined + ): Autofix[] | undefined { + const statements = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(express.expression.getText()), + ts.factory.createIdentifier(INSTANTIATE) + ), + undefined, + this.createArgs(args) + ); + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, statements, express.getSourceFile()); + return [{ start: express.getStart(), end: express.getEnd(), replacementText: replacementText }]; + } + + createArgs(args: ts.NodeArray | undefined): ts.Expression[] | undefined { + void this; + if (args && args.length > 0) { + return args.map((arg) => { + return ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(ES_VALUE), + ts.factory.createIdentifier(WRAP) + ), + undefined, + [ts.factory.createIdentifier(arg.getText())] + ); + }); + } + return undefined; + } + fixParameter(param: ts.ParameterDeclaration): Autofix[] { const newParam = ts.factory.createParameterDeclaration( param.modifiers, @@ -2626,14 +3310,44 @@ export class Autofixer { }); } - fixSingleImport( + removeImport(ident: ts.Identifier, importSpecifier: ts.ImportSpecifier): Autofix[] | undefined { + const namedImports = importSpecifier.parent; + const importClause = namedImports.parent; + const importDeclaration = importClause.parent; + if (!importDeclaration || !importClause) { + return undefined; + } + + if (namedImports.elements.length === 1 && !importClause.name) { + return this.removeNode(importDeclaration); + } + + if (namedImports.elements.length <= 0) { + return undefined; + } + + const specifiers = namedImports.elements.filter((specifier) => { + return specifier.name.text !== ident.text; + }); + + const newClause = ts.factory.createImportClause( + importClause.isTypeOnly, + importClause.name, + ts.factory.createNamedImports(specifiers) + ); + + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, newClause, ident.getSourceFile()); + return [{ start: importClause.getStart(), end: importClause.getEnd(), replacementText }]; + } + + fixInterfaceImport( interfacesNeedToImport: Set, - importedInterfaces: Set, + interfacesAlreadyImported: Set, sourceFile: ts.SourceFile ): Autofix[] { const importSpecifiers: ts.ImportSpecifier[] = []; interfacesNeedToImport.forEach((interfaceName) => { - if (importedInterfaces.has(interfaceName)) { + if (interfacesAlreadyImported.has(interfaceName)) { return; } const identifier = ts.factory.createIdentifier(interfaceName); @@ -2656,26 +3370,26 @@ export class Autofixer { let text = this.printer.printNode(ts.EmitHint.Unspecified, importDeclaration, sourceFile); if (annotationEndPos !== 0) { - text = '\n\n' + text; + text = this.getNewLine() + this.getNewLine() + text; } const codeStartLine = sourceFile.getLineAndCharacterOfPosition(sourceFile.getStart()).line; for (let i = 2; i > codeStartLine - annotationEndLine; i--) { - text = text + '\n'; + text = text + this.getNewLine(); } return [{ start: annotationEndPos, end: annotationEndPos, replacementText: text }]; } fixStylesDecoratorGlobal( funcDecl: ts.FunctionDeclaration, - calls: ts.CallExpression[], + calls: ts.Identifier[], needImport: Set ): Autofix[] | undefined { const block = funcDecl.body; const parameters: ts.MemberName[] = []; const values: ts.Expression[][] = []; const statements = block?.statements; - this.getParamsAndValues(statements, parameters, values); + Autofixer.getParamsAndValues(statements, parameters, values); const newBlock = Autofixer.createBlock(parameters, values, ts.factory.createIdentifier(INSTANCE_IDENTIFIER)); const parameDecl = ts.factory.createParameterDeclaration( undefined, @@ -2687,35 +3401,23 @@ export class Autofixer { ); const returnType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword); const newFuncDecl = Autofixer.createFunctionDeclaration(funcDecl, undefined, parameDecl, returnType, newBlock); - const MemoDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Memo)); needImport.add(COMMON_METHOD_IDENTIFIER); - needImport.add(CustomDecoratorName.Memo); - const text1 = this.printer.printNode(ts.EmitHint.Unspecified, MemoDecorator, funcDecl.getSourceFile()); - const text2 = this.printer.printNode(ts.EmitHint.Unspecified, newFuncDecl, funcDecl.getSourceFile()); - const text = text1 + '\n' + text2; + const text = this.printer.printNode(ts.EmitHint.Unspecified, newFuncDecl, funcDecl.getSourceFile()); const autofix = [{ start: funcDecl.getStart(), end: funcDecl.getEnd(), replacementText: text }]; - calls.forEach((call) => { - const callExpr = ts.factory.createCallExpression( - ts.factory.createIdentifier(APPLY_STYLES_IDENTIFIER), - undefined, - [funcDecl.name as ts.Identifier] - ); - const text = this.printer.printNode(ts.EmitHint.Unspecified, callExpr, call.getSourceFile()); - autofix.push({ start: call.getStart(), end: call.getEnd(), replacementText: text }); - }); + this.addAutofixFromCalls(calls, autofix, funcDecl.name as ts.Identifier); return autofix; } fixStylesDecoratorStruct( methodDecl: ts.MethodDeclaration, - calls: ts.CallExpression[], + calls: ts.Identifier[], needImport: Set ): Autofix[] | undefined { const block = methodDecl.body; const parameters: ts.MemberName[] = []; const values: ts.Expression[][] = []; const statements = block?.statements; - this.getParamsAndValues(statements, parameters, values); + Autofixer.getParamsAndValues(statements, parameters, values); const newBlock = Autofixer.createBlock(parameters, values, ts.factory.createIdentifier(INSTANCE_IDENTIFIER)); const parameDecl = ts.factory.createParameterDeclaration( undefined, @@ -2733,61 +3435,92 @@ export class Autofixer { ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), newBlock ); - const MemoDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Memo)); + const expr = ts.factory.createPropertyDeclaration(undefined, methodDecl.name, undefined, undefined, arrowFunc); needImport.add(COMMON_METHOD_IDENTIFIER); - needImport.add(CustomDecoratorName.Memo); - const text1 = this.printer.printNode(ts.EmitHint.Unspecified, methodDecl.name, methodDecl.getSourceFile()); - const text2 = this.printer.printNode( - ts.EmitHint.Unspecified, - ts.factory.createToken(ts.SyntaxKind.EqualsToken), - methodDecl.getSourceFile() - ); - const text3 = this.printer.printNode(ts.EmitHint.Unspecified, MemoDecorator, methodDecl.getSourceFile()); - const text4 = this.printer.printNode(ts.EmitHint.Unspecified, arrowFunc, methodDecl.getSourceFile()); - const text = text1 + ' ' + text2 + ' ' + text3 + ' ' + text4; + let text = this.printer.printNode(ts.EmitHint.Unspecified, expr, methodDecl.getSourceFile()); + const startPos = this.sourceFile.getLineAndCharacterOfPosition(methodDecl.getStart()).character; + text = this.adjustIndentation(text, startPos); const autofix = [{ start: methodDecl.getStart(), end: methodDecl.getEnd(), replacementText: text }]; - this.addAutofixFromCalls(calls, autofix, methodDecl.name as ts.Identifier); + const argument = ts.factory.createPropertyAccessExpression( + ts.factory.createThis(), + methodDecl.name as ts.Identifier + ); + this.addAutofixFromCalls(calls, autofix, argument); return autofix; } - private addAutofixFromCalls(calls: ts.CallExpression[], autofix: Autofix[], methodDeclName: ts.Identifier): void { + private adjustIndentation(text: string, startPos: number): string { + const lines = text.split(this.getNewLine()); + if (lines.length <= 1) { + return text; + } + + const firstLine = lines[0]; + const secondLine = lines[1]; + const currentIndent = secondLine.match(/^\s*/)?.[0].length || 0; + const indentBase = startPos - (currentIndent - INDENT_STEP); + + const middleLines = lines.slice(1, -1).map((line) => { + if (indentBase > 0) { + return ' '.repeat(indentBase) + line; + } + return line; + }); + + const lastLine = ' '.repeat(startPos) + lines[lines.length - 1]; + return [firstLine, ...middleLines, lastLine].join(this.getNewLine()); + } + + private addAutofixFromCalls(calls: ts.Identifier[], autofix: Autofix[], argument: ts.Expression): void { calls.forEach((call) => { const callExpr = ts.factory.createCallExpression( ts.factory.createIdentifier(APPLY_STYLES_IDENTIFIER), undefined, - [ts.factory.createPropertyAccessExpression(ts.factory.createThis(), methodDeclName)] + [argument] ); + + const start: number = call.getStart(); + let end: number = 0; + const expr = call.parent; + if (ts.isCallExpression(expr)) { + end = expr.getEnd(); + } + if (ts.isPropertyAccessExpression(expr) && ts.isCallExpression(expr.parent)) { + end = expr.parent.getEnd(); + } + if (end === 0) { + return; + } const text = this.printer.printNode(ts.EmitHint.Unspecified, callExpr, call.getSourceFile()); - autofix.push({ start: call.getStart(), end: call.getEnd(), replacementText: text }); + autofix.push({ start: start, end: end, replacementText: text }); }); } - fixStateStyles(object: ts.ObjectLiteralExpression, needImport: Set): Autofix[] | undefined { + fixStateStyles( + object: ts.ObjectLiteralExpression, + startNode: ts.Node, + needImport: Set + ): Autofix[] | undefined { const properties = object.properties; - const stateStyles: ts.Identifier[] = []; - const stateParams: ts.MemberName[][] = []; - const stateValues: ts.Expression[][][] = []; + const assignments: ts.PropertyAssignment[] = []; for (let i = 0; i < properties.length; i++) { const property = properties[i]; const stateStyle = property.name; - if (stateStyle && ts.isIdentifier(stateStyle)) { - stateStyles.push(stateStyle); - } - if (!ts.isPropertyAssignment(property)) { - return []; + if (!stateStyle || !ts.isIdentifier(stateStyle) || !ts.isPropertyAssignment(property)) { + return undefined; } - const object = property.initializer; - if (!ts.isObjectLiteralExpression(object)) { - return []; + if (!ts.isObjectLiteralExpression(property.initializer)) { + assignments.push(property); + continue; } - const propAssignments = object.properties; + const propAssignments = property.initializer.properties; const parameters: ts.MemberName[] = []; const values: ts.Expression[][] = []; for (let j = 0; j < propAssignments.length; j++) { const propAssignment = propAssignments[j]; const tempParas: ts.MemberName[] = []; const tempVals: ts.Expression[][] = []; - this.traverseNodes(propAssignment, tempParas, tempVals); + Autofixer.traverseNodes(propAssignment, tempParas, tempVals); if ( ts.isPropertyAssignment(propAssignment) && ts.isCallExpression(propAssignment.initializer) && @@ -2802,27 +3535,23 @@ export class Autofixer { values.push(tempVals[k]); } } - stateParams.push(parameters); - stateValues.push(values); + const assignment = Autofixer.createPropertyAssignment(parameters, values, stateStyle); + assignments.push(assignment); } needImport.add(COMMON_METHOD_IDENTIFIER); - needImport.add(CustomDecoratorName.Memo); - const text = this.createPropertyText(stateParams, stateValues, stateStyles); + const newExpr = ts.factory.createObjectLiteralExpression(assignments, true); + let text = this.printer.printNode(ts.EmitHint.Unspecified, newExpr, object.getSourceFile()); + const startPos = this.sourceFile.getLineAndCharacterOfPosition(startNode.getStart()).character - 1; + text = this.adjustIndentation(text, startPos); return [{ start: object.getStart(), end: object.getEnd(), replacementText: text }]; } - private createPropertyText( - stateParams: ts.MemberName[][], - sateValues: ts.Expression[][][], - stateStyles: ts.Identifier[] - ): string { - const blocks: ts.Block[] = []; - for (let i = 0; i < stateParams.length; i++) { - const parameters = stateParams[i]; - const values = sateValues[i]; - const block = Autofixer.createBlock(parameters, values, ts.factory.createIdentifier(INSTANCE_IDENTIFIER)); - blocks.push(block); - } + private static createPropertyAssignment( + stateParam: ts.MemberName[], + sateValue: ts.Expression[][], + stateStyle: ts.Identifier + ): ts.PropertyAssignment { + const block = Autofixer.createBlock(stateParam, sateValue, ts.factory.createIdentifier(INSTANCE_IDENTIFIER)); const parameterDecl = ts.factory.createParameterDeclaration( undefined, undefined, @@ -2833,42 +3562,729 @@ export class Autofixer { ); const voidToken = ts.factory.createToken(ts.SyntaxKind.VoidKeyword); const arrowToken = ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken); - const MemoDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Memo)); - const propertyTexts: string[] = []; - for (let i = 0; i < blocks.length; i++) { - const arrowFunc = ts.factory.createArrowFunction( + const property = ts.factory.createPropertyAssignment( + stateStyle, + ts.factory.createArrowFunction(undefined, undefined, [parameterDecl], voidToken, arrowToken, block) + ); + return property; + } + + fixDataObservation(classDecls: ts.ClassDeclaration[]): Autofix[] | undefined { + const autofixes: Autofix[] = []; + classDecls.forEach((classDecl) => { + const observedDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.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 }; + autofixes.push(autofix); + }); + return autofixes.length !== 0 ? autofixes : undefined; + } + + fixInteropTsType( + binaryExpr: ts.BinaryExpression, + lhs: ts.PropertyAccessExpression, + rhs: ts.Expression + ): Autofix[] | undefined { + void this; + const base = lhs.expression.getText(); + const prop = lhs.name.text; + const replacementText = `${base}.setPropertyByName('${prop}',ESValue.wrap(${rhs.getText()}))`; + + return [{ start: binaryExpr.getStart(), end: binaryExpr.getEnd(), replacementText }]; + } + + createReplacementForJsIndirectImportPropertyAccessExpression(node: ts.PropertyAccessExpression): Autofix[] { + // Bypass eslint-check + void this; + + const objName = node.expression.getText(); + const propName = node.name.getText(); + + let start = node.getStart(); + let end = node.getEnd(); + let replacementText = `${objName}.getPropertyByName('${propName}')`; + + // Check if there is an "as number" type assertion in the statement + if (ts.isAsExpression(node.parent) && node.parent.type.kind === ts.SyntaxKind.NumberKeyword) { + replacementText += '.toNumber()'; + start = node.parent.getStart(); + end = node.parent.getEnd(); + } + + return [{ replacementText, start, end }]; + } + + createReplacementForJsImportPropertyAccessExpression(node: ts.PropertyAccessExpression): Autofix[] { + const objName = node.expression.getText(); + const propName = node.name.getText(); + + const start = node.getStart(); + const end = node.getEnd(); + + const replacement = `${objName}.getPropertyByName('${propName}')${this.utils.findTypeOfNodeForConversion(node)}`; + + return [{ replacementText: replacement, start, end }]; + } + + createReplacementJsImportElementAccessExpression( + elementAccessExpr: ts.ElementAccessExpression, + identifier: ts.Identifier + ): Autofix[] { + const isParentBinaryExp = ts.isBinaryExpression(elementAccessExpr.parent); + const exprText = elementAccessExpr.argumentExpression.getText(); + const start = isParentBinaryExp ? elementAccessExpr.parent.getStart() : elementAccessExpr.getStart(); + const end = isParentBinaryExp ? elementAccessExpr.parent.getEnd() : elementAccessExpr.getEnd(); + + const replacementText = + isParentBinaryExp && elementAccessExpr.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken ? + `${identifier.text}.setPropertyByIndex(${exprText},` + + ` ESValue.wrap(${elementAccessExpr.parent.right.getText()}))` : + `${identifier.text}.getPropertyByIndex(${exprText})` + + this.utils.findTypeOfNodeForConversion(elementAccessExpr); + return [{ replacementText, start, end }]; + } + + fixSharedArrayBufferConstructor(node: ts.NewExpression): Autofix[] | undefined { + void this; + + // Ensure it's a constructor call to SharedArrayBuffer + if (!ts.isIdentifier(node.expression) || node.expression.text !== ESLIB_SHAREDARRAYBUFFER) { + return undefined; + } + + // Construct replacement + const replacementText = 'ArrayBuffer'; + + return [{ replacementText, start: node.expression.getStart(), end: node.expression.getEnd() }]; + } + + fixSharedArrayBufferTypeReference(node: ts.TypeReferenceNode): Autofix[] | undefined { + void this; + + if (!ts.isIdentifier(node.typeName) || node.typeName.text !== ESLIB_SHAREDARRAYBUFFER) { + return undefined; + } + + const replacementText = 'ArrayBuffer'; + + return [{ replacementText, start: node.getStart(), end: node.getEnd() }]; + } + + fixAppStorageCallExpression(callExpr: ts.CallExpression): Autofix[] | undefined { + const varDecl = Autofixer.findParentVariableDeclaration(callExpr); + if (!varDecl || varDecl.type) { + return undefined; + } + + const updatedVarDecl = ts.factory.updateVariableDeclaration( + varDecl, + varDecl.name, + undefined, + ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword), + varDecl.initializer + ); + + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, updatedVarDecl, varDecl.getSourceFile()); + + return [ + { + replacementText, + start: varDecl.getStart(), + end: varDecl.getEnd() + } + ]; + } + + private static findParentVariableDeclaration(node: ts.Node): ts.VariableDeclaration | undefined { + while (node) { + if (ts.isVariableDeclaration(node)) { + return node; + } + node = node.parent; + } + return undefined; + } + + private static createVariableForInteropImport( + newVarName: string, + interopObject: string, + interopMethod: string, + interopPropertyOrModule: string + ): ts.VariableStatement { + const newVarDecl = ts.factory.createVariableStatement( + undefined, + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(newVarName), + undefined, + undefined, + ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(interopObject), + ts.factory.createIdentifier(interopMethod) + ), + undefined, + [ts.factory.createStringLiteral(interopPropertyOrModule)] + ) + ) + ], + ts.NodeFlags.Let + ) + ); + return newVarDecl; + } + + private static getOriginalNameAtSymbol(symbolName: string, symbol?: ts.Symbol): string { + if (symbol) { + const originalDeclaration = symbol.declarations?.[0]; + let originalName = ''; + if (originalDeclaration) { + const isReturnNameOnSomeCase = + ts.isFunctionDeclaration(originalDeclaration) || + ts.isClassDeclaration(originalDeclaration) || + ts.isInterfaceDeclaration(originalDeclaration) || + ts.isEnumDeclaration(originalDeclaration); + if (isReturnNameOnSomeCase) { + originalName = originalDeclaration.name?.text || symbolName; + } else if (ts.isVariableDeclaration(originalDeclaration)) { + originalName = originalDeclaration.name.getText(); + } + } + return originalName; + } + return ''; + } + + private static fixInterOpImportJsWrapArgs(args: ts.NodeArray): string { + return args. + map((arg) => { + return `ESValue.wrap(${arg.getText()})`; + }). + join(', '); + } + + private fixInterOpImportJsProcessNode(node: ts.Node): string { + if (ts.isIdentifier(node)) { + return node.text; + } else if (ts.isCallExpression(node)) { + const callee = this.fixInterOpImportJsProcessNode(node.expression); + const args = Autofixer.fixInterOpImportJsWrapArgs(node.arguments); + return `${callee}.invoke(${args})`; + } else if (ts.isPropertyAccessExpression(node)) { + const base = this.fixInterOpImportJsProcessNode(node.expression); + const propName = node.name.text; + return `${base}.getPropertyByName('${propName}')`; + } else if (ts.isNewExpression(node)) { + const constructor = this.fixInterOpImportJsProcessNode(node.expression); + return `${constructor}.instantiate()`; + } + return ''; + } + + fixInterOpImportJs( + importDecl: ts.ImportDeclaration, + importClause: ts.ImportClause, + moduleSpecifier: string, + 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); + } + 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 (statements.length <= 0) { + return undefined; + } + let lastImportEnd = this.lastImportEndMap.get(this.sourceFile.fileName); + if (!lastImportEnd) { + lastImportEnd = this.getLastImportEnd(); + this.lastImportEndMap.set(this.sourceFile.fileName, lastImportEnd); + } + return [ + { start: importDecl.getStart(), end: importDecl.getEnd(), replacementText: '' }, + { + start: lastImportEnd, + end: lastImportEnd, + replacementText: statements.join(this.getNewLine()) + this.getNewLine() + } + ]; + } + + private constructAndSaveimportDecl2Arrays( + importDecl: ts.ImportDeclaration, + symbolName: string, + originalName: string | undefined, + statements: string[], + isLoad: boolean + ): 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_BY_NAME]; + const newVarDecl = Autofixer.createVariableForInteropImport( + constructDeclInfo[0], + constructDeclInfo[1], + constructDeclInfo[2], + propertyName + ); + const text = this.printer.printNode(ts.EmitHint.Unspecified, newVarDecl, importDecl.getSourceFile()); + statements.push(TsUtils.removeOrReplaceQuotes(text, true)); + return statements; + } + + private getLastImportEnd(): number { + let lastImportEnd = 0; + this.sourceFile.statements.forEach((statement) => { + if (ts.isImportDeclaration(statement)) { + lastImportEnd = statement.getEnd(); + } + }); + return lastImportEnd; + } + + fixInteropPropertyAccessExpression(express: ts.PropertyAccessExpression): Autofix[] | undefined { + let text: string = ''; + const statements = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(express.expression, ts.factory.createIdentifier(GET_PROPERTY_BY_NAME)), + undefined, + [ts.factory.createStringLiteral(express.name.getText())] + ); + text = this.printer.printNode(ts.EmitHint.Unspecified, statements, express.getSourceFile()); + return [{ start: express.getStart(), end: express.getEnd(), replacementText: text }]; + } + + fixInteropBinaryExpression(express: ts.BinaryExpression): Autofix[] | undefined { + const left = express.left; + const right = express.right; + let objectName = ''; + let propertyName = ''; + if (ts.isPropertyAccessExpression(left)) { + objectName = left.expression.getText(); + propertyName = left.name.text; + } else { + return undefined; + } + const statements = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(objectName), + ts.factory.createIdentifier(SET_PROPERTY_BY_NAME) + ), + undefined, + [ + ts.factory.createStringLiteral(propertyName), + ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(ES_VALUE), + ts.factory.createIdentifier(WRAP) + ), + undefined, + [ts.factory.createIdentifier(right.getText())] + ) + ] + ); + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, statements, express.getSourceFile()); + return [{ start: express.getStart(), end: express.getEnd(), replacementText: replacementText }]; + } + + fixInteropAsExpression(expression: ts.AsExpression): Autofix[] | undefined { + const castMap: Partial> = { + [ts.SyntaxKind.StringKeyword]: 'toString', + [ts.SyntaxKind.NumberKeyword]: 'toNumber', + [ts.SyntaxKind.BooleanKeyword]: 'toBoolean', + [ts.SyntaxKind.BigIntKeyword]: 'toBigInt' + }; + + const castMethod = castMap[expression.type.kind]; + if (!castMethod) { + return undefined; + } + const express = expression.expression; + if (!ts.isPropertyAccessExpression(express)) { + return undefined; + } + + const propertyAccess = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(express.expression, ts.factory.createIdentifier(GET_PROPERTY_BY_NAME)), + undefined, + [ts.factory.createStringLiteral(express.name.getText())] + ); + + const finalCall = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(propertyAccess, ts.factory.createIdentifier(castMethod)), + undefined, + [] + ); + + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, finalCall, expression.getSourceFile()); + + return [ + { + start: expression.getStart(), + end: expression.getEnd(), + replacementText + } + ]; + } + + fixInteropArrayElementAccessExpression(express: ts.ElementAccessExpression): Autofix[] | undefined { + const statements = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(express.expression, ts.factory.createIdentifier(GET_PROPERTY_BY_INDEX)), + undefined, + [express.argumentExpression] + ); + const text = this.printer.printNode(ts.EmitHint.Unspecified, statements, express.getSourceFile()); + return [{ start: express.getStart(), end: express.getEnd(), replacementText: text }]; + } + + fixInteropArrayBinaryExpression(express: ts.BinaryExpression): Autofix[] | undefined { + const left = express.left as ts.ElementAccessExpression; + const right = express.right; + const statements = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(left.expression.getText()), + ts.factory.createIdentifier(SET_PROPERTY_BY_INDEX) + ), + undefined, + [ + left.argumentExpression, + ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(ES_VALUE), + ts.factory.createIdentifier(WRAP) + ), + undefined, + [ts.factory.createIdentifier(right.getText())] + ) + ] + ); + const replacementText = this.printer.printNode(ts.EmitHint.Unspecified, statements, express.getSourceFile()); + return [{ start: express.getStart(), end: express.getEnd(), replacementText: replacementText }]; + } + + fixInterOpImportJsOnTypeOf(typeofExpress: ts.TypeOfExpression): Autofix[] | undefined { + const node = typeofExpress.expression; + const start = typeofExpress.getStart(); + const end = typeofExpress.getEnd(); + const processed = this.fixInterOpImportJsProcessNode(node); + const replacementText = `${processed}.typeOf()`; + return replacementText ? [{ start, end, replacementText }] : undefined; + } + + fixInteropInterfaceConvertNum(express: ts.PrefixUnaryExpression): Autofix[] | undefined { + const createConversionExpression = (propertyAccess: ts.PropertyAccessExpression): ts.Expression => { + const getPropertyCall = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(propertyAccess.expression.getText()), + ts.factory.createIdentifier(GET_PROPERTY_BY_NAME) + ), undefined, + [ts.factory.createStringLiteral(propertyAccess.name.getText())] + ); + + return ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression(getPropertyCall, ts.factory.createIdentifier(TO_NUMBER)), undefined, - [parameterDecl], - voidToken, - arrowToken, - blocks[i] + [] ); - const sourceFile = stateStyles[i].getSourceFile(); - const text1 = this.printer.printNode(ts.EmitHint.Unspecified, stateStyles[i], sourceFile); - const text2 = this.printer.printNode(ts.EmitHint.Unspecified, MemoDecorator, sourceFile); - const text3 = this.printer.printNode(ts.EmitHint.Unspecified, arrowFunc, sourceFile); - const propertyText = text1 + ': ' + text2 + ' ' + text3; - propertyTexts.push(propertyText); - } - let innerText = propertyTexts.join(',\n'); - innerText = innerText. - split('\n'). - map((line) => { - return ' ' + line; + }; + + let replacementExpression: ts.Expression | undefined; + if (ts.isPropertyAccessExpression(express.operand)) { + replacementExpression = createConversionExpression(express.operand); + } else if ( + ts.isParenthesizedExpression(express.operand) && + ts.isPropertyAccessExpression(express.operand.expression) + ) { + replacementExpression = ts.factory.createParenthesizedExpression( + createConversionExpression(express.operand.expression) + ); + } + + if (!replacementExpression) { + return undefined; + } + + const text = this.printer.printNode(ts.EmitHint.Unspecified, replacementExpression, express.getSourceFile()); + + return [{ start: express.operand.getStart(), end: express.operand.getEnd(), replacementText: text }]; + } + + 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() + ); + return [{ start: tsImportClause.getStart(), end: tsImportClause.getEnd(), replacementText }]; + } + + fixInteropEqualityOperator( + tsBinaryExpr: ts.BinaryExpression, + binaryOperator: ts.BinaryOperator + ): Autofix[] | undefined { + const text = this.replaceInteropEqualityOperator(tsBinaryExpr, binaryOperator); + if (text) { + return [{ start: tsBinaryExpr.getStart(), end: tsBinaryExpr.getEnd(), replacementText: text }]; + } + return undefined; + } + + replaceInteropEqualityOperator( + tsBinaryExpr: ts.BinaryExpression, + binaryOperator: ts.BinaryOperator + ): string | undefined { + const info = this.getInteropEqualityReplacementInfo(binaryOperator); + if (!info) { + return undefined; + } + + const tsLhsExpr = tsBinaryExpr.left; + const tsRhsExpr = tsBinaryExpr.right; + const callExpression = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(tsLhsExpr.getText()), + ts.factory.createIdentifier(info.functionName) + ), + undefined, + [ts.factory.createIdentifier(tsRhsExpr.getText())] + ); + + let text = this.printer.printNode(ts.EmitHint.Unspecified, callExpression, tsBinaryExpr.getSourceFile()); + if (info.isNegative) { + text = '!' + text; + } + return text; + } + + getInteropEqualityReplacementInfo( + binaryOperator: ts.BinaryOperator + ): { functionName: string; isNegative: boolean } | undefined { + void this; + switch (binaryOperator) { + case ts.SyntaxKind.EqualsEqualsToken: + return { functionName: ARE_EQUAL, isNegative: false }; + case ts.SyntaxKind.ExclamationEqualsToken: + return { functionName: ARE_EQUAL, isNegative: true }; + case ts.SyntaxKind.EqualsEqualsEqualsToken: + return { functionName: ARE_STRICTLY_EQUAL, isNegative: false }; + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + return { functionName: ARE_STRICTLY_EQUAL, isNegative: true }; + default: + return undefined; + } + } + + fixArrayIndexExprType(argExpr: ts.Expression): Autofix[] | undefined { + void this; + if (ts.isAsExpression(argExpr)) { + const innerExpr = argExpr.expression; + return [ + { + start: argExpr.getStart(), + end: argExpr.getEnd(), + replacementText: `${innerExpr ? innerExpr.getText() : ''} as int` + } + ]; + } + + if (ts.isBinaryExpression(argExpr)) { + return [{ start: argExpr.getStart(), end: argExpr.getEnd(), replacementText: `(${argExpr.getText()}) as int` }]; + } + + return [{ start: argExpr.getStart(), end: argExpr.getEnd(), replacementText: `${argExpr.getText()} as int` }]; + } + + fixNoTsLikeFunctionCall(identifier: ts.Node): Autofix[] { + void this; + const funcName = identifier.getText(); + const replacementText = `${funcName}.unSafeCall`; + return [ + { + replacementText, + start: identifier.getStart(), + end: identifier.getEnd() + } + ]; + } + + private static createBuiltInTypeInitializer(type: ts.TypeReferenceNode): ts.Expression | undefined { + const typeName = type.typeName.getText(); + + switch (typeName) { + case 'Date': + return ts.factory.createNewExpression(ts.factory.createIdentifier('Date'), undefined, []); + case 'Map': + case 'Set': + return ts.factory.createNewExpression(ts.factory.createIdentifier(typeName), type.typeArguments, []); + case 'Promise': + return ts.factory.createIdentifier('undefined'); + default: + return this.isNullableType(type) ? ts.factory.createIdentifier('undefined') : undefined; + } + } + + private static isNullableType(type: ts.TypeNode): boolean { + if (type.kind === ts.SyntaxKind.UndefinedKeyword) { + return true; + } + + if (ts.isUnionTypeNode(type)) { + return type.types.some((t) => { + return t.kind === ts.SyntaxKind.UndefinedKeyword; + }); + } + + return false; + } + + private static createExactObjectInitializer(type: ts.TypeLiteralNode): ts.ObjectLiteralExpression { + const properties = type.members. + filter((member): member is ts.PropertySignature => { + return ts.isPropertySignature(member); + }). + map((member) => { + const initializer = Autofixer.createInitializerForPropertySignature(member); + if (initializer) { + return ts.factory.createPropertyAssignment(member.name, initializer); + } + return null; }). - join('\n'); - return '{\n' + innerText + '\n}'; + filter((property): property is ts.PropertyAssignment => { + return property !== null; + }); + + return ts.factory.createObjectLiteralExpression(properties, true); } - fixDataObservation(classDecl: ts.ClassDeclaration | undefined): Autofix[] | undefined { - if (!classDecl) { + private static createInitializerForPropertySignature(member: ts.PropertySignature): ts.Expression | undefined { + return member.type ? Autofixer.createTypeBasedInitializer(member.type) : undefined; + } + + private static createTypeBasedInitializer(type?: ts.TypeNode): ts.Expression | undefined { + if (!type) { return undefined; } - const observedDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Observed)); - const sourceFile = classDecl.getSourceFile(); - const text = this.printer.printNode(ts.EmitHint.Unspecified, observedDecorator, sourceFile) + '\n'; - return [{ start: classDecl.getStart(), end: classDecl.getStart(), replacementText: text }]; + switch (type.kind) { + case ts.SyntaxKind.StringKeyword: + return ts.factory.createStringLiteral(''); + case ts.SyntaxKind.TypeLiteral: + return Autofixer.createExactObjectInitializer(type as ts.TypeLiteralNode); + case ts.SyntaxKind.ArrayType: + return ts.factory.createArrayLiteralExpression([], false); + case ts.SyntaxKind.TypeReference: + return Autofixer.createBuiltInTypeInitializer(type as ts.TypeReferenceNode); + default: + return this.isNullableType(type) ? ts.factory.createIdentifier('undefined') : undefined; + } + } + + private static isUserDefinedClass(type: ts.TypeReferenceNode): boolean { + const builtInTypes = new Set(['Date', 'Array', 'Map', 'Set', 'Promise', 'RegExp', 'Function']); + return !builtInTypes.has(type.typeName.getText()); + } + + fixGenericCallNoTypeArgs(node: ts.NewExpression): Autofix[] | undefined { + const typeNode = this.getTypeNodeForNewExpression(node); + if (!typeNode || !ts.isTypeReferenceNode(typeNode) || typeNode.typeName.getText() !== node.expression.getText()) { + return undefined; + } + + const reference: ts.TypeReferenceNode[] = []; + typeNode.typeArguments?.forEach((arg) => { + return reference.push(ts.factory.createTypeReferenceNode(arg.getText())); + }); + const srcFile = node.getSourceFile(); + const identifier = node.expression; + const args = node.arguments; + const newExpression = ts.factory.createNewExpression(identifier, reference, args); + const text = this.printer.printNode(ts.EmitHint.Unspecified, newExpression, srcFile); + return [{ start: node.getStart(), end: node.getEnd(), replacementText: text }]; + } + + private getTypeNodeForNewExpression(node: ts.NewExpression): ts.TypeNode | undefined { + if (ts.isVariableDeclaration(node.parent) || ts.isPropertyDeclaration(node.parent)) { + return node.parent.type; + } else if (ts.isBinaryExpression(node.parent)) { + return this.utils.getDeclarationTypeNode(node.parent.left); + } else if (ts.isReturnStatement(node.parent) && ts.isBlock(node.parent.parent)) { + const funcNode = node.parent.parent.parent; + const isFunc = ts.isFunctionDeclaration(funcNode) || ts.isMethodDeclaration(funcNode); + if (!isFunc || !funcNode.type) { + return undefined; + } + + const isAsync = TsUtils.hasModifier(funcNode.modifiers, ts.SyntaxKind.AsyncKeyword); + if (isAsync) { + if (ts.isTypeReferenceNode(funcNode.type) && funcNode.type.typeName.getText() === 'Promise') { + return funcNode.type?.typeArguments?.[0]; + } + } + return funcNode.type; + } + return undefined; + } + + fixMissingAttribute(node: ts.PropertyAccessExpression): Autofix[] { + const exprName = node.expression.getText(); + const propertyAccessExpr = ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(exprName), + ts.factory.createIdentifier(METHOD_KEYS) + ); + const replacement = this.printer.printNode(ts.EmitHint.Unspecified, propertyAccessExpr, node.getSourceFile()); + return [{ start: node.getStart(), end: node.getEnd(), replacementText: replacement }]; + } + + fixBuilderDecorators(decorator: ts.Decorator): Autofix[] | undefined { + const newDecorator = ts.factory.createDecorator(ts.factory.createIdentifier('Builder')); + const text = this.printer.printNode(ts.EmitHint.Unspecified, newDecorator, decorator.getSourceFile()); + return [{ start: decorator.getStart(), end: decorator.getEnd(), replacementText: text }]; + } + + fixCustomLayout(node: ts.StructDeclaration): Autofix[] { + const startPos = Autofixer.getStartPositionWithoutDecorators(node); + const decorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Layoutable)); + + const text = this.getNewLine() + this.printer.printNode(ts.EmitHint.Unspecified, decorator, node.getSourceFile()); + return [{ start: startPos, end: startPos, replacementText: text }]; + } + + private static getStartPositionWithoutDecorators(node: ts.StructDeclaration): number { + const decorators = ts.getDecorators(node); + if (!decorators || decorators.length === 0) { + return node.getStart(); + } + + return decorators[decorators.length - 1].getEnd(); + } + + fixNumericLiteralIntToNumber(node: ts.NumericLiteral): Autofix[] | undefined { + void this; + return [{ start: node.getStart(), end: node.getEnd(), replacementText: `${node.getText()}.0` }]; } } diff --git a/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts b/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts index 3605f29a37696dfee033ceb54eea513aadb131cb..462d6d8b133f691bbc7767e37e33d303726b79ca 100644 --- a/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts +++ b/ets2panda/linter/src/lib/autofixes/QuasiEditor.ts @@ -14,94 +14,117 @@ */ import * as fs from 'node:fs'; -import { Logger } from '../Logger'; +import * as path from 'node:path'; import type * as ts from 'typescript'; +import { Logger } from '../Logger'; import type { ProblemInfo } from '../ProblemInfo'; import type { Autofix } from './Autofixer'; +import type { LinterOptions } from '../LinterOptions'; +import { AUTOFIX_HTML_TEMPLATE_TEXT, AutofixHtmlTemplate } from './AutofixReportHtmlHelper'; const BACKUP_AFFIX = '~'; -const EOL = '\n'; -export const MAX_AUTOFIX_PASSES = 10; +export const DEFAULT_MAX_AUTOFIX_PASSES = 10; export class QuasiEditor { - private textBuffer: string; - private readonly dataBuffer: Buffer; - private readonly srcFileName: string; - wasError: boolean = false; - constructor( - readonly sourceFile: ts.SourceFile, - readonly passNumber?: number, - readonly cancellationToken?: ts.CancellationToken - ) { - this.srcFileName = this.sourceFile.fileName; - - /* - * need to backup only once "this.backupSrcFile();" - * load text into buffer - */ - this.dataBuffer = fs.readFileSync(this.srcFileName); - this.textBuffer = this.dataBuffer.toString(); - if (!passNumber) { - passNumber = 1; - } + readonly srcFileName: string, + readonly sourceText: string, + readonly linterOpts: LinterOptions, + readonly cancellationToken?: ts.CancellationToken, + readonly reportPath?: string + ) {} + + private static getBackupFileName(filePath: string): string { + return filePath + BACKUP_AFFIX; } - backupSrcFile(): void { - fs.copyFileSync(this.srcFileName, this.srcFileName + BACKUP_AFFIX); + static backupSrcFile(filePath: string): void { + fs.copyFileSync(filePath, QuasiEditor.getBackupFileName(filePath)); } - backupSrcFileDebug(pass: number): void { - fs.copyFileSync(this.srcFileName, this.srcFileName + BACKUP_AFFIX + pass.toString()); + static hasAnyAutofixes(problemInfos: ProblemInfo[]): boolean { + return problemInfos.some((problemInfo) => { + return problemInfo.autofix !== undefined; + }); } - private saveText(): void { - fs.truncateSync(this.srcFileName); + private generateReport(acceptedPatches: Autofix[]): void { + const report = { + filePath: this.srcFileName, + fixCount: acceptedPatches.length, + fixes: acceptedPatches.map((fix) => { + return { + line: fix.line, + colum: fix.column, + endLine: fix.endLine, + endColum: fix.endColumn, + start: fix.start, + end: fix.end, + replacement: fix.replacementText, + original: this.sourceText.slice(fix.start, fix.end) + }; + }) + }; - const srcLines = this.textBuffer.split(EOL); - for (let i = 0; i < srcLines.length - 1; i++) { - fs.appendFileSync(this.srcFileName, srcLines[i] + EOL); + let reportFilePath = './autofix-report.html'; + if (this.reportPath !== undefined) { + reportFilePath = path.join(path.normalize(this.reportPath), 'autofix-report.html'); } - // check if last line is empty out of loop to optimize - if (srcLines[srcLines.length - 1] !== '') { - fs.appendFileSync(this.srcFileName, srcLines[srcLines.length - 1] + EOL); + const getOldJsonArray = (reportFilePath: string): Set => { + try { + const RegexCaptureBraketFirst = 1; + const rawData = fs.readFileSync(reportFilePath, 'utf-8'); + const rawContent = rawData.match(/`([\s\S]*?)`/)?.[RegexCaptureBraketFirst] ?? ''; + return new Set(JSON.parse(rawContent) || []); + } catch { + return new Set(); + } + }; + + try { + const existingReports = getOldJsonArray(reportFilePath); + existingReports.add(report); + const str = JSON.stringify([...existingReports], null, 2); + const HtmlContent = AutofixHtmlTemplate.replace(AUTOFIX_HTML_TEMPLATE_TEXT, str); + if (!fs.existsSync(path.dirname(reportFilePath))) { + fs.mkdirSync(path.dirname(reportFilePath), { recursive: true }); + } + fs.writeFileSync(reportFilePath, HtmlContent, { encoding: 'utf-8' }); + } catch (error) { + Logger.error(`Failed to update autofix report: ${(error as Error).message}`); } } - private static hasAnyAutofixes(problemInfos: ProblemInfo[]): boolean { - return problemInfos.some((problemInfo) => { - return problemInfo.autofix !== undefined; - }); - } + fix(problemInfos: ProblemInfo[]): string { + const acceptedPatches = QuasiEditor.sortAndRemoveIntersections(problemInfos); + const result = this.applyFixes(acceptedPatches); - fix(problemInfos: ProblemInfo[]): void { - if (!QuasiEditor.hasAnyAutofixes(problemInfos)) { - return; + if (this.linterOpts.migrationReport) { + this.generateReport(acceptedPatches); } - const acceptedPatches = QuasiEditor.sortAndRemoveIntersections(problemInfos); - this.textBuffer = this.applyFixes(acceptedPatches); - this.saveText(); + + return result; } private applyFixes(autofixes: Autofix[]): string { let output: string = ''; - let lastPos = Number.NEGATIVE_INFINITY; + let lastFixEnd = Number.NEGATIVE_INFINITY; const doFix = (fix: Autofix): void => { const { replacementText, start, end } = fix; - if (lastPos >= start || start > end) { + if (lastFixEnd > start || start > end) { Logger.error(`Failed to apply autofix in range [${start}, ${end}] at ${this.srcFileName}`); return; } - output += this.textBuffer.slice(Math.max(0, lastPos), Math.max(0, start)); + output += this.sourceText.slice(Math.max(0, lastFixEnd), Math.max(0, start)); output += replacementText; - lastPos = end; + lastFixEnd = end; }; autofixes.forEach(doFix); - output += this.textBuffer.slice(Math.max(0, lastPos)); + output += this.sourceText.slice(Math.max(0, lastFixEnd)); return output; } @@ -109,7 +132,7 @@ export class QuasiEditor { private static sortAndRemoveIntersections(problemInfos: ProblemInfo[]): Autofix[] { let acceptedPatches: Autofix[] = []; - problemInfos.forEach((problemInfo) => { + problemInfos.forEach((problemInfo): void => { if (!problemInfo.autofix) { return; } @@ -127,7 +150,7 @@ export class QuasiEditor { } private static sortAutofixes(autofixes: Autofix[]): Autofix[] { - return autofixes.sort((a, b) => { + return autofixes.sort((a, b): number => { return a.start - b.start; }); } diff --git a/ets2panda/linter/src/lib/autofixes/SymbolCache.ts b/ets2panda/linter/src/lib/autofixes/SymbolCache.ts index 9a16be4fd08fed29d4eea6c15aa2efbd4dff35b9..7724bce4481a64af3261e65ac7a1c65fc9b15d23 100644 --- a/ets2panda/linter/src/lib/autofixes/SymbolCache.ts +++ b/ets2panda/linter/src/lib/autofixes/SymbolCache.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -14,7 +14,7 @@ */ import * as ts from 'typescript'; -import { LinterConfig } from '../TypeScriptLinterConfig'; +import { TypeScriptLinterConfig } from '../TypeScriptLinterConfig'; import { forEachNodeInSubtree } from '../utils/functions/ForEachNodeInSubtree'; import { isStructDeclaration } from '../utils/functions/IsStruct'; import type { TsUtils } from '../utils/TsUtils'; @@ -39,7 +39,7 @@ export class SymbolCache { }; const stopCondition = (node: ts.Node): boolean => { - return !node || LinterConfig.terminalTokens.has(node.kind); + return !node || TypeScriptLinterConfig.terminalTokens.has(node.kind); }; forEachNodeInSubtree(sourceFile, callback, stopCondition); diff --git a/ets2panda/linter/src/lib/data/BuiltinList.json b/ets2panda/linter/src/lib/data/BuiltinList.json new file mode 100644 index 0000000000000000000000000000000000000000..3ba53f2cbb312d567c6bdc3b9c58df079844fb3e --- /dev/null +++ b/ets2panda/linter/src/lib/data/BuiltinList.json @@ -0,0 +1,4631 @@ +{ + "api_list": [ + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 107, + "problem": "BuiltinAll", + "api_name": "PropertyKey", + "api_type": "TypeAliasDeclaration", + "api_func_args": [], + "parent_api": [], + "code_kind": 268, + "api_property_type": "string | number | symbol" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 110, + "problem": "NoPropertyDescriptor", + "api_name": "configurable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 111, + "problem": "NoPropertyDescriptor", + "api_name": "enumerable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 112, + "problem": "NoPropertyDescriptor", + "api_name": "value", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "any" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 113, + "problem": "NoPropertyDescriptor", + "api_name": "writable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 114, + "problem": "NoPropertyDescriptor", + "api_name": "get", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "any", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 115, + "problem": "NoPropertyDescriptor", + "api_name": "set", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "v", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 133, + "problem": "BuiltinAll", + "api_name": "valueOf", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Object", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Object", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 174, + "problem": "MissingAttributes", + "api_name": "getOwnPropertyNames", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "ObjectConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "string[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 156, + "problem": "BuiltinAll", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ObjectConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 157, + "problem": "BuiltinAll", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ObjectConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 392, + "problem": "BuiltinAll", + "api_name": "length", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "IArguments", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 393, + "problem": "BuiltinAll", + "api_name": "callee", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "IArguments", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "Function" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 522, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "StringConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 539, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "BooleanConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 576, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "NumberConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 608, + "problem": "BuiltinAll", + "api_name": "raw", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "TemplateStringsArray", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "readonly string[]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 916, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "DateConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1005, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "RegExpConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1006, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "RegExpConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1060, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1071, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "EvalErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1082, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "RangeErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1093, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ReferenceErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1104, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "SyntaxErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1115, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "TypeErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1126, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "URIErrorConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1139, + "problem": "BuiltinAll", + "api_name": "parse", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "text", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "reviver", + "type": "(this: any, key: string, value: any) => any", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "JSON", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "any", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1188, + "problem": "BuiltinAll", + "api_name": "concat", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "items", + "type": "(T | ConcatArray)[]", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1220, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => value is S", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1229, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1238, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1244, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, index: number, array: readonly T[]) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1250, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, index: number, array: readonly T[]) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "U[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1256, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => value is S", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "S[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1262, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: readonly T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1304, + "problem": "BuiltinAll", + "api_name": "length", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "number" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1334, + "problem": "BuiltinAll", + "api_name": "concat", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "items", + "type": "(T | ConcatArray)[]", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1411, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: T[]) => value is S", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1420, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1429, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1435, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, index: number, array: T[]) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1441, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, index: number, array: T[]) => U", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "U[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1453, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: T, index: number, array: T[]) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T[]", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1490, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "ArrayConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1498, + "problem": "NoPropertyDescriptor", + "api_name": "enumerable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1499, + "problem": "NoPropertyDescriptor", + "api_name": "configurable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1500, + "problem": "NoPropertyDescriptor", + "api_name": "writable", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "boolean" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1501, + "problem": "NoPropertyDescriptor", + "api_name": "value", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1502, + "problem": "NoPropertyDescriptor", + "api_name": "get", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "() => T" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1503, + "problem": "NoPropertyDescriptor", + "api_name": "set", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "TypedPropertyDescriptor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "(value: T) => void" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1506, + "problem": "BuiltinAll", + "api_name": "ClassDecorator", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "TFunction", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "TFunction | void", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1507, + "problem": "BuiltinAll", + "api_name": "PropertyDecorator", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "Object", + "is_optional": false + }, + { + "name": "propertyKey", + "type": "string | symbol", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "void", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1508, + "problem": "NoPropertyDescriptor", + "api_name": "MethodDecorator", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "Object", + "is_optional": false + }, + { + "name": "propertyKey", + "type": "string | symbol", + "is_optional": false + }, + { + "name": "descriptor", + "type": "TypedPropertyDescriptor", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "TypedPropertyDescriptor | void", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1509, + "problem": "BuiltinAll", + "api_name": "ParameterDecorator", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "target", + "type": "Object", + "is_optional": false + }, + { + "name": "propertyKey", + "type": "string | symbol", + "is_optional": false + }, + { + "name": "parameterIndex", + "type": "number", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "void", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1681, + "problem": "BuiltinAll", + "api_name": "ArrayBuffer", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ArrayBufferTypes", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ArrayBuffer" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1887, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int8Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1906, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int8Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1917, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int8Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1928, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int8Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1937, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int8Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 1975, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int8Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2054, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int8Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2169, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2188, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2199, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint8Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2210, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint8Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2219, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint8Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2257, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint8Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2336, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2451, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8ClampedArray) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2470, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8ClampedArray) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8ClampedArray", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2481, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint8ClampedArray) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2492, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint8ClampedArray) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2501, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint8ClampedArray) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2539, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint8ClampedArray) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint8ClampedArray", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2618, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint8ClampedArray) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2732, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int16Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2751, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int16Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2762, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int16Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2773, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int16Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2782, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int16Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2819, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int16Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 2898, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int16Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3014, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint16Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3033, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint16Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3044, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint16Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3055, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint16Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3064, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint16Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3102, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint16Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint16Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3181, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint16Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3296, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3315, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int32Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3326, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3337, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Int32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3346, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int32Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3384, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Int32Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Int32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3463, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Int32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3578, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3597, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint32Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3608, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3619, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Uint32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3628, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint32Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3665, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Uint32Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Uint32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3744, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Uint32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3859, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3878, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float32Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3889, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Float32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3900, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Float32Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3909, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Float32Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 3947, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Float32Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float32Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4026, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float32Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4142, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float64Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4161, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float64Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4172, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Float64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4183, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, obj: Float64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4192, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Float64Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4230, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: number, index: number, array: Float64Array) => number", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Float64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4309, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: number, index: number, array: Float64Array) => unknown", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4439, + "problem": "BuiltinAll", + "api_name": "prototype", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "NumberFormat" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es5.d.ts", + "api_info": { + "line": 4483, + "problem": "BuiltinAll", + "api_name": "prototype", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "Intl", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "DateTimeFormat" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 46, + "problem": "BuiltinAll", + "api_name": "return", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "value", + "type": "TReturn", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Iterator", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IteratorResult", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 47, + "problem": "BuiltinAll", + "api_name": "throw", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "e", + "type": "any", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Iterator", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IteratorResult", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 51, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Iterable", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Iterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 55, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "IterableIterator", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 60, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 96, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "ReadonlyArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 116, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "IArguments", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 121, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Map", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 141, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "ReadonlyMap", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator<[K, V]>", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 172, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Set", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 190, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "ReadonlySet", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 240, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "String", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 244, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Int8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 272, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Uint8Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 300, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Uint8ClampedArray", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 331, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Int16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 361, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Uint16Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 389, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Int32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 417, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Uint32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 445, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Float32Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.iterable.d.ts", + "api_info": { + "line": 473, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "Float64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 126, + "problem": "BuiltinNoCtorFunc", + "api_type": "CallSignature", + "parent_api": [ + { + "api_name": "BigIntConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 179 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 186, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 205, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "BigInt64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 216, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "bigint | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 227, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 236, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: bigint, index: number, array: BigInt64Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 282, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: bigint, index: number, array: BigInt64Array) => bigint", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "BigInt64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 357, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigInt64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 385, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "BigInt64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 458, + "problem": "ThisArg", + "api_name": "every", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 477, + "problem": "ThisArg", + "api_name": "filter", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => any", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "BigUint64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 488, + "problem": "ThisArg", + "api_name": "find", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "bigint | undefined", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 499, + "problem": "ThisArg", + "api_name": "findIndex", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 508, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: bigint, index: number, array: BigUint64Array) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 554, + "problem": "ThisArg", + "api_name": "map", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: bigint, index: number, array: BigUint64Array) => bigint", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "BigUint64Array", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 629, + "problem": "ThisArg", + "api_name": "some", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "predicate", + "type": "(value: bigint, index: number, array: BigUint64Array) => boolean", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2020.bigint.d.ts", + "api_info": { + "line": 657, + "problem": "SymbolIterator", + "api_name": "[Symbol.iterator]", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "BigUint64Array", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "IterableIterator", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 31, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: V, key: K, map: Map) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Map", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 59, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: V, key: K, map: ReadonlyMap) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlyMap", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 107, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, value2: T, set: Set) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "Set", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "lib.es2015.collection.d.ts", + "api_info": { + "line": 125, + "problem": "ThisArg", + "api_name": "forEach", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "callbackfn", + "type": "(value: T, value2: T, set: ReadonlySet) => void", + "is_optional": false, + "has_default": false + }, + { + "name": "thisArg", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ReadonlySet", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/src/lib/data/SdkWhitelist.json b/ets2panda/linter/src/lib/data/SdkWhitelist.json new file mode 100644 index 0000000000000000000000000000000000000000..b0c83d569625a4b150d31bd4a3f1b2fd4fbab1f0 --- /dev/null +++ b/ets2panda/linter/src/lib/data/SdkWhitelist.json @@ -0,0 +1,8466 @@ +{ + "api_list": [ + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 84, + "problem": "LimitedVoidType", + "api_name": "write", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "buffer", + "type": "ArrayBuffer", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "WriteFile", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 173 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 116, + "problem": "LimitedVoidType", + "api_name": "write", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "buffer", + "type": "ArrayBuffer", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "WriteStream", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 173 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 132, + "problem": "LimitedVoidType", + "api_name": "writeSync", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "buffer", + "type": "ArrayBuffer", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SyncWriteStream", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number | void", + "code_kind": 173 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 229, + "problem": "LimitedVoidType", + "api_name": "IncomingDataCallback", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "incomingData", + "type": "ArrayBuffer", + "is_optional": false + } + ], + "parent_api": [ + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 268 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 351, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NetworkOutputQueueConstructor", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "INetworkOutputQueue", + "code_kind": 180 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 359, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "maxSize", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NetworkOutputQueueConstructor", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "INetworkOutputQueue", + "code_kind": 180 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 368, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "maxSize", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "pausePolicyOverride", + "type": "ReceivingPausePolicy", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NetworkOutputQueueConstructor", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "INetworkOutputQueue", + "code_kind": 180 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 386, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NetworkInputQueueConstructor", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "INetworkInputQueue", + "code_kind": 180 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 394, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "maxSize", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NetworkInputQueueConstructor", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "INetworkInputQueue", + "code_kind": 180 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 404, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "maxSize", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "pausePolicyOverride", + "type": "SendingPausePolicy", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NetworkInputQueueConstructor", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "INetworkInputQueue", + "code_kind": 180 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 536, + "problem": "LiteralAsPropertyName", + "api_name": "'authorization'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 536, + "problem": "LiteralAsPropertyName", + "api_name": "'authorization'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 537, + "problem": "LiteralAsPropertyName", + "api_name": "'accept'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType | ContentType[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 537, + "problem": "LiteralAsPropertyName", + "api_name": "'accept'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType | ContentType[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 538, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-charset'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 538, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-charset'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 539, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-encoding'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentCoding | ContentCoding[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 539, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-encoding'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentCoding | ContentCoding[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 540, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-language'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 540, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-language'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 541, + "problem": "LiteralAsPropertyName", + "api_name": "'cache-control'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 541, + "problem": "LiteralAsPropertyName", + "api_name": "'cache-control'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 542, + "problem": "LiteralAsPropertyName", + "api_name": "'cookie'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 542, + "problem": "LiteralAsPropertyName", + "api_name": "'cookie'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 543, + "problem": "LiteralAsPropertyName", + "api_name": "'range'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 543, + "problem": "LiteralAsPropertyName", + "api_name": "'range'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 544, + "problem": "LiteralAsPropertyName", + "api_name": "'upgrade'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 544, + "problem": "LiteralAsPropertyName", + "api_name": "'upgrade'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 545, + "problem": "LiteralAsPropertyName", + "api_name": "'user-agent'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 545, + "problem": "LiteralAsPropertyName", + "api_name": "'user-agent'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 546, + "problem": "LiteralAsPropertyName", + "api_name": "'content-type'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 546, + "problem": "LiteralAsPropertyName", + "api_name": "'content-type'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "RequestHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 556, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-ranges'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "'none' | 'bytes' | (string & NonNullable)" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 556, + "problem": "LiteralAsPropertyName", + "api_name": "'accept-ranges'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "'none' | 'bytes' | (string & NonNullable)" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 557, + "problem": "LiteralAsPropertyName", + "api_name": "'allow'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "HttpMethod | HttpMethod[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 557, + "problem": "LiteralAsPropertyName", + "api_name": "'allow'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "HttpMethod | HttpMethod[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 558, + "problem": "LiteralAsPropertyName", + "api_name": "'cache-control'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 558, + "problem": "LiteralAsPropertyName", + "api_name": "'cache-control'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 559, + "problem": "LiteralAsPropertyName", + "api_name": "'content-encoding'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentCoding" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 559, + "problem": "LiteralAsPropertyName", + "api_name": "'content-encoding'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentCoding" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 560, + "problem": "LiteralAsPropertyName", + "api_name": "'content-range'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 560, + "problem": "LiteralAsPropertyName", + "api_name": "'content-range'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 561, + "problem": "LiteralAsPropertyName", + "api_name": "'content-type'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 561, + "problem": "LiteralAsPropertyName", + "api_name": "'content-type'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ContentType" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 562, + "problem": "LiteralAsPropertyName", + "api_name": "'date'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 562, + "problem": "LiteralAsPropertyName", + "api_name": "'date'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 563, + "problem": "LiteralAsPropertyName", + "api_name": "'etag'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 563, + "problem": "LiteralAsPropertyName", + "api_name": "'etag'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 564, + "problem": "LiteralAsPropertyName", + "api_name": "'expires'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 564, + "problem": "LiteralAsPropertyName", + "api_name": "'expires'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 565, + "problem": "LiteralAsPropertyName", + "api_name": "'location'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 565, + "problem": "LiteralAsPropertyName", + "api_name": "'location'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 566, + "problem": "LiteralAsPropertyName", + "api_name": "'retry-after'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 566, + "problem": "LiteralAsPropertyName", + "api_name": "'retry-after'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 567, + "problem": "LiteralAsPropertyName", + "api_name": "'set-cookie'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 567, + "problem": "LiteralAsPropertyName", + "api_name": "'set-cookie'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 568, + "problem": "LiteralAsPropertyName", + "api_name": "'server'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 568, + "problem": "LiteralAsPropertyName", + "api_name": "'server'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 569, + "problem": "LiteralAsPropertyName", + "api_name": "'www-authenticate'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 569, + "problem": "LiteralAsPropertyName", + "api_name": "'www-authenticate'", + "api_type": "PropertySignature", + "api_optional": true, + "parent_api": [ + { + "api_name": "ResponseHeaders", + "api_type": "TypeAliasDeclaration" + }, + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "string | string[]" + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.collaboration.rcp.d.ts", + "api_info": { + "line": 1355, + "problem": "LimitedVoidType", + "api_name": "OnDataReceive", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "incomingData", + "type": "ArrayBuffer", + "is_optional": false + } + ], + "parent_api": [ + { + "api_name": "rcp", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "number | void | Promise", + "code_kind": 268 + }, + "import_path": [ + "@hms.collaboration.rcp", + "@kit.RemoteCommunicationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.core.deviceCloudGateway.cloudDatabase.d.ts", + "api_info": { + "line": 285, + "problem": "ConstructorFuncs", + "api_name": "DatabaseQuery", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "entityClass", + "type": "new () => T", + "is_optional": false + } + ], + "parent_api": [ + { + "api_name": "cloudDatabase", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "DatabaseQuery", + "code_kind": 264 + }, + "import_path": [ + "@hms.core.deviceCloudGateway.cloudDatabase", + "@kit.CloudFoundationKit" + ], + "is_global": false + }, + { + "file_path": "api/@hms.core.map.mapCommon.d.ts", + "api_info": { + "line": 1877, + "problem": "OptionalMethod", + "api_name": "getCustomIcon", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "clusterItems", + "type": "Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ClusterOverlayParams", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "mapCommon", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 173 + }, + "import_path": [ + "@hms.core.map.mapCommon", + "@kit.MapKit" + ], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 54, + "problem": "OptionalMethod", + "api_name": "onCreate", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "FormBindingData", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 63, + "problem": "OptionalMethod", + "api_name": "onCastToNormal", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "formId", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 72, + "problem": "OptionalMethod", + "api_name": "onUpdate", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "formId", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 104, + "problem": "OptionalMethod", + "api_name": "onVisibilityChange", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "newStatus", + "type": "Record", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 117, + "problem": "OptionalMethod", + "api_name": "onEvent", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "formId", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "message", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 127, + "problem": "OptionalMethod", + "api_name": "onDestroy", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "formId", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 141, + "problem": "OptionalMethod", + "api_name": "onAcquireFormState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleForm", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "FormState", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 159, + "problem": "OptionalMethod", + "api_name": "onShow", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 167, + "problem": "OptionalMethod", + "api_name": "onHide", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 175, + "problem": "OptionalMethod", + "api_name": "onDestroy", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 183, + "problem": "OptionalMethod", + "api_name": "onCreate", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 192, + "problem": "OptionalMethod", + "api_name": "onStartContinuation", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 204, + "problem": "OptionalMethod", + "api_name": "onSaveData", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "data", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 216, + "problem": "OptionalMethod", + "api_name": "onCompleteContinuation", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "result", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 227, + "problem": "OptionalMethod", + "api_name": "onRestoreData", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "data", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 236, + "problem": "OptionalMethod", + "api_name": "onRemoteTerminated", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 248, + "problem": "OptionalMethod", + "api_name": "onSaveAbilityState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "outState", + "type": "PacMap", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 260, + "problem": "OptionalMethod", + "api_name": "onRestoreAbilityState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "inState", + "type": "PacMap", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 269, + "problem": "OptionalMethod", + "api_name": "onInactive", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 277, + "problem": "OptionalMethod", + "api_name": "onActive", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 286, + "problem": "OptionalMethod", + "api_name": "onNewWant", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 296, + "problem": "OptionalMethod", + "api_name": "onMemoryLevel", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "level", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleApp", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 315, + "problem": "OptionalMethod", + "api_name": "onStart", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 327, + "problem": "OptionalMethod", + "api_name": "onCommand", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + }, + { + "name": "startId", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 335, + "problem": "OptionalMethod", + "api_name": "onStop", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 345, + "problem": "OptionalMethod", + "api_name": "onConnect", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "RemoteObject", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 354, + "problem": "OptionalMethod", + "api_name": "onDisconnect", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 366, + "problem": "OptionalMethod", + "api_name": "onReconnect", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleService", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 390, + "problem": "OptionalMethod", + "api_name": "update", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "valueBucket", + "type": "rdb.ValuesBucket", + "is_optional": false, + "has_default": false + }, + { + "name": "predicates", + "type": "dataAbility.DataAbilityPredicates", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 405, + "problem": "OptionalMethod", + "api_name": "query", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "columns", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "predicates", + "type": "dataAbility.DataAbilityPredicates", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 418, + "problem": "OptionalMethod", + "api_name": "delete", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "predicates", + "type": "dataAbility.DataAbilityPredicates", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 431, + "problem": "OptionalMethod", + "api_name": "normalizeUri", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 443, + "problem": "OptionalMethod", + "api_name": "batchInsert", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "valueBuckets", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 455, + "problem": "OptionalMethod", + "api_name": "denormalizeUri", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 467, + "problem": "OptionalMethod", + "api_name": "insert", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "valueBucket", + "type": "rdb.ValuesBucket", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 483, + "problem": "OptionalMethod", + "api_name": "openFile", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "mode", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 499, + "problem": "OptionalMethod", + "api_name": "getFileTypes", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "mimeTypeFilter", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback>", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 508, + "problem": "OptionalMethod", + "api_name": "onInitialized", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "info", + "type": "AbilityInfo", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 521, + "problem": "OptionalMethod", + "api_name": "getType", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "uri", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 534, + "problem": "OptionalMethod", + "api_name": "executeBatch", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "ops", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback>", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@internal/full/lifecycle.d.ts", + "api_info": { + "line": 547, + "problem": "OptionalMethod", + "api_name": "call", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "method", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "arg", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "extras", + "type": "PacMap", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LifecycleData", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 83, + "problem": "OptionalMethod", + "api_name": "onAbilityWillCreate", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 125, + "problem": "OptionalMethod", + "api_name": "onWindowStageWillCreate", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + }, + { + "name": "windowStage", + "type": "window.WindowStage", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 135, + "problem": "OptionalMethod", + "api_name": "onWillNewWant", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 145, + "problem": "OptionalMethod", + "api_name": "onNewWant", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 227, + "problem": "OptionalMethod", + "api_name": "onWindowStageWillDestroy", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + }, + { + "name": "windowStage", + "type": "window.WindowStage", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 265, + "problem": "OptionalMethod", + "api_name": "onAbilityWillDestroy", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 303, + "problem": "OptionalMethod", + "api_name": "onAbilityWillForeground", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 341, + "problem": "OptionalMethod", + "api_name": "onAbilityWillBackground", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 369, + "problem": "OptionalMethod", + "api_name": "onAbilityWillContinue", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 380, + "problem": "OptionalMethod", + "api_name": "onWindowStageWillRestore", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + }, + { + "name": "windowStage", + "type": "window.WindowStage", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 391, + "problem": "OptionalMethod", + "api_name": "onWindowStageRestore", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + }, + { + "name": "windowStage", + "type": "window.WindowStage", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 401, + "problem": "OptionalMethod", + "api_name": "onAbilityWillSaveState", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.AbilityLifecycleCallback.d.ts", + "api_info": { + "line": 411, + "problem": "OptionalMethod", + "api_name": "onAbilitySaveState", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "ability", + "type": "UIAbility", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityLifecycleCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.AbilityLifecycleCallback", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.DriverExtensionAbility.d.ts", + "api_info": { + "line": 78, + "problem": "LimitedVoidType", + "api_name": "onDisconnect", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DriverExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.DriverExtensionAbility", + "@kit.DriverDevelopmentKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.PhotoEditorExtensionAbility.d.ts", + "api_info": { + "line": 73, + "problem": "LimitedVoidType", + "api_name": "onDestroy", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "PhotoEditorExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.PhotoEditorExtensionAbility", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.UIAbility.d.ts", + "api_info": { + "line": 472, + "problem": "LimitedVoidType", + "api_name": "onDestroy", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "UIAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.UIAbility", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.ability.UIExtensionAbility.d.ts", + "api_info": { + "line": 101, + "problem": "LimitedVoidType", + "api_name": "onDestroy", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "UIExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.UIExtensionAbility", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.appstartup.StartupConfigEntry.d.ts", + "api_info": { + "line": 36, + "problem": "OptionalMethod", + "api_name": "onConfig", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "StartupConfigEntry", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "StartupConfig", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.appstartup.StartupConfigEntry", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.appstartup.StartupListener.d.ts", + "api_info": { + "line": 36, + "problem": "OptionalMethod", + "api_name": "onCompleted", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "error", + "type": "BusinessError", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StartupListener", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.appstartup.StartupListener", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.appstartup.StartupTask.d.ets", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "onDependencyCompleted", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "dependency", + "type": "string", + "is_optional": false, + "has_default": false + }, + { + "name": "result", + "type": "Object", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StartupTask", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.appstartup.StartupTask", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.appstartup.StartupTask.d.ets", + "api_info": { + "line": 49, + "problem": "LimitedVoidType", + "api_name": "init", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "context", + "type": "AbilityStageContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StartupTask", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.appstartup.StartupTask", + "@kit.AbilityKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.form.FormExtensionAbility.d.ts", + "api_info": { + "line": 253, + "problem": "OptionalMethod", + "api_name": "onAcquireFormState", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "want", + "type": "Want", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "FormExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "FormState", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.form.FormExtensionAbility", + "@kit.FormKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.app.form.FormExtensionAbility.d.ts", + "api_info": { + "line": 262, + "problem": "OptionalMethod", + "api_name": "onStop", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "FormExtensionAbility", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.form.FormExtensionAbility", + "@kit.FormKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.Prefetcher.d.ts", + "api_info": { + "line": 41, + "problem": "LimitedVoidType", + "api_name": "prefetch", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "IDataSourcePrefetching", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 173 + }, + "import_path": [ + "@ohos.arkui.Prefetcher", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.Prefetcher.d.ts", + "api_info": { + "line": 53, + "problem": "OptionalMethod", + "api_name": "cancel", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "IDataSourcePrefetching", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 173 + }, + "import_path": [ + "@ohos.arkui.Prefetcher", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.Prefetcher.d.ts", + "api_info": { + "line": 53, + "problem": "LimitedVoidType", + "api_name": "cancel", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "IDataSourcePrefetching", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void | Promise", + "code_kind": 173 + }, + "import_path": [ + "@ohos.arkui.Prefetcher", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.StateManagement.d.ts", + "api_info": { + "line": 47, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "args", + "type": "any", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TypeConstructorWithArgs", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T", + "code_kind": 180 + }, + "import_path": [ + "@ohos.arkui.StateManagement", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.arkui.StateManagement.d.ts", + "api_info": { + "line": 156, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [], + "parent_api": [ + { + "api_name": "TypeConstructor", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "T", + "code_kind": 180 + }, + "import_path": [ + "@ohos.arkui.StateManagement", + "@kit.ArkUI" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.multimedia.audio.d.ts", + "api_info": { + "line": 5120, + "problem": "LimitedVoidType", + "api_name": "AudioRendererWriteDataCallback", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "data", + "type": "ArrayBuffer", + "is_optional": false + } + ], + "parent_api": [ + { + "api_name": "audio", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "AudioDataCallbackResult | void", + "code_kind": 268 + }, + "import_path": [ + "@ohos.multimedia.audio", + "@kit.AudioKit" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.web.webview.d.ts", + "api_info": { + "line": 6490, + "problem": "OptionalMethod", + "api_name": "resumePlayer", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NativeMediaPlayerBridge", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "webview", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [ + "@ohos.web.webview", + "@kit.ArkWeb" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.web.webview.d.ts", + "api_info": { + "line": 6500, + "problem": "OptionalMethod", + "api_name": "suspendPlayer", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "type", + "type": "SuspendType", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NativeMediaPlayerBridge", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "webview", + "api_type": "ModuleDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [ + "@ohos.web.webview", + "@kit.ArkWeb" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 492, + "problem": "LimitedVoidType", + "api_name": "EventListener", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 561, + "problem": "LimitedVoidType", + "api_name": "WorkerEventListener", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 869, + "problem": "TypeQuery", + "api_name": "self", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DedicatedWorkerGlobalScope", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "WorkerGlobalScope", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "WorkerGlobalScope & typeof globalThis" + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 869, + "problem": "GlobalThisError", + "api_name": "self", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "DedicatedWorkerGlobalScope", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "WorkerGlobalScope", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "WorkerGlobalScope & typeof globalThis" + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 970, + "problem": "TypeQuery", + "api_name": "self", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ThreadWorkerGlobalScope", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "GlobalScope", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "GlobalScope & typeof globalThis" + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/@ohos.worker.d.ts", + "api_info": { + "line": 970, + "problem": "GlobalThisError", + "api_name": "self", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ThreadWorkerGlobalScope", + "api_type": "InterfaceDeclaration" + }, + { + "api_name": "GlobalScope", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "GlobalScope & typeof globalThis" + }, + "import_path": [ + "@ohos.worker", + "@kit.ArkTS" + ], + "is_global": false + }, + { + "file_path": "api/app/context.d.ts", + "api_info": { + "line": 39, + "problem": "InterfaceExtendsClass", + "api_name": "Context", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": false + }, + { + "file_path": "api/application/AbilityStartCallback.d.ts", + "api_info": { + "line": 49, + "problem": "OptionalMethod", + "api_name": "onResult", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "parameter", + "type": "AbilityResult", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AbilityStartCallback", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.common" + ], + "is_global": false + }, + { + "file_path": "api/application/AccessibilityExtensionContext.d.ts", + "api_info": { + "line": 275, + "problem": "IndexedAccessType", + "api_name": "attributeValue", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "attributeName", + "type": "T", + "is_optional": false, + "has_default": false + }, + { + "name": "callback", + "type": "AsyncCallback", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AccessibilityElement", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [ + "@ohos.application.AccessibilityExtensionAbility", + "@kit.AccessibilityKit" + ], + "is_global": false + }, + { + "file_path": "api/application/AccessibilityExtensionContext.d.ts", + "api_info": { + "line": 290, + "problem": "IndexedAccessType", + "api_name": "attributeValue", + "api_type": "MethodSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "attributeName", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AccessibilityElement", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "Promise", + "code_kind": 173 + }, + "import_path": [ + "@ohos.application.AccessibilityExtensionAbility", + "@kit.AccessibilityKit" + ], + "is_global": false + }, + { + "file_path": "api/application/ErrorObserver.d.ts", + "api_info": { + "line": 64, + "problem": "OptionalMethod", + "api_name": "onException", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "errObject", + "type": "Error", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ErrorObserver", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.app.ability.errorManager" + ], + "is_global": false + }, + { + "file_path": "api/application/LoopObserver.d.ts", + "api_info": { + "line": 36, + "problem": "OptionalMethod", + "api_name": "onLoopTimeOut", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "timeout", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LoopObserver", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [ + "@ohos.app.ability.errorManager" + ], + "is_global": false + }, + { + "file_path": "api/arkui/AlphabetIndexerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "AlphabetIndexerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AlphabetIndexerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/AttributeUpdater.d.ts", + "api_info": { + "line": 49, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeUpdater", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/BlankModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "BlankAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BlankModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ButtonModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ButtonAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ButtonModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CalendarPickerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CalendarPickerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CalendarPickerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CheckboxGroupModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CheckboxGroupAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CheckboxGroupModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CheckboxModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CheckboxAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CheckboxModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ColumnModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ColumnAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ColumnModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ColumnSplitModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ColumnSplitAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ColumnSplitModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CommonModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CommonAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CommonModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ContainerSpanModifier.d.ts", + "api_info": { + "line": 39, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "containerSpanAttribute", + "type": "ContainerSpanAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ContainerSpanModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/CounterModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "CounterAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CounterModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/DataPanelModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "DataPanelAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DataPanelModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/DatePickerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "DatePickerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DatePickerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/DividerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "DividerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DividerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 545, + "problem": "OptionalMethod", + "api_name": "onDraw", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "context", + "type": "DrawContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "FrameNode", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 722, + "problem": "InterfaceExtendsClass", + "api_name": "TypedFrameNode", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1606, + "problem": "OptionalMethod", + "api_name": "onAttachToNode", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "target", + "type": "FrameNode", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1615, + "problem": "OptionalMethod", + "api_name": "onDetachFromNode", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1626, + "problem": "OptionalMethod", + "api_name": "onGetChildId", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "number", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1637, + "problem": "OptionalMethod", + "api_name": "onCreateChild", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "index", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "FrameNode", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1648, + "problem": "OptionalMethod", + "api_name": "onDisposeChild", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "id", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "node", + "type": "FrameNode", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/FrameNode.d.ts", + "api_info": { + "line": 1659, + "problem": "OptionalMethod", + "api_name": "onUpdateChild", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "id", + "type": "number", + "is_optional": false, + "has_default": false + }, + { + "name": "node", + "type": "FrameNode", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeAdapter", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GaugeModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GaugeAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GaugeModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GridColModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GridColAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridColModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GridItemModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GridItemAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridItemModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GridModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GridAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/GridRowModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "GridRowAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridRowModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/HyperlinkModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "HyperlinkAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "HyperlinkModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ImageAnimatorModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ImageAnimatorAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ImageAnimatorModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ImageModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ImageAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ImageModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ImageSpanModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ImageSpanAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ImageSpanModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/LineModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "LineAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LineModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ListItemGroupModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ListItemGroupAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ListItemGroupModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ListItemModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ListItemAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ListItemModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ListModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ListAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ListModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/LoadingProgressModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "LoadingProgressAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LoadingProgressModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/MarqueeModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "MarqueeAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "MarqueeModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/MenuItemModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "MenuItemAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "MenuItemModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/MenuModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "MenuAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "MenuModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NavDestinationModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "NavDestinationAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavDestinationModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NavigationModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "NavigationAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavigationModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NavigatorModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "NavigatorAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavigatorModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NavRouterModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "NavRouterAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavRouterModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NodeController.d.ts", + "api_info": { + "line": 81, + "problem": "OptionalMethod", + "api_name": "aboutToResize", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "size", + "type": "Size", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeController", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NodeController.d.ts", + "api_info": { + "line": 97, + "problem": "OptionalMethod", + "api_name": "aboutToAppear", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NodeController", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NodeController.d.ts", + "api_info": { + "line": 113, + "problem": "OptionalMethod", + "api_name": "aboutToDisappear", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NodeController", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/NodeController.d.ts", + "api_info": { + "line": 147, + "problem": "OptionalMethod", + "api_name": "onTouchEvent", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "event", + "type": "TouchEvent", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NodeController", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PanelModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PanelAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PanelModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ParticleModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "particleAttribute", + "type": "ParticleAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ParticleModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PathModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PathAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PathModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PatternLockModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PatternLockAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PatternLockModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PolygonModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PolygonAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PolygonModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/PolylineModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "PolylineAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PolylineModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ProgressModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ProgressAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ProgressModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/QRCodeModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "QRCodeAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "QRCodeModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RadioModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RadioAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RadioModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RatingModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RatingAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RatingModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RectModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RectAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RectModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RefreshModifier.d.ts", + "api_info": { + "line": 39, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RefreshAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RefreshModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RichEditorModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RichEditorAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RichEditorModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RowModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RowAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RowModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/RowSplitModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "RowSplitAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RowSplitModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ScrollModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ScrollAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ScrollModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SearchModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SearchAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SearchModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SelectModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SelectAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SelectModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ShapeModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ShapeAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ShapeModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SideBarContainerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SideBarContainerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SideBarContainerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SliderModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SliderAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SliderModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SpanModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SpanAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SpanModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/StackModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "StackAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StackModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/StepperItemModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "StepperItemAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "StepperItemModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SwiperModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SwiperAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SwiperModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SymbolGlyphModifier.d.ts", + "api_info": { + "line": 46, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "SymbolGlyphAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SymbolGlyphModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/SymbolSpanModifier.d.ts", + "api_info": { + "line": 46, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "attribute", + "type": "SymbolSpanAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "SymbolSpanModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TabsModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TabsAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TabsModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextAreaModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextAreaAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextAreaModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextClockModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextClockAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextClockModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextInputModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextInputAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextInputModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextPickerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextPickerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextPickerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TextTimerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TextTimerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TextTimerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/TimePickerModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "TimePickerAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "TimePickerModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/ToggleModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "ToggleAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ToggleModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/VideoModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "VideoAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "VideoModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "api/arkui/WaterFlowModifier.d.ts", + "api_info": { + "line": 38, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "WaterFlowAttribute", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "WaterFlowModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [ + "@ohos.arkui.modifier" + ], + "is_global": true + }, + { + "file_path": "declarations/alert_dialog.d.ts", + "api_info": { + "line": 502, + "problem": "DeclWithDuplicateName", + "api_name": "TextStyle", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/canvas.d.ts", + "api_info": { + "line": 529, + "problem": "DeclWithDuplicateName", + "api_name": "CanvasPath", + "api_type": "ClassDeclaration", + "api_func_args": [], + "parent_api": [], + "method_return_type": "CanvasPath", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/canvas.d.ts", + "api_info": { + "line": 1215, + "problem": "DeclWithDuplicateName", + "api_name": "CanvasPattern", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/canvas.d.ts", + "api_info": { + "line": 1286, + "problem": "DeclWithDuplicateName", + "api_name": "TextMetrics", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/circle.d.ts", + "api_info": { + "line": 198, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "CircleOptions", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CircleInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "CircleAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3882, + "problem": "OptionalMethod", + "api_name": "drawBehind", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "drawContext", + "type": "DrawContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DrawModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3893, + "problem": "OptionalMethod", + "api_name": "drawContent", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "drawContext", + "type": "DrawContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DrawModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3903, + "problem": "OptionalMethod", + "api_name": "drawFront", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "drawContext", + "type": "DrawContext", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DrawModifier", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3931, + "problem": "IndexedAccessType", + "api_name": "TransitionEffect", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "type", + "type": "Type", + "is_optional": false + }, + { + "name": "effect", + "type": "Effect", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "TransitionEffect", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 3931, + "problem": "IndexedAccessType", + "api_name": "TransitionEffect", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "type", + "type": "Type", + "is_optional": false + }, + { + "name": "effect", + "type": "Effect", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "TransitionEffect", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 5167, + "problem": "DeclWithDuplicateName", + "api_name": "EventTarget", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 7610, + "problem": "OptionalMethod", + "api_name": "getModifierKeyState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "keys", + "type": "Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "BaseEvent", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 8211, + "problem": "DeclWithDuplicateName", + "api_name": "MouseEvent", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 8866, + "problem": "DeclWithDuplicateName", + "api_name": "TouchEvent", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 9942, + "problem": "DeclWithDuplicateName", + "api_name": "DragEvent", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 10303, + "problem": "OptionalMethod", + "api_name": "getModifierKeyState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "keys", + "type": "Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "DragEvent", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 10640, + "problem": "OptionalMethod", + "api_name": "getModifierKeyState", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "keys", + "type": "Array", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "KeyEvent", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "boolean", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14270, + "problem": "OptionalMethod", + "api_name": "applyNormalAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14288, + "problem": "OptionalMethod", + "api_name": "applyPressedAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14306, + "problem": "OptionalMethod", + "api_name": "applyFocusedAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14324, + "problem": "OptionalMethod", + "api_name": "applyDisabledAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 14342, + "problem": "OptionalMethod", + "api_name": "applySelectedAttribute", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "instance", + "type": "T", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "AttributeModifier", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 20453, + "problem": "LimitedVoidType", + "api_name": "CustomBuilder", + "api_type": "TypeAliasDeclaration", + "api_func_args": [], + "parent_api": [], + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 21123, + "problem": "DeclWithDuplicateName", + "api_name": "LinearGradient", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22047, + "problem": "OptionalMethod", + "api_name": "aboutToAppear", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22086, + "problem": "OptionalMethod", + "api_name": "aboutToDisappear", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22104, + "problem": "OptionalMethod", + "api_name": "aboutToReuse", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "params", + "type": "{\n [key: string]: unknown;\n }", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22122, + "problem": "OptionalMethod", + "api_name": "aboutToRecycle", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22132, + "problem": "OptionalMethod", + "api_name": "onWillApplyTheme", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "theme", + "type": "Theme", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22144, + "problem": "OptionalMethod", + "api_name": "onLayout", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22166, + "problem": "OptionalMethod", + "api_name": "onPlaceChildren", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "selfLayoutInfo", + "type": "GeometryInfo", + "is_optional": false, + "has_default": false + }, + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22178, + "problem": "OptionalMethod", + "api_name": "onMeasure", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22200, + "problem": "OptionalMethod", + "api_name": "onMeasureSize", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "selfLayoutInfo", + "type": "GeometryInfo", + "is_optional": false, + "has_default": false + }, + { + "name": "children", + "type": "Array", + "is_optional": false, + "has_default": false + }, + { + "name": "constraint", + "type": "ConstraintSizeOptions", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "SizeResult", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22228, + "problem": "OptionalMethod", + "api_name": "onPageShow", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22256, + "problem": "OptionalMethod", + "api_name": "onPageHide", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22280, + "problem": "OptionalMethod", + "api_name": "onFormRecycle", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "string", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22300, + "problem": "OptionalMethod", + "api_name": "onFormRecover", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [ + { + "name": "statusData", + "type": "string", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22335, + "problem": "OptionalMethod", + "api_name": "onBackPress", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean | void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22335, + "problem": "LimitedVoidType", + "api_name": "onBackPress", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "boolean | void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22360, + "problem": "OptionalMethod", + "api_name": "pageTransition", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 22437, + "problem": "OptionalMethod", + "api_name": "onDidBuild", + "api_type": "MethodDeclaration", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "CustomComponent", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/common.d.ts", + "api_info": { + "line": 23015, + "problem": "LimitedVoidType", + "api_name": "OnWillScrollCallback", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "scrollOffset", + "type": "number", + "is_optional": false + }, + { + "name": "scrollState", + "type": "ScrollState", + "is_optional": false + }, + { + "name": "scrollSource", + "type": "ScrollSource", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "void | ScrollResult", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/data_panel.d.ts", + "api_info": { + "line": 180, + "problem": "DeclWithDuplicateName", + "api_name": "LinearGradient", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "colorStops", + "type": "ColorStop[]", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "LinearGradient", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/ellipse.d.ts", + "api_info": { + "line": 92, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: string | number;\n height?: string | number;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "EllipseInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "EllipseAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/grid.d.ts", + "api_info": { + "line": 925, + "problem": "LimitedVoidType", + "api_name": "onItemDragStart", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(event: ItemDragInfo, itemIndex: number) => (() => any) | void", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "GridAttribute", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "GridAttribute", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/hyperlink.d.ts", + "api_info": { + "line": 34, + "problem": "DeclWithDuplicateName", + "api_name": "HyperlinkInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/hyperlink.d.ts", + "api_info": { + "line": 122, + "problem": "DeclWithDuplicateName", + "api_name": "HyperlinkInterface", + "api_type": "FirstStatement", + "parent_api": [], + "code_kind": 244, + "api_property_type": "HyperlinkAttribute" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/line.d.ts", + "api_info": { + "line": 100, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: string | number;\n height?: string | number;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "LineInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "LineAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/list.d.ts", + "api_info": { + "line": 1643, + "problem": "LimitedVoidType", + "api_name": "onItemDragStart", + "api_type": "MethodDeclaration", + "api_optional": false, + "api_func_args": [ + { + "name": "event", + "type": "(event: ItemDragInfo, itemIndex: number) => ((() => any) | void)", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ListAttribute", + "api_type": "ClassDeclaration" + } + ], + "method_return_type": "ListAttribute", + "code_kind": 174 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/navigation.d.ts", + "api_info": { + "line": 2873, + "problem": "OptionalMethod", + "api_name": "cancelTransition", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "NavigationTransitionProxy", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/navigation.d.ts", + "api_info": { + "line": 2883, + "problem": "OptionalMethod", + "api_name": "updateTransition", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [ + { + "name": "progress", + "type": "number", + "is_optional": false, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "NavigationTransitionProxy", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "void", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/page_transition.d.ts", + "api_info": { + "line": 554, + "problem": "InterfaceExtendsClass", + "api_name": "PageTransitionEnterInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/page_transition.d.ts", + "api_info": { + "line": 638, + "problem": "InterfaceExtendsClass", + "api_name": "PageTransitionExitInterface", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/particle.d.ts", + "api_info": { + "line": 438, + "problem": "IndexedAccessType", + "api_name": "config", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "EmitterOptions", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ParticleConfigs[PARTICLE]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/particle.d.ts", + "api_info": { + "line": 696, + "problem": "IndexedAccessType", + "api_name": "config", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ParticlePropertyOptions", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ParticlePropertyUpdaterConfigs[UPDATER]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/particle.d.ts", + "api_info": { + "line": 849, + "problem": "IndexedAccessType", + "api_name": "config", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ParticleColorPropertyOptions", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ParticleColorPropertyUpdaterConfigs[UPDATER]" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/path.d.ts", + "api_info": { + "line": 92, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: number | string;\n height?: number | string;\n commands?: string;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PathInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "PathAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/polygon.d.ts", + "api_info": { + "line": 83, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: string | number;\n height?: string | number;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PolygonInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "PolygonAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/polyline.d.ts", + "api_info": { + "line": 84, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: string | number;\n height?: string | number;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "PolylineInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "PolylineAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1176, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.Linear]", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "LinearStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1191, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.Ring]", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "RingStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1206, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.Eclipse]", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "EclipseStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1221, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.ScaleRing]", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "ScaleRingStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1236, + "problem": "ComputedPropertyName", + "api_name": "[ProgressType.Capsule]", + "api_type": "PropertySignature", + "api_optional": false, + "parent_api": [ + { + "api_name": "ProgressStyleMap", + "api_type": "InterfaceDeclaration" + } + ], + "code_kind": 170, + "api_property_type": "CapsuleStyleOptions | ProgressStyleOptions" + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1347, + "problem": "IndexedAccessType", + "api_name": "ProgressAttribute", + "api_type": "ClassDeclaration", + "api_func_args": [], + "parent_api": [], + "method_return_type": "ProgressAttribute", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/progress.d.ts", + "api_info": { + "line": 1347, + "problem": "IndexedAccessType", + "api_name": "ProgressAttribute", + "api_type": "ClassDeclaration", + "api_func_args": [], + "parent_api": [], + "method_return_type": "ProgressAttribute", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/rect.d.ts", + "api_info": { + "line": 92, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "{\n width?: number | string;\n height?: number | string;\n radius?: number | string | Array;\n } | {\n width?: number | string;\n height?: number | string;\n radiusWidth?: number | string;\n radiusHeight?: number | string;\n }", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "RectInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "RectAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/scroll.d.ts", + "api_info": { + "line": 1397, + "problem": "LimitedVoidType", + "api_name": "ScrollOnWillScrollCallback", + "api_type": "TypeAliasDeclaration", + "api_func_args": [ + { + "name": "xOffset", + "type": "number", + "is_optional": false + }, + { + "name": "yOffset", + "type": "number", + "is_optional": false + }, + { + "name": "scrollState", + "type": "ScrollState", + "is_optional": false + }, + { + "name": "scrollSource", + "type": "ScrollSource", + "is_optional": false + } + ], + "parent_api": [], + "method_return_type": "void | OffsetResult", + "code_kind": 268 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/shape.d.ts", + "api_info": { + "line": 75, + "problem": "ConstructorIface", + "api_type": "ConstructSignature", + "api_optional": false, + "api_func_args": [ + { + "name": "value", + "type": "PixelMap", + "is_optional": true, + "has_default": false + } + ], + "parent_api": [ + { + "api_name": "ShapeInterface", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "ShapeAttribute", + "code_kind": 180 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/styled_string.d.ts", + "api_info": { + "line": 244, + "problem": "DeclWithDuplicateName", + "api_name": "TextStyle", + "api_type": "ClassDeclaration", + "api_func_args": [ + { + "name": "value", + "type": "TextStyleInterface", + "is_optional": true + } + ], + "parent_api": [], + "method_return_type": "TextStyle", + "code_kind": 264 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/text_common.d.ts", + "api_info": { + "line": 468, + "problem": "OptionalMethod", + "api_name": "getPreviewText", + "api_type": "MethodSignature", + "api_optional": true, + "api_func_args": [], + "parent_api": [ + { + "api_name": "TextEditControllerEx", + "api_type": "InterfaceDeclaration" + } + ], + "method_return_type": "PreviewText", + "code_kind": 173 + }, + "import_path": [], + "is_global": true + }, + { + "file_path": "declarations/text_input.d.ts", + "api_info": { + "line": 623, + "problem": "DeclWithDuplicateName", + "api_name": "SubmitEvent", + "api_type": "InterfaceDeclaration", + "parent_api": [], + "code_kind": 267 + }, + "import_path": [], + "is_global": true + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/src/lib/statistics/FileProblemStatistics.ts b/ets2panda/linter/src/lib/statistics/FileProblemStatistics.ts new file mode 100644 index 0000000000000000000000000000000000000000..8b95c12d27f1db9bf83b744f66b803689097c888 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/FileProblemStatistics.ts @@ -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. + */ + +export interface FileProblemStatistics { + errors: number; + warnings: number; + errorLines: number; + warningLines: number; + errorLineNumbersString: string; + warningLineNumbersString: string; +} diff --git a/ets2panda/linter/src/lib/statistics/FileStatistics.ts b/ets2panda/linter/src/lib/statistics/FileStatistics.ts new file mode 100644 index 0000000000000000000000000000000000000000..f9395d9c0a88007e3caf77296848cbc15fcd4d34 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/FileStatistics.ts @@ -0,0 +1,36 @@ +/* + * 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 { ProblemInfo } from '../ProblemInfo'; +import { FaultID } from '../Problems'; + +export class FileStatistics { + visitedNodes: number = 0; + nodeCounters: number[] = []; + lineCounters: Set[] = []; + srcFileName: string; + problems: ProblemInfo[]; + + constructor(srcFile: ts.SourceFile, problems: ProblemInfo[]) { + this.srcFileName = srcFile.fileName; + this.problems = problems; + + for (let i = 0; i < FaultID.LAST_ID; i++) { + this.nodeCounters[i] = 0; + this.lineCounters[i] = new Set(); + } + } +} diff --git a/ets2panda/linter/src/lib/statistics/ProjectStatistics.ts b/ets2panda/linter/src/lib/statistics/ProjectStatistics.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b2193729b3daa57ab97c9a60c778e2270a1886e --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/ProjectStatistics.ts @@ -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. + */ + +import { faultsAttrs } from '../FaultAttrs'; +import type { ProblemInfo } from '../ProblemInfo'; +import { ProblemSeverity } from '../ProblemSeverity'; +import type { FileStatistics } from './FileStatistics'; + +export class ProjectStatistics { + fileStats: FileStatistics[] = []; + + hasError(): boolean { + return this.fileStats.some((fileStats) => { + return fileStats.problems.some((problemInfo: ProblemInfo) => { + return faultsAttrs[problemInfo.faultId].severity === ProblemSeverity.ERROR; + }); + }); + } +} diff --git a/ets2panda/linter/src/lib/statistics/StatisticsLogger.ts b/ets2panda/linter/src/lib/statistics/StatisticsLogger.ts new file mode 100644 index 0000000000000000000000000000000000000000..da586f7a9198959df6e3bde597a257f2fe446782 --- /dev/null +++ b/ets2panda/linter/src/lib/statistics/StatisticsLogger.ts @@ -0,0 +1,180 @@ +/* + * 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 { faultsAttrs } from '../FaultAttrs'; +import { Logger } from '../Logger'; +import { FaultID } from '../Problems'; +import { ProblemSeverity } from '../ProblemSeverity'; +import type { ProblemInfo } from '../ProblemInfo'; +import { faultDesc } from '../FaultDesc'; +import type { FileStatistics } from './FileStatistics'; +import type { FileProblemStatistics } from './FileProblemStatistics'; +import type { ProjectStatistics } from './ProjectStatistics'; + +export function log(...args: unknown[]): void { + let outLine = ''; + for (let k = 0; k < args.length; k++) { + outLine += `${args[k]} `; + } + Logger.info(outLine); +} + +function logReport(srcFileName: string, problemInfo: ProblemInfo): void { + const faultDescr = faultDesc[problemInfo.faultId]; + const faultType = problemInfo.type; + Logger.info( + `Warning: ${srcFileName} (${problemInfo.line}, ${problemInfo.column}): ${faultDescr ? faultDescr : faultType}` + ); +} + +function logFileProblems(fileStats: FileStatistics): void { + for (const problem of fileStats.problems) { + logReport(fileStats.srcFileName, problem); + } +} + +function countProblemStats(fileStats: FileStatistics): FileProblemStatistics { + let errors = 0; + let warnings = 0; + const errorLines = new Set(); + const warningLines = new Set(); + fileStats.problems.forEach((problemInfo: ProblemInfo) => { + const line = problemInfo.line; + switch (faultsAttrs[problemInfo.faultId].severity) { + case ProblemSeverity.ERROR: { + errors++; + errorLines.add(line); + break; + } + case ProblemSeverity.WARNING: { + warnings++; + warningLines.add(line); + break; + } + default: + } + }); + const sortFunc = (a, b): number => { + return a - b; + }; + let errorLineNumbersString = ''; + Array.from(errorLines). + sort(sortFunc). + forEach((line) => { + errorLineNumbersString += line + ', '; + }); + let warningLineNumbersString = ''; + Array.from(warningLines). + sort(sortFunc). + forEach((line) => { + warningLineNumbersString += line + ', '; + }); + return { + errors, + warnings, + errorLines: errorLines.size, + warningLines: warningLines.size, + errorLineNumbersString, + warningLineNumbersString + }; +} + +function logProblemFileInfo(fileStats: FileStatistics, problemStats: FileProblemStatistics): void { + if (problemStats.errors > 0) { + const errorRate = (problemStats.errors / fileStats.visitedNodes * 100).toFixed(2); + const warningRate = (problemStats.warnings / fileStats.visitedNodes * 100).toFixed(2); + log(fileStats.srcFileName, ': ', '\n\tError lines: ', problemStats.errorLineNumbersString); + log(fileStats.srcFileName, ': ', '\n\tWarning lines: ', problemStats.warningLineNumbersString); + log( + '\n\tError constructs (%): ', + errorRate, + '\t[ of ', + fileStats.visitedNodes, + ' constructs ], \t', + problemStats.errorLines, + ' lines' + ); + log( + '\n\tWarning constructs (%): ', + warningRate, + '\t[ of ', + fileStats.visitedNodes, + ' constructs ], \t', + problemStats.warningLines, + ' lines' + ); + } +} + +function logTotalProblemsInfo( + totalErrors: number, + totalWarnings: number, + totalErrorLines: number, + totalWarningLines: number, + totalVisitedNodes: number +): void { + const errorRate = (totalErrors / totalVisitedNodes * 100).toFixed(2); + const warningRate = (totalWarnings / totalVisitedNodes * 100).toFixed(2); + log('\nTotal error constructs (%): ', errorRate); + log('\nTotal warning constructs (%): ', warningRate); + log('\nTotal error lines:', totalErrorLines, ' lines\n'); + log('\nTotal warning lines:', totalWarningLines, ' lines\n'); +} + +function logProblemsPercentageByFeatures(projectStats: ProjectStatistics, totalVisitedNodes: number): void { + log('\nPercent by features: '); + for (let i = 0; i < FaultID.LAST_ID; i++) { + let nodes = 0; + let lines = 0; + for (const fileStats of projectStats.fileStats) { + nodes += fileStats.nodeCounters[i]; + lines += fileStats.lineCounters[i].size; + } + const pecentage = (nodes / totalVisitedNodes * 100).toFixed(2).padEnd(7, ' '); + log(faultDesc[i].padEnd(55, ' '), pecentage, '[', nodes, ' constructs / ', lines, ' lines]'); + } +} + +export function logStatistics(projectStats: ProjectStatistics): void { + let filesWithErrors = 0; + let totalErrors = 0; + let totalWarnings = 0; + let totalErrorLines = 0; + let totalWarningLines = 0; + let totalVisitedNodes = 0; + + for (const fileStats of projectStats.fileStats) { + logFileProblems(fileStats); + + const problemStats = countProblemStats(fileStats); + logProblemFileInfo(fileStats, problemStats); + + if (problemStats.errors > 0) { + filesWithErrors++; + } + + totalErrors += problemStats.errors; + totalWarnings += problemStats.warnings; + totalErrorLines += problemStats.errorLines; + totalWarningLines += problemStats.warningLines; + totalVisitedNodes += fileStats.visitedNodes; + } + + log('\n\n\nFiles scanned: ', projectStats.fileStats.length); + log('\nFiles with problems: ', filesWithErrors); + + logTotalProblemsInfo(totalErrors, totalWarnings, totalErrorLines, totalWarningLines, totalVisitedNodes); + logProblemsPercentageByFeatures(projectStats, totalVisitedNodes); +} diff --git a/ets2panda/linter/src/cli/Compiler.ts b/ets2panda/linter/src/lib/ts-compiler/Compiler.ts similarity index 44% rename from ets2panda/linter/src/cli/Compiler.ts rename to ets2panda/linter/src/lib/ts-compiler/Compiler.ts index b37a0996a48405ef12819b87993059cdb4a1e72d..7708b647daccfddd1f5b85bbb074b7964b8d6f83 100644 --- a/ets2panda/linter/src/cli/Compiler.ts +++ b/ets2panda/linter/src/lib/ts-compiler/Compiler.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -14,16 +14,22 @@ */ import * as ts from 'typescript'; -import type { CommandLineOptions } from '../lib/CommandLineOptions'; -import { formTscOptions } from './ts-compiler/FormTscOptions'; -import { logTscDiagnostic } from '../lib/utils/functions/LogTscDiagnostic'; -import type { LinterConfig } from '../lib/LinterConfig'; -import { TSCCompiledProgramWithDiagnostics } from '../lib/ts-diagnostics/TSCCompiledProgram'; -import { Logger } from '../lib/Logger'; - -function compile(cmdOptions: CommandLineOptions, overrideCompilerOptions: ts.CompilerOptions): ts.Program { +import type { CommandLineOptions } from '../CommandLineOptions'; +import { formTscOptions } from './FormTscOptions'; +import { logTscDiagnostic } from '../utils/functions/LogTscDiagnostic'; +import type { LinterConfig } from '../LinterConfig'; +import { TSCCompiledProgramSimple, TSCCompiledProgramWithDiagnostics } from '../ts-diagnostics/TSCCompiledProgram'; +import { Logger } from '../Logger'; + +export type createProgramCallback = (createProgramOptions: ts.CreateProgramOptions) => ts.Program; + +function compile( + cmdOptions: CommandLineOptions, + overrideCompilerOptions: ts.CompilerOptions, + createProgramCb?: createProgramCallback +): ts.Program { const createProgramOptions = formTscOptions(cmdOptions, overrideCompilerOptions); - const program = ts.createProgram(createProgramOptions); + const program = createProgramCb ? createProgramCb(createProgramOptions) : ts.createProgram(createProgramOptions); // Log Tsc errors if needed if (cmdOptions.logTscErrors) { const diagnostics = ts.getPreEmitDiagnostics(program); @@ -32,9 +38,32 @@ function compile(cmdOptions: CommandLineOptions, overrideCompilerOptions: ts.Com return program; } -export function compileLintOptions(cmdOptions: CommandLineOptions): LinterConfig { - const strict = compile(cmdOptions, getOverrideCompilerOptions(true)); - const nonStrict = compile(cmdOptions, getOverrideCompilerOptions(false)); +export function compileLintOptions( + cmdOptions: CommandLineOptions, + createProgramCb?: createProgramCallback +): LinterConfig { + const linterConfig = cmdOptions.disableStrictDiagnostics ? + compileSimpleProgram(cmdOptions, createProgramCb) : + compileWithStrictDiagnostics(cmdOptions, createProgramCb); + + linterConfig.cmdOptions.linterOptions.etsLoaderPath = getEtsLoaderPath(linterConfig); + return linterConfig; +} + +function compileSimpleProgram(cmdOptions: CommandLineOptions, createProgramCb?: createProgramCallback): LinterConfig { + const program = compile(cmdOptions, getOverrideCompilerOptions(true), createProgramCb); + return { + cmdOptions: cmdOptions, + tscCompiledProgram: new TSCCompiledProgramSimple(program) + }; +} + +function compileWithStrictDiagnostics( + cmdOptions: CommandLineOptions, + createProgramCb?: createProgramCallback +): LinterConfig { + const strict = compile(cmdOptions, getOverrideCompilerOptions(true), createProgramCb); + const nonStrict = compile(cmdOptions, getOverrideCompilerOptions(false), createProgramCb); return { cmdOptions: cmdOptions, tscCompiledProgram: new TSCCompiledProgramWithDiagnostics(strict, nonStrict, cmdOptions.inputFiles) @@ -55,3 +84,8 @@ function getOverrideCompilerOptions(strict: boolean): ts.CompilerOptions { noImplicitReturns: strict }; } + +export function getEtsLoaderPath(linterConfig: LinterConfig): string | undefined { + const tsProgram = linterConfig.tscCompiledProgram.getProgram(); + return tsProgram.getCompilerOptions().etsLoaderPath; +} diff --git a/ets2panda/linter/src/cli/ts-compiler/FormTscOptions.ts b/ets2panda/linter/src/lib/ts-compiler/FormTscOptions.ts similarity index 66% rename from ets2panda/linter/src/cli/ts-compiler/FormTscOptions.ts rename to ets2panda/linter/src/lib/ts-compiler/FormTscOptions.ts index 1494a294fa8af16e79b56f81d81eec66cd3f505c..b29b42f3bb3b66554a2015fbc765ba4b6c238f45 100644 --- a/ets2panda/linter/src/cli/ts-compiler/FormTscOptions.ts +++ b/ets2panda/linter/src/lib/ts-compiler/FormTscOptions.ts @@ -14,8 +14,19 @@ */ import * as ts from 'typescript'; -import type { CommandLineOptions } from '../../lib/CommandLineOptions'; -import { createCompilerHost } from './ResolveSdks'; +import type { CommandLineOptions } from '../CommandLineOptions'; +import { createCompilerHost, readDeclareFiles } from './ResolveSdks'; + +function getTargetESVersionLib(optionsTarget: ts.ScriptTarget): string[] { + switch (optionsTarget) { + case ts.ScriptTarget.ES2017: + return ['lib.es2017.d.ts']; + case ts.ScriptTarget.ES2021: + return ['lib.es2021.d.ts']; + default: + return ['lib.es2021.d.ts']; + } +} export function formTscOptions( cmdOptions: CommandLineOptions, @@ -31,13 +42,18 @@ export function formTscOptions( options.options = Object.assign(options.options, overrideCompilerOptions); return options; } + const rootNames = cmdOptions.inputFiles.concat(readDeclareFiles(cmdOptions.sdkDefaultApiPath ?? '')); + const ESVersion = cmdOptions.followSdkSettings ? ts.ScriptTarget.ES2021 : ts.ScriptTarget.Latest; + const ESVersionLib = cmdOptions.followSdkSettings ? getTargetESVersionLib(ESVersion) : undefined; + const isCheckJs = !cmdOptions.followSdkSettings; const options: ts.CreateProgramOptions = { - rootNames: cmdOptions.inputFiles, + rootNames: rootNames, options: { - target: ts.ScriptTarget.Latest, + target: ESVersion, module: ts.ModuleKind.CommonJS, allowJs: true, - checkJs: true + checkJs: isCheckJs, + lib: ESVersionLib } }; if (cmdOptions.sdkDefaultApiPath && cmdOptions.arktsWholeProjectPath && cmdOptions.sdkExternalApiPath) { diff --git a/ets2panda/linter/src/cli/ts-compiler/ResolveSdks.ts b/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts similarity index 92% rename from ets2panda/linter/src/cli/ts-compiler/ResolveSdks.ts rename to ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts index f4a11b5fc7f7c79176a8731f88dbf3d0af8e34a2..290326c0fc66a1584faac14d1b9e8376931ab237 100644 --- a/ets2panda/linter/src/cli/ts-compiler/ResolveSdks.ts +++ b/ets2panda/linter/src/lib/ts-compiler/ResolveSdks.ts @@ -15,7 +15,7 @@ import * as path from 'node:path'; import * as fs from 'fs'; import * as ts from 'typescript'; -import { EXTNAME_JS, EXTNAME_TS, EXTNAME_D_ETS, EXTNAME_D_TS, EXTNAME_ETS } from '../../lib/utils/consts/ExtensionName'; +import { EXTNAME_JS, EXTNAME_TS, EXTNAME_D_ETS, EXTNAME_D_TS, EXTNAME_ETS } from '../utils/consts/ExtensionName'; interface ResolutionContext { sdkContext: SdkContext; @@ -30,6 +30,23 @@ interface SdkContext { sdkDefaultApiPath: string; } +export function readDeclareFiles(SdkPath: string): string[] { + if (SdkPath === '') { + return []; + } + const declarationsFileNames: string[] = []; + const declarationsPath = path.resolve(SdkPath, './build-tools/ets-loader/declarations'); + if (!fs.existsSync(declarationsPath)) { + throw new Error('get wrong sdkDefaultApiPath, declarationsPath not found'); + } + fs.readdirSync(declarationsPath).forEach((fileName: string) => { + if ((/\.d\.ts$/).test(fileName)) { + declarationsFileNames.push(path.resolve(SdkPath, './build-tools/ets-loader/declarations', fileName)); + } + }); + return declarationsFileNames; +} + export function createCompilerHost( sdkDefaultApiPath: string, sdkExternalApiPath: string[], @@ -298,28 +315,16 @@ function createResolutionContext(sdkContext: SdkContext, projectPath: string): R return { sdkContext, projectPath, - compilerOptions: createCompilerOptions(projectPath) + compilerOptions: createCompilerOptions(sdkContext, projectPath) }; } -function createCompilerOptions(projectPath: string): ts.CompilerOptions { +function createCompilerOptions(sdkContext: SdkContext, projectPath: string): ts.CompilerOptions { const compilerOptions: ts.CompilerOptions = ((): ts.CompilerOptions => { - let configPath: string | null = null; - let currentDir: string = __dirname; - - while (currentDir) { - const filePath = path.resolve(currentDir, 'tsconfig.json'); - if (fs.existsSync(filePath)) { - configPath = filePath; - break; - } - currentDir = path.dirname(currentDir); + const configPath = path.resolve(sdkContext.sdkDefaultApiPath, './build-tools/ets-loader/tsconfig.json'); + if (!fs.existsSync(configPath)) { + throw new Error('get wrong sdkDefaultApiPath, tsconfig.json not found'); } - - if (!configPath) { - throw new Error('tsconfig.json not found'); - } - const configFile = ts.readConfigFile(configPath, ts.sys.readFile); return configFile.config.compilerOptions; })(); diff --git a/ets2panda/linter/src/lib/ts-diagnostics/TSCCompiledProgram.ts b/ets2panda/linter/src/lib/ts-diagnostics/TSCCompiledProgram.ts index c4b5a7a19be630e1368583172feb16d2198b8af8..c3719cc50aa46d4b54a4f9fc5b92ca6fcbbf6eb4 100644 --- a/ets2panda/linter/src/lib/ts-diagnostics/TSCCompiledProgram.ts +++ b/ets2panda/linter/src/lib/ts-diagnostics/TSCCompiledProgram.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -97,6 +97,7 @@ export function transformDiagnostic(diagnostic: ts.Diagnostic): ProblemInfo { end: endPos, type: 'StrictModeError', // expect strict options to always present + faultId: faultId, severity: diagnostic.category === ts.DiagnosticCategory.Warning ? ProblemSeverity.WARNING : ProblemSeverity.ERROR, problem: FaultID[faultId], suggest: messageText, diff --git a/ets2panda/linter/src/lib/utils/TsUtils.ts b/ets2panda/linter/src/lib/utils/TsUtils.ts index a4a2de72845a8768a571eea12f471a3f75269cee..2327bf026c6769c0aebd3371a8236a1a6f0319de 100644 --- a/ets2panda/linter/src/lib/utils/TsUtils.ts +++ b/ets2panda/linter/src/lib/utils/TsUtils.ts @@ -15,10 +15,11 @@ import * as path from 'node:path'; import * as ts from 'typescript'; +import * as fs from 'fs'; import type { IsEtsFileCallback } from '../IsEtsFileCallback'; import { FaultID } from '../Problems'; import { ARKTS_IGNORE_DIRS, ARKTS_IGNORE_DIRS_OH_MODULES, ARKTS_IGNORE_FILES } from './consts/ArktsIgnorePaths'; -import { ES_OBJECT } from './consts/ESObject'; +import { ES_VALUE } from './consts/ESObject'; import { EXTENDED_BASE_TYPES } from './consts/ExtendedBaseTypes'; import { SENDABLE_DECORATOR } from './consts/SendableAPI'; import { USE_SHARED } from './consts/SharedModuleAPI'; @@ -43,12 +44,10 @@ import { isIntrinsicObjectType } from './functions/isIntrinsicObjectType'; import type { LinterOptions } from '../LinterOptions'; import { ETS } from './consts/TsSuffix'; import { STRINGLITERAL_NUMBER, STRINGLITERAL_NUMBER_ARRAY } from './consts/StringLiteral'; -import { - OH_COMPONENTS_MODULE, - OH_PAGES_MODULE, - VALID_OHM_COMPONENTS_MODULE_PATH, - VALID_OHM_PAGES_MODULE_PATH -} from './consts/OhmUrl'; +import { USE_STATIC } from './consts/InteropAPI'; +import { ETS_MODULE, PATH_SEPARATOR, VALID_OHM_COMPONENTS_MODULE_PATH } from './consts/OhmUrl'; +import { EXTNAME_ETS, EXTNAME_JS } from './consts/ExtensionName'; +import { STRING_ERROR_LITERAL } from './consts/Literals'; export const SYMBOL = 'Symbol'; export const SYMBOL_CONSTRUCTOR = 'SymbolConstructor'; @@ -128,7 +127,10 @@ export class TsUtils { return !!(tsSymbol.flags & ts.SymbolFlags.Enum); } - static hasModifier(tsModifiers: readonly ts.Modifier[] | ts.NodeArray | undefined, tsModifierKind: number): boolean { + static hasModifier( + tsModifiers: readonly ts.Modifier[] | ts.NodeArray | undefined, + tsModifierKind: number + ): boolean { if (!tsModifiers) { return false; } @@ -231,6 +233,58 @@ export class TsUtils { ); } + checkStatementForErrorClass(stmt: ts.ThrowStatement): boolean { + const newExpr = stmt.expression; + if (!ts.isNewExpression(newExpr)) { + return true; + } + const ident = newExpr.expression; + if (!ts.isIdentifier(ident)) { + return true; + } + + if (ident.text === STRING_ERROR_LITERAL) { + return false; + } + + const declaration = this.getDeclarationNode(ident); + if (!declaration || ident.text.includes(STRING_ERROR_LITERAL)) { + return false; + } + + if (!declaration || !ident.text.includes(STRING_ERROR_LITERAL)) { + return true; + } + + if (!ts.isClassDeclaration(declaration)) { + return true; + } + + if (!declaration.heritageClauses) { + return true; + } + + return !this.includesErrorClass(declaration.heritageClauses); + } + + includesErrorClass(hClauses: ts.NodeArray): boolean { + void this; + let includesErrorClass = false; + + for (const hClause of hClauses) { + for (const type of hClause.types) { + if (!ts.isIdentifier(type.expression)) { + continue; + } + if (type.expression.text === 'Error') { + includesErrorClass = true; + } + } + } + + return includesErrorClass; + } + static isPrimitiveLiteralType(type: ts.Type): boolean { return !!( type.flags & @@ -624,6 +678,9 @@ export class TsUtils { if (this.processExtendedParentTypes(typeA, typeB)) { return true; } + if (this.isStdIterableType(typeB) && this.hasSymbolIteratorMethod(typeA)) { + return true; + } if (!typeADecl.heritageClauses) { return false; } @@ -636,6 +693,25 @@ export class TsUtils { return false; } + hasSymbolIteratorMethod(type: ts.Type): boolean { + const rhsTypeProps = this.tsTypeChecker.getPropertiesOfType(type); + return rhsTypeProps.some((prop) => { + const propDecl = TsUtils.getDeclaration(prop); + return ( + propDecl && + (ts.isMethodSignature(propDecl) || ts.isMethodDeclaration(propDecl)) && + ts.isComputedPropertyName(propDecl.name) && + this.isSymbolIteratorExpression(propDecl.name.expression) + ); + }); + } + + isStdIterableType(type: ts.Type): boolean { + void this; + const sym = type.getSymbol(); + return !!sym && sym.getName() === 'Iterable' && isStdLibrarySymbol(sym); + } + static reduceReference(t: ts.Type): ts.Type { return TsUtils.isTypeReference(t) && t.target !== t ? t.target : t; } @@ -922,10 +998,25 @@ export class TsUtils { return result; } - private static hasDefaultCtor(type: ts.Type): boolean { + private hasDefaultCtor(type: ts.Type): boolean { + const checkBaseTypes = (type: ts.Type): boolean => { + if (!this.options.arkts2) { + return true; + } + const baseTypes = type.getBaseTypes()?.filter((baseType) => { + return baseType.isClass(); + }); + if (!baseTypes || baseTypes.length === 0) { + return true; + } + return baseTypes.some((baseType: ts.Type) => { + return this.hasDefaultCtor(baseType); + }); + }; + // No members -> no explicit constructors -> there is default ctor if (type.symbol.members === undefined) { - return true; + return checkBaseTypes(type); } // has any constructor @@ -950,7 +1041,11 @@ export class TsUtils { }); // Has no any explicit constructor -> has implicit default constructor. - return !hasCtor || hasDefaultCtor; + if (!hasCtor) { + return checkBaseTypes(type); + } + + return hasDefaultCtor; } private static isAbstractClass(type: ts.Type): boolean { @@ -982,7 +1077,7 @@ export class TsUtils { return false; } - static validateObjectLiteralType(type: ts.Type | undefined): boolean { + validateObjectLiteralType(type: ts.Type | undefined): boolean { if (!type) { return false; } @@ -990,7 +1085,7 @@ export class TsUtils { type = TsUtils.reduceReference(type); return ( type.isClassOrInterface() && - TsUtils.hasDefaultCtor(type) && + this.hasDefaultCtor(type) && !TsUtils.hasReadonlyFields(type) && !TsUtils.isAbstractClass(type) ); @@ -1096,7 +1191,7 @@ export class TsUtils { return this.validateRecordObjectKeys(rhsExpr); } return ( - TsUtils.validateObjectLiteralType(lhsType) && !this.hasMethods(lhsType) && this.validateFields(lhsType, rhsExpr) + this.validateObjectLiteralType(lhsType) && !this.hasMethods(lhsType) && this.validateFields(lhsType, rhsExpr) ); } @@ -1765,12 +1860,12 @@ export class TsUtils { return false; } - static isEsObjectType(typeNode: ts.TypeNode | undefined): boolean { + static isEsValueType(typeNode: ts.TypeNode | undefined): boolean { return ( !!typeNode && ts.isTypeReferenceNode(typeNode) && ts.isIdentifier(typeNode.typeName) && - typeNode.typeName.text === ES_OBJECT + typeNode.typeName.text === ES_VALUE ); } @@ -1785,11 +1880,11 @@ export class TsUtils { return false; } - static isEsObjectPossiblyAllowed(typeRef: ts.TypeReferenceNode): boolean { + static isEsValuePossiblyAllowed(typeRef: ts.TypeReferenceNode): boolean { return ts.isVariableDeclaration(typeRef.parent); } - isValueAssignableToESObject(node: ts.Node): boolean { + isValueAssignableToESValue(node: ts.Node): boolean { if (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) { return false; } @@ -1798,6 +1893,22 @@ export class TsUtils { } getVariableDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { + const sym = this.trueSymbolAtLocation(node); + if (sym === undefined) { + return undefined; + } + return TsUtils.getVariableSymbolDeclarationTypeNode(sym); + } + + static getVariableSymbolDeclarationTypeNode(sym: ts.Symbol): ts.TypeNode | undefined { + const decl = TsUtils.getDeclaration(sym); + if (!!decl && ts.isVariableDeclaration(decl)) { + return decl.type; + } + return undefined; + } + + getDeclarationTypeNode(node: ts.Node): ts.TypeNode | undefined { const sym = this.trueSymbolAtLocation(node); if (sym === undefined) { return undefined; @@ -1807,7 +1918,7 @@ export class TsUtils { static getSymbolDeclarationTypeNode(sym: ts.Symbol): ts.TypeNode | undefined { const decl = TsUtils.getDeclaration(sym); - if (!!decl && ts.isVariableDeclaration(decl)) { + if (!!decl && (ts.isVariableDeclaration(decl) || ts.isPropertyDeclaration(decl))) { return decl.type; } return undefined; @@ -1815,12 +1926,12 @@ export class TsUtils { hasEsObjectType(node: ts.Node): boolean { const typeNode = this.getVariableDeclarationTypeNode(node); - return typeNode !== undefined && TsUtils.isEsObjectType(typeNode); + return typeNode !== undefined && TsUtils.isEsValueType(typeNode); } static symbolHasEsObjectType(sym: ts.Symbol): boolean { - const typeNode = TsUtils.getSymbolDeclarationTypeNode(sym); - return typeNode !== undefined && TsUtils.isEsObjectType(typeNode); + const typeNode = TsUtils.getVariableSymbolDeclarationTypeNode(sym); + return typeNode !== undefined && TsUtils.isEsValueType(typeNode); } static isEsObjectSymbol(sym: ts.Symbol): boolean { @@ -1828,7 +1939,7 @@ export class TsUtils { return ( !!decl && ts.isTypeAliasDeclaration(decl) && - decl.name.escapedText === ES_OBJECT && + decl.name.escapedText === ES_VALUE && decl.type.kind === ts.SyntaxKind.AnyKeyword ); } @@ -2720,17 +2831,22 @@ export class TsUtils { return false; } - findIdentifierNameForSymbol(symbol: ts.Symbol): string | undefined { + findIdentifierNameForSymbol(symbol: ts.Symbol, enumMember?: ts.EnumMember): string | undefined { let name = TsUtils.getIdentifierNameFromString(symbol.name); if (name === undefined || name === symbol.name) { return name; } + const enumExpress = enumMember?.parent; const parentType = this.getTypeByProperty(symbol); if (parentType === undefined) { return undefined; } - + if (enumExpress) { + while (this.findEnumMember(enumExpress, name)) { + name = '_' + name; + } + } while (this.findProperty(parentType, name) !== undefined) { name = '_' + name; } @@ -2843,6 +2959,9 @@ export class TsUtils { } const symbol = tsType.symbol; + if (symbol === undefined) { + return false; + } const name = this.tsTypeChecker.getFullyQualifiedName(symbol); return name === 'String' && this.isGlobalSymbol(symbol); } @@ -3322,6 +3441,23 @@ export class TsUtils { ); } + static isAppStorageAccess(tsCallExpr: ts.CallExpression): boolean { + const propertyAccessExpr = tsCallExpr.expression; + if (!ts.isPropertyAccessExpression(propertyAccessExpr)) { + return false; + } + const accessedExpr = propertyAccessExpr.expression; + if (!ts.isIdentifier(accessedExpr)) { + return false; + } + + if (accessedExpr.text !== 'AppStorage') { + return false; + } + + return true; + } + static isArithmeticOperator(op: ts.BinaryOperatorToken): boolean { switch (op.kind) { case ts.SyntaxKind.PlusToken: @@ -3358,25 +3494,318 @@ export class TsUtils { return isNumberLike; } - static isOhModule(path: string): boolean { - if (path.includes(OH_COMPONENTS_MODULE)) { - return true; + static getModuleName(node: ts.Node): string | undefined { + const currentFilePath = node.getSourceFile().fileName; + if (!currentFilePath.includes('src')) { + return undefined; + } + + /* + * Assuming we are working with a path like "entry/src/main/ets/pages/test1.ets" + * we are splitting at "/src" and get the first item in the list + * in order to capture the "entry" group + * we could have worked with an absolute path like + * "home/user/projects/oh_project/entry/src/main/ets/pages/test1.sts" + * in that case, after the fist split we would have + * "home/user/projects/entry" + * so we split once again with "/" to separate out the directories + * + * and get the last item which is entry or our module + */ + const getPossibleModule = currentFilePath.split('/src')[0]; + if (getPossibleModule.length === 0) { + return undefined; } - if (path.includes(OH_PAGES_MODULE)) { + const sanitizedDirectories = getPossibleModule.split('/'); + return sanitizedDirectories[sanitizedDirectories.length - 1]; + } + + static checkFileExists( + importIncludesModule: boolean, + currentNode: ts.Node, + importFilePath: string, + projectPath: string, + extension: string = EXTNAME_ETS + ): boolean { + const currentModule = TsUtils.getModuleName(currentNode); + + /* + * some imports are like this + * ets/pages/test1 + * in this case, they are in the same module as the file we are trying to import to + * so we add the current module back in + */ + if (!importIncludesModule) { + if (!currentModule) { + return false; + } + + projectPath.concat(PATH_SEPARATOR + currentModule); + } + + const importedFile = path.resolve(projectPath, importFilePath + extension); + + return fs.existsSync(importedFile); + } + + isImportedFromJS(identifier: ts.Identifier): boolean { + const sym = this.trueSymbolAtLocation(identifier); + const declaration = sym?.declarations?.[0]; + return !!declaration?.getSourceFile().fileName.endsWith(EXTNAME_JS); + } + + isPossiblyImportedFromJS(node: ts.Node): boolean { + const identifier = this.findIdentifierInExpression(node); + if (!identifier) { + return false; + } + + // Direct import check + if (this.isImportedFromJS(identifier)) { return true; } + // Indirect import check + const originalIdentifier = this.findOriginalIdentifier(identifier); + return !!originalIdentifier && this.isImportedFromJS(originalIdentifier); + } + + /** + * Extracts the Identifier from the given node. returns undefined if no Identifier is found. + * + * Direct Identifier (foo) → Returns it. + * Binary Expressions (foo + bar) → Recursively checks left and right. + * Property Access (obj.foo) → Extracts obj. + * Function Calls (foo()) → Extracts foo. + * Array Access (arr[foo]) → Extracts foo. + * Variable Declaration (let foo = ...) → Extracts foo. + * Assignments (foo = ...) → Extracts foo. + */ + findIdentifierInExpression(node: ts.Node): ts.Identifier | undefined { + if (ts.isIdentifier(node)) { + return node; + } else if (ts.isBinaryExpression(node)) { + return this.findIdentifierInExpression(node.left) || this.findIdentifierInExpression(node.right); + } else if (ts.isPropertyAccessExpression(node)) { + return this.findIdentifierInExpression(node.expression); + } else if (ts.isCallExpression(node) || ts.isNewExpression(node)) { + return this.findIdentifierInExpression(node.expression); + } else if (ts.isElementAccessExpression(node)) { + return this.findIdentifierInExpression(node.expression); + } else if (ts.isAsExpression(node)) { + return this.findIdentifierInExpression(node.expression); + } else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)) { + return node.name; + } + return undefined; + } + + // Helper function: Find the variable declaration of an identifier -> let arr = foo.arr -> returns foo + findVariableDeclaration(identifier: ts.Identifier): ts.VariableDeclaration | undefined { + const sym = this.tsTypeChecker.getSymbolAtLocation(identifier); + const decl = TsUtils.getDeclaration(sym); + if (decl && ts.isVariableDeclaration(decl)) { + return decl; + } + return undefined; + } + + findOriginalIdentifier(identifier: ts.Identifier): ts.Identifier | undefined { + const variableDeclaration = this.findVariableDeclaration(identifier); + if (!variableDeclaration?.initializer) { + return undefined; + } + + const originalIdentifier = ts.isPropertyAccessExpression(variableDeclaration.initializer) ? + (variableDeclaration.initializer.expression as ts.Identifier) : + undefined; + + if (!originalIdentifier) { + return undefined; + } + + return originalIdentifier; + } + + findTypeOfNodeForConversion(node: ts.Node): string { + // Get type of the property + const type = this.tsTypeChecker.getTypeAtLocation(node); + // Default + let conversionMethod = ''; + + if (this.tsTypeChecker.typeToString(type) === 'boolean') { + conversionMethod = '.toBoolean()'; + } else if (this.tsTypeChecker.typeToString(type) === 'number') { + conversionMethod = '.toNumber()'; + } else if (this.tsTypeChecker.typeToString(type) === 'string') { + conversionMethod = '.toString()'; + } + + return conversionMethod; + } + + static isInsideIfCondition(node: ts.Node): boolean { + let current: ts.Node | undefined = node; + while (current) { + if (ts.isIfStatement(current)) { + if ( + ts.isBinaryExpression(node.parent) && + node.parent.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken + ) { + return false; + } + + return true; + } + current = current.parent; + } return false; } + static isOhModule(path: string): boolean { + return path.includes(ETS_MODULE); + } + static isValidOhModulePath(path: string): boolean { - if (path.includes(VALID_OHM_COMPONENTS_MODULE_PATH)) { - return true; + return path.includes(VALID_OHM_COMPONENTS_MODULE_PATH); + } + + findEnumMember(enumDecl: ts.EnumDeclaration | undefined, name: string): ts.Symbol | undefined { + if (!enumDecl) { + return undefined; } - if (path.includes(VALID_OHM_PAGES_MODULE_PATH)) { - return true; + + const syms: ts.Symbol[] = []; + for (const enumMember of enumDecl.members) { + const sym = this.trueSymbolAtLocation(enumMember.name); + if (sym) { + syms.push(sym); + } + } + + for (const sym of syms) { + if (sym.name === name) { + return sym; + } + } + + return undefined; + } + + /** + * Checks whether an exported identifier is imported from an ArkTS1 file. + * @param exportIdentifier The exported identifier to check. + * @param node The node where the export occurs (used to get the current source file). + * @returns true if imported from ArkTS1, false if not, undefined if undetermined. + */ + isExportImportedFromArkTs1(exportIdentifier: ts.Identifier, node: ts.Node): boolean | undefined { + // Get the symbol associated with the identifier. + const symbol = this.tsTypeChecker.getSymbolAtLocation(exportIdentifier); + if (!symbol) { + return undefined; } + // If the symbol is an alias (imported), resolve the real symbol. + const realSymbol = + (symbol.flags & ts.SymbolFlags.Alias) !== 0 ? this.tsTypeChecker.getAliasedSymbol(symbol) : undefined; + + const declarations = realSymbol?.getDeclarations(); + if (!declarations || declarations.length === 0) { + return undefined; + } + + // Get the source file where the declaration is located. + const importSourceFile = declarations[0].getSourceFile(); + + // Ensure import is from ArkTS1 file and usage is in ArkTS1.2 file + const currentSourceFile = node.getSourceFile(); + return ( + importSourceFile.fileName.endsWith(EXTNAME_ETS) && + currentSourceFile.fileName.endsWith(EXTNAME_ETS) && + !TsUtils.isArkts12File(importSourceFile) && + TsUtils.isArkts12File(currentSourceFile) + ); + } + + static isArkts12File(sourceFile: ts.SourceFile): boolean { + if (!sourceFile?.statements.length) { + return false; + } + const statements = sourceFile.statements; + return ( + ts.isExpressionStatement(statements[0]) && + ts.isStringLiteral(statements[0].expression) && + statements[0].expression.getText() === USE_STATIC + ); + } + + static removeOrReplaceQuotes(str: string, isReplace: boolean): string { + if (isReplace) { + const charArray = new Array(str.length); + for (let i = 0; i < str.length; i++) { + charArray[i] = str[i] === '"' ? '\'' : str[i]; + } + return charArray.join(''); + } + if (str.startsWith('\'') && str.endsWith('\'') || str.startsWith('"') && str.endsWith('"')) { + return str.slice(1, -1); + } + return str; + } + + isJsImport(node: ts.Node): boolean { + const symbol = this.trueSymbolAtLocation(node); + if (symbol) { + const declaration = symbol.declarations?.[0]; + if (declaration) { + const sourceFile = declaration.getSourceFile(); + return sourceFile.fileName.endsWith(EXTNAME_JS); + } + } return false; } + + static typeIsCapturedFromEnclosingLocalScope(type: ts.Type, enclosingStmt: ts.Node): boolean { + let symNode: ts.Node | undefined = TsUtils.getDeclaration(type.getSymbol()); + + while (symNode) { + if (symNode === enclosingStmt) { + return true; + } + symNode = symNode.parent; + } + + return false; + } + + nodeCapturesValueFromEnclosingLocalScope(targetNode: ts.Node, enclosingStmt: ts.Node): boolean { + let found = false; + + const callback = (node: ts.Node): void => { + if (!ts.isIdentifier(node)) { + return; + } + const sym = this.tsTypeChecker.getSymbolAtLocation(node); + let symNode: ts.Node | undefined = TsUtils.getDeclaration(sym); + while (symNode) { + if (symNode === targetNode) { + // Symbol originated from the target node. Skip and continue to search + return; + } + if (symNode === enclosingStmt) { + found = true; + return; + } + symNode = symNode.parent; + } + }; + + const stopCondition = (node: ts.Node): boolean => { + void node; + return found; + }; + + forEachNodeInSubtree(targetNode, callback, stopCondition); + return found; + } } diff --git a/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts b/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts index 313369cf092cae154cfe6751193e8670c8a24b6d..74a8769931be1a31aef12b527d120e2f36261ba9 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkTS2Rules.ts @@ -20,6 +20,7 @@ export const arkts2Rules: number[] = [ 34, 37, 29, + 111, 137, 139, 140, @@ -29,9 +30,11 @@ export const arkts2Rules: number[] = [ 184, 189, 190, + 191, 192, 193, 198, + 199, 202, 203, 206, @@ -41,6 +44,9 @@ export const arkts2Rules: number[] = [ 210, 211, 212, + 213, + 214, + 215, 222, 232, 233, @@ -59,10 +65,127 @@ export const arkts2Rules: number[] = [ 257, 258, 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 274, + 275, 300, 301, 302, 303, 304, - 305 + 305, + 306, + 307, + 308, + 309, + 310, + 311, + 312, + 313, + 314, + 315, + 316, + 317, + 318, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 326, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346, + 347, + 348, + 349, + 350, + 351, + 355, + 356, + 357, + 358, + 359, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378 ]; + +export const onlyArkts2SyntaxRules: Map = new Map([ + [1, 'arkts-identifiers-as-prop-names'], + [25, 'arkts-no-ctor-prop-decls'], + [29, 'arkts-no-props-by-index'], + [30, 'arkts-no-structural-typing'], + [34, 'arkts-no-inferred-generic-params'], + [37, 'arkts-no-regexp-literals'], + [111, 'arkts-no-enum-mixed-types'], + [137, 'arkts-no-globalthis'], + [139, 'arkts-no-func-props'], + [140, 'arkts-no-func-bind'], + [141, 'arkts-limited-stdlib'], + [149, 'arkts-no-classes-as-obj'], + [183, 'arkts-obj-literal-props'], + [184, 'arkts-optional-methods'], + [189, 'arkts-numeric-semantic'], + [190, 'arkts-incompatible-function-types'], + [191, 'arkts-no-need-stdlib-ason'], + [192, 'arkts-limited-void-type'], + [193, 'arkts-no-void-operator'], + [198, 'arkts-no-ts-overload'], + [202, 'arkts-limited-literal-types'], + [203, 'arkts-no-exponent-op'], + [207, 'arkts-no-arguments-obj'], + [208, 'arkts-no-tagged-templates'], + [209, 'arkts-array-index-expr-type'], + [210, 'arkts-switch-expr'], + [211, 'arkts-case-expr'], + [212, 'arkts-array-index-negative'], + [222, 'arkts-no-side-effect-import'], + [232, 'arkts-no-lazy-import'], + [233, 'arkts-no-dynamic-import'], + [234, 'arkts-no-ts-decorators'], + [235, 'arkts-common-union-member-access'], + [236, 'arkts-no-method-overriding-field'], + [237, 'arkts-no-tuples-arrays'], + [238, 'arkts-class-static-initialization'], + [239, 'arkts-invalid-identifier'], + [255, 'arkts-no-extends-expression'], + [300, 'arkts-no-ts-like-function-call'], + [301, 'arkts-ohmurl-full-path'], + [304, 'arkts-no-duplicate-function-name'] +]); diff --git a/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts b/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..8218ffc5113110bf9692d2a2f8ec847471e0dc93 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/ArkTSUtilsAPI.ts @@ -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. + */ + +export const ASON_TEXT = 'ASON'; +export const ASON_MODULES = ['@arkts.utils', '@kit.ArkTS']; +export const JSON_TEXT = 'JSON'; +export const ARKTS_UTILS_TEXT = 'ArkTSUtils'; diff --git a/ets2panda/linter/test/interop/oh_modules/ts_decorator.ts b/ets2panda/linter/src/lib/utils/consts/ArktsWhiteApiPaths.ts old mode 100644 new mode 100755 similarity index 84% rename from ets2panda/linter/test/interop/oh_modules/ts_decorator.ts rename to ets2panda/linter/src/lib/utils/consts/ArktsWhiteApiPaths.ts index 511202fa7900b891732d398dd9b5dc206ae8b029..bd6d904c9391bd94907a86c1fd70364e0f28c294 --- a/ets2panda/linter/test/interop/oh_modules/ts_decorator.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArktsWhiteApiPaths.ts @@ -13,5 +13,4 @@ * limitations under the License. */ -export function MyClassDecorator(klass: Object) { } -export function MyClassDecorator2(target: Function) { } \ No newline at end of file +export const ARKTS_WHITE_API_PATH_TEXTSTYLE = 'component/styled_string.d.ts'; diff --git a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts index 3cd63b15019573c103dfcc833548f1457ef30c8e..159e986494df2c7703b94db0a30018f0c5a127a0 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts @@ -20,15 +20,36 @@ export const INSTANCE_IDENTIFIER = 'instance'; export const COMMON_METHOD_IDENTIFIER = 'CommonMethod'; export const APPLY_STYLES_IDENTIFIER = 'applyStyles'; export const STATE_STYLES = 'stateStyles'; -export const ARKUI_PACKAGE_NAME = '@kits.ArkUI'; +export const ARKUI_PACKAGE_NAME = '@kit.ArkUI'; export const VALUE_IDENTIFIER = 'value'; +export const INDENT_STEP = 2; +export const MAKE_OBSERVED = 'makeObserved'; +export const ARKUI_STATE_MANAGEMENT = '@ohos.arkui.StateManagement'; export enum CustomDecoratorName { Extend = 'Extend', + LocalBuilder = 'LocalBuilder', Styles = 'Styles', AnimatableExtend = 'AnimatableExtend', Memo = 'Memo', - Observed = 'Observed' + Observed = 'Observed', + Layoutable = 'Layoutable' +} + +export enum StorageTypeName { + LocalStorage = 'LocalStorage', + AppStorage = 'AppStorage' +} + +export enum PropDecoratorName { + Prop = 'Prop', + StorageProp = 'StorageProp', + LocalStorageProp = 'LocalStorageProp' +} + +export enum PropFunctionName { + Prop = 'prop', + SetAndProp = 'setAndProp' } export const observedDecoratorName: Set = new Set([ @@ -44,4 +65,21 @@ export const observedDecoratorName: Set = new Set([ 'Track' ]); -export const skipImportDecoratorName: Set = new Set(['Extend', 'Styles', 'Sendable', 'Concurrent']); +export const skipImportDecoratorName: Set = new Set([ + 'Extend', + 'Styles', + 'Sendable', + 'Concurrent', + 'LocalBuilder' +]); + +export const customLayoutFunctionName: Set = new Set(['onMeasureSize', 'onPlaceChildren']); + +export const ENTRY_DECORATOR_NAME = 'Entry'; +export const ENTRY_STORAGE_PROPERITY = 'storage'; +export const LOCAL_STORAGE_TYPE_NAME = 'LocalStorage'; +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'; diff --git a/ets2panda/linter/src/lib/utils/consts/BuiltinGenericConstructor.ts b/ets2panda/linter/src/lib/utils/consts/BuiltinGenericConstructor.ts index dbadef70d4c093c250dc45878b6b3a7e23b04e73..211a86e8860932ce1da776c9429bc3a475aa83fa 100755 --- a/ets2panda/linter/src/lib/utils/consts/BuiltinGenericConstructor.ts +++ b/ets2panda/linter/src/lib/utils/consts/BuiltinGenericConstructor.ts @@ -19,5 +19,14 @@ export const BUILTIN_GENERIC_CONSTRUCTORS = new Set([ 'ReadonlyArray', 'Promise', 'WeakMap', - 'WeakSet' + 'WeakSet', + 'Deque', + 'ArrayList', + 'HashMap', + 'HashSet', + 'LinkedList', + 'PlainArray', + 'TreeMap', + 'TreeSet', + 'Queue' ]); diff --git a/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts b/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts new file mode 100644 index 0000000000000000000000000000000000000000..d4e4898557e485d0cb4c9c83c21c143be6314e61 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts @@ -0,0 +1,47 @@ +/* + * 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 enum BuiltinProblem { + LimitedThisArg = 'ThisArg', + SymbolIterator = 'SymbolIterator', + BuiltinNoCtorFunc = 'BuiltinNoCtorFunc', + BuiltinNoPropertyDescriptor = 'NoPropertyDescriptor', + MissingAttributes = 'MissingAttributes' +} + +export const SYMBOL_ITERATOR: string = 'Symbol.iterator'; + +export const GET_OWN_PROPERTY_NAMES_TEXT: string = 'Object.getOwnPropertyNames'; + +export const BUILTIN_DISABLE_CALLSIGNATURE = [ + 'AggregateError', + 'Array', + 'Array', + 'BigInt', + 'Boolean', + 'Date', + 'Error', + 'EvalError', + 'Number', + 'RangeError', + 'ReferenceError', + 'RegExp', + 'RegExp', + 'RegExp', + 'String', + 'SyntaxError', + 'TypeError', + 'URIError' +]; diff --git a/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.ts b/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..a7c1698e3ba00a285e16df6ee6b1c418f3832d4b --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/CollectionsAPI.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 const COLLECTIONS_TEXT = 'collections'; +export const COLLECTIONS_MODULES = ['@arkts.collections', '@kit.ArkTS']; diff --git a/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.ts b/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..5fc45d2e960b875ace2b3e42b94de233b7d33b66 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/ConcurrentAPI.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. + */ + +export const USE_CONCURRENT = 'use concurrent'; +export const USE_SHARED = 'use shared'; +export const ESLIB_SHAREDARRAYBUFFER = 'SharedArrayBuffer'; +export const ESLIB_SHAREDMEMORY_FILENAME = 'lib.es2017.sharedmemory.d.ts'; +export const TASKPOOL_MODULES = ['@kit.ArkTS', '@ohos.taskpool']; diff --git a/ets2panda/linter/src/lib/utils/consts/ESObject.ts b/ets2panda/linter/src/lib/utils/consts/ESObject.ts index 9394367c4b8e88826862eaea625d04a0b93dcdc7..3f541dc7c4074ab279ee1b5912cca831e9be6d3d 100644 --- a/ets2panda/linter/src/lib/utils/consts/ESObject.ts +++ b/ets2panda/linter/src/lib/utils/consts/ESObject.ts @@ -13,4 +13,4 @@ * limitations under the License. */ -export const ES_OBJECT = 'ESObject'; +export const ES_VALUE = 'ESValue'; diff --git a/ets2panda/linter/src/lib/utils/consts/InternalFunction.ts b/ets2panda/linter/src/lib/utils/consts/InternalFunction.ts new file mode 100644 index 0000000000000000000000000000000000000000..16d668bac1c265fc2e122aaa2e72180e0003c17a --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/InternalFunction.ts @@ -0,0 +1,30 @@ +/* + * 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 const interanlFunction = [ + 'getContext', + 'postCardAction', + '$r', + '$rawfile', + 'animateTo', + 'animateToImmediately', + 'vp2px', + 'px2vp', + 'fp2px', + 'px2fp', + 'lpx2px', + 'px2lpx', + 'wrapBuilder' +]; diff --git a/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts b/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts index 8571c768d5aee1c7a54ce271cda3d4ecf42ad78b..c3566b66db6a4acb482811cfb3857b8fdc716f61 100644 --- a/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/InteropAPI.ts @@ -14,6 +14,12 @@ */ export const USE_STATIC = '\'use static\''; +export const ARE_EQUAL = 'areEqual'; +export const ARE_STRICTLY_EQUAL = 'areStrictlyEqual'; +export const WRAP = 'wrap'; +export const INSTANTIATE = 'instantiate'; +export const INVOKE = 'invoke'; +export const INVOKE_METHOD = 'invokeMethod'; export const REFLECT_PROPERTIES = [ 'get', @@ -30,3 +36,40 @@ export const REFLECT_PROPERTIES = [ 'isExtensible', 'preventExtensions' ]; +export const OBJECT_PROPERTIES = [ + 'get', + 'set', + 'has', + 'hasOwn', + 'ownKeys', + 'keys', + 'getOwnPropertyDescriptor', + 'getOwnPropertyDescriptors', + 'getOwnPropertyName', + 'defineProperty', + 'deleteProperty', + 'apply', + 'construct', + 'getPrototypeOf', + 'setPrototypeOf', + 'isExtensible', + 'isFrozen', + 'isSealed' +]; +export const OBJECT_LITERAL = 'Object'; +export const REFLECT_LITERAL = 'Reflect'; +export const NONE = 'none'; +export type ForbidenAPICheckResult = 'Object' | 'Reflect' | 'none'; +export const LOAD = 'load'; +export const GET_PROPERTY_BY_NAME = 'getPropertyByName'; +export const SET_PROPERTY_BY_NAME = 'setPropertyByName'; +export const GET_PROPERTY_BY_INDEX = 'getPropertyByIndex'; +export const SET_PROPERTY_BY_INDEX = 'setPropertyByIndex'; +export const TO_NUMBER = 'toNumber'; + +export enum InteropType { + TS = 'TS', + JS = 'JS', + LEGACY = '1.0', + NONE = 'none' +} diff --git a/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts b/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts index 6853676eee99e61697df0cc40c6f0e4073b61556..ca9bdcd8431c31b723b45d592176955b315df23d 100644 --- a/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/LimitedStdAPI.ts @@ -151,3 +151,9 @@ export const LIMITED_STD_API = new Map = { + '@kit.ArkTS': ['taskpool', 'ArkTSUtils', 'process'], + '@ohos.process': ['process'], + '@ohos.taskpool': ['taskpool'] +}; diff --git a/ets2panda/linter/src/lib/utils/consts/Literals.ts b/ets2panda/linter/src/lib/utils/consts/Literals.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b543492615e2d214376244cdfcf0408aad1243b --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/Literals.ts @@ -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. + */ + +export const STRING_ERROR_LITERAL = 'Error'; diff --git a/ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts b/ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts new file mode 100644 index 0000000000000000000000000000000000000000..73ef2d0743a7fb9dc8cecec551eee9ba82eae738 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/MethodDeclaration.ts @@ -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. + */ + +export const METHOD_DECLARATION = 'MethodDeclaration'; diff --git a/ets2panda/linter/src/lib/utils/consts/MethodSignature.ts b/ets2panda/linter/src/lib/utils/consts/MethodSignature.ts new file mode 100644 index 0000000000000000000000000000000000000000..d3f3faf510e07f15707c2e0293054f6e12230184 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/MethodSignature.ts @@ -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. + */ + +export const METHOD_SIGNATURE = 'MethodSignature'; diff --git a/ets2panda/linter/src/lib/utils/consts/OhmUrl.ts b/ets2panda/linter/src/lib/utils/consts/OhmUrl.ts index 7e711701ac171acc3b9fb597d7699107bb6faa20..4318c41e5fcef18d25b3dd46bbbb224eb22da460 100644 --- a/ets2panda/linter/src/lib/utils/consts/OhmUrl.ts +++ b/ets2panda/linter/src/lib/utils/consts/OhmUrl.ts @@ -13,10 +13,9 @@ * limitations under the License. */ -export const VALID_OHM_COMPONENTS_MODULE_PATH = 'src/main/ets/components'; -export const VALID_OHM_PAGES_MODULE_PATH = 'src/main/ets/pages'; +export const VALID_OHM_COMPONENTS_MODULE_PATH = 'src/main/ets'; +export const ETS_MODULE = 'ets/'; export const SRC_AND_MAIN = 'src/main'; -export const OH_COMPONENTS_MODULE = 'ets/components'; -export const OH_PAGES_MODULE = 'ets/pages'; export const PATH_SEPARATOR = '/'; export const ETS_PART = 'ets'; +export const DEFAULT_MODULE_NAME = 'entry'; diff --git a/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts b/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts new file mode 100644 index 0000000000000000000000000000000000000000..336a74350cdd26e730ebbf2709fe0734ced88ec9 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/OptionalMethod.ts @@ -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. + */ + +export const OPTIONAL_METHOD = 'OptionalMethod'; diff --git a/ets2panda/linter/src/lib/utils/consts/RuntimeCheckAPI.ts b/ets2panda/linter/src/lib/utils/consts/RuntimeCheckAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..9fa38ab9fa8dabf173ef922af4e83eb50264daad --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/RuntimeCheckAPI.ts @@ -0,0 +1,39 @@ +/* + * 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 ts from 'typescript'; + +export type ArrayAccess = { + pos: number; + accessingIdentifier: 'number' | ts.Identifier; + arrayIdent: ts.Identifier; +}; + +export type UncheckedIdentifier = ts.Identifier | typeof NUMBER_LITERAL | undefined; +export type CheckedIdentifier = ts.Identifier | typeof NUMBER_LITERAL; + +export const NUMBER_LITERAL = 'number'; + +export enum LoopConditionChecked { + LEFT, + RIGHT, + NOT_CHECKED +} + +export enum CheckResult { + SKIP, + HAS_ARRAY_ACCES, + CHECKED +} diff --git a/ets2panda/linter/src/lib/utils/consts/SdkWhitelist.ts b/ets2panda/linter/src/lib/utils/consts/SdkWhitelist.ts new file mode 100644 index 0000000000000000000000000000000000000000..da2140601bdd69c2667b62a94f9a4259704bbcb4 --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/SdkWhitelist.ts @@ -0,0 +1,122 @@ +/* + * 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 enum SdkProblem { + LimitedVoidType = 'LimitedVoidType', + ConstructorIface = 'ConstructorIface', + LiteralAsPropertyName = 'LiteralAsPropertyName', + OptionalMethod = 'OptionalMethod', + ConstructorFuncs = 'ConstructorFuncs', + IndexedAccessType = 'IndexedAccessType', + SendablePropType = 'SendablePropType', + TypeQuery = 'TypeQuery', + GlobalThisError = 'GlobalThisError', + InterfaceExtendsClass = 'InterfaceExtendsClass', + DeclWithDuplicateName = 'DeclWithDuplicateName', + ComputedPropertyName = 'ComputedPropertyName' +} + +export enum SdkNameInfo { + ParentApiName = 'parent_api_name', + ImportPath = 'import_path' +} + +export const ARKTS_WHITE_API_PATH_TEXTSTYLE = 'component/styled_string.d.ts'; + +// Define function argument class +export class ApiFuncArg { + name: string; + type: string; + is_optional: boolean; + has_default?: boolean; + + constructor(data: Partial) { + this.name = data.name || ''; + this.type = data.type || ''; + this.is_optional = data.is_optional || false; + this.has_default = data.has_default || undefined; + } +} + +// Define the parent API class (recursive structure) +export class ParentApi { + api_name: string; + api_type: string; + + constructor(data: Partial) { + this.api_name = data.api_name || ''; + this.api_type = data.api_type || ''; + } +} + +// Define the API information class +export class ApiInfo { + problem: string; + api_name?: string; + api_type: string; + api_optional?: boolean; + api_auto_fix?: boolean; + api_auto_fix_context?: string; + api_func_args?: ApiFuncArg[]; + parent_api: ParentApi[]; + method_return_type?: string; + api_property_type?: string; + code_kind: number; + + constructor(data: Partial) { + this.problem = data.problem || ''; + this.api_name = data.api_name || undefined; + this.api_type = data.api_type || ''; + this.api_optional = data.api_optional || undefined; + this.api_auto_fix = data.api_auto_fix || undefined; + this.api_auto_fix_context = data.api_auto_fix_context || undefined; + this.api_func_args = + (data.api_func_args || []).map((arg) => { + return new ApiFuncArg(arg); + }) || undefined; + this.parent_api = (data.parent_api || []).map((parent) => { + return new ParentApi(parent); + }); + this.method_return_type = data.method_return_type || undefined; + this.api_property_type = data.api_property_type || undefined; + this.code_kind = data.code_kind || 0; + } +} + +// Define the API list item class +export class ApiListItem { + import_path: string[]; + file_path: string; + api_info: ApiInfo; + is_global: boolean; + + constructor(data: Partial) { + this.import_path = data.import_path || []; + this.file_path = data.file_path || ''; + this.api_info = new ApiInfo(data.api_info || {}); + this.is_global = data.is_global || false; + } +} + +// Define the top-level API list class +export class ApiList { + api_list: ApiListItem[]; + + constructor(data: Partial) { + this.api_list = (data.api_list || []).map((item) => { + return new ApiListItem(item); + }); + } +} diff --git a/ets2panda/linter/src/lib/utils/consts/SendableAPI.ts b/ets2panda/linter/src/lib/utils/consts/SendableAPI.ts index e6a6cdae377796c9b749a5c2ea0b5b12b682b1e7..2809e8afab971996abd65819ae3410ec964bb06f 100644 --- a/ets2panda/linter/src/lib/utils/consts/SendableAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/SendableAPI.ts @@ -17,6 +17,8 @@ import * as ts from 'typescript'; export const SENDABLE_DECORATOR = 'Sendable'; export const CONCURRENT_DECORATOR = 'Concurrent'; +export const TASKPOOL = 'taskpool'; +export const ISCONCURRENT = 'isConcurrent'; export const SENDABLE_DECORATOR_NODES = [ ts.SyntaxKind.ClassDeclaration, diff --git a/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts b/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts index 0f40d6a2d0992df4e5f0306e3128f025bad3b58b..67bafa00b4e4c15453ab47d0648e11bbbcb7e930 100644 --- a/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts +++ b/ets2panda/linter/src/lib/utils/consts/StringLiteral.ts @@ -17,3 +17,11 @@ export const STRINGLITERAL_NUMBER = 'number'; export const STRINGLITERAL_NUMBER_ARRAY = 'number[]'; export const STRINGLITERAL_STRING = 'string'; export const STRINGLITERAL_INT = 'int'; +export const STRINGLITERAL_BYTE = 'byte'; +export const STRINGLITERAL_SHORT = 'short'; +export const STRINGLITERAL_LONG = 'long'; +export const STRINGLITERAL_CHAR = 'char'; +export const STRINGLITERAL_ANY = 'ANY'; +export const STRINGLITERAL_ENUM = 'enum'; +export const STRINGLITERAL_FROM = 'from'; +export const STRINGLITERAL_ARRAY = 'Array'; diff --git a/ets2panda/linter/src/lib/utils/consts/TaskpoolAPI.ts b/ets2panda/linter/src/lib/utils/consts/TaskpoolAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..5414202732da6e0802fdf658b97ca4778b6c198f --- /dev/null +++ b/ets2panda/linter/src/lib/utils/consts/TaskpoolAPI.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. + */ + +export const STDLIB_TASKPOOL_OBJECT_NAME = 'taskpool'; +export const STDLIB_TASK_CLASS_NAME = 'Task'; + +export const DEPRECATED_TASKPOOL_METHOD_SETCLONELIST = 'setCloneList'; +export const DEPRECATED_TASKPOOL_METHOD_SETTRANSFERLIST = 'setTransferList'; diff --git a/ets2panda/linter/src/lib/utils/consts/WorkerAPI.ts b/ets2panda/linter/src/lib/utils/consts/WorkerAPI.ts index 087a676c1defb9b2f466ffc3f73cc0cc5483d7ab..a1e545f7b5103b0594a6af23bce7875c7d81886e 100644 --- a/ets2panda/linter/src/lib/utils/consts/WorkerAPI.ts +++ b/ets2panda/linter/src/lib/utils/consts/WorkerAPI.ts @@ -14,4 +14,4 @@ */ export const WORKER_TEXT = 'worker'; -export const WORKER_MODULES = ['@ohos.worker.d.ts', '@kit.ArkTS.d.ts']; +export const WORKER_MODULES = ['@ohos.worker', '@kit.ArkTS']; diff --git a/ets2panda/linter/src/lib/utils/functions/ArrayUtils.ts b/ets2panda/linter/src/lib/utils/functions/ArrayUtils.ts index 60bb8d6c96c091cc4bd7920c9a1955388b059681..83a75ea2ce972715e81bb15fafd11c0307140639 100644 --- a/ets2panda/linter/src/lib/utils/functions/ArrayUtils.ts +++ b/ets2panda/linter/src/lib/utils/functions/ArrayUtils.ts @@ -23,7 +23,7 @@ export default class ArrayUtils { list: readonly T[], deferChecker: (value: T, index: number, array: readonly T[]) => boolean, callbackfn: (value: T, index: number, array: readonly T[]) => void, - thisArg?: Object + thisArg?: object ): void { if (!list.length) { return; diff --git a/ets2panda/linter/src/lib/utils/functions/IsStruct.ts b/ets2panda/linter/src/lib/utils/functions/IsStruct.ts index b766931529cd9b5197d1ebe5fae4cc47f7ee37a1..7b450748c14b33b203e25612977ad833e0bdde85 100644 --- a/ets2panda/linter/src/lib/utils/functions/IsStruct.ts +++ b/ets2panda/linter/src/lib/utils/functions/IsStruct.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -14,7 +14,7 @@ */ import type * as ts from 'typescript'; -import { LinterConfig } from '../../TypeScriptLinterConfig'; +import { TypeScriptLinterConfig } from '../../TypeScriptLinterConfig'; export function isStruct(symbol: ts.Symbol): boolean { if (!symbol.declarations) { @@ -29,7 +29,7 @@ export function isStruct(symbol: ts.Symbol): boolean { } export function isStructDeclarationKind(kind: ts.SyntaxKind): boolean { - return LinterConfig.tsSyntaxKindNames[kind] === 'StructDeclaration'; + return TypeScriptLinterConfig.tsSyntaxKindNames[kind] === 'StructDeclaration'; } export function isStructDeclaration(node: ts.Node): boolean { diff --git a/ets2panda/linter/src/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts b/ets2panda/linter/src/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts index 340170715602ff4a3e7bbaa8eff1be011f1abf34..453f5f7e9af4f25ad70f3648becbda7234c098c6 100644 --- a/ets2panda/linter/src/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts +++ b/ets2panda/linter/src/lib/utils/functions/LibraryTypeCallDiagnosticChecker.ts @@ -133,7 +133,6 @@ export class LibraryTypeCallDiagnosticChecker { }); } - // eslint-disable-next-line max-lines-per-function filterDiagnostics( tscDiagnostics: readonly ts.Diagnostic[], expr: ts.CallExpression | ts.NewExpression, diff --git a/ets2panda/linter/src/sdk/linter_1_1/LintParameter.ts b/ets2panda/linter/src/sdk/linter_1_1/LintParameter.ts index ed31ce04a21708028f02fbeffbb622cc51413b8f..f3cdd6f08f870a2a9ce5a9d14d8c6eb9fc936fb6 100644 --- a/ets2panda/linter/src/sdk/linter_1_1/LintParameter.ts +++ b/ets2panda/linter/src/sdk/linter_1_1/LintParameter.ts @@ -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 @@ -14,16 +14,15 @@ */ import type * as ts from 'typescript'; -import type { InteropTypescriptLinter } from '../../lib/InteropTypescriptLinter'; -import type { TypeScriptLinter } from '../../lib/TypeScriptLinter'; import type { IncrementalLinterState } from './IncrementalLinter'; +import type { SdkOptions } from './SdkOptions'; export interface LintParameter { incrementalLinterState: IncrementalLinterState; - typeScriptLinter: TypeScriptLinter; - interopTypescriptLinter: InteropTypescriptLinter; tscStrictDiagnostics: Map; diagnostics: ts.Diagnostic[]; etsLoaderPath?: string; tsImportSendableEnable?: boolean; + program: ts.Program; + sdkOptions?: SdkOptions; } diff --git a/ets2panda/linter/src/sdk/linter_1_1/RunArkTSLinter.ts b/ets2panda/linter/src/sdk/linter_1_1/RunArkTSLinter.ts index 2f950ae644a6bedcaa0f9c670f5fe086551d89c2..cb6a206c377ca43f22eb69c24b713364d55d48a9 100644 --- a/ets2panda/linter/src/sdk/linter_1_1/RunArkTSLinter.ts +++ b/ets2panda/linter/src/sdk/linter_1_1/RunArkTSLinter.ts @@ -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 @@ -76,18 +76,17 @@ export function runArkTSLinter( timePrinterInstance.appendTime(TimePhase.GET_TSC_DIAGNOSTICS); const etsLoaderPath = program.getCompilerOptions().etsLoaderPath; const tsImportSendableEnable = program.getCompilerOptions().tsImportSendableEnable; - const typeScriptLinter = createTypeScriptLinter(program, tscStrictDiagnostics, sdkOptions); LibraryTypeCallDiagnosticChecker.instance.rebuildTscDiagnostics(tscStrictDiagnostics); - const interopTypescriptLinter = createInteropTypescriptLinter(program, !!sdkOptions?.isUseRtLogic); - processFiles(srcFiles, { + const lintParam: LintParameter = { incrementalLinterState, - typeScriptLinter, - interopTypescriptLinter, tscStrictDiagnostics, diagnostics, etsLoaderPath, - tsImportSendableEnable - }); + tsImportSendableEnable, + program, + sdkOptions + }; + processFiles(srcFiles, lintParam, tscStrictDiagnostics); timePrinterInstance.appendTime(TimePhase.LINT); if (buildInfoWriteFile) { IncrementalLinterState.emitBuildInfo(buildInfoWriteFile, tscDiagnosticsLinter.getBuilderProgram()); @@ -97,14 +96,18 @@ export function runArkTSLinter( return diagnostics; } -function processFiles(srcFiles: ts.SourceFile[], lintParameter: LintParameter): void { +function processFiles( + srcFiles: ts.SourceFile[], + lintParameter: LintParameter, + tscStrictDiagnostics: Map +): void { for (const fileToLint of srcFiles) { const scriptKind = getScriptKind(fileToLint); if (scriptKind !== ts.ScriptKind.ETS && scriptKind !== ts.ScriptKind.TS) { continue; } - const currentDiagnostics = getDiagnostic(fileToLint, scriptKind, lintParameter); + const currentDiagnostics = getDiagnostic(fileToLint, scriptKind, lintParameter, tscStrictDiagnostics); lintParameter.diagnostics.push(...currentDiagnostics); lintParameter.incrementalLinterState.updateDiagnostics(fileToLint, currentDiagnostics); } @@ -113,19 +116,20 @@ function processFiles(srcFiles: ts.SourceFile[], lintParameter: LintParameter): function getDiagnostic( fileToLint: ts.SourceFile, scriptKind: ts.ScriptKind, - lintParameter: LintParameter + lintParameter: LintParameter, + tscStrictDiagnostics: Map ): ts.Diagnostic[] { let currentDiagnostics: ts.Diagnostic[] = []; if (lintParameter.incrementalLinterState.isFileChanged(fileToLint)) { if (scriptKind === ts.ScriptKind.ETS) { - lintParameter.typeScriptLinter.lint(fileToLint); + const typeScriptLinter = createTypeScriptLinter(fileToLint, lintParameter, tscStrictDiagnostics); + typeScriptLinter.lint(); // Get list of bad nodes from the current run. currentDiagnostics = lintParameter.tscStrictDiagnostics.get(path.normalize(fileToLint.fileName)) ?? []; - lintParameter.typeScriptLinter.problemsInfos.forEach((x) => { + typeScriptLinter.problemsInfos.forEach((x) => { return currentDiagnostics.push(translateDiag(fileToLint, x)); }); - lintParameter.typeScriptLinter.problemsInfos.length = 0; } else { if ( path.basename(fileToLint.fileName).toLowerCase(). @@ -145,11 +149,11 @@ function getDiagnostic( return currentDiagnostics; } - lintParameter.interopTypescriptLinter.lint(fileToLint); - lintParameter.interopTypescriptLinter.problemsInfos.forEach((x) => { + const interopTypescriptLinter = createInteropTypescriptLinter(lintParameter.program, fileToLint, lintParameter); + interopTypescriptLinter.lint(); + interopTypescriptLinter.problemsInfos.forEach((x) => { return currentDiagnostics.push(translateDiag(fileToLint, x)); }); - lintParameter.interopTypescriptLinter.problemsInfos.length = 0; } } else { // Get diagnostics from old run. @@ -169,34 +173,38 @@ function getSrcFiles(program: ts.Program, srcFile?: ts.SourceFile): ts.SourceFil } function createTypeScriptLinter( - program: ts.Program, - tscStrictDiagnostics: Map, - sdkOptions?: SdkOptions + sourceFile: ts.SourceFile, + lintParameter: LintParameter, + tscStrictDiagnostics: Map ): TypeScriptLinter { TypeScriptLinter.initGlobals(); return new TypeScriptLinter( - program.getLinterTypeChecker(), + lintParameter.program.getLinterTypeChecker(), { - ideMode: true, - enableAutofix: sdkOptions?.needAutoFix, - useRtLogic: sdkOptions?.isUseRtLogic, - compatibleSdkVersion: program.getCompilerOptions().compatibleSdkVersion, - compatibleSdkVersionStage: program.getCompilerOptions().compatibleSdkVersionStage + enableAutofix: lintParameter.sdkOptions?.needAutoFix, + useRtLogic: lintParameter.sdkOptions?.isUseRtLogic, + compatibleSdkVersion: lintParameter.program.getCompilerOptions().compatibleSdkVersion, + compatibleSdkVersionStage: lintParameter.program.getCompilerOptions().compatibleSdkVersionStage }, + sourceFile, tscStrictDiagnostics ); } -function createInteropTypescriptLinter(program: ts.Program, useRtLogic: boolean): InteropTypescriptLinter { +function createInteropTypescriptLinter( + program: ts.Program, + sourceFile: ts.SourceFile, + lintParameter: LintParameter +): InteropTypescriptLinter { InteropTypescriptLinter.initGlobals(); return new InteropTypescriptLinter( program.getLinterTypeChecker(), program.getCompilerOptions(), { - ideMode: true, - useRtLogic: useRtLogic + etsLoaderPath: lintParameter.etsLoaderPath, + useRtLogic: lintParameter.sdkOptions?.isUseRtLogic }, - program.getCompilerOptions().etsLoaderPath + sourceFile ); } diff --git a/ets2panda/linter/src/testRunner/Consts.ts b/ets2panda/linter/src/testRunner/Consts.ts new file mode 100644 index 0000000000000000000000000000000000000000..cc5c33ea357d553c9eb2ba54a0a34d22602e851b --- /dev/null +++ b/ets2panda/linter/src/testRunner/Consts.ts @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022-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 const TAB = ' '; +export const RESULTS_DIR = 'results'; + +export const DIFF_EXT = '.diff'; +export const TEST_EXTENSION_ETS = '.ets'; +export const TEST_EXTENSION_D_ETS = '.d.ets'; + +export const MIGRATE_RESULT_SUFFIX = '.migrate'; diff --git a/ets2panda/linter/src/testRunner/FileUtil.ts b/ets2panda/linter/src/testRunner/FileUtil.ts new file mode 100644 index 0000000000000000000000000000000000000000..2d21d616d304b76bec728fff6df83151ac331c00 --- /dev/null +++ b/ets2panda/linter/src/testRunner/FileUtil.ts @@ -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. + */ + +import * as fs from 'node:fs'; + +export function readLines(filePath: string): string[] { + const text = fs.readFileSync(filePath).toString(); + return text.split(/\r\n|\n|\r/); +} diff --git a/ets2panda/linter/src/testRunner/LintTest.ts b/ets2panda/linter/src/testRunner/LintTest.ts new file mode 100644 index 0000000000000000000000000000000000000000..02db53dd4993067c10a6897c7fc08d5b0563dc62 --- /dev/null +++ b/ets2panda/linter/src/testRunner/LintTest.ts @@ -0,0 +1,199 @@ +/* + * 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 * as fs from 'node:fs'; +import * as path from 'node:path'; +import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import type { LinterConfig } from '../lib/LinterConfig'; +import { lint } from '../lib/LinterRunner'; +import { Logger } from '../lib/Logger'; +import { compileLintOptions } from '../lib/ts-compiler/Compiler'; +import type { TestModeProperties } from './TestMode'; +import { TestMode } from './TestMode'; +import { transformProblemInfos } from './TestUtil'; +import type { TestProblemInfo, TestResult } from './TestResult'; +import { validateTestResult } from './TestResult'; +import type { LintRunResult } from '../lib/LintRunResult'; +import { DIFF_EXT, RESULTS_DIR, TAB } from './Consts'; +import type { Autofix } from '../lib/autofixes/Autofixer'; +import type { CreateLintTestOptions } from './TestFactory'; + +export class LintTest { + readonly testDir: string; + readonly testFile: string; + readonly testModeProps: TestModeProperties; + readonly cmdOptions: CommandLineOptions; + + constructor(createLintTestOpts: CreateLintTestOptions) { + this.testDir = createLintTestOpts.testDir; + this.testFile = createLintTestOpts.testFile; + this.testModeProps = createLintTestOpts.testModeProps; + this.cmdOptions = createLintTestOpts.cmdOptions; + } + + run(): boolean { + Logger.info(`Running test ${this.testFile} (${TestMode[this.testModeProps.mode]} mode)`); + + const linterConfig = this.compile(); + const linterResult = lint(linterConfig); + return this.validate(linterResult); + } + + compile(): LinterConfig { + return compileLintOptions(this.cmdOptions); + } + + validate(actualLinterResult: LintRunResult): boolean { + // Get actual test results. + const fileProblems = actualLinterResult.problemsInfos.get(path.normalize(this.cmdOptions.inputFiles[0])); + if (fileProblems === undefined) { + return true; + } + const actualResult = transformProblemInfos(fileProblems, this.testModeProps.mode); + + // Read file with expected test result. + const resultDiff = this.compareLintResult(actualResult); + + // Write file with actual test results. + this.writeLintResultFile(actualResult, resultDiff); + return !resultDiff; + } + + private static readLintResultFile(testDir: string, testResultFileName: string): TestProblemInfo[] { + const filePath = path.join(testDir, testResultFileName); + try { + const testResult = fs.readFileSync(filePath).toString(); + return validateTestResult(JSON.parse(testResult)).result; + } catch (error) { + throw new Error(`Failed to process ${filePath}: ${(error as Error).message}`); + } + } + + private compareLintResult(actual: TestProblemInfo[]): string { + // Read file with expected test result. + let diff: string = ''; + const testResultFileName = this.testFile + this.testModeProps.resultFileExt; + try { + let expected = LintTest.readLintResultFile(this.testDir, testResultFileName); + + /** + * The exclusive field is added to identify whether the use case is exclusive to the RT or SDK + * RT means the RT exclusive + * SDK means the SDK exclusive + * undefined means shared + */ + expected = expected.filter((x) => { + return !x?.exclusive || x.exclusive === (this.cmdOptions.linterOptions.useRtLogic ? 'RT' : 'SDK'); + }); + + if (!expected || expected.length !== actual.length) { + const expectedResultCount = expected ? expected.length : 0; + diff = `Expected count: ${expectedResultCount} vs actual count: ${actual.length}`; + } else { + diff = LintTest.expectedAndActualMatch(expected, actual); + } + + if (diff) { + Logger.info(`${TAB}Lint test failed. Expected and actual results differ:\n${diff}`); + } + } catch (error) { + // Write error message to diff, as non-empty diff indicates that test has failed. + diff = (error as Error).message; + Logger.info(`${TAB}Failed to compare expected and actual results. ` + diff); + } + + return diff; + } + + private static expectedAndActualMatch(expectedNodes: TestProblemInfo[], actualNodes: TestProblemInfo[]): string { + // Compare expected and actual results. + for (let i = 0; i < actualNodes.length; i++) { + const actual = actualNodes[i]; + const expected = expectedNodes[i]; + if (!LintTest.locationMatch(expected, actual) || actual.problem !== expected.problem) { + return LintTest.reportLintResultDiff(expected, actual); + } + if (!LintTest.autofixArraysMatch(expected.autofix, actual.autofix)) { + return LintTest.reportLintResultDiff(expected, actual); + } + if (expected.suggest && actual.suggest !== expected.suggest) { + return LintTest.reportLintResultDiff(expected, actual); + } + if (expected.rule && actual.rule !== expected.rule) { + return LintTest.reportLintResultDiff(expected, actual); + } + if (expected.severity && actual.severity !== expected.severity) { + return LintTest.reportLintResultDiff(expected, actual); + } + } + + return ''; + } + + private static locationMatch(expected: TestProblemInfo, actual: TestProblemInfo): boolean { + return ( + actual.line === expected.line && + actual.column === expected.column && + (!expected.endLine || actual.endLine === expected.endLine) && + (!expected.endColumn || actual.endColumn === expected.endColumn) + ); + } + + private static autofixArraysMatch(expected: Autofix[] | undefined, actual: Autofix[] | undefined): boolean { + if (!expected && !actual) { + return true; + } + if (!(expected && actual) || expected.length !== actual.length) { + return false; + } + for (let i = 0; i < actual.length; ++i) { + if ( + actual[i].start !== expected[i].start || + actual[i].end !== expected[i].end || + actual[i].replacementText !== expected[i].replacementText + ) { + return false; + } + } + return true; + } + + private writeLintResultFile(actual: TestProblemInfo[], diff: string): void { + const actualResultsDir = path.join(this.testDir, RESULTS_DIR); + if (!fs.existsSync(actualResultsDir)) { + fs.mkdirSync(actualResultsDir); + } + + const actualTestResult: TestResult = { result: actual }; + const actualResultJSON = JSON.stringify(actualTestResult, null, 4); + fs.writeFileSync(path.join(actualResultsDir, this.testFile + this.testModeProps.resultFileExt), actualResultJSON); + + if (diff) { + fs.writeFileSync(path.join(actualResultsDir, this.testFile + this.testModeProps.resultFileExt + DIFF_EXT), diff); + } + } + + private static reportLintResultDiff(expected: TestProblemInfo, actual: TestProblemInfo): string { + const expectedNode = JSON.stringify({ nodes: [expected] }, null, 4); + const actualNode = JSON.stringify({ nodes: [actual] }, null, 4); + + const diff = `Expected: +${expectedNode} +Actual: +${actualNode}`; + + return diff; + } +} diff --git a/ets2panda/linter/src/testRunner/MigrateTest.ts b/ets2panda/linter/src/testRunner/MigrateTest.ts new file mode 100644 index 0000000000000000000000000000000000000000..a849e1db74e1a4cf46b88025c37a45501c958119 --- /dev/null +++ b/ets2panda/linter/src/testRunner/MigrateTest.ts @@ -0,0 +1,140 @@ +/* + * 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 * as fs from 'node:fs'; +import * as path from 'node:path'; +import type { LinterConfig } from '../lib/LinterConfig'; +import { Logger } from '../lib/Logger'; +import { compileLintOptions } from '../lib/ts-compiler/Compiler'; +import type { LintRunResult } from '../lib/LintRunResult'; +import { DIFF_EXT, MIGRATE_RESULT_SUFFIX, RESULTS_DIR, TAB } from './Consts'; +import { LintTest } from './LintTest'; +import type { CreateLintTestOptions } from './TestFactory'; +import { readLines } from './FileUtil'; + +export class MigrateTest extends LintTest { + constructor(createLintTestOpts: CreateLintTestOptions) { + super(createLintTestOpts); + } + + compile(): LinterConfig { + this.cmdOptions.linterOptions.migratorMode = true; + + // Set filepath mapping to write migration result at 'results' dir instead of modifying original test file + const filePathMap = new Map(); + filePathMap.set( + path.normalize(path.join(this.testDir, this.testFile)), + path.normalize(this.getActualMigrateResultsFilePath()) + ); + this.cmdOptions.linterOptions.migrationFilePathMap = filePathMap; + + return compileLintOptions(this.cmdOptions); + } + + validate(actualLinterResult: LintRunResult): boolean { + const validateBase = super.validate(actualLinterResult); + const validateMigrateResult = this.validateMigrateResult(); + return validateBase && validateMigrateResult; + } + + private validateMigrateResult(): boolean { + this.writeMigrationResultForUnchangedFiles(); + const resultDiff = this.compareMigrateResult(); + if (resultDiff) { + this.writeMigrateDiff(resultDiff); + } + return !resultDiff; + } + + private compareMigrateResult(): string { + let diff: string = ''; + try { + const expectedResult = readFileLines(this.getExpectedMigrateResultsFilePath()); + const actualResult = readFileLines(this.getActualMigrateResultsFilePath()); + + if (expectedResult.length !== actualResult.length) { + diff = `Expected lines: ${expectedResult.length} vs actual lines: ${actualResult.length}`; + } else { + diff = MigrateTest.compareTextLines(expectedResult, actualResult); + } + + if (diff) { + Logger.info(`${TAB}Migration test failed. Expected and actual results differ:\n${diff}`); + } + } catch (error) { + // Write error message to diff, as non-empty diff indicates that test has failed. + diff = (error as Error).message; + Logger.info(`${TAB}Failed to compare expected and actual results. ` + diff); + } + + return diff; + } + + private static compareTextLines(expected: string[], actual: string[]): string { + for (let i = 0; i < expected.length && i < actual.length; i++) { + if (expected[i] !== actual[i]) { + const diff = `Difference at line ${i + 1} +Expected: +${expected[i]} +Actual: +${actual[i]}`; + return diff; + } + } + return ''; + } + + writeMigrateDiff(diff: string): void { + fs.writeFileSync(this.getActualMigrateResultsFilePath() + DIFF_EXT, diff); + } + + writeMigrationResultForUnchangedFiles(): void { + + /* + * If test file doesn't produce any autofix, the migration result won't be created. + * In such case, use original text of the test file as migration result. + */ + const filePathMap = this.cmdOptions.linterOptions.migrationFilePathMap; + if (!filePathMap) { + return; + } + filePathMap.forEach((targetFile, srcFile) => { + if (fs.existsSync(targetFile)) { + return; + } + fs.copyFileSync(srcFile, targetFile); + }); + } + + private getMigrateResultFileName(): string { + return this.testFile + MIGRATE_RESULT_SUFFIX + path.extname(this.testFile); + } + + private getExpectedMigrateResultsFilePath(): string { + return path.join(this.testDir, this.getMigrateResultFileName()); + } + + private getActualMigrateResultsFilePath(): string { + return path.join(this.testDir, RESULTS_DIR, this.getMigrateResultFileName()); + } +} + +function readFileLines(filePath: string): string[] { + try { + return readLines(filePath); + } catch (error) { + throw new Error(`Failed to process ${filePath}: ${(error as Error).message}`); + } +} diff --git a/ets2panda/linter/src/testRunner/RunTestFileOptions.ts b/ets2panda/linter/src/testRunner/RunTestFileOptions.ts new file mode 100644 index 0000000000000000000000000000000000000000..0f894ccaf7446c48629640efbe15b2df01e08b29 --- /dev/null +++ b/ets2panda/linter/src/testRunner/RunTestFileOptions.ts @@ -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. + */ + +import type { TestRunnerOptions } from './TestRunnerOptions'; + +export interface RunTestFileOptions { + testDir: string; + testFile: string; + testRunnerOpts: TestRunnerOptions; +} diff --git a/ets2panda/linter/src/testRunner/TestArgs.ts b/ets2panda/linter/src/testRunner/TestArgs.ts index d18564e118183d9674aedf2e6ee92ed00a69f3a7..f29c782f7b0f40c848fe2633487ad1fdb432bd61 100644 --- a/ets2panda/linter/src/testRunner/TestArgs.ts +++ b/ets2panda/linter/src/testRunner/TestArgs.ts @@ -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 @@ -13,8 +13,11 @@ * limitations under the License. */ +import * as fs from 'node:fs'; +import * as path from 'node:path'; import * as yup from 'yup'; +const ARGS_CONFIG_EXT = '.args.json'; const TAB = ' '; /** @@ -60,6 +63,7 @@ export interface TestArguments { /** * Enables 'migrate' mode, runs test with '--migrate' option. + * Performs code migration and produces new test code. */ migrate?: string; }; @@ -90,3 +94,17 @@ export function validateTestArgs(value: object): TestArguments { throw error; } } + +export function readTestArgsFile(testDir: string, testFile: string): TestArguments | undefined { + const argsFileName = path.join(testDir, testFile + ARGS_CONFIG_EXT); + if (fs.existsSync(argsFileName)) { + try { + const data = fs.readFileSync(argsFileName).toString(); + const json = JSON.parse(data); + return validateTestArgs(json); + } catch (error) { + throw new Error(`Failed to process ${argsFileName}: ${(error as Error).message}`); + } + } + return undefined; +} diff --git a/ets2panda/linter/src/testRunner/TestFactory.ts b/ets2panda/linter/src/testRunner/TestFactory.ts new file mode 100644 index 0000000000000000000000000000000000000000..ef4a2906ab6cac5c4d8f173d897c30f90e1e67a0 --- /dev/null +++ b/ets2panda/linter/src/testRunner/TestFactory.ts @@ -0,0 +1,134 @@ +/* + * 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 * as path from 'node:path'; +import type { CommandLineOptions } from '../lib/CommandLineOptions'; +import type { LinterOptions } from '../lib/LinterOptions'; +import { LintTest } from './LintTest'; +import type { RunTestFileOptions } from './RunTestFileOptions'; +import { parseCommandLine } from '../cli/CommandLineParser'; +import { getCommandLineArguments } from './CommandLineUtil'; +import type { TestModeProperties } from './TestMode'; +import { DEFAULT_MODE_PROPERTIES, TestMode, testModePropsMap } from './TestMode'; +import type { TestArguments } from './TestArgs'; +import { readTestArgsFile } from './TestArgs'; +import { MigrateTest } from './MigrateTest'; + +interface CreateTestOptions { + runTestFileOpts: RunTestFileOptions; + testModeProps: TestModeProperties; + testModeArgs?: string; + testCommonOpts?: LinterOptions; +} + +export interface CreateLintTestOptions { + testDir: string; + testFile: string; + testModeProps: TestModeProperties; + cmdOptions: CommandLineOptions; +} + +export function createTests(runTestFileOpts: RunTestFileOptions): LintTest[] { + const testArgs = readTestArgsFile(runTestFileOpts.testDir, runTestFileOpts.testFile); + return testArgs ? + createTestsFromTestArgs(runTestFileOpts, testArgs) : + [createTest({ runTestFileOpts, testModeProps: DEFAULT_MODE_PROPERTIES })]; +} + +function createTestsFromTestArgs(runTestFileOpts: RunTestFileOptions, testArgs: TestArguments): LintTest[] { + const tests: LintTest[] = []; + const testCommonOpts = testArgs.commonArgs ? getLinterOptionsFromCommandLine(testArgs.commonArgs) : undefined; + + addDefaultModeIfNeeded(testArgs); + + if (testArgs.mode) { + for (const mode of Object.keys(testArgs.mode)) { + const testModeProps = testModePropsMap.get(mode); + if (!testModeProps) { + throw new Error(`Failed to create test. Unknown mode: '${mode}'`); + } + const testModeArgs: string | undefined = testArgs.mode[mode]; + tests.push(createTest({ runTestFileOpts, testModeProps, testCommonOpts, testModeArgs })); + } + } + + return tests; +} + +function addDefaultModeIfNeeded(testArgs: TestArguments): void { + if (testArgs.mode?.default === undefined) { + // For convenience, always add 'default' mode as first + testArgs.mode = Object.assign({ default: '' }, testArgs.mode); + } +} + +function createTest(createTestOpts: CreateTestOptions): LintTest { + const opts = createCreateLintTestOpts(createTestOpts); + if (createTestOpts.testModeProps.mode === TestMode.MIGRATE) { + return new MigrateTest(opts); + } + return new LintTest(opts); +} + +function createCreateLintTestOpts(createTestConfigOpts: CreateTestOptions): CreateLintTestOptions { + const { runTestFileOpts, testCommonOpts, testModeArgs, testModeProps } = createTestConfigOpts; + const { testDir, testFile, testRunnerOpts } = runTestFileOpts; + + /* + * Test options are formed in the following order (from lowest to highest priority): + * - default test options; + * - [test_args_file] --> 'commonArgs'; + * - [test_args_file] --> the arguments specified for a mode; + * - options specified by TestRunner command-line arguments; + * - options that enable specific mode. + */ + const linterOpts = getDefaultTestOptions(); + if (testCommonOpts) { + Object.assign(linterOpts, testCommonOpts); + } + if (testModeArgs) { + Object.assign(linterOpts, getLinterOptionsFromCommandLine(testModeArgs)); + } + Object.assign(linterOpts, testRunnerOpts.linterOptions); + Object.assign(linterOpts, testModeProps.modeOpts); + + const cmdOptions: CommandLineOptions = { + inputFiles: [path.join(testDir, testFile)], + linterOptions: linterOpts + }; + + return { + testDir, + testFile, + testModeProps, + cmdOptions + }; +} + +function getLinterOptionsFromCommandLine(cmdLine: string): LinterOptions { + return parseCommandLine(getCommandLineArguments(cmdLine), { exitOnFail: false, disableErrorOutput: true }). + linterOptions; +} + +function getDefaultTestOptions(): LinterOptions { + return { + useRtLogic: true, + checkTsAsSource: + true /* By default, treat any test file with '.ts' extension as a source file (as opposed to library) */, + compatibleSdkVersion: 12, + compatibleSdkVersionStage: 'beta3', + checkTsAndJs: true + }; +} diff --git a/ets2panda/linter/src/testRunner/TestMode.ts b/ets2panda/linter/src/testRunner/TestMode.ts new file mode 100644 index 0000000000000000000000000000000000000000..7bec4187e586487de43dcbb7d9cf21aee36e4d52 --- /dev/null +++ b/ets2panda/linter/src/testRunner/TestMode.ts @@ -0,0 +1,64 @@ +/* + * 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 { LinterOptions } from '../lib/LinterOptions'; + +export enum TestMode { + DEFAULT, + AUTOFIX, + ARKTS2, + MIGRATE +} + +export interface TestModeProperties { + resultFileExt: string; + mode: TestMode; + modeOpts: LinterOptions; +} + +export const DEFAULT_MODE_PROPERTIES: TestModeProperties = { + resultFileExt: '.json', + mode: TestMode.DEFAULT, + modeOpts: {} +}; +const AUTOFIX_MODE_PROPERTIES: TestModeProperties = { + resultFileExt: '.autofix.json', + mode: TestMode.AUTOFIX, + modeOpts: { + enableAutofix: true + } +}; +const ARKTS2_MODE_PROPERTIES: TestModeProperties = { + resultFileExt: '.arkts2.json', + mode: TestMode.ARKTS2, + modeOpts: { + arkts2: true + } +}; +const MIGRATE_MODE_PROPERTIES: TestModeProperties = { + resultFileExt: '.migrate.json', + mode: TestMode.MIGRATE, + modeOpts: { + migratorMode: true, + noMigrationBackupFile: true + } +}; + +export const testModePropsMap: Map = new Map([ + ['default', DEFAULT_MODE_PROPERTIES], + ['autofix', AUTOFIX_MODE_PROPERTIES], + ['arkts2', ARKTS2_MODE_PROPERTIES], + ['migrate', MIGRATE_MODE_PROPERTIES] +]); diff --git a/ets2panda/linter/src/testRunner/TestResult.ts b/ets2panda/linter/src/testRunner/TestResult.ts index 37e064e22d42cf6d2b091b3a0518b70fd2af6983..d1754cdebab468718d2b101428bbe29f3e767c9b 100644 --- a/ets2panda/linter/src/testRunner/TestResult.ts +++ b/ets2panda/linter/src/testRunner/TestResult.ts @@ -38,7 +38,11 @@ export interface TestProblemInfo { const autofixResultSchema: yup.ObjectSchema = yup.object({ replacementText: yup.string().defined(), start: yup.number().required(), - end: yup.number().required() + end: yup.number().required(), + line: yup.number().optional(), + column: yup.number().optional(), + endLine: yup.number().optional(), + endColumn: yup.number().optional() }); const testResultSchema: yup.ObjectSchema = yup.object({ diff --git a/ets2panda/linter/src/testRunner/TestRunner.ts b/ets2panda/linter/src/testRunner/TestRunner.ts index 62ce4f9d4415e4c642009a3235f3a7af6b25e985..4d3639fb3225a8fe9765d4f8207e96fd82ed8667 100755 --- a/ets2panda/linter/src/testRunner/TestRunner.ts +++ b/ets2panda/linter/src/testRunner/TestRunner.ts @@ -13,118 +13,29 @@ * limitations under the License. */ -import { Logger } from '../lib/Logger'; -import { LoggerImpl } from '../cli/LoggerImpl'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as ts from 'typescript'; -import type { CommandLineOptions } from '../lib/CommandLineOptions'; -import { lint } from '../lib/LinterRunner'; -import { TypeScriptLinter } from '../lib/TypeScriptLinter'; -import { InteropTypescriptLinter } from '../lib/InteropTypescriptLinter'; -import type { Autofix } from '../lib/autofixes/Autofixer'; -import { parseCommandLine as parseLinterCommandLine } from '../cli/CommandLineParser'; -import { compileLintOptions } from '../cli/Compiler'; -import { getEtsLoaderPath } from '../cli/LinterCLI'; -import { ProblemSeverity } from '../lib/ProblemSeverity'; -import type { ProblemInfo } from '../lib/ProblemInfo'; -import type { TestArguments } from './TestArgs'; -import { validateTestArgs } from './TestArgs'; -import type { LinterOptions } from '../lib/LinterOptions'; +import { Logger } from '../lib/Logger'; +import { LoggerImpl } from '../cli/LoggerImpl'; import { Command } from 'commander'; import { rimrafSync } from 'rimraf'; -import type { TestProblemInfo, TestResult } from './TestResult'; -import { validateTestResult } from './TestResult'; import { globSync } from 'glob'; import type { Path } from 'path-scurry'; import { PathScurry } from 'path-scurry'; -import { getCommandLineArguments } from './CommandLineUtil'; +import { createTests } from './TestFactory'; +import type { LintTest } from './LintTest'; +import type { TestRunnerOptions } from './TestRunnerOptions'; +import type { RunTestFileOptions } from './RunTestFileOptions'; +import { MIGRATE_RESULT_SUFFIX, RESULTS_DIR, TAB } from './Consts'; Logger.init(new LoggerImpl()); -const TAB = ' '; -const RESULTS_DIR = 'results'; - -const ARGS_CONFIG_EXT = '.args.json'; -const DIFF_EXT = '.diff'; -const TEST_EXTENSION_ETS = '.ets'; -const TEST_EXTENSION_ETSX = '.etsx'; -const TEST_EXTENSION_D_ETS = '.d.ets'; - interface TestStatistics { passed: number; failed: number; } -enum TestMode { - DEFAULT, - AUTOFIX, - ARKTS2, - MIGRATE -} - -interface CreateTestConfigurationOptions { - runTestFileOpts: RunTestFileOptions; - testModeProps: TestModeProperties; - testModeArgs?: string; - testCommonOpts?: LinterOptions; -} - -interface TestRunnerOptions { - linterOptions: LinterOptions; - testDirs: string[]; - testPattern?: string; -} - -interface RunTestFileOptions { - testDir: string; - testFile: string; - testRunnerOpts: TestRunnerOptions; -} - -interface TestModeProperties { - resultFileExt: string; - mode: TestMode; - modeOpts: LinterOptions; -} - -const DEFAULT_MODE_PROPERTIES: TestModeProperties = { - resultFileExt: '.json', - mode: TestMode.DEFAULT, - modeOpts: {} -}; -const AUTOFIX_MODE_PROPERTIES: TestModeProperties = { - resultFileExt: '.autofix.json', - mode: TestMode.AUTOFIX, - modeOpts: { - enableAutofix: true - } -}; -const ARKTS2_MODE_PROPERTIES: TestModeProperties = { - resultFileExt: '.arkts2.json', - mode: TestMode.ARKTS2, - modeOpts: { - arkts2: true - } -}; - -const MIGRATE_MODE_PROPERTIES: TestModeProperties = { - resultFileExt: '.migrate.json', - mode: TestMode.MIGRATE, - modeOpts: { - arkts2: true, - migratorMode: true, - ideMode: false - } -}; - -interface TestConfiguration { - testDir: string; - testFile: string; - testModeProps: TestModeProperties; - cmdOptions: CommandLineOptions; -} - export function getSdkConfigOptions(configFile: string): ts.CompilerOptions { // initial configuration const options = ts.readConfigFile(configFile, ts.sys.readFile).config.compilerOptions; @@ -219,12 +130,12 @@ function runTests(): boolean { collectTestFilesWithGlob(testDir, testRunnerOpts.testPattern) : fs.readdirSync(testDir); testFiles = testFiles.filter((x) => { + const file = x.trimEnd(); return ( - x.trimEnd().endsWith(ts.Extension.Ts) && !x.trimEnd().endsWith(ts.Extension.Dts) || - x.trimEnd().endsWith(ts.Extension.Tsx) || - x.trimEnd().endsWith(ts.Extension.Ets) || - x.trimEnd().endsWith(TEST_EXTENSION_ETS) && !x.trimEnd().endsWith(TEST_EXTENSION_D_ETS) || - x.trimEnd().endsWith(TEST_EXTENSION_ETSX) + (file.endsWith(ts.Extension.Ts) && !file.endsWith(ts.Extension.Dts) || + file.endsWith(ts.Extension.Tsx) || + file.endsWith(ts.Extension.Ets)) && + !file.endsWith(MIGRATE_RESULT_SUFFIX + path.extname(file)) ); }); runTestFiles(testFiles, testDir, testRunnerOpts, testStats); @@ -264,41 +175,10 @@ function runTestFiles( } function runTestFile(runTestFileOpts: RunTestFileOptions, testStats: TestStatistics): void { - const testConfigs: TestConfiguration[] = []; - - const testArgs = processTestArgsFile(runTestFileOpts.testDir, runTestFileOpts.testFile); - if (testArgs) { - const testCommonOpts = testArgs.commonArgs ? getLinterOptionsFromCommandLine(testArgs.commonArgs) : undefined; - addTestConfiguration(testConfigs, { - runTestFileOpts, - testModeProps: DEFAULT_MODE_PROPERTIES, - testModeArgs: testArgs.mode?.default, - testCommonOpts - }); - addTestConfiguration(testConfigs, { - runTestFileOpts, - testModeProps: AUTOFIX_MODE_PROPERTIES, - testModeArgs: testArgs.mode?.autofix, - testCommonOpts - }); - addTestConfiguration(testConfigs, { - runTestFileOpts, - testModeProps: ARKTS2_MODE_PROPERTIES, - testModeArgs: testArgs.mode?.arkts2, - testCommonOpts - }); - addTestConfiguration(testConfigs, { - runTestFileOpts, - testModeProps: MIGRATE_MODE_PROPERTIES, - testModeArgs: testArgs.mode?.migrate, - testCommonOpts - }); - } else { - addTestConfiguration(testConfigs, { runTestFileOpts, testModeProps: DEFAULT_MODE_PROPERTIES }); - } + const tests: LintTest[] = createTests(runTestFileOpts); - testConfigs.forEach((config: TestConfiguration) => { - if (runTest(config)) { + tests.forEach((test: LintTest) => { + if (test.run()) { ++testStats.passed; } else { ++testStats.failed; @@ -306,259 +186,4 @@ function runTestFile(runTestFileOpts: RunTestFileOptions, testStats: TestStatist }); } -function processTestArgsFile(testDir: string, testFile: string): TestArguments | undefined { - const argsFileName = path.join(testDir, testFile + ARGS_CONFIG_EXT); - if (fs.existsSync(argsFileName)) { - try { - const data = fs.readFileSync(argsFileName).toString(); - const json = JSON.parse(data); - return validateTestArgs(json); - } catch (error) { - throw new Error(`Failed to process ${argsFileName}: ${(error as Error).message}`); - } - } - return undefined; -} - -function addTestConfiguration( - testConfigs: TestConfiguration[], - createTestConfigOpts: CreateTestConfigurationOptions -): void { - const { runTestFileOpts, testModeProps, testModeArgs, testCommonOpts } = createTestConfigOpts; - const { testDir, testFile, testRunnerOpts } = runTestFileOpts; - - if (testModeArgs === undefined && testModeProps.mode !== TestMode.DEFAULT) { - return; - } - - /* - * Test options are formed in the following order (from lowest to highest priority): - * - default test options; - * - [test_args_file] --> 'commonArgs'; - * - [test_args_file] --> the arguments specified for a mode; - * - options specified by TestRunner command-line arguments; - * - options that enable specific mode. - */ - const linterOpts = getDefaultTestOptions(); - if (testCommonOpts) { - Object.assign(linterOpts, testCommonOpts); - } - if (testModeArgs) { - Object.assign(linterOpts, getLinterOptionsFromCommandLine(testModeArgs)); - } - Object.assign(linterOpts, testRunnerOpts.linterOptions); - Object.assign(linterOpts, testModeProps.modeOpts); - - const cmdOptions: CommandLineOptions = { - inputFiles: [path.join(testDir, testFile)], - linterOptions: linterOpts - }; - - testConfigs.push({ - testDir, - testFile, - testModeProps, - cmdOptions - }); -} - -function getDefaultTestOptions(): LinterOptions { - - /* - * Set the IDE mode manually to enable storing information - * about found bad nodes and also disable the log output. - */ - return { - ideMode: true, - useRtLogic: true, - checkTsAsSource: true /* Currently, tests have '.ts' extension, therefore, enable this flag by default */, - compatibleSdkVersion: 12, - compatibleSdkVersionStage: 'beta3' - }; -} - -function getLinterOptionsFromCommandLine(cmdLine: string): LinterOptions { - return parseLinterCommandLine(getCommandLineArguments(cmdLine), { exitOnFail: false, disableErrorOutput: true }). - linterOptions; -} - -function runTest(testConfig: TestConfiguration): boolean { - Logger.info(`Running test ${testConfig.testFile} (${TestMode[testConfig.testModeProps.mode]} mode)`); - - TypeScriptLinter.initGlobals(); - InteropTypescriptLinter.initGlobals(); - - const linterConfig = compileLintOptions(testConfig.cmdOptions); - const linterResult = lint(linterConfig, getEtsLoaderPath(linterConfig)); - - // Get actual test results. - const fileProblems = linterResult.problemsInfos.get(path.normalize(testConfig.cmdOptions.inputFiles[0])); - if (fileProblems === undefined) { - return true; - } - const actualResult = transformProblemInfos(fileProblems, testConfig.testModeProps.mode); - - // Read file with expected test result. - const resultDiff = compareExpectedAndActual(testConfig, actualResult); - - // Write file with actual test results. - writeActualResultFile(testConfig, actualResult, resultDiff); - - return !resultDiff; -} - -function readTestResultFile(testDir: string, testResultFileName: string): TestProblemInfo[] { - const filePath = path.join(testDir, testResultFileName); - try { - const testResult = fs.readFileSync(filePath).toString(); - return validateTestResult(JSON.parse(testResult)).result; - } catch (error) { - throw new Error(`Failed to process ${filePath}: ${(error as Error).message}`); - } -} - -function transformProblemInfos(fileProblems: ProblemInfo[], mode: TestMode): TestProblemInfo[] { - return fileProblems.map((x) => { - return { - line: x.line, - column: x.column, - endLine: x.endLine, - endColumn: x.endColumn, - problem: x.problem, - autofix: mode === TestMode.AUTOFIX ? x.autofix : undefined, - suggest: x.suggest, - rule: x.rule, - severity: ProblemSeverity[x.severity] - }; - }); -} - -function compareExpectedAndActual(testConfig: TestConfiguration, actual: TestProblemInfo[]): string { - const { - testDir, - testFile, - cmdOptions: { linterOptions }, - testModeProps: { resultFileExt } - } = testConfig; - - // Read file with expected test result. - let diff: string = ''; - const testResultFileName = testFile + resultFileExt; - try { - let expected = readTestResultFile(testDir, testResultFileName); - - /** - * The exclusive field is added to identify whether the use case is exclusive to the RT or SDK - * RT means the RT exclusive - * SDK means the SDK exclusive - * undefined means shared - */ - expected = expected.filter((x) => { - return !x?.exclusive || x.exclusive === (linterOptions.useRtLogic ? 'RT' : 'SDK'); - }); - - if (!expected || expected.length !== actual.length) { - const expectedResultCount = expected ? expected.length : 0; - diff = `Expected count: ${expectedResultCount} vs actual count: ${actual.length}`; - Logger.info(`${TAB}${diff}`); - } else { - diff = expectedAndActualMatch(expected, actual); - } - - if (diff) { - Logger.info(`${TAB}Test failed. Expected and actual results differ.`); - } - } catch (error) { - // Write error message to diff, as non-empty diff indicates that test has failed. - diff = (error as Error).message; - Logger.info(`${TAB}Failed to compare expected and actual results. ` + diff); - } - - return diff; -} - -function expectedAndActualMatch(expectedNodes: TestProblemInfo[], actualNodes: TestProblemInfo[]): string { - // Compare expected and actual results. - for (let i = 0; i < actualNodes.length; i++) { - const actual = actualNodes[i]; - const expect = expectedNodes[i]; - if (!locationMatch(expect, actual) || actual.problem !== expect.problem) { - return reportDiff(expect, actual); - } - if (!autofixArraysMatch(expect.autofix, actual.autofix)) { - return reportDiff(expect, actual); - } - if (expect.suggest && actual.suggest !== expect.suggest) { - return reportDiff(expect, actual); - } - if (expect.rule && actual.rule !== expect.rule) { - return reportDiff(expect, actual); - } - if (expect.severity && actual.severity !== expect.severity) { - return reportDiff(expect, actual); - } - } - - return ''; -} - -function locationMatch(expected: TestProblemInfo, actual: TestProblemInfo): boolean { - return ( - actual.line === expected.line && - actual.column === expected.column && - (!expected.endLine || actual.endLine === expected.endLine) && - (!expected.endColumn || actual.endColumn === expected.endColumn) - ); -} - -function autofixArraysMatch(expected: Autofix[] | undefined, actual: Autofix[] | undefined): boolean { - if (!expected && !actual) { - return true; - } - if (!(expected && actual) || expected.length !== actual.length) { - return false; - } - for (let i = 0; i < actual.length; ++i) { - if ( - actual[i].start !== expected[i].start || - actual[i].end !== expected[i].end || - actual[i].replacementText !== expected[i].replacementText - ) { - return false; - } - } - return true; -} - -function writeActualResultFile(testConfig: TestConfiguration, actual: TestProblemInfo[], diff: string): void { - const { - testModeProps: { resultFileExt } - } = testConfig; - const actualResultsDir = path.join(testConfig.testDir, RESULTS_DIR); - if (!fs.existsSync(actualResultsDir)) { - fs.mkdirSync(actualResultsDir); - } - - const actualTestResult: TestResult = { result: actual }; - const actualResultJSON = JSON.stringify(actualTestResult, null, 4); - fs.writeFileSync(path.join(actualResultsDir, testConfig.testFile + resultFileExt), actualResultJSON); - - if (diff) { - fs.writeFileSync(path.join(actualResultsDir, testConfig.testFile + resultFileExt + DIFF_EXT), diff); - } -} - -function reportDiff(expected: TestProblemInfo, actual: TestProblemInfo): string { - const expectedNode = JSON.stringify({ nodes: [expected] }, null, 4); - const actualNode = JSON.stringify({ nodes: [actual] }, null, 4); - - const diff = `Expected: -${expectedNode} -Actual: -${actualNode}`; - - Logger.info(diff); - return diff; -} - runTests(); diff --git a/ets2panda/linter/src/testRunner/TestRunnerOptions.ts b/ets2panda/linter/src/testRunner/TestRunnerOptions.ts new file mode 100644 index 0000000000000000000000000000000000000000..bae4b12fd87ef3762f772b2c49ade58ae4867f70 --- /dev/null +++ b/ets2panda/linter/src/testRunner/TestRunnerOptions.ts @@ -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. + */ + +import type { LinterOptions } from '../lib/LinterOptions'; + +export interface TestRunnerOptions { + linterOptions: LinterOptions; + testDirs: string[]; + testPattern?: string; +} diff --git a/ets2panda/linter/src/testRunner/TestUtil.ts b/ets2panda/linter/src/testRunner/TestUtil.ts new file mode 100644 index 0000000000000000000000000000000000000000..aab666fef07b4789e1735762d2193b221b1f2fed --- /dev/null +++ b/ets2panda/linter/src/testRunner/TestUtil.ts @@ -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. + */ + +import type { ProblemInfo } from '../lib/ProblemInfo'; +import { ProblemSeverity } from '../lib/ProblemSeverity'; +import { TestMode } from './TestMode'; +import type { TestProblemInfo } from './TestResult'; + +export function transformProblemInfos(fileProblems: ProblemInfo[], mode: TestMode): TestProblemInfo[] { + return fileProblems.map((x) => { + return { + line: x.line, + column: x.column, + endLine: x.endLine, + endColumn: x.endColumn, + problem: x.problem, + autofix: mode === TestMode.AUTOFIX ? x.autofix : undefined, + suggest: x.suggest, + rule: x.rule, + severity: ProblemSeverity[x.severity] + }; + }); +} diff --git a/ets2panda/linter/test/builtin/builtin_callsignature.ets b/ets2panda/linter/test/builtin/builtin_callsignature.ets new file mode 100644 index 0000000000000000000000000000000000000000..ccb7f4de952f3bc32e079f785565ea9e8f313d9f --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_callsignature.ets @@ -0,0 +1,37 @@ +/* + * 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 createArray(ctor: ArrayConstructor) { // ERROR + return ctor(1, 2, 3); // ERROR +} +function createArrayDirect() { + return Array(1, 2, 3) +} + +function createBigInt(ctor: BigIntConstructor) { // ERROR + return ctor(1); // ERROR +} +function createBigIntDirect() { + return BigInt(1); +} + +function anotherName(ctorName0: BigIntConstructor) { // ERROR + ctorName0(1); // ERROR + const ctorName1 = ctorName0 + const rs1 = ctorName1(1); // ERROR + type BigIntConstructor1 = BigIntConstructor; // ERROR + let ctorName2:BigIntConstructor1 = ctorName1 // ERROR + const rs2 = ctorName2(1); // ERROR +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/func_return_type.ts.args.json b/ets2panda/linter/test/builtin/builtin_callsignature.ets.args.json similarity index 90% rename from ets2panda/linter/test/migrate/func_return_type.ts.args.json rename to ets2panda/linter/test/builtin/builtin_callsignature.ets.args.json index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..3ef4496a819a201892114d1c90f78ae32053c334 100644 --- a/ets2panda/linter/test/migrate/func_return_type.ts.args.json +++ b/ets2panda/linter/test/builtin/builtin_callsignature.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 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", @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "migrate": "" + "arkts2": "" } } diff --git a/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8392e8d8cfaa6a0d22987e6025e28a6c910e1a4b --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_callsignature.ets.arkts2.json @@ -0,0 +1,228 @@ +{ + "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": 28, + "endLine": 16, + "endColumn": 44, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 14, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 23, + "endLine": 17, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 26, + "endLine": 17, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 29, + "endLine": 17, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 24, + "endLine": 20, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 27, + "endLine": 20, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 30, + "endLine": 20, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 29, + "endLine": 23, + "endColumn": 46, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 14, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 15, + "endLine": 24, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 17, + "endLine": 27, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 33, + "endLine": 30, + "endColumn": 50, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 12, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 13, + "endLine": 31, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 24, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 25, + "endLine": 33, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 29, + "endLine": 34, + "endColumn": 46, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 17, + "endLine": 35, + "endColumn": 35, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 15, + "endLine": 36, + "endColumn": 24, + "problem": "BuiltinNoCtorFunc", + "suggest": "", + "rule": "API is not support ctor signature and func (arkts-builtin-cotr)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 25, + "endLine": 36, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.json b/ets2panda/linter/test/builtin/builtin_callsignature.ets.json similarity index 100% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.json rename to ets2panda/linter/test/builtin/builtin_callsignature.ets.json diff --git a/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets new file mode 100644 index 0000000000000000000000000000000000000000..bbcf905f52086774901aaaf5935b292117222037 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.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. + */ + +function f(a: PropertyDescriptor) { + a.configurable; + a.enumerable; + a.value; + a.writable; + a.get; + a.set; +} + +let desc: TypedPropertyDescriptor = { + value:1, + get():number {return this.value}, + set(v): void {this.value = v}, + enumerable: false, + configurable: false, + writable: true +} + +type MyPropertyDescriptor = PropertyDescriptor; +type MyTypedPropertyDescriptor = TypedPropertyDescriptor; + +function f(a: MyPropertyDescriptor) { + a.configurable; + a.enumerable; + a.value; + a.writable; + a.get; + a.set; +} + +let desc: MyTypedPropertyDescriptor = { + value: 1, + get(): number { return this.value; }, + set(v): void {this.value = v}, + enumerable: false, + configurable: false, + writable: true +}; + +interface APropertyDescriptor {} +interface PropertyDescriptorA {} +interface PropertyDescriptor {} + +let a1: APropertyDescriptor = {} +let a2: PropertyDescriptorA = {} +let a3: PropertyDescriptor = {} \ No newline at end of file diff --git a/ets2panda/linter/test/main/data_observation_1.ets.args.json b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.args.json similarity index 93% rename from ets2panda/linter/test/main/data_observation_1.ets.args.json rename to ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.args.json index 5efbceacdc279d08c370af862c859f2d6300fafb..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 100644 --- a/ets2panda/linter/test/main/data_observation_1.ets.args.json +++ b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.args.json @@ -14,7 +14,6 @@ "limitations under the License." ], "mode": { - "arkts2": "", - "autofix": "--arkts-2" + "arkts2": "" } } \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..79538ccf9be3b4529be2e9e2784427a3101e063a --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.arkts2.json @@ -0,0 +1,328 @@ +{ + "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": 1, + "endLine": 23, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 12, + "endLine": 16, + "endColumn": 13, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 15, + "endLine": 16, + "endColumn": 33, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 3, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 2, + "endLine": 18, + "endColumn": 3, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 3, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 3, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 3, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 3, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 9, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 11, + "endLine": 25, + "endColumn": 34, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 3, + "endLine": 27, + "endColumn": 35, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 3, + "endLine": 28, + "endColumn": 32, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 9, + "endLine": 26, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 1, + "endLine": 44, + "endColumn": 2, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 13, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 6, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 6, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 6, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 6, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 5, + "endLine": 42, + "endColumn": 6, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 5, + "endLine": 43, + "endColumn": 6, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 9, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 41, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 34, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 11, + "endLine": 57, + "endColumn": 29, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 1, + "endLine": 57, + "endColumn": 32, + "problem": "InterfaceMerging", + "suggest": "", + "rule": "Declaration merging is not supported (arkts-no-decl-merging)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 7, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 9, + "endLine": 61, + "endColumn": 27, + "problem": "NoPropertyDescriptor", + "suggest": "", + "rule": "Not support propertydescriptor (arkts-builtin-no-property-descriptor)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 30, + "endLine": 61, + "endColumn": 31, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.json b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..53088745400793978e1891873f56604fa1470ae9 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_not_support_property_descriptor.ets.json @@ -0,0 +1,38 @@ +{ + "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": 57, + "column": 1, + "endLine": 57, + "endColumn": 32, + "problem": "InterfaceMerging", + "suggest": "", + "rule": "Declaration merging is not supported (arkts-no-decl-merging)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 30, + "endLine": 61, + "endColumn": 31, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets new file mode 100755 index 0000000000000000000000000000000000000000..331af9c7c152be315a62ab0e0062787ff2d29f1c --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.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. + */ + +class MyClass {} +const myClass = new MyClass(); +Object.getOwnPropertyNames(a); diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.args.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..6958168fef2a70000342107f7d5f2b5805c14fae --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.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" + } +} diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..699eba3d8526bc0607ed09da4e67988ec9896a5e --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.arkts2.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": 18, + "column": 1, + "endLine": 18, + "endColumn": 27, + "problem": "BuiltinGetOwnPropertyNames", + "suggest": "", + "rule": "Using \"Object.getOwnPropertyNames\" is not allowed in this API (arkts-builtin-object-getOwnPropertyNames))", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.autofix.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..f2aa6d9af0353f48106c09ea44013acdd4ace123 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.autofix.json @@ -0,0 +1,35 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 27, + "problem": "BuiltinGetOwnPropertyNames", + "autofix": [ + { + "start": 653, + "end": 679, + "replacementText": "Object.keys" + } + ], + "suggest": "", + "rule": "Using \"Object.getOwnPropertyNames\" is not allowed in this API (arkts-builtin-object-getOwnPropertyNames))", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..8af4f78669b31c787e4cd40ae005aff560769df3 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.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/builtin/builtin_object_getownpropertynames.ets.migrate.ets b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..eecf3e8f2af7c95151171fbd66405c3c2588ecef --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.migrate.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. + */ + +class MyClass {} +const myClass = new MyClass(); +Object.keys(a); diff --git a/ets2panda/linter/test/interop/ts_decorator.ets.json b/ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.migrate.json similarity index 100% rename from ets2panda/linter/test/interop/ts_decorator.ets.json rename to ets2panda/linter/test/builtin/builtin_object_getownpropertynames.ets.migrate.json diff --git a/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets new file mode 100755 index 0000000000000000000000000000000000000000..2b2843d8b18aa41a7d8b21e83cf6b7cf51a755de --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_symbol_iterator.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. + */ + +let map: Map = new Map(); +let iterFromReflect = Reflect.get(map, Symbol.iterator); +let iterFromProp = map[Symbol.iterator](); + +let symbolIter = Symbol.iterator; diff --git a/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.args.json b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_symbol_iterator.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/builtin/builtin_symbol_iterator.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..36254158540286646fc21063b6b306396f132eb7 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.arkts2.json @@ -0,0 +1,58 @@ +{ + "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": 17, + "column": 40, + "endLine": 17, + "endColumn": 55, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 20, + "endLine": 18, + "endColumn": 40, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 24, + "endLine": 18, + "endColumn": 39, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 18, + "endLine": 20, + "endColumn": 33, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.json b/ets2panda/linter/test/builtin/builtin_symbol_iterator.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..8af4f78669b31c787e4cd40ae005aff560769df3 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_symbol_iterator.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/builtin/builtin_thisArgs.ets b/ets2panda/linter/test/builtin/builtin_thisArgs.ets new file mode 100755 index 0000000000000000000000000000000000000000..2a73669055134cc6b5b85d4c122a6da9a8e27bfb --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_thisArgs.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. + */ + +Class MyClass { + base: number; + constructor(base: number) { + this.base = base; + } + compare((value: number, index:number, arr: Array)) { + return value < this.base + } +} + +let arr: Array = new Array(1, 2, 3); +let a = new MyClass(2); +let b = new MyClass(3); +arr.filter(a.compare, a); +arr.filter(a.compare); +arr.filter(a.compare, b); \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_thisArgs.ets.args.json b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_thisArgs.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/builtin/builtin_thisArgs.ets.arkts2.json b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..d59ceafe4b14eee60ea08cd58850bd42ef50165f --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.arkts2.json @@ -0,0 +1,138 @@ +{ + "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": 21, + "column": 11, + "endLine": 21, + "endColumn": 60, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 44, + "endLine": 26, + "endColumn": 45, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 47, + "endLine": 26, + "endColumn": 48, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 50, + "endLine": 26, + "endColumn": 51, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 13, + "endLine": 27, + "endColumn": 20, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 21, + "endLine": 27, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 13, + "endLine": 28, + "endColumn": 20, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 21, + "endLine": 28, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 25, + "problem": "BuiltinThisArgs", + "suggest": "", + "rule": "Using thisArgs as a type is not allowed in this API (arkts-builtin-thisArgs)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 1, + "endLine": 31, + "endColumn": 25, + "problem": "BuiltinThisArgs", + "suggest": "", + "rule": "Using thisArgs as a type is not allowed in this API (arkts-builtin-thisArgs)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/builtin/builtin_thisArgs.ets.json b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..132dc5e988043d737f194d6ab97afc52cf5e6429 --- /dev/null +++ b/ets2panda/linter/test/builtin/builtin_thisArgs.ets.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": 21, + "column": 11, + "endLine": 21, + "endColumn": 60, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 23, + "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/main/concurrent_decorator_arkts2.ets b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets similarity index 75% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets rename to ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets index 6dcc3645123a905a30f4e55b7445b4069d61ea77..91b0af14666257a5ce36d9dcd94ef1242c8ec5f1 100644 --- a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.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 @@ -12,6 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' @Concurrent // ERROR function func() {} + +@Concurrent +type a2 = number +let n18: a2 = 10; + +@Concurrent +type funtType1 = () => void + +@Concurrent +type funtType2 = () => void | number diff --git a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.args.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.args.json similarity index 92% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.args.json rename to ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.args.json index 4e9dc628f7cbbb3ac73a21b2ce9f794758fcaae0..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100644 --- a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.args.json +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..4acb9cbb1698ce0a77c8707c316d08ae2a08f0a4 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.arkts2.json @@ -0,0 +1,78 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 12, + "problem": "LimitedStdLibNoDoncurrentDecorator", + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 12, + "problem": "LimitedStdLibNoDoncurrentDecorator", + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 15, + "endLine": 22, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 12, + "problem": "LimitedStdLibNoDoncurrentDecorator", + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 12, + "problem": "LimitedStdLibNoDoncurrentDecorator", + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 24, + "endLine": 28, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.autofix.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..8dc3e4461258ccd2b5965fa63e99341224995e46 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.autofix.json @@ -0,0 +1,133 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 12, + "problem": "LimitedStdLibNoDoncurrentDecorator", + "autofix": [ + { + "start": 618, + "end": 629, + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 12, + "problem": "LimitedStdLibNoDoncurrentDecorator", + "autofix": [ + { + "start": 659, + "end": 670, + "replacementText": "", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 15, + "endLine": 22, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 702, + "end": 704, + "replacementText": "10.0", + "line": 22, + "column": 15, + "endLine": 22, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 12, + "problem": "LimitedStdLibNoDoncurrentDecorator", + "autofix": [ + { + "start": 707, + "end": 718, + "replacementText": "", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 12, + "problem": "LimitedStdLibNoDoncurrentDecorator", + "autofix": [ + { + "start": 748, + "end": 759, + "replacementText": "", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-concurrent-decorator)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 24, + "endLine": 28, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.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": [] +} diff --git a/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.ets b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e0b04d3ed096c42b9933ae0400d1a5173d65383c --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.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. + */ +'use static' + + // ERROR +function func() {} + + +type a2 = number +let n18: a2 = 10.0; + + +type funtType1 = () => void + + +type funtType2 = () => void | number diff --git a/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.json b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..1dde4c017ff67ea59646f54c9659df8ebbe66411 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_decorator_arkts2.ets.migrate.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": 28, + "column": 24, + "endLine": 28, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets new file mode 100644 index 0000000000000000000000000000000000000000..d3e0b2ca58ad6fde6ac4d5ba2e1d5e38bafd84a0 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +let typeName: SharedArrayBuffer; // ERROR +let sab: SharedArrayBuffer = new SharedArrayBuffer(0) // 2 ERROR + +type NewTypeName = SharedArrayBuffer // ERROR +let newTypeName: NewTypeName +// disable use new NewTypeName() +let ntn: NewTypeName = new SharedArrayBuffer(0) // ERROR + +function foo(atmo: Atomics) {} // NOT ERROR \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.args.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.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" + } +} diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..fa8024c8d379432c1df90cff56452f46adf572b1 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.arkts2.json @@ -0,0 +1,88 @@ +{ + "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": 15, + "endLine": 16, + "endColumn": 32, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 27, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 34, + "endLine": 17, + "endColumn": 51, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 52, + "endLine": 17, + "endColumn": 53, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 20, + "endLine": 19, + "endColumn": 37, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 28, + "endLine": 22, + "endColumn": 45, + "problem": "SharedArrayBufferDeprecated", + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 46, + "endLine": 22, + "endColumn": 47, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..01e6621c9d4fa857cd90d0c8cf61deab97cebef2 --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.autofix.json @@ -0,0 +1,165 @@ +{ + "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": 15, + "endLine": 16, + "endColumn": 32, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 624, + "end": 641, + "line": 16, + "column": 15, + "endLine": 16, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 27, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 661, + "end": 678, + "line": 17, + "column": 10, + "endLine": 17, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 34, + "endLine": 17, + "endColumn": 51, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 685, + "end": 702, + "line": 17, + "column": 34, + "endLine": 17, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 52, + "endLine": 17, + "endColumn": 53, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 703, + "end": 704, + "replacementText": "0.0", + "line": 17, + "column": 52, + "endLine": 17, + "endColumn": 53 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 20, + "endLine": 19, + "endColumn": 37, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 737, + "end": 754, + "line": 19, + "column": 20, + "endLine": 19, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 28, + "endLine": 22, + "endColumn": 45, + "problem": "SharedArrayBufferDeprecated", + "autofix": [ + { + "replacementText": "ArrayBuffer", + "start": 853, + "end": 870, + "line": 22, + "column": 28, + "endLine": 22, + "endColumn": 45 + } + ], + "suggest": "", + "rule": "SharedArrayBuffer is not supported (arkts-no-need-stdlib-sharedArrayBuffer)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 46, + "endLine": 22, + "endColumn": 47, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 871, + "end": 872, + "replacementText": "0.0", + "line": 22, + "column": 46, + "endLine": 22, + "endColumn": 47 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.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": [] +} diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..7a393ab10fe816bdd7c0aac6177253fc60e97e4a --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +let typeName: ArrayBuffer; // ERROR +let sab: ArrayBuffer = new ArrayBuffer(0.0) // 2 ERROR + +type NewTypeName = ArrayBuffer // ERROR +let newTypeName: NewTypeName +// disable use new NewTypeName() +let ntn: NewTypeName = new ArrayBuffer(0.0) // ERROR + +function foo(atmo: Atomics) {} // NOT ERROR \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..43cb4a27bcc78710d4aa5130c22ee053f66c3fbc --- /dev/null +++ b/ets2panda/linter/test/concurrent/concurrent_sharedarraybuffer_arkts2.ets.migrate.json @@ -0,0 +1,3 @@ +{ + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets new file mode 100644 index 0000000000000000000000000000000000000000..40c096babbf596df9d09e3532d3f9035f2bfc0d8 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent.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 { taskpool } from '../main/oh_modules/@kit.ArkTS' +import { taskpool as tp } from '../main/oh_modules/@ohos.taskpool' +import { taskpool as kp } from '@some.module' + +@Concurrent +function test() { } + +let result: Boolean = taskpool.isConcurrent(test); + +let result2: Boolean = tp.isConcurrent(test); + +let result3: Boolean = kp.isConcurrent(test); + +let result4: Boolean = taskpool.foo(test); + +class testObject { + isConcurrent(): string { + return "Test"; + } +}; + +const result: string = testObject.isConcurrent(); diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.args.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..e2b903f0aa82e6ca4108ff67d5272bf49d6c2a5b --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent.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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.arkts2.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ca28292f8e4d54b3a473114b5d2238f3fa55c03f --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 23, + "column": 32, + "endLine": 23, + "endColumn": 44, + "problem": "IsConcurrentDeprecated", + "suggest": "", + "rule": "isConcurrent is not supported (arkts-limited-stdlib-no-support-isConcurrent)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 39, + "problem": "IsConcurrentDeprecated", + "suggest": "", + "rule": "isConcurrent is not supported (arkts-limited-stdlib-no-support-isConcurrent)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.json b/ets2panda/linter/test/concurrent/no_support_isconcurrent.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..b9331d05ba1f182a8a451c219c9e51bcd4e67188 --- /dev/null +++ b/ets2panda/linter/test/concurrent/no_support_isconcurrent.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/concurrent/use_limited_and_concurrent.ets b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets new file mode 100644 index 0000000000000000000000000000000000000000..22ef20b645ce008ca5ad7b59f5a35eed82cac0c0 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets @@ -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. + */ + +"use shared" +export function sharedFunction() {} + +function concurrentFunc() { + "use concurrent" +} + +function normal() {} + +normal('use concurrent'); + +const variable = 'use concurrent'; + +switch (variable) { + case 'use concurrent: + break; +} + +normal('use shared'); + +const variable2 = 'use shared'; + +switch (variable2) { + case 'use shared': + break; +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.args.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..6958168fef2a70000342107f7d5f2b5805c14fae --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.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" + } +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.arkts2.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..0a82914a53a6b965b052de59bd9d4bfe1d740554 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.arkts2.json @@ -0,0 +1,48 @@ +{ + "copyright": [ + "Copyright (c) 2023-2024 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": 1, + "endLine": 16, + "endColumn": 13, + "problem": "UseSharedDeprecated", + "suggest": "", + "rule": "\"use shared\" is not supported (arkts-limited-stdlib-no-use-shared)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 17, + "endLine": 17, + "endColumn": 31, + "problem": "SharedModuleExports", + "suggest": "", + "rule": "Only \"Sendable\" entities can be exported in shared module (arkts-shared-module-exports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 21, + "problem": "UseConcurrentDeprecated", + "suggest": "", + "rule": "\"use concurrent\" is not supported (arkts-limited-stdlib-no-use-concurrent)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.autofix.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..052fc5f382c68d4ab6c6584c022fc23f840cb135 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.autofix.json @@ -0,0 +1,62 @@ +{ + "copyright": [ + "Copyright (c) 2023-2024 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": 1, + "endLine": 16, + "endColumn": 13, + "problem": "UseSharedDeprecated", + "autofix": [ + { + "start": 605, + "end": 617, + "replacementText": "" + } + ], + "suggest": "", + "rule": "\"use shared\" is not supported (arkts-limited-stdlib-no-use-shared)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 17, + "endLine": 17, + "endColumn": 31, + "problem": "SharedModuleExports", + "suggest": "", + "rule": "Only \"Sendable\" entities can be exported in shared module (arkts-shared-module-exports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 21, + "problem": "UseConcurrentDeprecated", + "autofix": [ + { + "start": 687, + "end": 703, + "replacementText": "" + } + ], + "suggest": "", + "rule": "\"use concurrent\" is not supported (arkts-limited-stdlib-no-use-concurrent)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..443a9bc21b1895e83165cb1648e9e101f1d11877 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.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": 17, + "column": 17, + "endLine": 17, + "endColumn": 31, + "problem": "SharedModuleExports", + "suggest": "", + "rule": "Only \"Sendable\" entities can be exported in shared module (arkts-shared-module-exports)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.ets b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5224e3b79f6ce4d369dcfc9ebaa26a63bc1b9219 --- /dev/null +++ b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.ets @@ -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. + */ + + +export function sharedFunction() {} + +function concurrentFunc() { + +} + +function normal() {} + +normal('use concurrent'); + +const variable = 'use concurrent'; + +switch (variable) { + case 'use concurrent: + break; +} + +normal('use shared'); + +const variable2 = 'use shared'; + +switch (variable2) { + case 'use shared': + break; +} diff --git a/ets2panda/linter/test/main/data_observation_2.ets.json b/ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.json similarity index 100% rename from ets2panda/linter/test/main/data_observation_2.ets.json rename to ets2panda/linter/test/concurrent/use_limited_and_concurrent.ets.migrate.json diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets b/ets2panda/linter/test/interop/binary_operation_js_obj.ets new file mode 100755 index 0000000000000000000000000000000000000000..29bfa417e57a9375c0c37fa471bf0fa9b52f0080 --- /dev/null +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.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. + */ +'use static' +import {foo} from "./binary_operation_js_obj_js" +let a = foo.a +let b = foo.b +a + b +a - b +a * b +a / b +a % b +a ** b \ No newline at end of file diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.args.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..3318ebbbcfd0ce90dc5f69df69452a3201e4204d --- /dev/null +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.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" + } +} diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.arkts2.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..f069ac9eeb23b6d2519c4392de77121237d91a2f --- /dev/null +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.arkts2.json @@ -0,0 +1,208 @@ +{ + "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": 1, + "endLine": 16, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 49, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 6, + "endLine": 24, + "endColumn": 7, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 5, + "problem": "ExponentOp", + "suggest": "", + "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100755 index 0000000000000000000000000000000000000000..18043cd8a08542f8160a583dfa44dbd06ee190d6 --- /dev/null +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json @@ -0,0 +1,283 @@ +{ + "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": 1, + "endLine": 16, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 49, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 617, + "end": 665, + "replacementText": "", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 49 + }, + { + "start": 665, + "end": 665, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./binary_operation_js_obj_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 674, + "end": 679, + "replacementText": "foo.getPropertyByName(\"a\")", + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('a').toNumber()", + "start": 674, + "end": 679, + "line": 17, + "column": 9, + "endLine": 17, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 688, + "end": 693, + "replacementText": "foo.getPropertyByName(\"b\")", + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('b').toNumber()", + "start": 688, + "end": 693, + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 6, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 2, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 6, + "endLine": 24, + "endColumn": 7, + "problem": "BinaryOperations", + "suggest": "", + "rule": "Binary operations on js objects (arkts-interop-js2s-binary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 5, + "problem": "ExponentOp", + "autofix": [ + { + "replacementText": "Math.pow(a, b)", + "start": 724, + "end": 730, + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 5 + } + ], + "suggest": "", + "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.arkts2.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.json old mode 100644 new mode 100755 similarity index 82% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.arkts2.json rename to ets2panda/linter/test/interop/binary_operation_js_obj.ets.json index b74e38da0ecb0c7f572be06dd70cde4d44f3135c..24e48e6dcb622409f469756ff0b09fbb2879d9cc --- a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.json @@ -18,11 +18,11 @@ "line": 16, "column": 1, "endLine": 16, - "endColumn": 12, - "problem": "LimitedStdLibApi", + "endColumn": 49, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" } ] -} +} \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..72c3c6c688c6661b162927589e92e506e543da91 --- /dev/null +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.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. + */ +'use static' +let GeneratedImportVar_1 = ESValue.load('./binary_operation_js_obj_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); + +let a = foo.getPropertyByName("a") +let b = foo.getPropertyByName("b") +a + b +a - b +a * b +a / b +a % b +Math.pow(a, b) \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..2caa23e507419af4d11c9232fc89618c12ad92f1 --- /dev/null +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.json @@ -0,0 +1,68 @@ +{ + "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": 5, + "endLine": 16, + "endColumn": 72, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 15, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj_js.js b/ets2panda/linter/test/interop/binary_operation_js_obj_js.js new file mode 100755 index 0000000000000000000000000000000000000000..aaf9c1dd4e9e4e7e46d0cf3efb92bb573817fde8 --- /dev/null +++ b/ets2panda/linter/test/interop/binary_operation_js_obj_js.js @@ -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. + */ + +export let foo = {a: 1, b: 2} diff --git a/ets2panda/linter/test/interop/call_function.ets b/ets2panda/linter/test/interop/call_function.ets new file mode 100644 index 0000000000000000000000000000000000000000..b76d862f4a67e010fbb3cd04176ba255c400dab8 --- /dev/null +++ b/ets2panda/linter/test/interop/call_function.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. + */ +'use static' +import {foo,bar} from "./call_function_js" + +foo() +bar(123) \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_function.ets.args.json b/ets2panda/linter/test/interop/call_function.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..9c3d9734324a7b8b9c89fa7f62dce43ac44888ca --- /dev/null +++ b/ets2panda/linter/test/interop/call_function.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_function.ets.arkts2.json b/ets2panda/linter/test/interop/call_function.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ed940011235b6ccb492d75ad97bafe0ec9ff7cdd --- /dev/null +++ b/ets2panda/linter/test/interop/call_function.ets.arkts2.json @@ -0,0 +1,68 @@ +{ + "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": 1, + "endLine": 16, + "endColumn": 43, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 43, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 6, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.autofix.json b/ets2panda/linter/test/interop/call_function.ets.json similarity index 72% rename from ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.autofix.json rename to ets2panda/linter/test/interop/call_function.ets.json index ba5d03fc2c1257d9beca8b2252243128339296d9..08b4bd7b56c82c9eeb61e1bd092388f21bb9f59a 100644 --- a/ets2panda/linter/test/main/concurrent_decorator_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/interop/call_function.ets.json @@ -18,18 +18,11 @@ "line": 16, "column": 1, "endLine": 16, - "endColumn": 12, - "problem": "LimitedStdLibApi", - "autofix": [ - { - "start": 610, - "end": 621, - "replacementText": "" - } - ], + "endColumn": 43, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_function_js.js b/ets2panda/linter/test/interop/call_function_js.js new file mode 100644 index 0000000000000000000000000000000000000000..1ca0a23aebf1d5ffa73f72c779aa2d87675ab0da --- /dev/null +++ b/ets2panda/linter/test/interop/call_function_js.js @@ -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 function foo(){} +export function bar(a){} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_object_methods.ets b/ets2panda/linter/test/interop/call_object_methods.ets new file mode 100644 index 0000000000000000000000000000000000000000..ee45f2bcf310af18a40e73daac122f063494253f --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods.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. + */ +'use static' +import { foo } from "./call_object_methods_js" + +foo.bar(123) + diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.args.json b/ets2panda/linter/test/interop/call_object_methods.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b023016d6bc3b2713d4e02b6f765940828db476b --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods.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/interop/call_object_methods.ets.arkts2.json b/ets2panda/linter/test/interop/call_object_methods.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..d088101b49fff0479cfefc0586220ee0b8fbc083 --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods.ets.arkts2.json @@ -0,0 +1,58 @@ +{ + "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": 1, + "endLine": 16, + "endColumn": 47, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 47, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 13, + "problem": "InteropCallObjectMethods", + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json b/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..85d3430d1725844bedd73cfcc4fb57b884650714 --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json @@ -0,0 +1,96 @@ +{ + "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": 1, + "endLine": 16, + "endColumn": 47, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 47, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 617, + "end": 663, + "replacementText": "", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 47 + }, + { + "start": 663, + "end": 663, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./call_object_methods_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 47 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 13, + "problem": "InteropCallObjectMethods", + "autofix": [ + { + "start": 665, + "end": 677, + "replacementText": "foo.invokeMethod(\"bar\", ESValue.wrap(123))" + } + ], + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 673, + "end": 676, + "replacementText": "123.0", + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.json b/ets2panda/linter/test/interop/call_object_methods.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8866623ce527a677439958b81b87b48a69851ee5 --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods.ets.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": 1, + "endLine": 16, + "endColumn": 47, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..aeed85e3005d17573e9aff15dc9b681399b58f3f --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.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. + */ +'use static' +let GeneratedImportVar_1 = ESValue.load('./call_object_methods_js'); +let foo = GeneratedImportVar_1.getPropertyByName('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 new file mode 100644 index 0000000000000000000000000000000000000000..5399cc769ed6721762185bea9cbc142c2fc048fb --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 5, + "endLine": 16, + "endColumn": 68, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/call_object_methods_js.js b/ets2panda/linter/test/interop/call_object_methods_js.js new file mode 100644 index 0000000000000000000000000000000000000000..d1803ae0dde2b758de1c65fa68c7994dcdc1b6a7 --- /dev/null +++ b/ets2panda/linter/test/interop/call_object_methods_js.js @@ -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 Foo { + bar(a){ + } +} +export let foo = new Foo() \ No newline at end of file diff --git a/ets2panda/linter/test/interop/ignore_files/unique_types.ts b/ets2panda/linter/test/interop/ignore_files/unique_types.ts new file mode 100644 index 0000000000000000000000000000000000000000..1c19752b632c2db52b8a99eee6213add566520d7 --- /dev/null +++ b/ets2panda/linter/test/interop/ignore_files/unique_types.ts @@ -0,0 +1,36 @@ +/* + * 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 SomeType = { + name: string, +} + +enum X { + a = 0, + b = '1', +} + +type UnionString = "A" | "B"; +type TemplateLiteralType = `${UnionString}_id`; + +export let objectLiteralType: SomeType; +export let mixedEnumType: X; +export let intersectionType: SomeType & X; +export let templateLiteralType: TemplateLiteralType; + +export function tsFunction() { + throw 123; +}; +export let stringType: string; diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets new file mode 100755 index 0000000000000000000000000000000000000000..e1d4d726e42ed9cf3f7fa79d50e53f253d739e58 --- /dev/null +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.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. + */ +'use static' +import {foo} from "./increases_decreases_js_obj_js" +let a: number =0 +a = foo.num++ +a = ++foo.num +a = foo.num-- +a = --foo.num diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.args.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..3318ebbbcfd0ce90dc5f69df69452a3201e4204d --- /dev/null +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.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" + } +} diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.arkts2.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..5e29c71a76559ae730740cb0b5a9e50a74732c6a --- /dev/null +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.arkts2.json @@ -0,0 +1,168 @@ +{ + "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": 1, + "endLine": 16, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 52, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 12, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 12, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 14, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 14, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100755 index 0000000000000000000000000000000000000000..06540703433696ac72e8700e6d11d7e7924f05b5 --- /dev/null +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json @@ -0,0 +1,287 @@ +{ + "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": 1, + "endLine": 16, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 52, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 617, + "end": 668, + "replacementText": "", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 52 + }, + { + "start": 668, + "end": 668, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./increases_decreases_js_obj_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 52 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 684, + "end": 685, + "replacementText": "0.0", + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 12, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 690, + "end": 697, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 12, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 690, + "end": 697, + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 706, + "end": 713, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 706, + "end": 713, + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 718, + "end": 725, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 718, + "end": 725, + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 14, + "problem": "InteropIncrementDecrement", + "suggest": "", + "rule": "Interop objects can't be incremented or decremented (arkts-interop-js2s-self-addtion-reduction)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 14, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 734, + "end": 741, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 734, + "end": 741, + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..cf493da1d6fe4df6133341a3e3a1db1489feb321 --- /dev/null +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.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": 1, + "endLine": 16, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..3be959d07a495d4fd85795cabcff73c1ea30ae9f --- /dev/null +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.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. + */ +'use static' +let GeneratedImportVar_1 = ESValue.load('./increases_decreases_js_obj_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); + +let a: number =0.0 +a = foo.getPropertyByName("num")++ +a = ++foo.getPropertyByName("num") +a = foo.getPropertyByName("num")-- +a = --foo.getPropertyByName("num") 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 new file mode 100644 index 0000000000000000000000000000000000000000..f6439adcf2637a788231915451071c18bc2f4736 --- /dev/null +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 5, + "endLine": 16, + "endColumn": 75, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/test/parser/ets/user_defined_4.ets b/ets2panda/linter/test/interop/increases_decreases_js_obj_js.js old mode 100644 new mode 100755 similarity index 88% rename from ets2panda/test/parser/ets/user_defined_4.ets rename to ets2panda/linter/test/interop/increases_decreases_js_obj_js.js index f429e7107f92d66c99dfdc60889b9a08649ec66f..88eed7f647dac7b416c98ab03936b753c39a5af5 --- a/ets2panda/test/parser/ets/user_defined_4.ets +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj_js.js @@ -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 @@ -13,4 +13,4 @@ * limitations under the License. */ -function boolean(){} +export let foo = {num: 0} diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets b/ets2panda/linter/test/interop/instantiated_js_obj.ets new file mode 100644 index 0000000000000000000000000000000000000000..f24de83f1ac2aea42269962eaa365a8f430dd622 --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets @@ -0,0 +1,33 @@ +/* + * 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. + */ + +'use static' +import {Foo, Foo1} from "./instantiated_js_obj_js" +class A { + num: number = 1; + constructor() { + } +} +new Foo(123) +new Foo('hello') +new Foo(new A()) +let a: A = new A(); +new Foo(a.num) +new Foo(a) +function test(): number { + return 1; +} +new Foo(test()) +new Foo1(123, 'hello') \ No newline at end of file diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.args.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..06cb3b904659ffe15c21fcd31bec1c4209becfe2 --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj.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/interop/instantiated_js_obj.ets.arkts2.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..d5efb9f32d78bbd43cb4eddaf8e40a4781344054 --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.arkts2.json @@ -0,0 +1,148 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 19, + "endLine": 19, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 13, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 9, + "endLine": 23, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 17, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 17, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 15, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 11, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 16, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 1, + "endLine": 33, + "endColumn": 23, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..7a22b7b9aa6a59570819d9daf7c69979b32837e8 --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json @@ -0,0 +1,285 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 618, + "end": 668, + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51 + }, + { + "start": 668, + "end": 668, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./instantiated_js_obj_js');\nlet Foo = GeneratedImportVar_1.getPropertyByName('Foo');\nlet Foo1 = GeneratedImportVar_1.getPropertyByName('Foo1');\n", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 19, + "endLine": 19, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 697, + "end": 698, + "replacementText": "1.0", + "line": 19, + "column": 19, + "endLine": 19, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 13, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 728, + "end": 740, + "replacementText": "Foo.instantiate(ESValue.wrap(123))", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 9, + "endLine": 23, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 736, + "end": 739, + "replacementText": "123.0", + "line": 23, + "column": 9, + "endLine": 23, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 17, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 741, + "end": 757, + "replacementText": "Foo.instantiate(ESValue.wrap('hello'))", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 17, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 758, + "end": 774, + "replacementText": "Foo.instantiate(ESValue.wrap(new A()))", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 15, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 795, + "end": 809, + "replacementText": "Foo.instantiate(ESValue.wrap(a.num))", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 11, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 810, + "end": 820, + "replacementText": "Foo.instantiate(ESValue.wrap(a))", + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 856, + "end": 857, + "replacementText": "1.0", + "line": 30, + "column": 10, + "endLine": 30, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 16, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 861, + "end": 876, + "replacementText": "Foo.instantiate(ESValue.wrap(test()))", + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 1, + "endLine": 33, + "endColumn": 23, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 877, + "end": 899, + "replacementText": "Foo1.instantiate(ESValue.wrap(123), ESValue.wrap('hello'))" + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 886, + "end": 889, + "replacementText": "123.0", + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ad8f5eb1ae4e1f2ec507367301510cbc9e65607a --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..06c8b9ee788e412fb2c6fb8714383fc97dd0c4c7 --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets @@ -0,0 +1,36 @@ +/* + * 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. + */ + +'use static' +let GeneratedImportVar_1 = ESValue.load('./instantiated_js_obj_js'); +let Foo = GeneratedImportVar_1.getPropertyByName('Foo'); +let Foo1 = GeneratedImportVar_1.getPropertyByName('Foo1'); + +class A { + num: number = 1.0; + constructor() { + } +} +Foo.instantiate(ESValue.wrap(123.0)) +Foo.instantiate(ESValue.wrap('hello')) +Foo.instantiate(ESValue.wrap(new A())) +let a: A = new A(); +Foo.instantiate(ESValue.wrap(a.num)) +Foo.instantiate(ESValue.wrap(a)) +function test(): number { + return 1.0; +} +Foo.instantiate(ESValue.wrap(test())) +Foo1.instantiate(ESValue.wrap(123.0), ESValue.wrap('hello')) \ No newline at end of file diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..915dad64c5a1d8dc688978d40079ee4b0251ddbb --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.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": 17, + "column": 5, + "endLine": 17, + "endColumn": 68, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/instantiated_js_obj_js.js b/ets2panda/linter/test/interop/instantiated_js_obj_js.js new file mode 100644 index 0000000000000000000000000000000000000000..76d9721f901f36c0f38f6d2653dd184862c284ea --- /dev/null +++ b/ets2panda/linter/test/interop/instantiated_js_obj_js.js @@ -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. + */ + +export class Foo { + constructor(a) {} +} + +export class Foo1 { + constructor(a, b) {} +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets b/ets2panda/linter/test/interop/interop_convert_import.ets new file mode 100755 index 0000000000000000000000000000000000000000..e5fa5c03c701717dc5e791b70d1043afd8c49411 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import.ets @@ -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. + */ + 'use static' + + import {foo, foo2, foo3, foo4, array_val, null_val, undefined_val} from "./interop_convert_import_js.js" + + let a: number = foo.num as number + let a1: boolean = foo2.bool as boolean + let a2: string = foo3.str as string + let a3: bigint = foo4.big as bigint + +test_helper.test(() => { +return (array_val as Array).toString() === new Array(1, 2, 3).toString();// 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "array_val as Array === [1, 2, 3]"); + +// convert type - Array +test_helper.test(() => { +return (array_val as number[]).toString() === [1,2,3].toString();// 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "array_val as Array === [1, 2, 3]"); + +// convert type - null +test_helper.test(() => { +return null_val as null === null;// 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "null_val as null === null"); + +// convert type - undefined +test_helper.test(() => { +return undefined_val as undefined === undefined; // 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "undefined_val as undefined === undefined"); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.args.json b/ets2panda/linter/test/interop/interop_convert_import.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..b023016d6bc3b2713d4e02b6f765940828db476b --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import.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/interop/interop_convert_import.ets.arkts2.json b/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..b6255d07e7a6601ae97f487ce3c873f2526dea10 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.arkts2.json @@ -0,0 +1,268 @@ +{ + "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": 17, + "column": 2, + "endLine": 17, + "endColumn": 106, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 106, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 18, + "endLine": 19, + "endColumn": 35, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 18, + "endLine": 19, + "endColumn": 25, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 18, + "endLine": 19, + "endColumn": 25, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 41, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 29, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 29, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 38, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 27, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 27, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 38, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 27, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 27, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 9, + "endLine": 25, + "endColumn": 27, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 44, + "endLine": 25, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 54, + "endLine": 25, + "endColumn": 55, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 57, + "endLine": 25, + "endColumn": 58, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 60, + "endLine": 25, + "endColumn": 61, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 30, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 48, + "endLine": 30, + "endColumn": 49, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 50, + "endLine": 30, + "endColumn": 51, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 52, + "endLine": 30, + "endColumn": 53, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 8, + "endLine": 35, + "endColumn": 24, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 34, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.autofix.json b/ets2panda/linter/test/interop/interop_convert_import.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..5aca1b631b25ea9f330ddc65ce1643eda034b81d --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.autofix.json @@ -0,0 +1,486 @@ +{ + "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": 17, + "column": 2, + "endLine": 17, + "endColumn": 106, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 106, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 636, + "end": 740, + "replacementText": "", + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 106 + }, + { + "start": 740, + "end": 740, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_convert_import_js.js');\r\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\r\nlet foo2 = GeneratedImportVar_1.getPropertyByName('foo2');\r\nlet foo3 = GeneratedImportVar_1.getPropertyByName('foo3');\r\nlet foo4 = GeneratedImportVar_1.getPropertyByName('foo4');\r\nlet array_val = GeneratedImportVar_1.getPropertyByName('array_val');\r\nlet null_val = GeneratedImportVar_1.getPropertyByName('null_val');\r\nlet undefined_val = GeneratedImportVar_1.getPropertyByName('undefined_val');\r\n", + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 106 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 18, + "endLine": 19, + "endColumn": 35, + "problem": "InterOpConvertImport", + "autofix": [ + { + "start": 761, + "end": 778, + "replacementText": "foo.getPropertyByName(\"num\").toNumber()", + "line": 19, + "column": 18, + "endLine": 19, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 18, + "endLine": 19, + "endColumn": 25, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 761, + "end": 768, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 19, + "column": 18, + "endLine": 19, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 18, + "endLine": 19, + "endColumn": 25, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num')", + "start": 761, + "end": 768, + "line": 19, + "column": 18, + "endLine": 19, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 41, + "problem": "InterOpConvertImport", + "autofix": [ + { + "start": 799, + "end": 820, + "replacementText": "foo2.getPropertyByName(\"bool\").toBoolean()", + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 41 + } + ], + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 29, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 799, + "end": 808, + "replacementText": "foo2.getPropertyByName(\"bool\")", + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 29 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 29, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo2.getPropertyByName('bool').toBoolean()", + "start": 799, + "end": 808, + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 29 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 38, + "problem": "InterOpConvertImport", + "autofix": [ + { + "start": 840, + "end": 859, + "replacementText": "foo3.getPropertyByName(\"str\").toString()", + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 27, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 840, + "end": 848, + "replacementText": "foo3.getPropertyByName(\"str\")", + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 27, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo3.getPropertyByName('str').toString()", + "start": 840, + "end": 848, + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 38, + "problem": "InterOpConvertImport", + "autofix": [ + { + "start": 879, + "end": 898, + "replacementText": "foo4.getPropertyByName(\"big\").toBigInt()", + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 27, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 879, + "end": 887, + "replacementText": "foo4.getPropertyByName(\"big\")", + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 27, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo4.getPropertyByName('big')", + "start": 879, + "end": 887, + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 9, + "endLine": 25, + "endColumn": 27, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 44, + "endLine": 25, + "endColumn": 62, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 54, + "endLine": 25, + "endColumn": 55, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 981, + "end": 982, + "replacementText": "1.0", + "line": 25, + "column": 54, + "endLine": 25, + "endColumn": 55 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 57, + "endLine": 25, + "endColumn": 58, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 984, + "end": 985, + "replacementText": "2.0", + "line": 25, + "column": 57, + "endLine": 25, + "endColumn": 58 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 60, + "endLine": 25, + "endColumn": 61, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 987, + "end": 988, + "replacementText": "3.0", + "line": 25, + "column": 60, + "endLine": 25, + "endColumn": 61 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 30, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 48, + "endLine": 30, + "endColumn": 49, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1195, + "end": 1196, + "replacementText": "1.0", + "line": 30, + "column": 48, + "endLine": 30, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 50, + "endLine": 30, + "endColumn": 51, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1197, + "end": 1198, + "replacementText": "2.0", + "line": 30, + "column": 50, + "endLine": 30, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 52, + "endLine": 30, + "endColumn": 53, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1199, + "end": 1200, + "replacementText": "3.0", + "line": 30, + "column": 52, + "endLine": 30, + "endColumn": 53 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 8, + "endLine": 35, + "endColumn": 24, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 34, + "problem": "InterOpConvertImport", + "suggest": "", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.json b/ets2panda/linter/test/interop/interop_convert_import.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ac2dfbe6f88152a66598a802845b33446231f158 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.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": 17, + "column": 2, + "endLine": 17, + "endColumn": 106, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.ets b/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a1c78f19fe4dd5abd335e8077954a615728ff605 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.ets @@ -0,0 +1,49 @@ +/* + * 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. + */ + 'use static' + + let GeneratedImportVar_1 = ESValue.load('./interop_convert_import_js.js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); +let foo2 = GeneratedImportVar_1.getPropertyByName('foo2'); +let foo3 = GeneratedImportVar_1.getPropertyByName('foo3'); +let foo4 = GeneratedImportVar_1.getPropertyByName('foo4'); +let array_val = GeneratedImportVar_1.getPropertyByName('array_val'); +let null_val = GeneratedImportVar_1.getPropertyByName('null_val'); +let undefined_val = GeneratedImportVar_1.getPropertyByName('undefined_val'); + + + let a: number = foo.getPropertyByName("num").toNumber() + let a1: boolean = foo2.getPropertyByName("bool").toBoolean() + let a2: string = foo3.getPropertyByName("str").toString() + let a3: bigint = foo4.getPropertyByName("big").toBigInt() + +test_helper.test(() => { +return (array_val as Array).toString() === new Array(1.0, 2.0, 3.0).toString();// 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "array_val as Array === [1, 2, 3]"); + +// convert type - Array +test_helper.test(() => { +return (array_val as number[]).toString() === [1.0,2.0,3.0].toString();// 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "array_val as Array === [1, 2, 3]"); + +// convert type - null +test_helper.test(() => { +return null_val as null === null;// 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "null_val as null === null"); + +// convert type - undefined +test_helper.test(() => { +return undefined_val as undefined === undefined; // 扫描出 arkts-interop-js2s-convert-js-type - no pass +}, "undefined_val as undefined === undefined"); \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/parameter_properties.ts.json b/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.json similarity index 47% rename from ets2panda/linter/test/migrate/parameter_properties.ts.json rename to ets2panda/linter/test/interop/interop_convert_import.ets.migrate.json index 52dc9cb7b7b1cab65bfd84efe2784bc7bc8d87b3..85e135eccaf3a8ff3af35cc57543a8218bd575ba 100644 --- a/ets2panda/linter/test/migrate/parameter_properties.ts.json +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 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", @@ -14,104 +14,104 @@ "limitations under the License." ], "result": [ + { + "line": 17, + "column": 6, + "endLine": 17, + "endColumn": 75, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, { "line": 18, "column": 5, "endLine": 18, - "endColumn": 11, - "problem": "ParameterProperties", + "endColumn": 56, + "problem": "AnyType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { "line": 19, "column": 5, "endLine": 19, - "endColumn": 14, - "problem": "ParameterProperties", + "endColumn": 58, + "problem": "AnyType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { "line": 20, "column": 5, "endLine": 20, - "endColumn": 12, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 26, - "endLine": 34, - "endColumn": 32, - "problem": "ParameterProperties", + "endColumn": 58, + "problem": "AnyType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 34, - "column": 60, - "endLine": 34, - "endColumn": 67, - "problem": "ParameterProperties", + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 58, + "problem": "AnyType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 43, - "column": 15, - "endLine": 43, - "endColumn": 21, - "problem": "ParameterProperties", + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 68, + "problem": "AnyType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 43, - "column": 25, - "endLine": 43, - "endColumn": 28, + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 66, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 47, - "column": 15, - "endLine": 47, - "endColumn": 21, - "problem": "ParameterProperties", + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 76, + "problem": "AnyType", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 47, - "column": 33, - "endLine": 47, - "endColumn": 40, - "problem": "ParameterProperties", + "line": 33, + "column": 44, + "endLine": 33, + "endColumn": 68, + "problem": "GenericCallNoTypeArgs", "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, { - "line": 47, - "column": 44, - "endLine": 47, - "endColumn": 45, - "problem": "ObjectTypeLiteral", + "line": 43, + "column": 8, + "endLine": 43, + "endColumn": 24, + "problem": "InterOpConvertImport", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Casting interop JS objects to primitive types is not allowed (arkts-interop-js2s-convert-js-type)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_convert_import_js.js b/ets2panda/linter/test/interop/interop_convert_import_js.js new file mode 100755 index 0000000000000000000000000000000000000000..cce72a8fb7f192f91addc00968c283556c0d205f --- /dev/null +++ b/ets2panda/linter/test/interop/interop_convert_import_js.js @@ -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. + */ + +export let foo = {name: 123} +export let foo2 = {bool: true} +export let foo3 = {str: '123'} +export let foo4 = {big: 123n} +export let array_val = [1, 2, 3]; +export let null_val = null; +export let undefined_val = undefined; \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets b/ets2panda/linter/test/interop/interop_equality_judgment.ets new file mode 100644 index 0000000000000000000000000000000000000000..7fe09978d32180c20921249f108ba7cdcd3eea11 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment.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. + */ + +'use static' +import {a, b} from "./interop_equality_judgment_js" +a == b +a != b +a === b +a !== b \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.args.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment.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/interop/interop_equality_judgment.ets.arkts2.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..916e1b51ca421151b76bc22d2ee1aa9b32f60213 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.arkts2.json @@ -0,0 +1,78 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 52, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 7, + "problem": "InteropEqualityJudgment", + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7, + "problem": "InteropEqualityJudgment", + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 8, + "problem": "InteropEqualityJudgment", + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 8, + "problem": "InteropEqualityJudgment", + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..c198972221d4d346f4dde0fe036a3063555b2754 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json @@ -0,0 +1,118 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 52, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 618, + "end": 669, + "replacementText": "" + }, + { + "start": 669, + "end": 669, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_equality_judgment_js');\nlet a = GeneratedImportVar_1.getPropertyByName('a');\nlet b = GeneratedImportVar_1.getPropertyByName('b');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 7, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 670, + "end": 676, + "replacementText": "a.areEqual(b)" + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 677, + "end": 683, + "replacementText": "!a.areEqual(b)" + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 8, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 684, + "end": 691, + "replacementText": "a.areStrictlyEqual(b)" + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 8, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 692, + "end": 699, + "replacementText": "!a.areStrictlyEqual(b)" + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..e48cf9a99b2e3b05e8a7816bda0738a37d257d25 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 52, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..8bbbd750c94aad92eee85fa254a6b36667be9a91 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.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. + */ + +'use static' +let GeneratedImportVar_1 = ESValue.load('./interop_equality_judgment_js'); +let a = GeneratedImportVar_1.getPropertyByName('a'); +let b = GeneratedImportVar_1.getPropertyByName('b'); + +a.areEqual(b) +!a.areEqual(b) +a.areStrictlyEqual(b) +!a.areStrictlyEqual(b) \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..a3c218b7b22380ea1dc4fdd6c6b1353462bb2ec7 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.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": 17, + "column": 5, + "endLine": 17, + "endColumn": 74, + "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, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_equality_judgment_js.js b/ets2panda/linter/test/interop/interop_equality_judgment_js.js new file mode 100644 index 0000000000000000000000000000000000000000..6461191d6871a2e1ead802773ac1e5cc635fc707 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_equality_judgment_js.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. + */ + +class A {} +export let a = new A() +export let b = new A() \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets b/ets2panda/linter/test/interop/interop_export_js_rules.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e6b76262c18f4311735b63c041db527415e7491 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.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. + */ +'use static' + +import { ff1 } from "./interop_import_js_rules_js" + +export {ff1} // imported from js. Error is shown + +export { ff2 } from "./interop_import_js_rules_js" // ff2 is imported from js. Error is shown + +export { MyDecorator } from "./oh_modules/ets_decorator" // MyDecorator is imported from arkts1. Error is shown + +export { foo as bar } from "./oh_modules/reflect_export" // foo is imported from arkts1.2. No error. + +export * as namespace1 from "./oh_modules/ets_decorator" + +export * as namespace2 from "./interop_import_js_rules_js" diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.args.json b/ets2panda/linter/test/interop/interop_export_js_rules.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.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/interop/interop_export_js_rules.ets.arkts2.json b/ets2panda/linter/test/interop/interop_export_js_rules.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..4fc44d8a3c257a8f336c85a17edce0306d0745b6 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.arkts2.json @@ -0,0 +1,88 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 13, + "problem": "InteropJsObjectExport", + "suggest": "", + "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 51, + "problem": "InteropJsObjectExport", + "suggest": "", + "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 57, + "problem": "InteropArkTs1ObjectExport", + "suggest": "", + "rule": "Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 57, + "problem": "InteropArkTs1ObjectExport", + "suggest": "", + "rule": "Direct export of interop ArkTS1.0 objects is not supported (arkts-interop-d2s-export-entity)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 59, + "problem": "InteropJsObjectExport", + "suggest": "", + "rule": "Direct export of interop JS objects is not supported (arkts-interop-js2s-export-js)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_export_js_rules.ets.json b/ets2panda/linter/test/interop/interop_export_js_rules.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..91f5b61ed193b5db1f2d82123a53ba9fe017a31c --- /dev/null +++ b/ets2panda/linter/test/interop/interop_export_js_rules.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js.ets b/ets2panda/linter/test/interop/interop_import_js.ets new file mode 100755 index 0000000000000000000000000000000000000000..3325f1bdd99c47feb42c89a27bb2d2255338121a --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js.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. + */ + +'use static' +import { Cjs } from '../main/js_lib'; +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 { 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.args.json b/ets2panda/linter/test/interop/interop_import_js.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..df6e67a5c9292c4c7e7aa5e976a3b8d1104fa082 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js.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/interop/interop_import_js.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..17f26fd8dcbe4b296c8ad46a6dbf16de2323964d --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json @@ -0,0 +1,158 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 38, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 38, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 64, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 64, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 44, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 44, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 57, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 57, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 53, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 53, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 59, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 59, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json new file mode 100755 index 0000000000000000000000000000000000000000..295af0943a99c5d99568ab2f2bae99ac55c17fa7 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json @@ -0,0 +1,242 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 38, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 619, + "end": 656, + "replacementText": "" + }, + { + "start": 971, + "end": 971, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('../main/js_lib');\nlet Cjs = GeneratedImportVar_1.getPropertyByName('Cjs');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 38, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 657, + "end": 694, + "replacementText": "" + }, + { + "start": 971, + "end": 971, + "replacementText": "let GeneratedImportVar_2 = ESValue.load('../main/js_lib');\nlet fjs = GeneratedImportVar_2.getPropertyByName('fjs');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 64, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 64, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 695, + "end": 758, + "replacementText": "" + }, + { + "start": 971, + "end": 971, + "replacementText": "let GeneratedImportVar_3 = ESValue.load('./jsfiles/preview_import_js');\nlet CPreview = GeneratedImportVar_3.getPropertyByName('CPreview');\nlet bar = GeneratedImportVar_3.getPropertyByName('bar');\nlet foo = GeneratedImportVar_3.getPropertyByName('foo');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 44, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 44, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 759, + "end": 802, + "replacementText": "" + }, + { + "start": 971, + "end": 971, + "replacementText": "let GeneratedImportVar_4 = ESValue.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_4.getPropertyByName('aaa');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 57, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 57, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 803, + "end": 859, + "replacementText": "" + }, + { + "start": 971, + "end": 971, + "replacementText": "let GeneratedImportVar_5 = ESValue.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_5.getPropertyByName('aaa');\nlet ClassA = GeneratedImportVar_5.getPropertyByName('ClassA');\nlet Dog = GeneratedImportVar_5.getPropertyByName('Dog');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 53, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 53, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 860, + "end": 912, + "replacementText": "" + }, + { + "start": 971, + "end": 971, + "replacementText": "let GeneratedImportVar_6 = ESValue.load('./interop_import_js_js');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 59, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 59, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 913, + "end": 971, + "replacementText": "" + }, + { + "start": 971, + "end": 971, + "replacementText": "let GeneratedImportVar_7 = ESValue.load('./interop_import_js_js');\nlet Wiki = GeneratedImportVar_7.getPropertyByName('Wiki');\nlet Doge = GeneratedImportVar_7.getPropertyByName('Dog');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/ts_decorator.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js.ets.json old mode 100644 new mode 100755 similarity index 48% rename from ets2panda/linter/test/interop/ts_decorator.ets.arkts2.json rename to ets2panda/linter/test/interop/interop_import_js.ets.json index 5c199b08051d5aa3486159a6e3603fd92e6d2f41..c75509e775c31d463f6997a7c8d8ac7ee81ec2bd --- a/ets2panda/linter/test/interop/ts_decorator.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.json @@ -15,73 +15,73 @@ ], "result": [ { - "line": 19, + "line": 17, "column": 1, - "endLine": 19, - "endColumn": 18, - "problem": "InteropNoDecorators", + "endLine": 17, + "endColumn": 38, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Typescript class decorators are not allowed (arkts-interop-no-decorators)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { - "line": 19, + "line": 18, "column": 1, - "endLine": 19, - "endColumn": 18, - "problem": "DecoratorsNotSupported", + "endLine": 18, + "endColumn": 38, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { - "line": 25, + "line": 19, "column": 1, - "endLine": 25, - "endColumn": 13, - "problem": "DecoratorsNotSupported", + "endLine": 19, + "endColumn": 64, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { - "line": 28, + "line": 20, "column": 1, - "endLine": 28, - "endColumn": 19, - "problem": "InteropNoDecorators", + "endLine": 20, + "endColumn": 44, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Typescript class decorators are not allowed (arkts-interop-no-decorators)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { - "line": 28, + "line": 21, "column": 1, - "endLine": 28, - "endColumn": 19, - "problem": "DecoratorsNotSupported", + "endLine": 21, + "endColumn": 57, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { - "line": 32, - "column": 3, - "endLine": 32, - "endColumn": 21, - "problem": "DecoratorsNotSupported", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 53, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" }, { - "line": 22, - "column": 2, - "endLine": 22, - "endColumn": 7, - "problem": "UIInterfaceImport", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 59, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..4aa7a4bbf12a582e7ae13712ed83c712f8d96b2d --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.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. + */ + +'use static' + + + + + + +let GeneratedImportVar_7 = ESValue.load('./interop_import_js_js'); +let Wiki = GeneratedImportVar_7.getPropertyByName('Wiki'); +let Doge = GeneratedImportVar_7.getPropertyByName('Dog'); +let GeneratedImportVar_6 = ESValue.load('./interop_import_js_js'); +let GeneratedImportVar_5 = ESValue.load('./interop_import_js_js'); +let myAaa = GeneratedImportVar_5.getPropertyByName('aaa'); +let ClassA = GeneratedImportVar_5.getPropertyByName('ClassA'); +let Dog = GeneratedImportVar_5.getPropertyByName('Dog'); +let GeneratedImportVar_4 = ESValue.load('./interop_import_js_js'); +let myAaa = GeneratedImportVar_4.getPropertyByName('aaa'); +let GeneratedImportVar_3 = ESValue.load('./jsfiles/preview_import_js'); +let CPreview = GeneratedImportVar_3.getPropertyByName('CPreview'); +let bar = GeneratedImportVar_3.getPropertyByName('bar'); +let foo = GeneratedImportVar_3.getPropertyByName('foo'); +let GeneratedImportVar_2 = ESValue.load('../main/js_lib'); +let fjs = GeneratedImportVar_2.getPropertyByName('fjs'); +let GeneratedImportVar_1 = ESValue.load('../main/js_lib'); +let Cjs = GeneratedImportVar_1.getPropertyByName('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 new file mode 100644 index 0000000000000000000000000000000000000000..625afb93e1e3f253b76950465544c88637ab6973 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json @@ -0,0 +1,198 @@ +{ + "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": 23, + "column": 5, + "endLine": 23, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 62, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 71, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 5, + "endLine": 37, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets b/ets2panda/linter/test/interop/interop_import_js_compare.ets new file mode 100644 index 0000000000000000000000000000000000000000..496fe91c554cc5de1e7fafcb58c00041a11234a9 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets @@ -0,0 +1,44 @@ +/* + * 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. + */ + +'use static' + +import {foo, m, n} from "./interop_import_js_compare_js" +let a = foo.a +let b = foo.b +a > b +a < b +a >= b +a <= b +a = 1 + +m > n +m = 1 + +let x = 1, y = 2; +x > y; +x < y; +x >= y; +x <= y; + +let bar = { a: 1, b: 2 }; + +let x2 = bar.a, y2 = bar.b; +x2 > y2; +x2 < y2; +x2 >= y2; +x2 <= y2; + +foo.a > foo.b; \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.args.json b/ets2panda/linter/test/interop/interop_import_js_compare.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..e2b903f0aa82e6ca4108ff67d5272bf49d6c2a5b --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_compare.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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js_compare.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..4ce217d61eb50c1edbeaeda10aea16054d519d78 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_compare.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": 18, + "column": 1, + "endLine": 18, + "endColumn": 57, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 57, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 9, + "endLine": 19, + "endColumn": 14, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 9, + "endLine": 19, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 9, + "endLine": 20, + "endColumn": 14, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 9, + "endLine": 20, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 2, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 6, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 2, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 6, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 2, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 6, + "endLine": 23, + "endColumn": 7, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 2, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 6, + "endLine": 24, + "endColumn": 7, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 6, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 2, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 6, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 6, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 12, + "endLine": 30, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 16, + "endLine": 30, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 11, + "endLine": 36, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 16, + "endLine": 36, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 22, + "endLine": 36, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 6, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 9, + "endLine": 44, + "endColumn": 14, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 6, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 6, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 9, + "endLine": 44, + "endColumn": 14, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 9, + "endLine": 44, + "endColumn": 14, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.json b/ets2panda/linter/test/interop/interop_import_js_compare.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..25d2c46ecd313256af4ef2245da60133617674c2 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 57, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 11, + "endLine": 36, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_compare_js.js b/ets2panda/linter/test/interop/interop_import_js_compare_js.js new file mode 100644 index 0000000000000000000000000000000000000000..8135cf86aaaf939e674c323cc50122773087844f --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_compare_js.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. + */ + +export let foo = {a: 1, b: 2} +export let m = 1 +export let n = 2 \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets b/ets2panda/linter/test/interop/interop_import_js_index.ets new file mode 100644 index 0000000000000000000000000000000000000000..daf1403ab2b8397e96835718602982113a32a281 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index.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. + */ + +'use static' +import {foo} from "./interop_import_js_index_js" +let arr = foo.arr +arr[1] +arr[3] = 4 \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.args.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..fb061d2224432ee084a838573999bd32414cad57 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index.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/interop/interop_import_js_index.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..01e50a4c695af769ff96c170ff87134ac1086f5e --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.arkts2.json @@ -0,0 +1,114 @@ +{ + "result": [ + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 49, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 18, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 18, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 7, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 11, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "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" + } + ] +} \ 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 new file mode 100644 index 0000000000000000000000000000000000000000..f5e605ca862cb81d76bd021611bd3a80d07b6efc --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json @@ -0,0 +1,217 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 49, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 619, + "end": 667, + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 49 + }, + { + "start": 667, + "end": 667, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_import_js_index_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 18, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 678, + "end": 685, + "replacementText": "foo.getPropertyByName(\"arr\")", + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 18, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('arr')", + "start": 678, + "end": 685, + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr.getPropertyByIndex(1).toNumber()", + "start": 686, + "end": 692, + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 686, + "end": 692, + "replacementText": "arr.getPropertyByIndex(1)", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 7, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 7, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr.setPropertyByIndex(3, ESValue.wrap(4))", + "start": 693, + "end": 703, + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 11, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 693, + "end": 703, + "replacementText": "arr.setPropertyByIndex(3, ESValue.wrap(4))" + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 702, + "end": 703, + "replacementText": "4.0", + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..5619e69d7898491f1269e2a8a45cc426ed25574a --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..65d9325e8baee8c6496caf7282ec5ef05eaaf771 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.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. + */ + +'use static' +let GeneratedImportVar_1 = ESValue.load('./interop_import_js_index_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); + +let arr = foo.getPropertyByName("arr") +arr.getPropertyByIndex(1.0).toNumber() +arr.setPropertyByIndex(3.0, ESValue.wrap(4.0)) \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..957ef0239d9624c92e24c298a3c7b6e3b2d549ac --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.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": 17, + "column": 5, + "endLine": 17, + "endColumn": 72, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 39, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js_index_js.js b/ets2panda/linter/test/interop/interop_import_js_index_js.js new file mode 100644 index 0000000000000000000000000000000000000000..168f73cb83826ba9312726a57dbac696fe3e38cd --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_index_js.js @@ -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. + */ + +export let foo = {arr: [1, 2, 3]} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_js.js b/ets2panda/linter/test/interop/interop_import_js_js.js new file mode 100755 index 0000000000000000000000000000000000000000..37abf27ef64c4eda43a6e4414bacb95dbb8e8680 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_js.js @@ -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. + */ + +export default function aaa() { + return "Hello Default Export"; +} +export class ClassA {} +export function Dog(a) { } +export let Wiki = { name: "123" } +export class Person { + name = "" + age = 0 + location = "" + getName() { + return this.name; + } + setAge(age) { + this.age = age; + } +} + +export let aaa = 1 diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets b/ets2panda/linter/test/interop/interop_import_js_rules.ets new file mode 100644 index 0000000000000000000000000000000000000000..d7e3b52fcab8ce824276f7f944f792e00a219ad9 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets @@ -0,0 +1,81 @@ +/* + * 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. + */ +'use static'; + +import { foo } from "./interop_import_js_rules_js" +import { ff1, ff2 } from "./interop_import_js_rules_js" + +import { A } from "./interop_import_js_rules_js" +import { C } from "./interop_import_js_rules_js" + +import { ff3 } from "./interop_import_js_rules_js" + +import { ff4 } from "./interop_import_js_rules_js" + +import { handle } from "./interop_import_js_rules_js" + +import { expand } from "./interop_import_js_rules_js" +import { orange } from "./interop_import_js_rules_js" +if (foo.isGood) {} + +if (ff1.f1 > 18) { + console.log("adult"); +} + +class B extends A {} +let b = new B() +let c = new B() + +class E extends C {} // no autofix+error, handled in different pr + +try { + ff4() +} catch (e) { + e as number // 123 +} + +let arr = ff3.arr +let len = arr.length as number +for (let i = 0; i < len; ++i) { + let x = arr[i] + arr[i] = 0 +} + +interface Person { + name: string +} + +function foo2(p: Person) {} +let lambda = (p: Person) => {} + +handle(foo2) +handle(lambda) + +class X{a = 1; b= 2; c= 3} +expand(new X()) // ERROR expand-static +class Y { + str: string = 'str'; + bool: boolean = false; +} +let testY: Y = { + str: "hello", + bool: false, +} +expand(testY); +expand({x: '1', y: "hello", z: false}); +let flag = false; +if (orange.isVegetable1 === 123) { +flag = true +} diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets.args.json b/ets2panda/linter/test/interop/interop_import_js_rules.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ff420e583913728909c7fcf2bdd2619017551173 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_rules.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": "", + "autofix": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js_rules.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..299b2732c88f92fb55f66b3b14a65b390fd40dab --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.arkts2.json @@ -0,0 +1,628 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 54, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "InteropJsObjectConditionJudgment", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InteropJsObjectConditionJudgment", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 14, + "endLine": 33, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 1, + "endLine": 37, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "InteropJSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch JS errors is not permitted (arkts-interop-js2s-js-exception)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 47, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 11, + "endLine": 50, + "endColumn": 21, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 14, + "endLine": 51, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9, + "problem": "InteropJsObjectTraverseJsInstance", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 13, + "problem": "InterOpImportJsIndex", + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 12, + "endLine": 53, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 8, + "endLine": 63, + "endColumn": 12, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 13, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 8, + "endLine": 64, + "endColumn": 14, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 15, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 9, + "endLine": 66, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 13, + "endLine": 66, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 19, + "endLine": 66, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 22, + "endLine": 66, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 25, + "endLine": 66, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 8, + "endLine": 67, + "endColumn": 15, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 16, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 8, + "endLine": 76, + "endColumn": 13, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 1, + "endLine": 76, + "endColumn": 14, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 8, + "endLine": 77, + "endColumn": 38, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 1, + "endLine": 77, + "endColumn": 39, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 32, + "problem": "InteropEqualityJudgment", + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 24, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 24, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 29, + "endLine": 79, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..4e7f1b6c7acc8979fbd86d4ce8eb5aa2b31f59bd --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json @@ -0,0 +1,1149 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 619, + "end": 669, + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51 + }, + { + "start": 1092, + "end": 1092, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_import_js_rules_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 670, + "end": 725, + "replacementText": "", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56 + }, + { + "start": 1092, + "end": 1092, + "replacementText": "let GeneratedImportVar_2 = ESValue.load('./interop_import_js_rules_js');\nlet ff1 = GeneratedImportVar_2.getPropertyByName('ff1');\nlet ff2 = GeneratedImportVar_2.getPropertyByName('ff2');\n", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 727, + "end": 775, + "replacementText": "", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49 + }, + { + "start": 1092, + "end": 1092, + "replacementText": "let GeneratedImportVar_3 = ESValue.load('./interop_import_js_rules_js');\nlet A = GeneratedImportVar_3.getPropertyByName('A');\n", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 776, + "end": 824, + "replacementText": "", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49 + }, + { + "start": 1092, + "end": 1092, + "replacementText": "let GeneratedImportVar_4 = ESValue.load('./interop_import_js_rules_js');\nlet C = GeneratedImportVar_4.getPropertyByName('C');\n", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 826, + "end": 876, + "replacementText": "", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51 + }, + { + "start": 1092, + "end": 1092, + "replacementText": "let GeneratedImportVar_5 = ESValue.load('./interop_import_js_rules_js');\nlet ff3 = GeneratedImportVar_5.getPropertyByName('ff3');\n", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 878, + "end": 928, + "replacementText": "", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51 + }, + { + "start": 1092, + "end": 1092, + "replacementText": "let GeneratedImportVar_6 = ESValue.load('./interop_import_js_rules_js');\nlet ff4 = GeneratedImportVar_6.getPropertyByName('ff4');\n", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 930, + "end": 983, + "replacementText": "", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54 + }, + { + "start": 1092, + "end": 1092, + "replacementText": "let GeneratedImportVar_7 = ESValue.load('./interop_import_js_rules_js');\nlet handle = GeneratedImportVar_7.getPropertyByName('handle');\n", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 985, + "end": 1038, + "replacementText": "", + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54 + }, + { + "start": 1092, + "end": 1092, + "replacementText": "let GeneratedImportVar_8 = ESValue.load('./interop_import_js_rules_js');\nlet expand = GeneratedImportVar_8.getPropertyByName('expand');\n", + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 54, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 1039, + "end": 1092, + "replacementText": "", + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 54 + }, + { + "start": 1092, + "end": 1092, + "replacementText": "let GeneratedImportVar_9 = ESValue.load('./interop_import_js_rules_js');\nlet orange = GeneratedImportVar_9.getPropertyByName('orange');\n", + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1097, + "end": 1107, + "replacementText": "foo.getPropertyByName(\"isGood\")", + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15, + "problem": "InteropJsObjectConditionJudgment", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('isGood').toBoolean()", + "start": 1097, + "end": 1107, + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InterOpImportJsDataCompare", + "suggest": "", + "rule": "Importing data directly from the \"JS\" module for comparison is not supported (arkts-interop-js2s-compare-js-data)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1117, + "end": 1123, + "replacementText": "ff1.getPropertyByName(\"f1\")", + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11, + "problem": "InteropJsObjectConditionJudgment", + "autofix": [ + { + "replacementText": "ff1.getPropertyByName('f1').toNumber()", + "start": 1117, + "end": 1123, + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 14, + "endLine": 33, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1126, + "end": 1128, + "replacementText": "18.0", + "line": 33, + "column": 14, + "endLine": 33, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 1, + "endLine": 37, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 21, + "problem": "InteropJsObjectInheritance", + "suggest": "", + "rule": "Direct inheritance of interop JS classes is not supported (arkts-interop-js2s-inherit-js-class)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "InteropJSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch JS errors is not permitted (arkts-interop-js2s-js-exception)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1288, + "end": 1293, + "replacementText": "ff4.invoke()", + "line": 44, + "column": 3, + "endLine": 44, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 47, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1343, + "end": 1350, + "replacementText": "ff3.getPropertyByName(\"arr\")", + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "ff3.getPropertyByName('arr')", + "start": 1343, + "end": 1350, + "line": 49, + "column": 11, + "endLine": 49, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 11, + "endLine": 50, + "endColumn": 21, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "arr.getPropertyByName('length').toNumber()", + "start": 1361, + "end": 1381, + "line": 50, + "column": 11, + "endLine": 50, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1391, + "end": 1396, + "replacementText": "i: number = 0", + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 14, + "endLine": 51, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1395, + "end": 1396, + "replacementText": "0.0", + "line": 51, + "column": 14, + "endLine": 51, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr.getPropertyByIndex(i).toNumber()", + "start": 1424, + "end": 1430, + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 1424, + "end": 1430, + "replacementText": "arr.getPropertyByIndex(i)", + "line": 52, + "column": 11, + "endLine": 52, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9, + "problem": "InteropJsObjectTraverseJsInstance", + "autofix": [ + { + "replacementText": "arr.setPropertyByIndex(i, ESValue.wrap(0))", + "start": 1433, + "end": 1443, + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-traverse-js-instance)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 13, + "problem": "InterOpImportJsIndex", + "autofix": [ + { + "start": 1433, + "end": 1443, + "replacementText": "arr.setPropertyByIndex(i, ESValue.wrap(0))", + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Interop objects can't be indexed directly (arkts-interop-js2s-access-js-index)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 12, + "endLine": 53, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1442, + "end": 1443, + "replacementText": "0.0", + "line": 53, + "column": 12, + "endLine": 53, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 8, + "endLine": 63, + "endColumn": 12, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 13, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1544, + "end": 1556, + "replacementText": "handle.invoke(ESValue.wrap(foo2))", + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 8, + "endLine": 64, + "endColumn": 14, + "problem": "InteropJsObjectCallStaticFunc", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-call-static-function)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 15, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1557, + "end": 1571, + "replacementText": "handle.invoke(ESValue.wrap(lambda))", + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 9, + "endLine": 66, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1581, + "end": 1587, + "replacementText": "a: number = 1;", + "line": 66, + "column": 9, + "endLine": 66, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 13, + "endLine": 66, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1585, + "end": 1586, + "replacementText": "1.0", + "line": 66, + "column": 13, + "endLine": 66, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1588, + "end": 1593, + "replacementText": "b: number = 2;", + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 19, + "endLine": 66, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1591, + "end": 1592, + "replacementText": "2.0", + "line": 66, + "column": 19, + "endLine": 66, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 22, + "endLine": 66, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1594, + "end": 1598, + "replacementText": "c: number = 3;", + "line": 66, + "column": 22, + "endLine": 66, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 25, + "endLine": 66, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1597, + "end": 1598, + "replacementText": "3.0", + "line": 66, + "column": 25, + "endLine": 66, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 8, + "endLine": 67, + "endColumn": 15, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 16, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1600, + "end": 1615, + "replacementText": "expand.invoke(ESValue.wrap(new X()))", + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 8, + "endLine": 76, + "endColumn": 13, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 1, + "endLine": 76, + "endColumn": 14, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1749, + "end": 1762, + "replacementText": "expand.invoke(ESValue.wrap(testY))", + "line": 76, + "column": 1, + "endLine": 76, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 8, + "endLine": 77, + "endColumn": 38, + "problem": "InteropJsObjectExpandStaticInstance", + "suggest": "", + "rule": "Direct usage of interop JS functions is not supported (arkts-interop-js2s-js-expand-static-instance)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 1, + "endLine": 77, + "endColumn": 39, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 1764, + "end": 1802, + "replacementText": "expand.invoke(ESValue.wrap({x: '1', y: \"hello\", z: false}))", + "line": 77, + "column": 1, + "endLine": 77, + "endColumn": 39 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 32, + "problem": "InteropEqualityJudgment", + "autofix": [ + { + "start": 1826, + "end": 1853, + "replacementText": "orange.isVegetable1.areStrictlyEqual(123)", + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "\"JS\" objects can't be used directly as operands of the equality operators (arkts-interop-js2s-equality-judgment)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 24, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1826, + "end": 1845, + "replacementText": "orange.getPropertyByName(\"isVegetable1\")", + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 24, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "orange.getPropertyByName('isVegetable1').toNumber()", + "start": 1826, + "end": 1845, + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 29, + "endLine": 79, + "endColumn": 32, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1850, + "end": 1853, + "replacementText": "123.0", + "line": 79, + "column": 29, + "endLine": 79, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets.json b/ets2panda/linter/test/interop/interop_import_js_rules.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..097539546e670b2be7a38f6e744498ccf306b277 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.json @@ -0,0 +1,108 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 56, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 51, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_js_rules_js.js b/ets2panda/linter/test/interop/interop_import_js_rules_js.js new file mode 100644 index 0000000000000000000000000000000000000000..cef219665e794ef06e76275a89ed5e52a93e67b3 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_js_rules_js.js @@ -0,0 +1,43 @@ +/* + * 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 let foo = {isGood: true} +export let ff1 = {f1: 10} +export let ff2 = {f2: 15} + +export class A {} +export class C {} + +export let ff3 = {arr: [1, 2, 3, 4, 5, 6, 7, 8, 9]} + +export function ff4() { + throw 123 +} + +export function handle(cb) { + let p = {name: 'hello'} + cb(p) +} + +export function expand(obj) { + let x = obj; + let {a, b, c} = obj; +} + +export let orange = { + isFruit: true, + isVegetable: false, + isVegetable1: 123 +} diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets b/ets2panda/linter/test/interop/interop_import_typeof_js.ets new file mode 100755 index 0000000000000000000000000000000000000000..3c4c0728f9b58e0b9753a086eb6110913b0a1170 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets @@ -0,0 +1,73 @@ +/* + * 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. + */ + +'use static' +import myAaa,{ClassA,Dog,Person,Wiki} from "./interop_import_js_js"; +import { Dog as Doge } from './interop_import_js_js'; +import { Wiki as wiki } from './interop_import_js_js'; + +typeof myAaa(); //error +let fun = myAaa(); +typeof fun; +typeof Dog; //error +typeof Dog('doge'); //error +typeof Doge('doge'); //error +typeof Wiki //error +typeof Wiki.name //error +typeof wiki //error +let val = wiki.name +typeof val; +const aClass:ClassA = new ClassA() +typeof new ClassA() //error +typeof aClass; +let person:Person = new Person(); +let name =person.name +let name2 =person.getName() +function getPersonInfo(){ + typeof person; + typeof person.getName(); + typeof name2; + typeof name; + typeof person.setAge(111); + typeof person; + typeof new Person(); //error +} + +const age = typeof person.setAge(111); +let person2 = typeof person +class Object { + code: string = "www" + location: string = typeof ('123') + getLocation(){ + console.log(`nameType=${ typeof code} `); + return typeof this.location; + } + setLocation(location: string){ + this.location = location; + typeof location; + } + tips(){ + typeof wiki.name; //error + typeof age; + typeof person2; + typeof fun; + console.log(`ClassA=${ typeof new ClassA()} `); //error + } +} + +typeof myAaa; //error +typeof new Person().name //error +typeof new Person().getName() //error +typeof new Person().setAge(22) //error diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.args.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..df6e67a5c9292c4c7e7aa5e976a3b8d1104fa082 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.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/interop/interop_import_typeof_js.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..07bd2108126e7d5c111d51ef715798f359641175 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.arkts2.json @@ -0,0 +1,488 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 69, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 69, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 54, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 55, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 55, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 15, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 18, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 11, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 19, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 8, + "endLine": 25, + "endColumn": 19, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 20, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 8, + "endLine": 26, + "endColumn": 20, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 12, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 17, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 17, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 17, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 12, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 11, + "endLine": 30, + "endColumn": 20, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 11, + "endLine": 30, + "endColumn": 20, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 23, + "endLine": 32, + "endColumn": 35, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 1, + "endLine": 33, + "endColumn": 20, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 20, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 21, + "endLine": 35, + "endColumn": 33, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 28, + "problem": "InteropCallObjectMethods", + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 10, + "endLine": 43, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 24, + "endLine": 43, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 22, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 10, + "endLine": 45, + "endColumn": 22, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 21, + "endLine": 48, + "endColumn": 39, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 35, + "endLine": 48, + "endColumn": 38, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 7, + "endLine": 50, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 5, + "endLine": 62, + "endColumn": 21, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 21, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 21, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 28, + "endLine": 66, + "endColumn": 47, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 35, + "endLine": 66, + "endColumn": 47, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 13, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 25, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 25, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 20, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 30, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 8, + "endLine": 72, + "endColumn": 20, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 31, + "problem": "InterOpImportJsForTypeOf", + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 8, + "endLine": 73, + "endColumn": 31, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 8, + "endLine": 73, + "endColumn": 20, + "problem": "InstantiatedJsOjbect", + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 28, + "endLine": 73, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} 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 new file mode 100755 index 0000000000000000000000000000000000000000..e913452998228a35b20b4ce06d1df47e221e9368 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json @@ -0,0 +1,933 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 69, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 69, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 618, + "end": 686, + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 69 + }, + { + "start": 795, + "end": 795, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_1.getPropertyByName('aaa');\nlet ClassA = GeneratedImportVar_1.getPropertyByName('ClassA');\nlet Dog = GeneratedImportVar_1.getPropertyByName('Dog');\nlet Person = GeneratedImportVar_1.getPropertyByName('Person');\nlet Wiki = GeneratedImportVar_1.getPropertyByName('Wiki');\n", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 69 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 54, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 687, + "end": 740, + "replacementText": "", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 54 + }, + { + "start": 795, + "end": 795, + "replacementText": "let GeneratedImportVar_2 = ESValue.load('./interop_import_js_js');\nlet Doge = GeneratedImportVar_2.getPropertyByName('Dog');\n", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 55, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 55, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 741, + "end": 795, + "replacementText": "", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 55 + }, + { + "start": 795, + "end": 795, + "replacementText": "let GeneratedImportVar_3 = ESValue.load('./interop_import_js_js');\nlet wiki = GeneratedImportVar_3.getPropertyByName('Wiki');\n", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 55 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 15, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 797, + "end": 811, + "replacementText": "myAaa.invoke().typeOf()", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 18, + "problem": "CallJSFunction", + "autofix": [ + { + "start": 831, + "end": 838, + "replacementText": "myAaa.invoke()", + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 11, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 852, + "end": 862, + "replacementText": "Dog.typeOf()", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 19, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 872, + "end": 890, + "replacementText": "Dog.invoke(ESValue.wrap('doge')).typeOf()", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 8, + "endLine": 25, + "endColumn": 19, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 20, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 900, + "end": 919, + "replacementText": "Doge.invoke(ESValue.wrap('doge')).typeOf()", + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 8, + "endLine": 26, + "endColumn": 20, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 12, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 929, + "end": 940, + "replacementText": "Wiki.typeOf()", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 17, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 949, + "end": 965, + "replacementText": "Wiki.getPropertyByName('name').typeOf()", + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 17, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 956, + "end": 965, + "replacementText": "Wiki.getPropertyByName(\"name\")", + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 17, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "Wiki.getPropertyByName('name').toString()", + "start": 956, + "end": 965, + "line": 28, + "column": 8, + "endLine": 28, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 12, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 974, + "end": 985, + "replacementText": "wiki.typeOf()", + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 11, + "endLine": 30, + "endColumn": 20, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1004, + "end": 1013, + "replacementText": "wiki.getPropertyByName(\"name\")", + "line": 30, + "column": 11, + "endLine": 30, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 11, + "endLine": 30, + "endColumn": 20, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "wiki.getPropertyByName('name').toString()", + "start": 1004, + "end": 1013, + "line": 30, + "column": 11, + "endLine": 30, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 23, + "endLine": 32, + "endColumn": 35, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1048, + "end": 1060, + "replacementText": "ClassA.instantiate()", + "line": 32, + "column": 23, + "endLine": 32, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 1, + "endLine": 33, + "endColumn": 20, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 1061, + "end": 1080, + "replacementText": "ClassA.instantiate().typeOf()", + "line": 33, + "column": 1, + "endLine": 33, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 20, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1068, + "end": 1080, + "replacementText": "ClassA.instantiate()", + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 21, + "endLine": 35, + "endColumn": 33, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1124, + "end": 1136, + "replacementText": "Person.instantiate()", + "line": 35, + "column": 21, + "endLine": 35, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 28, + "problem": "InteropCallObjectMethods", + "autofix": [ + { + "start": 1171, + "end": 1187, + "replacementText": "person.invokeMethod(\"getName\")", + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "Calling methods of JS Object directly in interop is not allowed (arkts-interop-js2s-call-js-method)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 10, + "endLine": 43, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 24, + "endLine": 43, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1312, + "end": 1315, + "replacementText": "111.0", + "line": 43, + "column": 24, + "endLine": 43, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 22, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 1337, + "end": 1356, + "replacementText": "Person.instantiate().typeOf()", + "line": 45, + "column": 3, + "endLine": 45, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 10, + "endLine": 45, + "endColumn": 22, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1344, + "end": 1356, + "replacementText": "Person.instantiate()", + "line": 45, + "column": 10, + "endLine": 45, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 21, + "endLine": 48, + "endColumn": 39, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 35, + "endLine": 48, + "endColumn": 38, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1403, + "end": 1406, + "replacementText": "111.0", + "line": 48, + "column": 35, + "endLine": 48, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 7, + "endLine": 50, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 5, + "endLine": 62, + "endColumn": 21, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 1713, + "end": 1729, + "replacementText": "wiki.getPropertyByName('name').typeOf()", + "line": 62, + "column": 5, + "endLine": 62, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 21, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 1720, + "end": 1729, + "replacementText": "wiki.getPropertyByName(\"name\")", + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 21, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "wiki.getPropertyByName('name').toString()", + "start": 1720, + "end": 1729, + "line": 62, + "column": 12, + "endLine": 62, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 28, + "endLine": 66, + "endColumn": 47, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 1818, + "end": 1837, + "replacementText": "ClassA.instantiate().typeOf()", + "line": 66, + "column": 28, + "endLine": 66, + "endColumn": 47 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 35, + "endLine": 66, + "endColumn": 47, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1825, + "end": 1837, + "replacementText": "ClassA.instantiate()", + "line": 66, + "column": 35, + "endLine": 66, + "endColumn": 47 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 13, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 1858, + "end": 1870, + "replacementText": "myAaa.typeOf()", + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 25, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 1880, + "end": 1904, + "replacementText": "Person.instantiate().getPropertyByName('name').typeOf()", + "line": 71, + "column": 1, + "endLine": 71, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 25, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "new Person().getPropertyByName('name').toString()", + "start": 1887, + "end": 1904, + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 20, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1887, + "end": 1899, + "replacementText": "Person.instantiate()", + "line": 71, + "column": 8, + "endLine": 71, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 30, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 1914, + "end": 1943, + "replacementText": "Person.instantiate().getPropertyByName('getName').invoke().typeOf()", + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 30 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 8, + "endLine": 72, + "endColumn": 20, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1921, + "end": 1933, + "replacementText": "Person.instantiate()", + "line": 72, + "column": 8, + "endLine": 72, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 31, + "problem": "InterOpImportJsForTypeOf", + "autofix": [ + { + "start": 1952, + "end": 1982, + "replacementText": "Person.instantiate().getPropertyByName('setAge').invoke(ESValue.wrap(22)).typeOf()", + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 31 + } + ], + "suggest": "", + "rule": "The \"typeof\" expression can't be used with interop JS objects (arkts-interop-js2s-typeof-js-type)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 8, + "endLine": 73, + "endColumn": 31, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 8, + "endLine": 73, + "endColumn": 20, + "problem": "InstantiatedJsOjbect", + "autofix": [ + { + "start": 1959, + "end": 1971, + "replacementText": "Person.instantiate()", + "line": 73, + "column": 8, + "endLine": 73, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "ArkTS directly instantiated JS objects is not supported (arkts-interop-js2s-create-js-instance)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 28, + "endLine": 73, + "endColumn": 30, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1979, + "end": 1981, + "replacementText": "22.0", + "line": 73, + "column": 28, + "endLine": 73, + "endColumn": 30 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..b61974a218a0379e953f24d569b9397beafd431a --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 69, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 54, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 55, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..c5dde90dd5e0a65915cd87a53c1ba9bfdd491f29 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets @@ -0,0 +1,83 @@ +/* + * 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. + */ + +'use static' + + +let GeneratedImportVar_3 = ESValue.load('./interop_import_js_js'); +let wiki = GeneratedImportVar_3.getPropertyByName('Wiki'); +let GeneratedImportVar_2 = ESValue.load('./interop_import_js_js'); +let Doge = GeneratedImportVar_2.getPropertyByName('Dog'); +let GeneratedImportVar_1 = ESValue.load('./interop_import_js_js'); +let myAaa = GeneratedImportVar_1.getPropertyByName('aaa'); +let ClassA = GeneratedImportVar_1.getPropertyByName('ClassA'); +let Dog = GeneratedImportVar_1.getPropertyByName('Dog'); +let Person = GeneratedImportVar_1.getPropertyByName('Person'); +let Wiki = GeneratedImportVar_1.getPropertyByName('Wiki'); + + +myAaa.invoke().typeOf(); //error +let fun = myAaa.invoke(); +typeof fun; +Dog.typeOf(); //error +Dog.invoke(ESValue.wrap('doge')).typeOf(); //error +Doge.invoke(ESValue.wrap('doge')).typeOf(); //error +Wiki.typeOf() //error +Wiki.getPropertyByName('name').typeOf() //error +wiki.typeOf() //error +let val = wiki.getPropertyByName("name") +typeof val; +const aClass:ClassA = ClassA.instantiate() +ClassA.instantiate().typeOf() //error +typeof aClass; +let person:Person = Person.instantiate(); +let name =person.name +let name2 =person.invokeMethod("getName") +function getPersonInfo(){ + typeof person; + typeof person.getName(); + typeof name2; + typeof name; + typeof person.setAge(111.0); + typeof person; + Person.instantiate().typeOf(); //error +} + +const age = typeof person.setAge(111.0); +let person2 = typeof person +class Object { + code: string = "www" + location: string = typeof ('123') + getLocation(){ + console.log(`nameType=${ typeof code} `); + return typeof this.location; + } + setLocation(location: string){ + this.location = location; + typeof location; + } + tips(){ + wiki.getPropertyByName('name').typeOf(); //error + typeof age; + typeof person2; + typeof fun; + console.log(`ClassA=${ ClassA.instantiate().typeOf()} `); //error + } +} + +myAaa.typeOf(); //error +Person.instantiate().getPropertyByName('name').typeOf() //error +Person.instantiate().getPropertyByName('getName').invoke().typeOf() //error +Person.instantiate().getPropertyByName('setAge').invoke(ESValue.wrap(22.0)).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 new file mode 100644 index 0000000000000000000000000000000000000000..983fb8071ba4854eebeec49606eff3ab4d27a456 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json @@ -0,0 +1,168 @@ +{ + "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": 19, + "column": 5, + "endLine": 19, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 57, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 62, + "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": 62, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 58, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 41, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 42, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 7, + "endLine": 60, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets new file mode 100755 index 0000000000000000000000000000000000000000..3f72e3cf20095970eca698f3f6e5f605c259e563 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.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. + */ +'use static' + +import {foo, person} from "./interop_not_have_property_js" + +foo.name +foo.name = "456" +person.age = 23 +person.male = [2, 3] +foo.age = 12 \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.args.json b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.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/interop/interop_not_have_property_arkts2.ets.arkts2.json b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..ce2c2d2d380e4a8a2c01955ae168963ec398e48d --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.arkts2.json @@ -0,0 +1,178 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 59, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 59, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 17, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 16, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 11, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 14, + "endLine": 21, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 21, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 12, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 16, + "endLine": 22, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 13, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 8, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 11, + "endLine": 23, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100755 index 0000000000000000000000000000000000000000..0c4beba4af8407234f89cb6c304fa5bf7b5a4016 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.autofix.json @@ -0,0 +1,352 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 59, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 59, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 618, + "end": 676, + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 59 + }, + { + "start": 676, + "end": 676, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_not_have_property_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\nlet person = GeneratedImportVar_1.getPropertyByName('person');\n", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 59 + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 678, + "end": 686, + "replacementText": "foo.getPropertyByName(\"name\")", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('name').toString()", + "start": 678, + "end": 686, + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 17, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 687, + "end": 703, + "replacementText": "foo.setPropertyByName(\"name\", ESValue.wrap(\"456\"))", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('name').toString()", + "start": 687, + "end": 695, + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 16, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 704, + "end": 719, + "replacementText": "person.setPropertyByName(\"age\", ESValue.wrap(23))", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 11, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "person.getPropertyByName('age').toNumber()", + "start": 704, + "end": 714, + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 14, + "endLine": 21, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 717, + "end": 719, + "replacementText": "23.0", + "line": 21, + "column": 14, + "endLine": 21, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 21, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 720, + "end": 740, + "replacementText": "person.setPropertyByName(\"male\", ESValue.wrap([2, 3]))", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 12, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "person.getPropertyByName('male')", + "start": 720, + "end": 731, + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 16, + "endLine": 22, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 735, + "end": 736, + "replacementText": "2.0", + "line": 22, + "column": 16, + "endLine": 22, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 738, + "end": 739, + "replacementText": "3.0", + "line": 22, + "column": 19, + "endLine": 22, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 13, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 741, + "end": 753, + "replacementText": "foo.setPropertyByName(\"age\", ESValue.wrap(12))", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 8, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('age')", + "start": 741, + "end": 748, + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 11, + "endLine": 23, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 751, + "end": 753, + "replacementText": "12.0", + "line": 23, + "column": 11, + "endLine": 23, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.json b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..838a0500a51da618680219ad2074df304e1eff66 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 59, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..586868511b0fe70e32df6c0f516fd64bba41c9a5 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.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. + */ +'use static' + +let GeneratedImportVar_1 = ESValue.load('./interop_not_have_property_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); +let person = GeneratedImportVar_1.getPropertyByName('person'); + + +foo.getPropertyByName("name") +foo.setPropertyByName("name", ESValue.wrap("456")) +person.setPropertyByName("age", ESValue.wrap(23.0)) +person.setPropertyByName("male", ESValue.wrap([2.0, 3.0])) +foo.setPropertyByName("age", ESValue.wrap(12.0)) \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..17bc19346aae749d288ae9fe18ae878cdee8d9ef --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.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": 17, + "column": 5, + "endLine": 17, + "endColumn": 74, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 62, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_not_have_property_js.js b/ets2panda/linter/test/interop/interop_not_have_property_js.js new file mode 100755 index 0000000000000000000000000000000000000000..cd3b2ad79c827240efb0dfeb83a5057f3238fb3d --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_js.js @@ -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. + */ +export let foo = {name: "123"} +export let person = {age: 12, male: [1, 2, 3]} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets new file mode 100755 index 0000000000000000000000000000000000000000..1049aac0f00e701d6e1ad108fcc92ab88dcf7933 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.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. + */ +'use static' + +import {foo} from "./interop_property_num_js" + ++foo.num; +-foo.num; +!foo.num; +~foo.num; ++(foo.num); +-(foo.num); +!(foo.num); +~(foo.num); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.args.json b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.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/interop/interop_not_have_property_num_arkts2.ets.arkts2.json b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..414d9f77210b68d5546e3d261c39852de9ee43a0 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.arkts2.json @@ -0,0 +1,278 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 46, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 46, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 9, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 9, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 9, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 9, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100755 index 0000000000000000000000000000000000000000..4452cefcfd558d981573f96c553799bb22d28897 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.autofix.json @@ -0,0 +1,558 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 46, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 46, + "problem": "InterOpImportJs", + "autofix": [ + { + "start": 618, + "end": 663, + "replacementText": "", + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 46 + }, + { + "start": 663, + "end": 663, + "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_property_num_js');\nlet foo = GeneratedImportVar_1.getPropertyByName('foo');\n" + } + ], + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 666, + "end": 673, + "replacementText": "foo.getPropertyByName(\"num\").toNumber()", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 9, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 666, + "end": 673, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 666, + "end": 673, + "line": 19, + "column": 2, + "endLine": 19, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 676, + "end": 683, + "replacementText": "foo.getPropertyByName(\"num\").toNumber()", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 9, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 676, + "end": 683, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 676, + "end": 683, + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 686, + "end": 693, + "replacementText": "foo.getPropertyByName(\"num\").toNumber()", + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 9, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 686, + "end": 693, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 686, + "end": 693, + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 9, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 696, + "end": 703, + "replacementText": "foo.getPropertyByName(\"num\").toNumber()", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 9, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 696, + "end": 703, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 9, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 696, + "end": 703, + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 706, + "end": 715, + "replacementText": "(foo.getPropertyByName(\"num\").toNumber())", + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 707, + "end": 714, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 707, + "end": 714, + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 718, + "end": 727, + "replacementText": "(foo.getPropertyByName(\"num\").toNumber())", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 719, + "end": 726, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 719, + "end": 726, + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 730, + "end": 739, + "replacementText": "(foo.getPropertyByName(\"num\").toNumber())", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 731, + "end": 738, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 731, + "end": 738, + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 11, + "problem": "InteropNoHaveNum", + "autofix": [ + { + "start": 742, + "end": 751, + "replacementText": "(foo.getPropertyByName(\"num\").toNumber())", + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Interop object does not have property num (arkts-interop-js2s-unary-op)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "InteropObjectProperty", + "autofix": [ + { + "start": 743, + "end": 750, + "replacementText": "foo.getPropertyByName(\"num\")", + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10, + "problem": "InteropJsObjectUsage", + "autofix": [ + { + "replacementText": "foo.getPropertyByName('num').toNumber()", + "start": 743, + "end": 750, + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.json b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..456612d680838522a6a4843c38b2df4fa326df96 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 46, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/union_string_literals_7.ets b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets similarity index 55% rename from ets2panda/test/ast/compiler/ets/FixedArray/union_string_literals_7.ets rename to ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets index 7d62d58dba546c5f37b413b6d3b2d37883a417d3..1a22e1418c9a3fbf82d7e96e9db282d67d53e8e9 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/union_string_literals_7.ets +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets @@ -12,15 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' -function foo(a: "aa"|"bb") { - return a -} +let GeneratedImportVar_1 = ESValue.load('./interop_property_num_js'); +let foo = GeneratedImportVar_1.getPropertyByName('foo'); -let x = ["aa", "bb", "aa"] // type of x is FixedArray -let y = foo(x) -/* @@? 21:9 Error TypeError: No matching call signature for foo(String[]) */ -/* @@? 21:9 Error TypeError: No matching call signature for foo(String[]) */ -/* @@? 21:13 Error TypeError: Type 'String[]' is not compatible with type '"aa"|"bb"' at index 1 */ -/* @@? 21:13 Error TypeError: Type 'String[]' is not compatible with type '"aa"|"bb"' at index 1 */ ++foo.getPropertyByName("num").toNumber(); +-foo.getPropertyByName("num").toNumber(); +!foo.getPropertyByName("num").toNumber(); +~foo.getPropertyByName("num").toNumber(); ++(foo.getPropertyByName("num").toNumber()); +-(foo.getPropertyByName("num").toNumber()); +!(foo.getPropertyByName("num").toNumber()); +~(foo.getPropertyByName("num").toNumber()); \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..01cf629ed9743d2f465bfce367539feebf811ed4 --- /dev/null +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json @@ -0,0 +1,98 @@ +{ + "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": 17, + "column": 5, + "endLine": 17, + "endColumn": 69, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 41, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 41, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 41, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 43, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 43, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 43, + "problem": "UnaryArithmNotNumber", + "suggest": "", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/interop_property_num_js.js b/ets2panda/linter/test/interop/interop_property_num_js.js new file mode 100755 index 0000000000000000000000000000000000000000..a248e1f84bd5e268900334fcf1364bfe065dd6fd --- /dev/null +++ b/ets2panda/linter/test/interop/interop_property_num_js.js @@ -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. + */ + +export let foo = {num: 0} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/jsfiles/preview_import_js.js b/ets2panda/linter/test/interop/jsfiles/preview_import_js.js new file mode 100755 index 0000000000000000000000000000000000000000..f9e84c9a1b2ebecdbaf40db3f1076afec02fd1fb --- /dev/null +++ b/ets2panda/linter/test/interop/jsfiles/preview_import_js.js @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023-2024 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 class CPreview {} +export function bar(a){} +export let foo = {name: "123"} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_await_js_promise.ets b/ets2panda/linter/test/interop/no_await_js_promise.ets new file mode 100755 index 0000000000000000000000000000000000000000..9247c363b44ed65bb043a4311584031f31e6d8fd --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets @@ -0,0 +1,65 @@ +/* + * 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. + */ +'use static' + +import { p, foo, pFuncCall, arrowFunc, pArrowCall } from "./no_await_js_promise_export"; + +async function awaitPromise() { + return await p; +} + +async function awaitFunctionCall() { + return await foo(); +} + +async function awaitFuncResult() { + return await pFuncCall; +} + +async function awaitArrowCall() { + return await arrowFunc(); +} + +async function awaitArrowResult() { + return await pArrowCall; +} + +class ExampleClass { + async classMethod() { + return await p; + } + + handler = async () => { + return await pFuncCall; + }; +} + +const exampleObj = { + async objMethod() { + return await pArrowCall; + }, + + arrowHandler: async () => { + return await foo(); + } +}; + +(async function() { + console.log("IIFE result:", await p); +})(); + +(async () => { + console.log("IIFE Arrow result:", await arrowFunc()); +})(); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_await_js_promise.ets.args.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_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/interop/no_await_js_promise.ets.arkts2.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..5021d02c431e482be957465ba47d4f742f95d3f9 --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.arkts2.json @@ -0,0 +1,218 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 89, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 89, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 17, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 21, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 16, + "endLine": 24, + "endColumn": 21, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 10, + "endLine": 28, + "endColumn": 25, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 10, + "endLine": 32, + "endColumn": 27, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 16, + "endLine": 32, + "endColumn": 27, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 10, + "endLine": 36, + "endColumn": 26, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 19, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 12, + "endLine": 45, + "endColumn": 27, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 20, + "endLine": 49, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 3, + "endLine": 52, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 12, + "endLine": 51, + "endColumn": 28, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 12, + "endLine": 55, + "endColumn": 23, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 18, + "endLine": 55, + "endColumn": 23, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 2, + "endLine": 61, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 31, + "endLine": 60, + "endColumn": 38, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 37, + "endLine": 64, + "endColumn": 54, + "problem": "NoAwaitJsPromise", + "suggest": "", + "rule": "\"Await\" operator can't be used with interop objects (arkts-interop-js2s-await-js-promise)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 43, + "endLine": 64, + "endColumn": 54, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_await_js_promise.ets.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..5285bc41f634a1abbb69521c2609a6c4aebd006d --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 89, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 20, + "endLine": 49, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 2, + "endLine": 61, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_await_js_promise_export.js b/ets2panda/linter/test/interop/no_await_js_promise_export.js new file mode 100755 index 0000000000000000000000000000000000000000..0707e733bbb95949629784f96013070d5f1862ee --- /dev/null +++ b/ets2panda/linter/test/interop/no_await_js_promise_export.js @@ -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. + */ + +export const p = Promise.resolve("resolved value"); +export async function foo() { + return "foo result"; +} +export const pFuncCall = foo(); +export const arrowFunc = async () => "arrow result"; +export const pArrowCall = arrowFunc(); \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets b/ets2panda/linter/test/interop/no_js_instanceof.ets new file mode 100755 index 0000000000000000000000000000000000000000..f3e57eeee88a4fecf7bfddc410314089fdd77036 --- /dev/null +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets @@ -0,0 +1,77 @@ +/* + * 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. + */ +'use static' + +import { Foo, foo, CreatePerson, a , b, MyNamespace } from "./no_js_instanceof_file.js" + +class Foo1 {} + +let foo1 = new Foo1() + +if(foo1 instanceof Foo1) { + +} + +if(foo instanceof Foo) { + +} + +if(foo1 instanceof Foo) { + +} + +if(foo instanceof Foo1) { + +} + +let person: CreatePerson = CreatePerson('xc', 18) + +if(person instanceof CreatePerson) { + +} + +function test1(): void { + if(person instanceof CreatePerson) { + + } +} + +const test2 = (): void => { + if(person instanceof CreatePerson) { + + } +} + +class Test3 { + init(): void { + if(person instanceof CreatePerson) { + + } + } +} + +if(a instanceof Array) { + +} + +if(b() instanceof Array) { + +} + +const myDog: MyNamespace.Dog = new MyNamespace.Dog('Buddy'); + +if (myDog instanceof MyNamespace.Dog) { + console.log("This is a Dog!"); +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/destructuring_assignments.ts.args.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.args.json old mode 100644 new mode 100755 similarity index 90% rename from ets2panda/linter/test/migrate/destructuring_assignments.ts.args.json rename to ets2panda/linter/test/interop/no_js_instanceof.ets.args.json index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..3ef4496a819a201892114d1c90f78ae32053c334 --- a/ets2panda/linter/test/migrate/destructuring_assignments.ts.args.json +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 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", @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "migrate": "" + "arkts2": "" } } diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..31d9a91eefed798e8b18bad28feaf7e89200c341 --- /dev/null +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.arkts2.json @@ -0,0 +1,218 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 88, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 88, + "problem": "InterOpImportJs", + "suggest": "", + "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 4, + "endLine": 27, + "endColumn": 22, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 4, + "endLine": 31, + "endColumn": 23, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 4, + "endLine": 35, + "endColumn": 23, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 28, + "endLine": 39, + "endColumn": 50, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 47, + "endLine": 39, + "endColumn": 49, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 4, + "endLine": 41, + "endColumn": 34, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 8, + "endLine": 46, + "endColumn": 38, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 8, + "endLine": 52, + "endColumn": 38, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 12, + "endLine": 59, + "endColumn": 42, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 4, + "endLine": 65, + "endColumn": 22, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 4, + "endLine": 69, + "endColumn": 24, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 4, + "endLine": 69, + "endColumn": 7, + "problem": "CallJSFunction", + "suggest": "", + "rule": "ArkTS directly call JS functions or parameters is not supported (arkts-interop-js2s-call-js-func)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 36, + "endLine": 73, + "endColumn": 51, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 36, + "endLine": 73, + "endColumn": 51, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 36, + "endLine": 73, + "endColumn": 51, + "problem": "InteropJsObjectUsage", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js-object-usage)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 5, + "endLine": 75, + "endColumn": 37, + "problem": "InteropJsInstanceof", + "suggest": "", + "rule": "Usage of \"instanceof\" operator is not allowed with interop objects (arkts-interop-js2s-instanceof-js-type)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 22, + "endLine": 75, + "endColumn": 37, + "problem": "InteropObjectProperty", + "suggest": "", + "rule": "Properties of interop objects can't be accessed directly (arkts-interop-js2s-access-js-prop)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 22, + "endLine": 75, + "endColumn": 37, + "problem": "InteropJsObjectConditionJudgment", + "suggest": "", + "rule": "Direct usage of interop JS objects is not supported (arkts-interop-js2s-condition-judgment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..e6955adae6bac5e78b91f1b2779d27117f1fde2f --- /dev/null +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.json @@ -0,0 +1,29 @@ +{ + + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 88, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_js_instanceof_file.js b/ets2panda/linter/test/interop/no_js_instanceof_file.js new file mode 100755 index 0000000000000000000000000000000000000000..4e16bdf2a50a98ed8fcd5df3f8276f33d6372b16 --- /dev/null +++ b/ets2panda/linter/test/interop/no_js_instanceof_file.js @@ -0,0 +1,44 @@ +/* + * 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 class Foo{} +export let foo = new Foo() +export function CreatePerson(name, age) { + return { + name, + age, + greet() { + return `Hello, I'm ${this.name}`; + } + }; +} +export const a = [1,2,3] +export function b () { + return [1,2,3] +} +export class Animal {} +export class Dog extends Animal {} +export const MyNamespace = { + Animal: class { + constructor(name) { + this.name = name; + } + }, + Dog: class extends MyNamespace.Animal { + bark() { + return 'Woof!'; + } + } +}; \ No newline at end of file diff --git a/ets2panda/linter/test/interop/object_built_in.ets b/ets2panda/linter/test/interop/object_built_in.ets index 52776ecdd455ee96dbf548f5ca4091eb1e49cfd0..7797930ffdc48c71b861f8f690b58f811efd2319 100644 --- a/ets2panda/linter/test/interop/object_built_in.ets +++ b/ets2panda/linter/test/interop/object_built_in.ets @@ -12,9 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' -import { foo } from "./oh_modules/object_built_in" +import { X } from "./oh_modules/object_built_in" -class X { a = 1 }; +export function foo(prx: Object) { + Object.assign({}, prx); + Object.entries(prx); + Object.keys(prx); + Object.values(prx); + prx.hasOwnProperty("a"); +} foo(new X()); // Illegal diff --git a/ets2panda/linter/test/interop/object_built_in.ets.args.json b/ets2panda/linter/test/interop/object_built_in.ets.args.json index 0adede204e309a92c8aac08d89f6af16d9c93f78..aac366be5e8658d7672f4da2855a3c4740c7bcd3 100644 --- a/ets2panda/linter/test/interop/object_built_in.ets.args.json +++ b/ets2panda/linter/test/interop/object_built_in.ets.args.json @@ -14,5 +14,6 @@ "limitations under the License." ], "mode": { + "arkts2": "" } } diff --git a/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json b/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..07296c65fcf827975765e901537551ce63c21858 --- /dev/null +++ b/ets2panda/linter/test/interop/object_built_in.ets.arkts2.json @@ -0,0 +1,68 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 12, + "endLine": 20, + "endColumn": 18, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 19, + "endLine": 20, + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 23, + "problem": "LimitedStdLibApi", + "suggest": "", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 14, + "problem": "InteropCallObjectParam", + "suggest": "", + "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/object_built_in.ets.json b/ets2panda/linter/test/interop/object_built_in.ets.json index 00d0c7765488f81d3137fec09ad16d7225c35cb5..582a700d940a62a7f8b6fae343ed7bf79d4da05e 100644 --- a/ets2panda/linter/test/interop/object_built_in.ets.json +++ b/ets2panda/linter/test/interop/object_built_in.ets.json @@ -14,24 +14,44 @@ "limitations under the License." ], "result": [ - { - "line": 20, + { + "line": 17, "column": 1, + "endLine": 17, + "endColumn": 49, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, "endLine": 20, - "endColumn": 13, - "problem": "InteropCallObjectParam", + "endColumn": 27, + "problem": "LimitedStdLibApi", "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-call-object-param)", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, - { + { "line": 20, - "column": 1, + "column": 19, "endLine": 20, - "endColumn": 13, - "problem": "InteropCallObjectParam", + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 28, + "problem": "LimitedStdLibApi", "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-call-object-param)", + "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/object_literal_constructor.ets b/ets2panda/linter/test/interop/object_literal_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..7c15e1bf64f1cfa040ef5ebaf62e84285eba0321 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets @@ -0,0 +1,83 @@ +'use static' +/* + * Copyright (c) 2022-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 { User, Person, Fruit, Apple, foo, bar, X, Y } from "./oh_modules/object_literal_constructor" + +//Variable Declaration +let user: User = { id: 1 } + +let fruit: Fruit = new Fruit("fruit"); // legal + +let person: Person = { name: "Furkan", age: "25" } + +const base = { title: 'value' }; +const y: X = { ...base }; + +// Call expression +foo({name:" cfe"}); +foo(new X("cfe")); //legal +bar({name:" cfe"}); //legal + +//Return statement +function createItem(): X { + return { title: 'item' }; +} + +function getClass(): X { + return new X("cfe"); //legal +} + +function createItem2(): Y { + return { title: 'item' }; //legal +} + +// Property Declaration +class Wrapper { + item: X = { title: 'invalid' }; +} + +class WrapperLegal { + item: X = new X("cfe"); //legal +} + +// As Expression +const x = { title: 'value' } as X; +const val = new X("cfe") as X; //legal + +// Conditional Expression +const condition = true; + +const value: X = condition ? { title: 'hello' } : new X("cfe"); + +const value2: X = condition ? new Fruit("ase") : new X("sea"); //legal + +//Binary Expression +let u: X; + +u = { + a: 'assign', + b: 88 +}; + +u = new Fruit("apple") // legal + +//ArrayLiteralExpression +const arr: X[] = [ + { a: 'fail', b: 5 }, + { a: 'bad', b: 6 } + ]; + +const arrLegal: X[] = [new X("cfe"), new X("cfe")]; //legal \ No newline at end of file diff --git a/ets2panda/linter/test/interop/ts_decorator.ets.args.json b/ets2panda/linter/test/interop/object_literal_constructor.ets.args.json similarity index 100% rename from ets2panda/linter/test/interop/ts_decorator.ets.args.json rename to ets2panda/linter/test/interop/object_literal_constructor.ets.args.json diff --git a/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json b/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..6a51dd80b2384cb85784952c10f738f84aaa2cbd --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets.arkts2.json @@ -0,0 +1,208 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 101, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 18, + "endLine": 20, + "endColumn": 27, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 24, + "endLine": 20, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 22, + "endLine": 24, + "endColumn": 51, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 14, + "endLine": 26, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 14, + "endLine": 27, + "endColumn": 25, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 16, + "endLine": 27, + "endColumn": 23, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 16, + "endLine": 27, + "endColumn": 23, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 18, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 12, + "endLine": 36, + "endColumn": 29, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 15, + "endLine": 49, + "endColumn": 35, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 11, + "endLine": 57, + "endColumn": 29, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 30, + "endLine": 63, + "endColumn": 48, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 5, + "endLine": 73, + "endColumn": 2, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 6, + "endLine": 72, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 24, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 23, + "problem": "InteropObjectLiteralClass", + "suggest": "", + "rule": "Object literal cannot be directly assigned to class with a constructor. (arkts-interop-d2s-object-literal-no-args-constructor)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 21, + "endLine": 79, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 20, + "endLine": 80, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/object_literal_constructor.ets.json b/ets2panda/linter/test/interop/object_literal_constructor.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bafc2e9e5484c606da27a671a0708fcec32cba92 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_constructor.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 101, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 14, + "endLine": 26, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 16, + "endLine": 27, + "endColumn": 23, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/object_literal_union_type.ets b/ets2panda/linter/test/interop/object_literal_union_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..f57fd51379483dadc616f4982de7a53d521c2656 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets @@ -0,0 +1,29 @@ +'use static' +/* + * Copyright (c) 2022-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 {X, Y, Z} from "./oh_modules/object_literal_union_type" + +import {A, B} from "./oh_modules/object_literal_union_type_arkts2" + +let xy: X | Y = { name: "xy" } + +let yz: Y | Z = { name: "yz" } + +let xyz: X | Y | Z = { name: "xyz" } + +let ab: A | B = { name: "hello" } // legal + +let y: X | Y = { name: "hello" } as Y; // legal \ No newline at end of file diff --git a/ets2panda/linter/test/main/worker_module.ts.args.json b/ets2panda/linter/test/interop/object_literal_union_type.ets.args.json similarity index 100% rename from ets2panda/linter/test/main/worker_module.ts.args.json rename to ets2panda/linter/test/interop/object_literal_union_type.ets.args.json diff --git a/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json b/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5c02f0cb4d9911bc2709610266b70dc0caf4d404 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets.arkts2.json @@ -0,0 +1,68 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 63, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 67, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 31, + "problem": "InteropObjectLiteralAmbiguity", + "suggest": "", + "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 31, + "problem": "InteropObjectLiteralAmbiguity", + "suggest": "", + "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 37, + "problem": "InteropObjectLiteralAmbiguity", + "suggest": "", + "rule": "Object literal not compatible with target union type. (arkts-interop-d2s-object-literal-no-ambiguity)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/object_literal_union_type.ets.json b/ets2panda/linter/test/interop/object_literal_union_type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..25154ac0c6605dd88492da69d54ca7d7a2cda0d5 --- /dev/null +++ b/ets2panda/linter/test/interop/object_literal_union_type.ets.json @@ -0,0 +1,38 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 63, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 67, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/oh_modules/object_built_in.ets b/ets2panda/linter/test/interop/oh_modules/object_built_in.ets index 0d30fa2156dff4eb11c6477da1f32fdbe495b82a..e06b3e23f981bc11f0556445e190d436daa48ab1 100644 --- a/ets2panda/linter/test/interop/oh_modules/object_built_in.ets +++ b/ets2panda/linter/test/interop/oh_modules/object_built_in.ets @@ -1,5 +1,3 @@ -'use static' - /* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,13 +13,6 @@ * limitations under the License. */ -export function foo(prx: Object) { - Object.assign({}, prx); - Object.entries(prx); - Object.keys(prx); - Object.values(prx); - prx.hasOwnProperty("a"); -} - +export class X { a = 1 }; diff --git a/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets b/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..f1f0a6f8e8589a99637d0dbc049ec3a105909001 --- /dev/null +++ b/ets2panda/linter/test/interop/oh_modules/object_literal_constructor.ets @@ -0,0 +1,53 @@ +/* + * 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 class User { + id: number; + constructor(arg: number) { + this.id = arg + } +} +export class Person { + name: string; + age: number; + constructor(arg1: string, arg2: number) { + this.name = arg1; + this.age = arg2; + } +} +export class Fruit { + name: string; + constructor(arg: string) { + this.name = arg; + } +} +export class Apple extends Fruit { + color: string; + constructor(string: string, arg2: string) { + super(string) + this.color = arg2; + } +} + +export class X { + name: string = ""; + constructor(arg: string) { + this.name = arg; + } +} + +export interface Y {data: number} +export function foo(arg: X){} +export function bar(arg: Y){} diff --git a/ets2panda/linter/test/interop/oh_modules/object_literal_union_type.ets b/ets2panda/linter/test/interop/oh_modules/object_literal_union_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..34b50528bd07629c1060f3fa524fcf1e1778eddd --- /dev/null +++ b/ets2panda/linter/test/interop/oh_modules/object_literal_union_type.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. + */ + +export class X { + name: string = '' + str: string = '' +} + +export class Y { + name: string = '' + bool: boolean = false +} + +export interface Z {name: string, age: number} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/oh_modules/object_literal_union_type_arkts2.ets b/ets2panda/linter/test/interop/oh_modules/object_literal_union_type_arkts2.ets new file mode 100644 index 0000000000000000000000000000000000000000..dad32c88bac85147e6236659ba62ac53ecb691ea --- /dev/null +++ b/ets2panda/linter/test/interop/oh_modules/object_literal_union_type_arkts2.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. + */ +'use static' + +export class A { name: string = '' } +export interface B { name: string, age?: number } diff --git a/ets2panda/linter/test/interop/oh_modules/reflect_export.ets b/ets2panda/linter/test/interop/oh_modules/reflect_export.ets index d7e2351412eae61ef01109655a97ad97bd9d129d..4fd2894dd8489f827482c493f3d1782ef57e0d1a 100644 --- a/ets2panda/linter/test/interop/oh_modules/reflect_export.ets +++ b/ets2panda/linter/test/interop/oh_modules/reflect_export.ets @@ -24,3 +24,7 @@ export function bar(obj: Object) { return Reflect.has(obj, 'prop'); } +export class X { + a: string = 'hello' + getName() { return this.a } +} diff --git a/ets2panda/linter/test/interop/oh_modules/static_object_literals_export.ets b/ets2panda/linter/test/interop/oh_modules/static_object_literals_export.ets new file mode 100644 index 0000000000000000000000000000000000000000..2191e0197101822d16e3f3af4bc71f7162305b9b --- /dev/null +++ b/ets2panda/linter/test/interop/oh_modules/static_object_literals_export.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. + */ +'use static' + +export class X { name: string = '' } + +export interface Y { data: number } + +export function foo(arg: X) {} + +export function bar(arg: Y) {} + +export function CreateY(d: number): Y { + let y: Y = {data: d} + return y +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets b/ets2panda/linter/test/interop/reflect_built_in.ets index b108f1bc48bd8cc588066dd261a5fe10492745e9..96b0800185e89fcc3bdf12c6ce9ac7dfd106ec0e 100644 --- a/ets2panda/linter/test/interop/reflect_built_in.ets +++ b/ets2panda/linter/test/interop/reflect_built_in.ets @@ -12,32 +12,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' -import { foo, bar, safe } from "./oh_modules/reflect_export" -import { safeVersion } from "./oh_modules/reflect_export_safe" +import { X } from "./oh_modules/reflect_export" -class X { - a: string = 'hello' - getName() { return this.a } +export function foo(prx: Object) { + Reflect.get(prx, 'a') // 'hello' + Reflect.set(prx, 'a', 'world') // true + Reflect.ownKeys(prx) // ['a'] } -foo(new X()); - -class Y { - prop = 42; -} - -bar(new Y()); - -class Z { - a: string = 'hello'; - getName() { return this.a; } +export function bar(obj: Object) { + return Reflect.has(obj, 'prop'); } -safe(new Z()); //legal - -class A { - prop = 34; -} +foo(new X()); //illegal -safeVersion(new A()) //legal \ No newline at end of file +bar(new X()); //illegal diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets.args.json b/ets2panda/linter/test/interop/reflect_built_in.ets.args.json index c90ca155ab68f764f82b37c70e465eda447db3c1..bc4d2071daf6e9354e711c3b74b6be2b56659066 100644 --- a/ets2panda/linter/test/interop/reflect_built_in.ets.args.json +++ b/ets2panda/linter/test/interop/reflect_built_in.ets.args.json @@ -13,5 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "mode": {} -} \ No newline at end of file + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets.arkts2.json b/ets2panda/linter/test/interop/reflect_built_in.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..f16e3c2498d6026be25ace4fff06b3a1efb26bde --- /dev/null +++ b/ets2panda/linter/test/interop/reflect_built_in.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 48, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 14, + "problem": "InteropCallReflect", + "suggest": "", + "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-d2s-static-reflect-on-dynamic-instance)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 1, + "endLine": 31, + "endColumn": 14, + "problem": "InteropCallReflect", + "suggest": "", + "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-d2s-static-reflect-on-dynamic-instance)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/reflect_built_in.ets.json b/ets2panda/linter/test/interop/reflect_built_in.ets.json index f3826718fbe30280289a3da2d88781887c4ee9ed..0ee87e87fb38c2290a997111c093fa85d4809a32 100644 --- a/ets2panda/linter/test/interop/reflect_built_in.ets.json +++ b/ets2panda/linter/test/interop/reflect_built_in.ets.json @@ -15,83 +15,13 @@ ], "result": [ { - "line": 24, + "line": 17, "column": 1, - "endLine": 24, - "endColumn": 13, - "problem": "InteropCallObjectParam", + "endLine": 17, + "endColumn": 48, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-call-object-param)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 1, - "endLine": 24, - "endColumn": 14, - "problem": "InteropCallReflect", - "suggest": "", - "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-call-reflect)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 1, - "endLine": 24, - "endColumn": 13, - "problem": "InteropCallObjectParam", - "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-call-object-param)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 1, - "endLine": 24, - "endColumn": 14, - "problem": "InteropCallReflect", - "suggest": "", - "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-call-reflect)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 13, - "problem": "InteropCallObjectParam", - "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-call-object-param)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 14, - "problem": "InteropCallReflect", - "suggest": "", - "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-call-reflect)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 13, - "problem": "InteropCallObjectParam", - "suggest": "", - "rule": "Class type is not compatible with \"Object\" parameter in interop call (arkts-interop-call-object-param)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 14, - "problem": "InteropCallReflect", - "suggest": "", - "rule": "Reflect API usage is not allowed in interop calls when an \"Object\" parameter receives a class instance (arkts-interop-call-reflect)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/static_object_literals.ets b/ets2panda/linter/test/interop/static_object_literals.ets new file mode 100644 index 0000000000000000000000000000000000000000..82b3db8dd11e119268fdcfae10a07e0bf417f189 --- /dev/null +++ b/ets2panda/linter/test/interop/static_object_literals.ets @@ -0,0 +1,44 @@ +/* + * 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 { X, Y, foo, bar } from "./oh_modules/static_object_literals_export" + +let x: X = { name: "hello" } + +let a: X = new X("hello") // legal + +let y: Y = { data: 123 } + +let b: Y = createY(123) // legal + +foo({ name: "world" }); + +foo(new X("world")) // legal + +bar({ data: 456 }); + +bar(createY(456)) // legal + +function zoo(): X { + return { name: "hello" } +} + +interface Z { x: X } + +let z: Z = { x: { name: "hello" } } + + + + diff --git a/ets2panda/linter/test/interop/static_object_literals.ets.args.json b/ets2panda/linter/test/interop/static_object_literals.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..c90ca155ab68f764f82b37c70e465eda447db3c1 --- /dev/null +++ b/ets2panda/linter/test/interop/static_object_literals.ets.args.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." + ], + "mode": {} +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/static_object_literals.ets.json b/ets2panda/linter/test/interop/static_object_literals.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..12d46c0860e9c1e8e2b8ea429ab13cae1448e3da --- /dev/null +++ b/ets2panda/linter/test/interop/static_object_literals.ets.json @@ -0,0 +1,78 @@ +{ + "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": 18, + "column": 12, + "endLine": 18, + "endColumn": 29, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 12, + "endLine": 22, + "endColumn": 25, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 22, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 18, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 12, + "endLine": 35, + "endColumn": 29, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 17, + "endLine": 40, + "endColumn": 34, + "problem": "InteropStaticObjectLiterals", + "suggest": "", + "rule": "It is not allowed to create object literal in interop calls (arkts-interop-s2d-object-literal)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/unique_types.ets b/ets2panda/linter/test/interop/unique_types.ets new file mode 100644 index 0000000000000000000000000000000000000000..35f8bae39116bc89fb0ff43ffec5b8c810c399a3 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types.ets @@ -0,0 +1,36 @@ +/* + * 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. +*/ +'use static' + +import { + objectLiteralType, + intersectionType, + tsFunction, + stringType, + enumType +} from "./ignore_files/unique_types"; + +objectLiteralType.name = "test" + +intersectionType.name = "test"; + +try { +tsFunction(); +} catch (e) { +} + +stringType = "test" //should pass + +enumType = "A"; //should fail diff --git a/ets2panda/linter/test/interop/unique_types.ets.args.json b/ets2panda/linter/test/interop/unique_types.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d3ae885df4b870f3e78bd30cc8960f4b2b72b3d9 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types.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": { + "autofix": "--arkts-2", + "migrate": "--arkts-2", + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/interop/unique_types.ets.arkts2.json b/ets2panda/linter/test/interop/unique_types.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..3c2bcf66a72cc5310f800eb87ad21c0a03a8d0cd --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types.ets.arkts2.json @@ -0,0 +1,98 @@ +{ + "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": 17, + "column": 1, + "endLine": 23, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 23, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 22, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 13, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 11, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 32, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 1, + "endLine": 34, + "endColumn": 20, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 1, + "endLine": 34, + "endColumn": 11, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/interop/unique_types.ets.autofix.json b/ets2panda/linter/test/interop/unique_types.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..5f1b6e40b9633eca99cf4f49bf543f25cd3118c7 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types.ets.autofix.json @@ -0,0 +1,120 @@ +{ + "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": 17, + "column": 1, + "endLine": 23, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 23, + "problem": "InteropDirectAccessToTSTypes", + "autofix": [ + { + "start": 744, + "end": 775, + "replacementText": "objectLiteralType.setPropertyByName('name',ESValue.wrap(\"test\"))", + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 22, + "problem": "InteropDirectAccessToTSTypes", + "autofix": [ + { + "start": 777, + "end": 807, + "replacementText": "intersectionType.setPropertyByName('name',ESValue.wrap(\"test\"))", + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 13, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 11, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 32, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 1, + "endLine": 34, + "endColumn": 20, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 1, + "endLine": 34, + "endColumn": 11, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/migrate/class_static_block.ts.migrate.json b/ets2panda/linter/test/interop/unique_types.ets.json similarity index 35% rename from ets2panda/linter/test/migrate/class_static_block.ts.migrate.json rename to ets2panda/linter/test/interop/unique_types.ets.json index ed0f91dab0cfef35674166dfa5b99734f4d08549..3e8e488310b0cc25d757e85c0dad6e55c2c622c1 100644 --- a/ets2panda/linter/test/migrate/class_static_block.ts.migrate.json +++ b/ets2panda/linter/test/interop/unique_types.ets.json @@ -1,13 +1,13 @@ { "result": [ { - "line": 23, - "column": 3, + "line": 17, + "column": 1, "endLine": 23, - "endColumn": 9, - "problem": "MultipleStaticBlocks", + "endColumn": 38, + "problem": "ImportAfterStatement", "suggest": "", - "rule": "Only one static block is supported (arkts-no-multiple-static-blocks)", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/interop/unique_types.ets.migrate.ets b/ets2panda/linter/test/interop/unique_types.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..86dd5f4ed051b0282bcfb8c8cfe7d67a1c107233 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types.ets.migrate.ets @@ -0,0 +1,36 @@ +/* + * 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. +*/ +'use static' + +import { + objectLiteralType, + intersectionType, + tsFunction, + stringType, + enumType +} from "./ignore_files/unique_types"; + +objectLiteralType.setPropertyByName('name',ESValue.wrap("test")) + +intersectionType.setPropertyByName('name',ESValue.wrap("test")); + +try { +tsFunction(); +} catch (e) { +} + +stringType = "test" //should pass + +enumType = "A"; //should fail diff --git a/ets2panda/linter/test/interop/unique_types.ets.migrate.json b/ets2panda/linter/test/interop/unique_types.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..4eb8c2c72d3dad88d8e0550785ad1a4a133a9f98 --- /dev/null +++ b/ets2panda/linter/test/interop/unique_types.ets.migrate.json @@ -0,0 +1,78 @@ +{ + "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": 17, + "column": 1, + "endLine": 23, + "endColumn": 38, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 13, + "problem": "InteropTSFunctionInvoke", + "suggest": "", + "rule": "Trying to catch typescript errors is not permitted (arkts-interop-ts2s-ts-exception)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 11, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 32, + "endColumn": 2, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 1, + "endLine": 34, + "endColumn": 20, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 1, + "endLine": 34, + "endColumn": 11, + "problem": "InteropDirectAccessToTSTypes", + "suggest": "", + "rule": "Cannot access typescript types directly (arkts-interop-ts2s-static-access-ts-type)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.args.json b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.args.json index 5efbceacdc279d08c370af862c859f2d6300fafb..e7a5dbc614c695778265e9fb7d345a304a601675 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.args.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.arkts2.json b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.arkts2.json index 5734f269a9f52d90ced6725f98e61bd3b8a17b2d..b35596cae20fb4d1bd2ba6b07eea07985d574598 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.arkts2.json @@ -24,6 +24,66 @@ "rule": "\"@AnimatableExtend\" decorator should be transformed to use receiver (arkui-animatableextend-use-receiver)", "severity": "ERROR" }, + { + "line": 24, + "column": 30, + "endLine": 24, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 32, + "endLine": 30, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 46, + "endLine": 33, + "endColumn": 48, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 51, + "endLine": 33, + "endColumn": 54, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 57, + "endLine": 33, + "endColumn": 59, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 14, + "endLine": 36, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 16, "column": 2, diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.autofix.json b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.autofix.json index 7fb38a659a008950e105287dd5ec808ee12ec45c..4a99d7ea8cf975bce36d80b2603d8c7db24f5b04 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.autofix.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.autofix.json @@ -24,19 +24,160 @@ { "start": 605, "end": 688, - "replacementText": "@AnimatableExtend\n@Memo\nfunction animatableWidth(this: TextAttribute, width: number): this {\n this.width(width);\n return this;\n}" + "replacementText": "@AnimatableExtend\nfunction animatableWidth(this: TextAttribute, width: number): this {\n this.width(width);\n return this;\n}", + "line": 16, + "column": 1, + "endLine": 19, + "endColumn": 2 } ], "suggest": "", "rule": "\"@AnimatableExtend\" decorator should be transformed to use receiver (arkui-animatableextend-use-receiver)", "severity": "ERROR" }, + { + "line": 24, + "column": 30, + "endLine": 24, + "endColumn": 32, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 772, + "end": 774, + "replacementText": "80.0", + "line": 24, + "column": 30, + "endLine": 24, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 32, + "endLine": 30, + "endColumn": 36, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 909, + "end": 913, + "replacementText": "2000.0", + "line": 30, + "column": 32, + "endLine": 30, + "endColumn": 36 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 46, + "endLine": 33, + "endColumn": 48, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1027, + "end": 1029, + "replacementText": "80.0", + "line": 33, + "column": 46, + "endLine": 33, + "endColumn": 48 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 51, + "endLine": 33, + "endColumn": 54, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1032, + "end": 1035, + "replacementText": "160.0", + "line": 33, + "column": 51, + "endLine": 33, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 57, + "endLine": 33, + "endColumn": 59, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1038, + "end": 1040, + "replacementText": "80.0", + "line": 33, + "column": 57, + "endLine": 33, + "endColumn": 59 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 14, + "endLine": 36, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1086, + "end": 1088, + "replacementText": "10.0", + "line": 36, + "column": 14, + "endLine": 36, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 16, "column": 2, "endLine": 16, "endColumn": 18, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -47,6 +188,17 @@ "endLine": 21, "endColumn": 7, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -57,6 +209,17 @@ "endLine": 22, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -67,6 +230,17 @@ "endLine": 24, "endColumn": 9, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -77,6 +251,17 @@ "endLine": 27, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -87,6 +272,17 @@ "endLine": 28, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -97,6 +293,17 @@ "endLine": 30, "endColumn": 50, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -111,7 +318,11 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { TextAttribute, Memo, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kits.ArkUI';" + "replacementText": "\n\nimport { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI';", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.ets b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..cc98fd6d8de63901b4897bf178e5ec16d979e6a1 --- /dev/null +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.ets @@ -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. + */ + +import { TextAttribute, AnimatableExtend, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI'; + +@AnimatableExtend +function animatableWidth(this: TextAttribute, width: number): this { + this.width(width); + return this; +} + +@Entry +@Component +struct AnimatablePropertyExample { + @State textWidth: number = 80.0; + + build() { + Column() { + Text("AnimatableProperty") + .animatableWidth(this.textWidth) + .animation({ duration: 2000.0, curve: Curve.Ease }) + Button("Play") + .onClick(() => { + this.textWidth = this.textWidth == 80.0 ? 160.0 : 80.0; + }) + }.width("100%") + .padding(10.0) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.json b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..32075de8acc822612c282834429443c8f3af2fbd --- /dev/null +++ b/ets2panda/linter/test/main/animatable_extend_decorator_1.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 5, + "endLine": 20, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 12, + "endLine": 21, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 26, + "endLine": 19, + "endColumn": 30, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 63, + "endLine": 19, + "endColumn": 67, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets index f0db2d19c56280c3fed00cdf4f2d56662dc3df80..eebe111df2e33343a1fb5e71e0907fc66edadba9 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets @@ -13,12 +13,10 @@ * limitations under the License. */ -import { AnimatableExtend, Memo, TextAttribute, Entry, Component, State, Column, Text, Curve, Button } from '@kits.ArkUI'; +import { AnimatableExtend, TextAttribute, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI'; @AnimatableExtend -@Memo -function animatableWidth(this: TextAttribute, width: number): TextAttribute -{ +function animatableWidth(this: TextAttribute, width: number): this { this.width(width); return this; } diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.args.json b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.args.json index 5efbceacdc279d08c370af862c859f2d6300fafb..e7a5dbc614c695778265e9fb7d345a304a601675 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.args.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.arkts2.json b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.arkts2.json index 8ce069d6e0875854016bd7fba2b0ca9ad3d3f826..23ad6343c0c6da41bfc51fb86fce089eda85a6b2 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.arkts2.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 22, + "line": 20, "column": 3, - "endLine": 22, + "endLine": 20, "endColumn": 7, "problem": "FunctionContainsThis", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 23, + "line": 21, "column": 10, - "endLine": 23, + "endLine": 21, "endColumn": 14, "problem": "FunctionContainsThis", "suggest": "", @@ -36,22 +36,82 @@ }, { "line": 19, - "column": 1, + "column": 26, "endLine": 19, - "endColumn": 6, - "problem": "DecoratorsNotSupported", + "endColumn": 30, + "problem": "InvalidIdentifier", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" }, { - "line": 20, - "column": 26, - "endLine": 20, - "endColumn": 30, - "problem": "InvalidIdentifier", + "line": 19, + "column": 63, + "endLine": 19, + "endColumn": 67, + "problem": "ThisType", "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 30, + "endLine": 27, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 32, + "endLine": 33, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 46, + "endLine": 36, + "endColumn": 48, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 51, + "endLine": 36, + "endColumn": 54, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 57, + "endLine": 36, + "endColumn": 59, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.autofix.json b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.autofix.json index 8ce069d6e0875854016bd7fba2b0ca9ad3d3f826..e9e0e09c8a0529b7038f0b4ebc9331c7b8047850 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.autofix.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.autofix.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 22, + "line": 20, "column": 3, - "endLine": 22, + "endLine": 20, "endColumn": 7, "problem": "FunctionContainsThis", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 23, + "line": 21, "column": 10, - "endLine": 23, + "endLine": 21, "endColumn": 14, "problem": "FunctionContainsThis", "suggest": "", @@ -36,22 +36,148 @@ }, { "line": 19, - "column": 1, + "column": 26, "endLine": 19, - "endColumn": 6, - "problem": "DecoratorsNotSupported", + "endColumn": 30, + "problem": "InvalidIdentifier", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" }, { - "line": 20, - "column": 26, - "endLine": 20, - "endColumn": 30, - "problem": "InvalidIdentifier", + "line": 19, + "column": 63, + "endLine": 19, + "endColumn": 67, + "problem": "ThisType", "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 30, + "endLine": 27, + "endColumn": 32, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 930, + "end": 932, + "replacementText": "80.0", + "line": 27, + "column": 30, + "endLine": 27, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 32, + "endLine": 33, + "endColumn": 36, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1067, + "end": 1071, + "replacementText": "2000.0", + "line": 33, + "column": 32, + "endLine": 33, + "endColumn": 36 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 46, + "endLine": 36, + "endColumn": 48, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1185, + "end": 1187, + "replacementText": "80.0", + "line": 36, + "column": 46, + "endLine": 36, + "endColumn": 48 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 51, + "endLine": 36, + "endColumn": 54, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1190, + "end": 1193, + "replacementText": "160.0", + "line": 36, + "column": 51, + "endLine": 36, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 57, + "endLine": 36, + "endColumn": 59, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1196, + "end": 1198, + "replacementText": "80.0", + "line": 36, + "column": 57, + "endLine": 36, + "endColumn": 59 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1244, + "end": 1246, + "replacementText": "10.0", + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.json b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.json index 156384300fa4220fce53cdfb49de2e8b2d28e692..f82417ac3c0a0e80647f3b1ae3d0e4a13bbccf91 100644 --- a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.json +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 22, + "line": 20, "column": 3, - "endLine": 22, + "endLine": 20, "endColumn": 7, "problem": "FunctionContainsThis", "suggest": "", @@ -25,14 +25,24 @@ "severity": "ERROR" }, { - "line": 23, + "line": 21, "column": 10, - "endLine": 23, + "endLine": 21, "endColumn": 14, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" + }, + { + "line": 19, + "column": 63, + "endLine": 19, + "endColumn": 67, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.ets b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e108e0f7ea65230feb100d7a93b891fe8b0ae650 --- /dev/null +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.ets @@ -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. + */ + +import { AnimatableExtend, TextAttribute, Entry, Component, State, Column, Text, Curve, Button } from '@kit.ArkUI'; + +@AnimatableExtend +function animatableWidth(this: TextAttribute, width: number): this { + this.width(width); + return this; +} + +@Entry +@Component +struct AnimatablePropertyExample { + @State textWidth: number = 80.0; + + build() { + Column() { + Text("AnimatableProperty") + .animatableWidth(this.textWidth) + .animation({ duration: 2000.0, curve: Curve.Ease }) + Button("Play") + .onClick(() => { + this.textWidth = this.textWidth == 80.0 ? 160.0 : 80.0; + }) + }.width("100%") + .padding(10.0) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.json b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..4e365eb63e844f5a0e63f2d388f14f693d0936c3 --- /dev/null +++ b/ets2panda/linter/test/main/animatable_extend_decorator_2.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 3, + "endLine": 20, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 26, + "endLine": 19, + "endColumn": 30, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 63, + "endLine": 19, + "endColumn": 67, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-array-type-immutable.ets b/ets2panda/linter/test/main/arkts-array-type-immutable.ets new file mode 100644 index 0000000000000000000000000000000000000000..75a02116dd78aca7e564933a329955ca512e8641 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.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. + */ + +let a: number[] = [1] +let b: (number | string)[] = a // error + +let a1: (number | string)[] = [1] +let b1: (number | string)[] = a1 // ok + +let b2: (number | string)[]; +b2 = a // error + +class A { + a: (number | string)[] = [1]; +} + +let aA: A = new A(); +aA.a = a; // error + +let a3: (number | string)[] = new Array(1, 2); // error + +function test(a: number[]): void { + let b: (number | string)[] = [1]; + b = a; // error +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-array-type-immutable.ets.args.json b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.json b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..50fb25efbd4e185ee01f34994c9860a16d181cac --- /dev/null +++ b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.arkts2.json @@ -0,0 +1,128 @@ +{ + "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": 20, + "endLine": 16, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 31, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 32, + "endLine": 19, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 7, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 31, + "endLine": 26, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 9, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 54, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 49, + "endLine": 32, + "endColumn": 50, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 52, + "endLine": 32, + "endColumn": 53, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 33, + "endLine": 35, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 8, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/worker_module.ts.json b/ets2panda/linter/test/main/arkts-array-type-immutable.ets.json similarity index 100% rename from ets2panda/linter/test/main/worker_module.ts.json rename to ets2panda/linter/test/main/arkts-array-type-immutable.ets.json diff --git a/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e05df4b070f3c8182a47729796cadd4024d4427 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-primitive-type-normalization.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. + */ + +typeof new Number(1) // error +new Number(1) == new Number(1) // error +if (new Boolean(false)) {} // error +let a = new String('111') // error +new Boolean // error +new String // error +new Number // error \ No newline at end of file diff --git a/ets2panda/linter/test/main/data_observation_2.ets.args.json b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.args.json similarity index 93% rename from ets2panda/linter/test/main/data_observation_2.ets.args.json rename to ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.args.json index 5efbceacdc279d08c370af862c859f2d6300fafb..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 100644 --- a/ets2panda/linter/test/main/data_observation_2.ets.args.json +++ b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.args.json @@ -14,7 +14,6 @@ "limitations under the License." ], "mode": { - "arkts2": "", - "autofix": "--arkts-2" + "arkts2": "" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.arkts2.json b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..fc8bfe9fd884d40b45f2e95f6a6869ef1b3d4937 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.arkts2.json @@ -0,0 +1,128 @@ +{ + "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": 8, + "endLine": 16, + "endColumn": 21, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 19, + "endLine": 16, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 1, + "endLine": 17, + "endColumn": 14, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 12, + "endLine": 17, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 18, + "endLine": 17, + "endColumn": 31, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 29, + "endLine": 17, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 23, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 9, + "endLine": 19, + "endColumn": 26, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 12, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 11, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 11, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.json b/ets2panda/linter/test/main/arkts-primitive-type-normalization.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/arkts-primitive-type-normalization.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/arkts_no_duplicate_function_name3.ets.arkts2.json b/ets2panda/linter/test/main/arkts_no_duplicate_function_name3.ets.arkts2.json index 6a6fa4756fcc296dfcc11584a72563f237a6d62a..478be3ec9a33a0350977bb79233c96a9e98ad162 100644 --- a/ets2panda/linter/test/main/arkts_no_duplicate_function_name3.ets.arkts2.json +++ b/ets2panda/linter/test/main/arkts_no_duplicate_function_name3.ets.arkts2.json @@ -54,6 +54,16 @@ "rule": "Duplicate function name in namespace are not allowed (arkts-no-duplicate-function-name)", "severity": "ERROR" }, + { + "line": 31, + "column": 23, + "endLine": 31, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 35, "column": 3, @@ -64,6 +74,36 @@ "rule": "Duplicate function name in namespace are not allowed (arkts-no-duplicate-function-name)", "severity": "ERROR" }, + { + "line": 35, + "column": 23, + "endLine": 35, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 19, + "endLine": 39, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 34, + "endLine": 39, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 47, "column": 3, @@ -84,6 +124,66 @@ "rule": "Duplicate function name in namespace are not allowed (arkts-no-duplicate-function-name)", "severity": "ERROR" }, + { + "line": 59, + "column": 19, + "endLine": 59, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 34, + "endLine": 59, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 19, + "endLine": 63, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 34, + "endLine": 63, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 19, + "endLine": 67, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 34, + "endLine": 67, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 71, "column": 3, @@ -93,6 +193,26 @@ "suggest": "", "rule": "Duplicate function name in namespace are not allowed (arkts-no-duplicate-function-name)", "severity": "ERROR" + }, + { + "line": 71, + "column": 19, + "endLine": 71, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 34, + "endLine": 71, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/arktsutils_module.ets b/ets2panda/linter/test/main/arktsutils_module.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e81dea82b9caa9f42f8000a32557894ad38463d --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { utils } from './oh_modules/@arkts.utils'; + +import { utils as ArkTSUtilsAlias } from './oh_modules/@arkts.utils'; + +import { utils as kitArkTSUtils } from './oh_modules/@kit.ArkTS'; + +import { utils as definedArkTSUtils } from 'user_defined_worker'; //legal + +export { utils } from './oh_modules/@arkts.utils'; + +function tesCollectionsUsage() { + + const utils1: string = utils.ASON.stringify(1); + + const utils2 = ArkTSUtilsAlias.ASON.stringify(1); + + const utils3 = kitArkTSUtils.ASON.stringify(1); + + const utils4: string = ArkTSUtilsAlias.ASON.stringify(1); + + type CreatedType = ArkTSUtils.ASON.SomeType; + + const someType: CreatedType = ArkTSUtils.ASON.SomeType; +} diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.args.json b/ets2panda/linter/test/main/arktsutils_module.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b13bb90d5b5f6d3dc5f0d054663eeba637fcc7dd --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.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" + } +} diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json b/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..6da6e6ae1588b4a7791270d2b02b227b7b9cf6eb --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets.arkts2.json @@ -0,0 +1,118 @@ +{ + "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": 27, + "column": 26, + "endLine": 27, + "endColumn": 31, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 47, + "endLine": 27, + "endColumn": 48, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 33, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 49, + "endLine": 29, + "endColumn": 50, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 18, + "endLine": 31, + "endColumn": 31, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 47, + "endLine": 31, + "endColumn": 48, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 41, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 57, + "endLine": 33, + "endColumn": 58, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 22, + "endLine": 35, + "endColumn": 32, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 33, + "endLine": 37, + "endColumn": 43, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json b/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..d6868a9cbf4f513be46a17011c04913690564267 --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets.autofix.json @@ -0,0 +1,162 @@ +{ + "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": 27, + "column": 26, + "endLine": 27, + "endColumn": 31, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 47, + "endLine": 27, + "endColumn": 48, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1001, + "end": 1002, + "replacementText": "1.0", + "line": 27, + "column": 47, + "endLine": 27, + "endColumn": 48 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 33, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 49, + "endLine": 29, + "endColumn": 50, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1054, + "end": 1055, + "replacementText": "1.0", + "line": 29, + "column": 49, + "endLine": 29, + "endColumn": 50 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 18, + "endLine": 31, + "endColumn": 31, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 47, + "endLine": 31, + "endColumn": 48, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1105, + "end": 1106, + "replacementText": "1.0", + "line": 31, + "column": 47, + "endLine": 31, + "endColumn": 48 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 41, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 57, + "endLine": 33, + "endColumn": 58, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1166, + "end": 1167, + "replacementText": "1.0", + "line": 33, + "column": 57, + "endLine": 33, + "endColumn": 58 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 22, + "endLine": 35, + "endColumn": 32, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 33, + "endLine": 37, + "endColumn": 43, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.json b/ets2panda/linter/test/main/arktsutils_module.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.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/arktsutils_module.ets.migrate.ets b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3b1d7e17b6e5f116f3051c61fe671e0dee13327e --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { utils } from './oh_modules/@arkts.utils'; + +import { utils as ArkTSUtilsAlias } from './oh_modules/@arkts.utils'; + +import { utils as kitArkTSUtils } from './oh_modules/@kit.ArkTS'; + +import { utils as definedArkTSUtils } from 'user_defined_worker'; //legal + +export { utils } from './oh_modules/@arkts.utils'; + +function tesCollectionsUsage() { + + const utils1: string = utils.ASON.stringify(1.0); + + const utils2 = ArkTSUtilsAlias.ASON.stringify(1.0); + + const utils3 = kitArkTSUtils.ASON.stringify(1.0); + + const utils4: string = ArkTSUtilsAlias.ASON.stringify(1.0); + + type CreatedType = ArkTSUtils.ASON.SomeType; + + const someType: CreatedType = ArkTSUtils.ASON.SomeType; +} diff --git a/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..1b597eff5b8579d13d203bafc99002f5f4b2ce85 --- /dev/null +++ b/ets2panda/linter/test/main/arktsutils_module.ets.migrate.json @@ -0,0 +1,78 @@ +{ + "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": 27, + "column": 26, + "endLine": 27, + "endColumn": 31, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 33, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 18, + "endLine": 31, + "endColumn": 31, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 41, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 22, + "endLine": 35, + "endColumn": 32, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 33, + "endLine": 37, + "endColumn": 43, + "problem": "LimitedStdLibNoASON", + "suggest": "", + "rule": "ASON is not supported. (arkts-no-need-stdlib-ason)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets b/ets2panda/linter/test/main/array_index_expr_type.ets index 5c8d438eafbb5477624736e6338bb0453976715f..fe370c16cdb5ee0ec55a04f685b25b665d6c4bb1 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets +++ b/ets2panda/linter/test/main/array_index_expr_type.ets @@ -70,4 +70,16 @@ arr1[+0]; arr1[-0]; arr1[+1]; arr1[-1]; -arr1[1.1 as number]; \ No newline at end of file +arr1[1.1 as number]; + +let a:short = 1; +let b:byte = 1; +let c:int = 1; +let d:long = 1; + +let arr:number[] = [1,2,3] +arr[true?1.3:1.2] +arr[a] = 1; +arr[b] = 1; +arr[c] = 1; +arr[d] = 1; diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.args.json b/ets2panda/linter/test/main/array_index_expr_type.ets.args.json index 1b80aa9e7367c4d206bb53f8fc43c77fc24045d7..e7a5dbc614c695778265e9fb7d345a304a601675 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.args.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.args.json @@ -14,6 +14,8 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json b/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json index 5e19a4451b599cf483f1c2b1b365a51d8e027864..40493eb17563e97e8f44bded1361261fa9b00f25 100644 --- a/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.arkts2.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": 17, @@ -24,6 +24,36 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 17, + "column": 19, + "endLine": 17, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 21, + "endLine": 17, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 23, + "endLine": 17, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 18, "column": 7, @@ -54,6 +84,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 19, + "column": 21, + "endLine": 19, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 20, "column": 7, @@ -64,6 +104,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 20, + "column": 21, + "endLine": 20, + "endColumn": 32, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 21, "column": 7, @@ -194,6 +244,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 27, + "column": 20, + "endLine": 27, + "endColumn": 23, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 28, "column": 7, @@ -204,6 +264,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 29, "column": 7, @@ -264,6 +334,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 32, + "column": 20, + "endLine": 32, + "endColumn": 43, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 35, "column": 5, @@ -274,6 +354,46 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 35, + "column": 14, + "endLine": 35, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 16, + "endLine": 35, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 18, + "endLine": 35, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 23, + "endLine": 38, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 39, "column": 7, @@ -294,6 +414,46 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 41, + "column": 7, + "endLine": 41, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 20, + "endLine": 42, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 7, + "endLine": 45, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 26, + "endLine": 48, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 50, "column": 5, @@ -304,6 +464,36 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 50, + "column": 15, + "endLine": 50, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 18, + "endLine": 50, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 21, + "endLine": 50, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 51, "column": 8, @@ -324,6 +514,96 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 53, + "column": 15, + "endLine": 53, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 18, + "endLine": 53, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 21, + "endLine": 53, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 22, + "endLine": 54, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 22, + "endLine": 55, + "endColumn": 23, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 19, + "endLine": 58, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 22, + "endLine": 62, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 25, + "endLine": 62, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 28, + "endLine": 62, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 64, "column": 3, @@ -363,6 +643,126 @@ "suggest": "", "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" + }, + { + "line": 75, + "column": 15, + "endLine": 75, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 14, + "endLine": 76, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 13, + "endLine": 77, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 14, + "endLine": 78, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 21, + "endLine": 80, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 23, + "endLine": 80, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 25, + "endLine": 80, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 17, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 10, + "endLine": 82, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 10, + "endLine": 83, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 10, + "endLine": 84, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 10, + "endLine": 85, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json b/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..ec4168139c9bca5ac69a6316b4577582c358b1b6 --- /dev/null +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.autofix.json @@ -0,0 +1,1461 @@ +{ + "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": 17, + "column": 7, + "endLine": 17, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 639, + "end": 657, + "replacementText": "an_array: number[] = [1, 2, 3]", + "line": 17, + "column": 7, + "endLine": 17, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 19, + "endLine": 17, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 651, + "end": 652, + "replacementText": "1.0", + "line": 17, + "column": 19, + "endLine": 17, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 21, + "endLine": 17, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 653, + "end": 654, + "replacementText": "2.0", + "line": 17, + "column": 21, + "endLine": 17, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 23, + "endLine": 17, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 655, + "end": 656, + "replacementText": "3.0", + "line": 17, + "column": 23, + "endLine": 17, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 7, + "endLine": 18, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 664, + "end": 683, + "replacementText": "a: number = an_array[index]", + "line": 18, + "column": 7, + "endLine": 18, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 20, + "endLine": 18, + "endColumn": 25, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 677, + "end": 682, + "replacementText": "index as int", + "line": 18, + "column": 20, + "endLine": 18, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 31, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 690, + "end": 714, + "replacementText": "a1: number = an_array[index + 1]", + "line": 19, + "column": 7, + "endLine": 19, + "endColumn": 31 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 21, + "endLine": 19, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 704, + "end": 713, + "replacementText": "(index + 1) as int", + "line": 19, + "column": 21, + "endLine": 19, + "endColumn": 30 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 721, + "end": 747, + "replacementText": "a2: number = an_array[index + 1.1]", + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 21, + "endLine": 20, + "endColumn": 32, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 735, + "end": 746, + "replacementText": "(index + 1.1) as int", + "line": 20, + "column": 21, + "endLine": 20, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 754, + "end": 772, + "replacementText": "b: number = an_array[1.23]", + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 20, + "endLine": 21, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 767, + "end": 771, + "replacementText": "1.23 as int", + "line": 21, + "column": 20, + "endLine": 21, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 20, + "endLine": 22, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 20, + "endLine": 23, + "endColumn": 27, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 20, + "endLine": 24, + "endColumn": 29, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 20, + "endLine": 25, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 7, + "endLine": 26, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 887, + "end": 901, + "replacementText": "g: number = an_array[]", + "line": 26, + "column": 7, + "endLine": 26, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 20, + "endLine": 26, + "endColumn": 20, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 908, + "end": 925, + "replacementText": "h: number = an_array[12.]", + "line": 27, + "column": 7, + "endLine": 27, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 20, + "endLine": 27, + "endColumn": 23, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 921, + "end": 924, + "replacementText": "12. as int", + "line": 27, + "column": 20, + "endLine": 27, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 932, + "end": 950, + "replacementText": "i: number = an_array[12.0]", + "line": 28, + "column": 7, + "endLine": 28, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 945, + "end": 949, + "replacementText": "12.0 as int", + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 957, + "end": 972, + "replacementText": "j: number = an_array[0]", + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 7, + "endLine": 30, + "endColumn": 37, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 979, + "end": 1009, + "replacementText": "k: number = an_array[Number.MAX_VALUE]", + "line": 30, + "column": 7, + "endLine": 30, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 36, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 992, + "end": 1008, + "replacementText": "Number.MAX_VALUE as int", + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 36 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 37, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1016, + "end": 1046, + "replacementText": "l: number = an_array[Number.MIN_VALUE]", + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 20, + "endLine": 31, + "endColumn": 36, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1029, + "end": 1045, + "replacementText": "Number.MIN_VALUE as int", + "line": 31, + "column": 20, + "endLine": 31, + "endColumn": 36 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 44, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1053, + "end": 1090, + "replacementText": "m: number = an_array[Number.MAX_SAFE_INTEGER]", + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 20, + "endLine": 32, + "endColumn": 43, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1066, + "end": 1089, + "replacementText": "Number.MAX_SAFE_INTEGER as int", + "line": 32, + "column": 20, + "endLine": 32, + "endColumn": 43 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1098, + "end": 1113, + "replacementText": "array: number[] = [1, 2, 3]", + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 14, + "endLine": 35, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1107, + "end": 1108, + "replacementText": "1.0", + "line": 35, + "column": 14, + "endLine": 35, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 16, + "endLine": 35, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1109, + "end": 1110, + "replacementText": "2.0", + "line": 35, + "column": 16, + "endLine": 35, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 18, + "endLine": 35, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1111, + "end": 1112, + "replacementText": "3.0", + "line": 35, + "column": 18, + "endLine": 35, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 23, + "endLine": 38, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1192, + "end": 1193, + "replacementText": "1.0", + "line": 38, + "column": 23, + "endLine": 38, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1201, + "end": 1208, + "replacementText": "index_1 as int", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1217, + "end": 1224, + "replacementText": "index_2 as int", + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 7, + "endLine": 41, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1233, + "end": 1240, + "replacementText": "index_3 as int", + "line": 41, + "column": 7, + "endLine": 41, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 20, + "endLine": 42, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1262, + "end": 1263, + "replacementText": "2.0", + "line": 42, + "column": 20, + "endLine": 42, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 7, + "endLine": 45, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1315, + "end": 1322, + "replacementText": "index_5 as int", + "line": 45, + "column": 7, + "endLine": 45, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 26, + "endLine": 48, + "endColumn": 28, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1381, + "end": 1383, + "replacementText": "10.0", + "line": 48, + "column": 26, + "endLine": 48, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1391, + "end": 1409, + "replacementText": "array1: number[] = [1, 2, 3]", + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 15, + "endLine": 50, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1401, + "end": 1402, + "replacementText": "1.0", + "line": 50, + "column": 15, + "endLine": 50, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 18, + "endLine": 50, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1404, + "end": 1405, + "replacementText": "2.0", + "line": 50, + "column": 18, + "endLine": 50, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 21, + "endLine": 50, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1407, + "end": 1408, + "replacementText": "3.0", + "line": 50, + "column": 21, + "endLine": 50, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 8, + "endLine": 51, + "endColumn": 18, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1418, + "end": 1428, + "replacementText": "getIndex() as int", + "line": 51, + "column": 8, + "endLine": 51, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 5, + "endLine": 53, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1436, + "end": 1454, + "replacementText": "array2: number[] = [1, 2, 3]", + "line": 53, + "column": 5, + "endLine": 53, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 15, + "endLine": 53, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1446, + "end": 1447, + "replacementText": "1.0", + "line": 53, + "column": 15, + "endLine": 53, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 18, + "endLine": 53, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1449, + "end": 1450, + "replacementText": "2.0", + "line": 53, + "column": 18, + "endLine": 53, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 21, + "endLine": 53, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1452, + "end": 1453, + "replacementText": "3.0", + "line": 53, + "column": 21, + "endLine": 53, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 22, + "endLine": 54, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1477, + "end": 1478, + "replacementText": "0.0", + "line": 54, + "column": 22, + "endLine": 54, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 22, + "endLine": 55, + "endColumn": 23, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1527, + "end": 1528, + "replacementText": "i as int", + "line": 55, + "column": 22, + "endLine": 55, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 19, + "endLine": 58, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1553, + "end": 1554, + "replacementText": "0.0", + "line": 58, + "column": 19, + "endLine": 58, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 22, + "endLine": 62, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1632, + "end": 1633, + "replacementText": "1.0", + "line": 62, + "column": 22, + "endLine": 62, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 25, + "endLine": 62, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1635, + "end": 1636, + "replacementText": "2.0", + "line": 62, + "column": 25, + "endLine": 62, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 28, + "endLine": 62, + "endColumn": 29, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1638, + "end": 1639, + "replacementText": "3.0", + "line": 62, + "column": 28, + "endLine": 62, + "endColumn": 29 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 3, + "endLine": 64, + "endColumn": 12, + "problem": "EnumMemberNonConstInit", + "suggest": "", + "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 6, + "endLine": 67, + "endColumn": 11, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1678, + "end": 1683, + "replacementText": "TE.AA as int", + "line": 67, + "column": 6, + "endLine": 67, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 9, + "problem": "IndexNegative", + "suggest": "", + "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 6, + "endLine": 73, + "endColumn": 9, + "problem": "ArrayIndexExprType", + "autofix": [ + { + "start": 1744, + "end": 1757, + "replacementText": "1.1 as int", + "line": 73, + "column": 6, + "endLine": 73, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 15, + "endLine": 75, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1775, + "end": 1776, + "replacementText": "1.0", + "line": 75, + "column": 15, + "endLine": 75, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 14, + "endLine": 76, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1791, + "end": 1792, + "replacementText": "1.0", + "line": 76, + "column": 14, + "endLine": 76, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 13, + "endLine": 77, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1806, + "end": 1807, + "replacementText": "1.0", + "line": 77, + "column": 13, + "endLine": 77, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 14, + "endLine": 78, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1822, + "end": 1823, + "replacementText": "1.0", + "line": 78, + "column": 14, + "endLine": 78, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 21, + "endLine": 80, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1846, + "end": 1847, + "replacementText": "1.0", + "line": 80, + "column": 21, + "endLine": 80, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 23, + "endLine": 80, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1848, + "end": 1849, + "replacementText": "2.0", + "line": 80, + "column": 23, + "endLine": 80, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 25, + "endLine": 80, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1850, + "end": 1851, + "replacementText": "3.0", + "line": 80, + "column": 25, + "endLine": 80, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 17, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 10, + "endLine": 82, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1880, + "end": 1881, + "replacementText": "1.0", + "line": 82, + "column": 10, + "endLine": 82, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 10, + "endLine": 83, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1892, + "end": 1893, + "replacementText": "1.0", + "line": 83, + "column": 10, + "endLine": 83, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 10, + "endLine": 84, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1904, + "end": 1905, + "replacementText": "1.0", + "line": 84, + "column": 10, + "endLine": 84, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 10, + "endLine": 85, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1916, + "end": 1917, + "replacementText": "1.0", + "line": 85, + "column": 10, + "endLine": 85, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5ba7613e1bb2ecbe420289a8147ba00b8740e6ad --- /dev/null +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.ets @@ -0,0 +1,85 @@ +/* + * 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(index:number){ + let an_array: number[] = [1.0, 2.0, 3.0] + let a: number = an_array[index as int] + let a1: number = an_array[(index + 1) as int] + let a2: number = an_array[(index + 1.1) as int] + let b: number = an_array[1.23 as int] + let c = an_array[true] + let d = an_array['index'] + let e = an_array[undefined] + let f = an_array[null] + let g: number = an_array[] + let h: number = an_array[12. as int] + let i: number = an_array[12.0 as int] + let j: number = an_array[0] + let k: number = an_array[Number.MAX_VALUE as int] + let l: number = an_array[Number.MIN_VALUE as int] + let m: number = an_array[Number.MAX_SAFE_INTEGER as int] +} + +let array: number[] = [1.0, 2.0, 3.0] +const index_1: number = 1.3; +let index_2: number = 1.3; +let index_3: number = 1.0; +array[index_1 as int]; +array[index_2 as int]; +array[index_3 as int]; +let index_4: int = 2.0 +array[index_4]; +const index_5: number = 1.0; +array[index_5 as int]; + +function getIndex(): number { + return Math.random() * 10.0; +} +let array1: number[] = [1.0, 2.0, 3.0]; +array1[getIndex() as int]; + +let array2: number[] = [1.0, 2.0, 3.0]; +for (let i: number = 0.0; i < array2.length; i++) { + console.log(array2[i as int]); +} + +for (let i: int = 0.0; i < array2.length; i++) { + console.log(array2[i]); +} + +let arr1:number[] = [1.0, 2.0, 3.0] +enum TE{ + AA = 1.12 + BB = 0 +} +arr1[TE.AA as int]; +arr1[TE.BB]; +arr1[+0]; +arr1[-0]; +arr1[+1]; +arr1[-1]; +arr1[1.1 as int]; + +let a:short = 1.0; +let b:byte = 1.0; +let c:int = 1.0; +let d:long = 1.0; + +let arr:number[] = [1.0,2.0,3.0] +arr[true?1.3:1.2] +arr[a] = 1.0; +arr[b] = 1.0; +arr[c] = 1.0; +arr[d] = 1.0; diff --git a/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8407a76e0f1a39a6b7313c0ba4b4143b441bb8ad --- /dev/null +++ b/ets2panda/linter/test/main/array_index_expr_type.ets.migrate.json @@ -0,0 +1,138 @@ +{ + "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": 7, + "endLine": 22, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 20, + "endLine": 22, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 7, + "endLine": 23, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 20, + "endLine": 23, + "endColumn": 27, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 20, + "endLine": 24, + "endColumn": 29, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 7, + "endLine": 25, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 20, + "endLine": 25, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 28, + "endLine": 26, + "endColumn": 28, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 3, + "endLine": 64, + "endColumn": 12, + "problem": "EnumMemberNonConstInit", + "suggest": "", + "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 9, + "problem": "IndexNegative", + "suggest": "", + "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 17, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/avoid_using_union_types.ets b/ets2panda/linter/test/main/avoid_using_union_types.ets index 907449c2fa6cf690316687315692376de55b20bf..4b633916d9b3e45a0a9abcb39b92ebda00f9abe4 100644 --- a/ets2panda/linter/test/main/avoid_using_union_types.ets +++ b/ets2panda/linter/test/main/avoid_using_union_types.ets @@ -33,4 +33,7 @@ function foo(a: A | B | C) { a.x; // No error here, since TypeScript already checks this case and reports an error. No need to duplicate this logic a.y; // Report error here, type of `y` is different: 'number' in A, C and 'string' in B a.z; // No error, the code is valid -} \ No newline at end of file +} + +let data: Uint8Array = new Uint8Array(); +let reqPb = data.buffer.slice(data.byteOffset, data.byteLength + data.byteOffset); \ No newline at end of file diff --git a/ets2panda/linter/test/main/avoid_using_union_types.ets.arkts2.json b/ets2panda/linter/test/main/avoid_using_union_types.ets.arkts2.json index 9e19899d4a4d2295ddbc6d85cb9b342d93a1b7a9..eb04bc47b74dd3fb2dc09d59dc97a0b85df3cba9 100644 --- a/ets2panda/linter/test/main/avoid_using_union_types.ets.arkts2.json +++ b/ets2panda/linter/test/main/avoid_using_union_types.ets.arkts2.json @@ -14,15 +14,75 @@ "limitations under the License." ], "result": [ - { - "line": 34, - "column": 5, - "endLine": 34, - "endColumn": 8, - "problem": "AvoidUnionTypes", - "suggest": "", - "rule": "Avoid using union types (arkts-common-union-member-access)", - "severity": "ERROR" - } + { + "line": 17, + "column": 17, + "endLine": 17, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 17, + "endLine": 18, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 17, + "endLine": 19, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 17, + "endLine": 24, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 17, + "endLine": 28, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 17, + "endLine": 29, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 8, + "problem": "AvoidUnionTypes", + "suggest": "", + "rule": "Avoid using union types (arkts-common-union-member-access)", + "severity": "ERROR" + } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/case_expr.ets.arkts2.json b/ets2panda/linter/test/main/case_expr.ets.arkts2.json index feece0064b76082f5b8d0a055bd6a5a44bd70921..abc2f67950850ae0e8ee1634cee91d1c7cc073f1 100755 --- a/ets2panda/linter/test/main/case_expr.ets.arkts2.json +++ b/ets2panda/linter/test/main/case_expr.ets.arkts2.json @@ -1,18 +1,18 @@ { - "copyright": [ - "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." - ], + "copyright": [ + "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." + ], "result": [ { "line": 17, @@ -24,6 +24,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 17, + "column": 13, + "endLine": 17, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 19, "column": 7, @@ -34,6 +44,26 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 19, + "column": 14, + "endLine": 19, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 19, + "endLine": 19, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 21, "column": 1, @@ -54,6 +84,36 @@ "rule": "No two case constant expressions have identical values.(arkts-case-expr)", "severity": "ERROR" }, + { + "line": 26, + "column": 8, + "endLine": 26, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 8, + "endLine": 29, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 15, + "endLine": 35, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 44, "column": 9, @@ -61,7 +121,7 @@ "endColumn": 12, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/catch_clause.ets.args.json b/ets2panda/linter/test/main/catch_clause.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/catch_clause.ets.args.json +++ b/ets2panda/linter/test/main/catch_clause.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/catch_clause.ets.migrate.ets b/ets2panda/linter/test/main/catch_clause.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..0559c93caa0efe8814e2116f7fa16fdd61fddb1b --- /dev/null +++ b/ets2panda/linter/test/main/catch_clause.ets.migrate.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022-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. + */ + +try { + if (true) throw "Catch with 'any' type"; +} catch (e) { + console.log(e); +} + +try { + if (true) throw "Catch with 'unknown' type"; +} catch (e) { + console.log(e); +} + +try { + if (true) throw 'Catch without explicit type'; +} catch (e) { + console.log(e); +} diff --git a/ets2panda/linter/test/main/catch_clause.ets.migrate.json b/ets2panda/linter/test/main/catch_clause.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..1ad3035275c5a4d94aa8e255c95a2bf7fe1b20d3 --- /dev/null +++ b/ets2panda/linter/test/main/catch_clause.ets.migrate.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": 17, + "column": 13, + "endLine": 17, + "endColumn": 43, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 13, + "endLine": 23, + "endColumn": 47, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 13, + "endLine": 29, + "endColumn": 49, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/class_as_object.ets b/ets2panda/linter/test/main/class_as_object.ets index b1e3cf1f68f04a8b8de93792284935553b2ae2d6..fcc5a362509dbc1bff8eeb8cb5d96f8848fc914e 100644 --- a/ets2panda/linter/test/main/class_as_object.ets +++ b/ets2panda/linter/test/main/class_as_object.ets @@ -185,4 +185,22 @@ const str = String('value'); const sym = Symbol('symbol1'); const syntaxErr = SyntaxError('message'); const typeErr = TypeError('message'); -const uriErr = URIError('message'); \ No newline at end of file +const uriErr = URIError('message'); + +let aaa4 = typeof DataView; + +let obj = new Object(); +switch (obj) { + case Object: + console.log('A'); + break; + default: + console.log('F'); +} + +function parse(type: "number" | "boolean", value: string): number | boolean { + return type === "number" ? Number(value) : value === "true"; +} +function format(input: string | number): string[] | number[] { + return typeof input === "string" ? input.split("") : input.toString().split("").map(Number); +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/class_as_object.ets.arkts2.json b/ets2panda/linter/test/main/class_as_object.ets.arkts2.json index 3d497ea7a80369114a9865e100691766091a7c28..3bf41adaebabc702af23e7f93af0ad0ce71cc015 100644 --- a/ets2panda/linter/test/main/class_as_object.ets.arkts2.json +++ b/ets2panda/linter/test/main/class_as_object.ets.arkts2.json @@ -24,6 +24,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 19, + "column": 16, + "endLine": 19, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 20, "column": 5, @@ -34,6 +44,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 20, + "column": 16, + "endLine": 20, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 27, "column": 9, @@ -234,6 +254,16 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, + { + "line": 81, + "column": 14, + "endLine": 81, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, { "line": 87, "column": 10, @@ -244,6 +274,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 87, + "column": 17, + "endLine": 87, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 87, "column": 39, @@ -304,6 +344,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 116, + "column": 17, + "endLine": 116, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 116, "column": 42, @@ -344,16 +394,6 @@ "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "ERROR" }, - { - "line": 128, - "column": 15, - "endLine": 128, - "endColumn": 23, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 129, "column": 15, @@ -775,14 +815,24 @@ "severity": "ERROR" }, { - "line": 178, - "column": 14, - "endLine": 178, - "endColumn": 22, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" + "line": 172, + "column": 29, + "endLine": 172, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 19, + "endLine": 173, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" }, { "line": 179, @@ -823,6 +873,46 @@ "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)", "severity": "ERROR" + }, + { + "line": 190, + "column": 19, + "endLine": 190, + "endColumn": 27, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 9, + "endLine": 193, + "endColumn": 12, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 8, + "endLine": 194, + "endColumn": 14, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 87, + "endLine": 205, + "endColumn": 93, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/class_as_object.ets.json b/ets2panda/linter/test/main/class_as_object.ets.json index 9a3588b472ea253357c2f90939961e3fdaace4dd..cb35d6177679bf650989f405a3789586682d341a 100644 --- a/ets2panda/linter/test/main/class_as_object.ets.json +++ b/ets2panda/linter/test/main/class_as_object.ets.json @@ -192,6 +192,436 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 127, + "column": 15, + "endLine": 127, + "endColumn": 21, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 128, + "column": 15, + "endLine": 128, + "endColumn": 23, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 129, + "column": 15, + "endLine": 129, + "endColumn": 21, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 130, + "column": 15, + "endLine": 130, + "endColumn": 22, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 131, + "column": 15, + "endLine": 131, + "endColumn": 21, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 132, + "column": 15, + "endLine": 132, + "endColumn": 19, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 133, + "column": 15, + "endLine": 133, + "endColumn": 19, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 134, + "column": 15, + "endLine": 134, + "endColumn": 21, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 135, + "column": 15, + "endLine": 135, + "endColumn": 20, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 136, + "column": 15, + "endLine": 136, + "endColumn": 24, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 137, + "column": 15, + "endLine": 137, + "endColumn": 25, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 138, + "column": 15, + "endLine": 138, + "endColumn": 29, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 139, + "column": 15, + "endLine": 139, + "endColumn": 26, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 140, + "column": 15, + "endLine": 140, + "endColumn": 24, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 141, + "column": 15, + "endLine": 141, + "endColumn": 23, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 142, + "column": 15, + "endLine": 142, + "endColumn": 29, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 143, + "column": 15, + "endLine": 143, + "endColumn": 19, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 144, + "column": 15, + "endLine": 144, + "endColumn": 20, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 145, + "column": 15, + "endLine": 145, + "endColumn": 26, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 146, + "column": 15, + "endLine": 146, + "endColumn": 23, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 147, + "column": 15, + "endLine": 147, + "endColumn": 24, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 148, + "column": 15, + "endLine": 148, + "endColumn": 25, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 149, + "column": 15, + "endLine": 149, + "endColumn": 32, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 150, + "column": 15, + "endLine": 150, + "endColumn": 25, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 151, + "column": 15, + "endLine": 151, + "endColumn": 26, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 152, + "column": 15, + "endLine": 152, + "endColumn": 25, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 153, + "column": 15, + "endLine": 153, + "endColumn": 26, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 154, + "column": 15, + "endLine": 154, + "endColumn": 27, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 155, + "column": 15, + "endLine": 155, + "endColumn": 27, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 156, + "column": 15, + "endLine": 156, + "endColumn": 18, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 157, + "column": 15, + "endLine": 157, + "endColumn": 22, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 158, + "column": 15, + "endLine": 158, + "endColumn": 18, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 159, + "column": 15, + "endLine": 159, + "endColumn": 22, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 160, + "column": 15, + "endLine": 160, + "endColumn": 22, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 161, + "column": 15, + "endLine": 161, + "endColumn": 20, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 162, + "column": 15, + "endLine": 162, + "endColumn": 21, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 163, + "column": 15, + "endLine": 163, + "endColumn": 32, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 164, + "column": 15, + "endLine": 164, + "endColumn": 22, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 165, + "column": 15, + "endLine": 165, + "endColumn": 21, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 166, + "column": 15, + "endLine": 166, + "endColumn": 28, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 167, + "column": 15, + "endLine": 167, + "endColumn": 29, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 168, + "column": 15, + "endLine": 168, + "endColumn": 22, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 169, + "column": 15, + "endLine": 169, + "endColumn": 35, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, { "line": 180, "column": 7, @@ -211,6 +641,36 @@ "suggest": "", "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)", "severity": "ERROR" + }, + { + "line": 190, + "column": 19, + "endLine": 190, + "endColumn": 27, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 194, + "column": 8, + "endLine": 194, + "endColumn": 14, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 205, + "column": 87, + "endLine": 205, + "endColumn": 93, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/class_no_constructor.ets b/ets2panda/linter/test/main/class_no_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..c13aa9b54ab1233ccdae9d6496c2f0e0147d1570 --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.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. + */ +'use static' + +class A {} + +const variable = new A().constructor diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.args.json b/ets2panda/linter/test/main/class_no_constructor.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..8a4be28991e8164c0366b8b3ad0dffbc04910a27 --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.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": "", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.json b/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..12f07f6aefeab765323013130ba3901be22f8c2f --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.ets.arkts2.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": 19, + "column": 18, + "endLine": 19, + "endColumn": 37, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "The Class object does not have a constructor. (arkts-no-arkts-constructor)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.json b/ets2panda/linter/test/main/class_no_constructor.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bd1b7140ca95b67336908f5fca6dec77fb46b2c0 --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.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": [] +} diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.migrate.ets b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..c13aa9b54ab1233ccdae9d6496c2f0e0147d1570 --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.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. + */ +'use static' + +class A {} + +const variable = new A().constructor diff --git a/ets2panda/linter/test/main/class_no_constructor.ets.migrate.json b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..12f07f6aefeab765323013130ba3901be22f8c2f --- /dev/null +++ b/ets2panda/linter/test/main/class_no_constructor.ets.migrate.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": 19, + "column": 18, + "endLine": 19, + "endColumn": 37, + "problem": "NoConstructorOnClass", + "suggest": "", + "rule": "The Class object does not have a constructor. (arkts-no-arkts-constructor)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/class_static_block.ets.args.json b/ets2panda/linter/test/main/class_static_block.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/class_static_block.ets.args.json +++ b/ets2panda/linter/test/main/class_static_block.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/migrate/class_static_block.sts b/ets2panda/linter/test/main/class_static_block.ets.migrate.ets similarity index 93% rename from ets2panda/linter/test/migrate/class_static_block.sts rename to ets2panda/linter/test/main/class_static_block.ets.migrate.ets index 2e9ad55a382e574292b3a88d72c0a90fad00b090..111e4f30bb45f109307f2db6c31d221583ec54c6 100644 --- a/ets2panda/linter/test/migrate/class_static_block.sts +++ b/ets2panda/linter/test/main/class_static_block.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -17,12 +17,11 @@ class C { static s: string; static { C.s = 'string'; - } + C.n = C.s.length; +} static n: number; - static { - C.n = C.s.length; - } + } class B { diff --git a/ets2panda/linter/test/main/class_static_block.ets.migrate.json b/ets2panda/linter/test/main/class_static_block.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/class_static_block.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 diff --git a/ets2panda/linter/test/main/class_static_init.ets b/ets2panda/linter/test/main/class_static_init.ets index 29c91f9a869279c5e62eaa22dae20bb1e287e91c..c74ec693d923b780a737b7bae7c058db3e8696d4 100755 --- a/ets2panda/linter/test/main/class_static_init.ets +++ b/ets2panda/linter/test/main/class_static_init.ets @@ -50,4 +50,128 @@ struct Index { .height('100%') .width('100%') } -} \ No newline at end of file +} + +// Top 0 case +class BB {} + +class AA { + static b: BB; +} + +class CC { + static count: number; +} + +class DD { + static config: { theme: string}; +} + +class EE { + static name: string; + constructor() { + E.name = "default" + } +} + +// Basic Types +class PrimitiveTypes { + static uninitializedString: string; + static uninitializedNumber: number; + static uninitializedBoolean: boolean; +} + +// Array Types +class ArrayTypes { + static uninitializedStringArray: string[]; + static uninitializedNumberArray: number[]; + static uninitializedObjectArray: { id: number }[]; + static uninitializedUnionArray: (string | number)[]; +} + +// Object Types +class ObjectTypes { + static uninitializedSimpleObject: { name: string; age: number }; + static uninitializedNestedObject: { + id: number; + metadata: { + createdAt: Date; + tags: string[]; + }; + }; +} + +// Special Built-in Types +class BuiltInTypes { + static uninitializedDate: Date; + static uninitializedMap: Map; + static uninitializedSet: Set; + static uninitializedPromise: Promise; +} + +// Union and Intersection Types +class AdvancedTypes { + static uninitializedUnion: string | number; + static uninitializedIntersection: { name: string } & { age: number }; + static uninitializedLiteralUnion: 'success' | 'error'; +} + +// Optional and Nullable Types +class NullableTypes { + static uninitializedOptional?: string; + static uninitializedNull: null; + static uninitializedUndefined: undefined; +} + +// Generic Types +class GenericTypes { + static uninitializedGenericArray: T[]; + static uninitializedGenericValue: T; +} + +// Function Types +class FunctionTypes { + static uninitializedFunction: () => void; + static uninitializedCallback: (result: string) => number; +} + +// Complex Combined Types +class ComplexTypes { + static uninitializedComplexArray: Array<{ id: number; data: Map> }>; + static uninitializedRecord: Record; + static uninitializedTuple: [string, number, boolean?]; +} + +// Custom Class Types +class User { + id: number; + name: string; +} + +class CustomClassTypes { + static uninitializedUser: User; + static uninitializedUsers: User[]; +} + +// Enum Types +enum Status { + Active, + Inactive +} + +class EnumTypes { + static uninitializedStatus: Status; + static uninitializedStatusArray: Status[]; +} + +// Never and Unknown Types +class SpecialTypes { + static uninitializedNever: never; + static uninitializedUnknown: unknown; + static uninitializedAny: any; +} + + +class Test1 { + static count: string | undefined; +} diff --git a/ets2panda/linter/test/main/class_static_init.ets.arkts2.json b/ets2panda/linter/test/main/class_static_init.ets.arkts2.json index 2b682eca6edc35d435e54a21fe6006b9ba6e70e6..17db245900a4df3e63c8fb82090b3ba1c3d0e4a1 100755 --- a/ets2panda/linter/test/main/class_static_init.ets.arkts2.json +++ b/ets2panda/linter/test/main/class_static_init.ets.arkts2.json @@ -64,6 +64,436 @@ "rule": "The static property has no initializer (arkts-class-static-initialization)", "severity": "ERROR" }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 16, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 35, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 18, + "endLine": 67, + "endColumn": 19, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 3, + "endLine": 71, + "endColumn": 23, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 3, + "endLine": 79, + "endColumn": 38, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 3, + "endLine": 86, + "endColumn": 45, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 3, + "endLine": 87, + "endColumn": 45, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 3, + "endLine": 88, + "endColumn": 53, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 36, + "endLine": 88, + "endColumn": 37, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 3, + "endLine": 89, + "endColumn": 55, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 67, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 37, + "endLine": 94, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 3, + "endLine": 101, + "endColumn": 5, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 37, + "endLine": 95, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 15, + "endLine": 97, + "endColumn": 16, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 3, + "endLine": 106, + "endColumn": 34, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 3, + "endLine": 107, + "endColumn": 48, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 3, + "endLine": 108, + "endColumn": 40, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 3, + "endLine": 109, + "endColumn": 46, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 3, + "endLine": 114, + "endColumn": 46, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 3, + "endLine": 115, + "endColumn": 72, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 71, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 56, + "endLine": 115, + "endColumn": 57, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 3, + "endLine": 116, + "endColumn": 57, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 3, + "endLine": 128, + "endColumn": 41, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 3, + "endLine": 129, + "endColumn": 39, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 3, + "endLine": 134, + "endColumn": 44, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 135, + "column": 3, + "endLine": 135, + "endColumn": 60, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 3, + "endLine": 140, + "endColumn": 91, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 43, + "endLine": 140, + "endColumn": 44, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 3, + "endLine": 141, + "endColumn": 65, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 46, + "endLine": 141, + "endColumn": 47, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 3, + "endLine": 142, + "endColumn": 57, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 3, + "endLine": 152, + "endColumn": 34, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 3, + "endLine": 153, + "endColumn": 37, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 3, + "endLine": 163, + "endColumn": 38, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 3, + "endLine": 164, + "endColumn": 45, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 3, + "endLine": 169, + "endColumn": 36, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 3, + "endLine": 170, + "endColumn": 40, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 32, + "endLine": 170, + "endColumn": 39, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 3, + "endLine": 171, + "endColumn": 32, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 28, + "endLine": 171, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, { "line": 42, "column": 2, @@ -103,6 +533,26 @@ "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" + }, + { + "line": 147, + "column": 3, + "endLine": 147, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 148, + "column": 3, + "endLine": 148, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/class_static_init.ets.json b/ets2panda/linter/test/main/class_static_init.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..d9c1c79cdcb82d17fe50614f5315786b6907bbaa 100755 --- a/ets2panda/linter/test/main/class_static_init.ets.json +++ b/ets2panda/linter/test/main/class_static_init.ets.json @@ -13,5 +13,146 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 67, + "column": 18, + "endLine": 67, + "endColumn": 19, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 36, + "endLine": 88, + "endColumn": 37, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 37, + "endLine": 94, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 37, + "endLine": 95, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 15, + "endLine": 97, + "endColumn": 16, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 71, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 37, + "endLine": 115, + "endColumn": 38, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 56, + "endLine": 115, + "endColumn": 57, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 43, + "endLine": 140, + "endColumn": 44, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 46, + "endLine": 141, + "endColumn": 47, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 32, + "endLine": 170, + "endColumn": 39, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 28, + "endLine": 171, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 147, + "column": 3, + "endLine": 147, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'id' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 148, + "column": 3, + "endLine": 148, + "endColumn": 7, + "problem": "StrictDiagnostic", + "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'name' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/collections_module.ets b/ets2panda/linter/test/main/collections_module.ets new file mode 100644 index 0000000000000000000000000000000000000000..5fba982f6b6426a38730e4019763ff9658df5fc2 --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { collections } from './oh_modules/@arkts.collections'; + +import { collections as collectionsAlias } from './oh_modules/@arkts.collections'; + +import { collections as kitCollections } from './oh_modules/@kit.ArkTS'; + +import { collections as definedCollections } from 'user_defined_worker'; //legal + +function tesCollectionsUsage() { + + const collections1: collections.Array = new collections.Array(); + + const collections2 = new collectionsAlias.Array(); + + const collections3 = new kitCollections.Array(); + + let collections4: collectionsAlias.Array; + + const collections5: collectionsAlias.Array = new collectionsAlias.Array(); + + let collections6: definedCollections.Array; // legal + +} diff --git a/ets2panda/linter/test/main/collections_module.ets.args.json b/ets2panda/linter/test/main/collections_module.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b13bb90d5b5f6d3dc5f0d054663eeba637fcc7dd --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.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" + } +} diff --git a/ets2panda/linter/test/main/collections_module.ets.arkts2.json b/ets2panda/linter/test/main/collections_module.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..584e375a01ba06e7a2ecd03772a34d762c5ccbba --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets.arkts2.json @@ -0,0 +1,138 @@ +{ + "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": 10, + "endLine": 16, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 25, + "endLine": 18, + "endColumn": 41, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 25, + "endLine": 20, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 23, + "endLine": 26, + "endColumn": 34, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 55, + "endLine": 26, + "endColumn": 66, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 28, + "endLine": 28, + "endColumn": 44, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 28, + "endLine": 30, + "endColumn": 42, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 21, + "endLine": 32, + "endColumn": 37, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 23, + "endLine": 34, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 76, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/collections_module.ets.autofix.json b/ets2panda/linter/test/main/collections_module.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..3b091c13f428361247667bb4cc8bd51cef9274b9 --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets.autofix.json @@ -0,0 +1,222 @@ +{ + "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": 10, + "endLine": 16, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 605, + "end": 667, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 669, + "end": 751, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 25, + "endLine": 18, + "endColumn": 41, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 669, + "end": 751, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 753, + "end": 825, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 25, + "endLine": 20, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 753, + "end": 825, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 23, + "endLine": 26, + "endColumn": 34, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 965, + "end": 982, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 55, + "endLine": 26, + "endColumn": 66, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 997, + "end": 1014, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 28, + "endLine": 28, + "endColumn": 44, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1054, + "end": 1076, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 28, + "endLine": 30, + "endColumn": 42, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1116, + "end": 1136, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 21, + "endLine": 32, + "endColumn": 37, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1169, + "end": 1191, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 23, + "endLine": 34, + "endColumn": 39, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1224, + "end": 1246, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 76, + "problem": "NoNeedStdLibSendableContainer", + "autofix": [ + { + "start": 1261, + "end": 1283, + "replacementText": "Array" + } + ], + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/collections_module.ets.json b/ets2panda/linter/test/main/collections_module.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.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/collections_module.ets.migrate.ets b/ets2panda/linter/test/main/collections_module.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..02fc9aaad5de07117bf611e6701de10bcfd98aa1 --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets.migrate.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + + + + + +import { collections as definedCollections } from 'user_defined_worker'; //legal + +function tesCollectionsUsage() { + + const collections1: Array = new Array(); + + const collections2: number[] = new Array(); + + const collections3: number[] = new Array(); + + let collections4: Array; + + const collections5: Array = new Array(); + + let collections6: definedCollections.Array; // legal + +} diff --git a/ets2panda/linter/test/main/collections_module.ets.migrate.json b/ets2panda/linter/test/main/collections_module.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..4dcf9e56dbc14e1fbd427eeb3ad24f841cacf0ce --- /dev/null +++ b/ets2panda/linter/test/main/collections_module.ets.migrate.json @@ -0,0 +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." + ], + "result": [] +} + diff --git a/ets2panda/linter/test/main/custom_layout.ets b/ets2panda/linter/test/main/custom_layout.ets new file mode 100644 index 0000000000000000000000000000000000000000..233a5aaa79d649a1bb3495a25e6cac4ec5b782e9 --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets @@ -0,0 +1,100 @@ +/* + * 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 +@Component +struct Index { + build() { + Column() { + CustomLayout1({ builder: ColumnChildren }) + CustomLayout2({ builder: ColumnChildren }) + } + } +} + +@Builder +function ColumnChildren() { + ForEach([1, 2, 3], (index: number) => { //暂不支持lazyForEach的写法 + Text('S' + index) + .fontSize(30) + .width(100) + .height(100) + .borderWidth(2) + .offset({ x: 10, y: 20 }) + }) +} + +@Component +struct CustomLayout1 { + @Builder + doNothingBuilder() { + }; + + @BuilderParam builder: () => void = this.doNothingBuilder; + @State startSize: number = 100; + result: SizeResult = { + width: 0, + height: 0 + }; + + onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { + let startPos = 300; + children.forEach((child) => { + let pos = startPos - child.measureResult.height; + child.layout({ x: pos, y: pos }) + }) + } + + build() { + this.builder() + } +} + +@Component +struct CustomLayout2 { + @Builder + doNothingBuilder() { + }; + + @BuilderParam builder: () => void = this.doNothingBuilder; + @State startSize: number = 100; + result: SizeResult = { + width: 0, + height: 0 + }; + + onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { + let size = 100; + children.forEach((child) => { + let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size }) + size += result.width / 2 + ; + }) + this.result.width = 100; + this.result.height = 400; + return this.result; + } + + build() { + this.builder() + } +} + +@Component +struct CustomLayout3 { + build { + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/custom_layout.ets.args.json b/ets2panda/linter/test/main/custom_layout.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.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/custom_layout.ets.arkts2.json b/ets2panda/linter/test/main/custom_layout.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..32ddf7ff59f064b474e0b4aed22002fead6accf4 --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets.arkts2.json @@ -0,0 +1,518 @@ +{ + "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": 29, + "column": 12, + "endLine": 29, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 15, + "endLine": 29, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 17, + "endLine": 31, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 14, + "endLine": 32, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 20, + "endLine": 34, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 27, + "endLine": 35, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", + "suggest": "", + "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 30, + "endLine": 46, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 13, + "endLine": 49, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 9, + "endLine": 53, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 20, + "endLine": 53, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 11, + "endLine": 55, + "endColumn": 54, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 8, + "endLine": 66, + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", + "suggest": "", + "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 30, + "endLine": 72, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 12, + "endLine": 74, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 13, + "endLine": 75, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 9, + "endLine": 79, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 16, + "endLine": 79, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 30, + "endLine": 82, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 25, + "endLine": 85, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 26, + "endLine": 86, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 2, + "endLine": 27, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 10, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 2, + "endLine": 39, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 4, + "endLine": 41, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 4, + "endLine": 45, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 4, + "endLine": 46, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 11, + "endLine": 47, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 35, + "endLine": 52, + "endColumn": 47, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 65, + "endLine": 52, + "endColumn": 75, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 90, + "endLine": 52, + "endColumn": 111, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 2, + "endLine": 65, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 4, + "endLine": 67, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 4, + "endLine": 71, + "endColumn": 16, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 4, + "endLine": 72, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 11, + "endLine": 73, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 33, + "endLine": 78, + "endColumn": 45, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 63, + "endLine": 78, + "endColumn": 73, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 88, + "endLine": 78, + "endColumn": 109, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 19, + "endLine": 81, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/custom_layout.ets.autofix.json b/ets2panda/linter/test/main/custom_layout.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..889e3da043f798014c3b27fdea9aef9bcc108344 --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets.autofix.json @@ -0,0 +1,1057 @@ +{ + "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": 29, + "column": 12, + "endLine": 29, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 824, + "end": 825, + "replacementText": "1.0", + "line": 29, + "column": 12, + "endLine": 29, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 15, + "endLine": 29, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 827, + "end": 828, + "replacementText": "2.0", + "line": 29, + "column": 15, + "endLine": 29, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 830, + "end": 831, + "replacementText": "3.0", + "line": 29, + "column": 18, + "endLine": 29, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 17, + "endLine": 31, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 914, + "end": 916, + "replacementText": "30.0", + "line": 31, + "column": 17, + "endLine": 31, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 14, + "endLine": 32, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 931, + "end": 934, + "replacementText": "100.0", + "line": 32, + "column": 14, + "endLine": 32, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 950, + "end": 953, + "replacementText": "100.0", + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 20, + "endLine": 34, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 974, + "end": 975, + "replacementText": "2.0", + "line": 34, + "column": 20, + "endLine": 34, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 996, + "end": 998, + "replacementText": "10.0", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 27, + "endLine": 35, + "endColumn": 29, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1003, + "end": 1005, + "replacementText": "20.0", + "line": 35, + "column": 27, + "endLine": 35, + "endColumn": 29 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", + "autofix": [ + { + "start": 1027, + "end": 1027, + "replacementText": "\n@Layoutable", + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 30, + "endLine": 46, + "endColumn": 33, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1181, + "end": 1184, + "replacementText": "100.0", + "line": 46, + "column": 30, + "endLine": 46, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1222, + "end": 1223, + "replacementText": "0.0", + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 13, + "endLine": 49, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1237, + "end": 1238, + "replacementText": "0.0", + "line": 49, + "column": 13, + "endLine": 49, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 9, + "endLine": 53, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1367, + "end": 1381, + "replacementText": "startPos: number = 300", + "line": 53, + "column": 9, + "endLine": 53, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 20, + "endLine": 53, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1378, + "end": 1381, + "replacementText": "300.0", + "line": 53, + "column": 20, + "endLine": 53, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 11, + "endLine": 55, + "endColumn": 54, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1427, + "end": 1470, + "replacementText": "pos: number = startPos - child.measureResult.height", + "line": 55, + "column": 11, + "endLine": 55, + "endColumn": 54 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 8, + "endLine": 66, + "endColumn": 21, + "problem": "CustomLayoutNeedAddDecorator", + "autofix": [ + { + "start": 1571, + "end": 1571, + "replacementText": "\n@Layoutable", + "line": 66, + "column": 8, + "endLine": 66, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Custom components with custom layout capability need to add the \"@Layoutable\" decorator (arkui-custom-layout-need-add-decorator)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 30, + "endLine": 72, + "endColumn": 33, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1725, + "end": 1728, + "replacementText": "100.0", + "line": 72, + "column": 30, + "endLine": 72, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 12, + "endLine": 74, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1766, + "end": 1767, + "replacementText": "0.0", + "line": 74, + "column": 12, + "endLine": 74, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 13, + "endLine": 75, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1781, + "end": 1782, + "replacementText": "0.0", + "line": 75, + "column": 13, + "endLine": 75, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 9, + "endLine": 79, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1909, + "end": 1919, + "replacementText": "size: number = 100", + "line": 79, + "column": 9, + "endLine": 79, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 16, + "endLine": 79, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1916, + "end": 1919, + "replacementText": "100.0", + "line": 79, + "column": 16, + "endLine": 79, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 30, + "endLine": 82, + "endColumn": 31, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2102, + "end": 2103, + "replacementText": "2.0", + "line": 82, + "column": 30, + "endLine": 82, + "endColumn": 31 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 25, + "endLine": 85, + "endColumn": 28, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2143, + "end": 2146, + "replacementText": "100.0", + "line": 85, + "column": 25, + "endLine": 85, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 26, + "endLine": 86, + "endColumn": 29, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2173, + "end": 2176, + "replacementText": "400.0", + "line": 86, + "column": 26, + "endLine": 86, + "endColumn": 29 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 8, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 2, + "endLine": 27, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 10, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 2, + "endLine": 39, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 4, + "endLine": 41, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 4, + "endLine": 45, + "endColumn": 16, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 4, + "endLine": 46, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 11, + "endLine": 47, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 35, + "endLine": 52, + "endColumn": 47, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 65, + "endLine": 52, + "endColumn": 75, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 90, + "endLine": 52, + "endColumn": 111, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 2, + "endLine": 65, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 4, + "endLine": 67, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 4, + "endLine": 71, + "endColumn": 16, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 4, + "endLine": 72, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 11, + "endLine": 73, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 33, + "endLine": 78, + "endColumn": 45, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 63, + "endLine": 78, + "endColumn": 73, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 88, + "endLine": 78, + "endColumn": 109, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 19, + "endLine": 81, + "endColumn": 32, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI';", + "line": 95, + "column": 2, + "endLine": 95, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/custom_layout.ets.json b/ets2panda/linter/test/main/custom_layout.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..5d769b466be894ca7e944a9048b170f15ac0ae1c --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets.json @@ -0,0 +1,38 @@ +{ + "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": 78, + "column": 3, + "endLine": 78, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 8, + "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/main/custom_layout.ets.migrate.ets b/ets2panda/linter/test/main/custom_layout.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..97dd101026b6341d1c89f2b955d001b79a3e420d --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets.migrate.ets @@ -0,0 +1,104 @@ +/* + * 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, Component, Column, Builder, ForEach, Text, BuilderParam, State, SizeResult, GeometryInfo, Layoutable, ConstraintSizeOptions, Measurable, MeasureResult } from '@kit.ArkUI'; + +@Entry +@Component +struct Index { + build() { + Column() { + CustomLayout1({ builder: ColumnChildren }) + CustomLayout2({ builder: ColumnChildren }) + } + } +} + +@Builder +function ColumnChildren() { + ForEach([1.0, 2.0, 3.0], (index: number) => { //暂不支持lazyForEach的写法 + Text('S' + index) + .fontSize(30.0) + .width(100.0) + .height(100.0) + .borderWidth(2.0) + .offset({ x: 10.0, y: 20.0 }) + }) +} + +@Component +@Layoutable +struct CustomLayout1 { + @Builder + doNothingBuilder() { + }; + + @BuilderParam builder: () => void = this.doNothingBuilder; + @State startSize: number = 100.0; + result: SizeResult = { + width: 0.0, + height: 0.0 + }; + + onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { + let startPos: number = 300.0; + children.forEach((child) => { + let pos: number = startPos - child.measureResult.height; + child.layout({ x: pos, y: pos }) + }) + } + + build() { + this.builder() + } +} + +@Component +@Layoutable +struct CustomLayout2 { + @Builder + doNothingBuilder() { + }; + + @BuilderParam builder: () => void = this.doNothingBuilder; + @State startSize: number = 100.0; + result: SizeResult = { + width: 0.0, + height: 0.0 + }; + + onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array, constraint: ConstraintSizeOptions) { + let size: number = 100.0; + children.forEach((child) => { + let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size }) + size += result.width / 2.0 + ; + }) + this.result.width = 100.0; + this.result.height = 400.0; + return this.result; + } + + build() { + this.builder() + } +} + +@Component +struct CustomLayout3 { + build { + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/custom_layout.ets.migrate.json b/ets2panda/linter/test/main/custom_layout.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..6c283c3ef1beea2a8d290ae40cecd19853e44771 --- /dev/null +++ b/ets2panda/linter/test/main/custom_layout.ets.migrate.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": 42, + "column": 1, + "endLine": 42, + "endColumn": 12, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 1, + "endLine": 69, + "endColumn": 12, + "problem": "DecoratorsNotSupported", + "suggest": "", + "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 3, + "endLine": 101, + "endColumn": 8, + "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/main/debugger_statememt.ets.args.json b/ets2panda/linter/test/main/debugger_statememt.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..f56752f2284e65fb08a317502e548ab26eee7c70 100644 --- a/ets2panda/linter/test/main/debugger_statememt.ets.args.json +++ b/ets2panda/linter/test/main/debugger_statememt.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json b/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json index f972e0b8b5b201938b2fac548ccdbf8c9bdd44ee..6c9d73e3d1b95d4073a99e0e9c4d36a103b55faa 100644 --- a/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json +++ b/ets2panda/linter/test/main/debugger_statememt.ets.autofix.json @@ -24,7 +24,7 @@ { "start": 605, "end": 614, - "replacementText": "specialAutofixLib.debugger()" + "replacementText": "specialAutofixLib.debugger();" } ], "suggest": "", @@ -41,7 +41,7 @@ { "start": 633, "end": 642, - "replacementText": "specialAutofixLib.debugger()" + "replacementText": "specialAutofixLib.debugger();" } ], "suggest": "", diff --git a/ets2panda/linter/test/main/debugger_statememt.ets.migrate.ets b/ets2panda/linter/test/main/debugger_statememt.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..04eeeb8969692e0bcd2becb26ad2df9437c05370 --- /dev/null +++ b/ets2panda/linter/test/main/debugger_statememt.ets.migrate.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. + */ + +specialAutofixLib.debugger(); + +function a() { + specialAutofixLib.debugger(); +} + +console.log('debugger'); \ No newline at end of file diff --git a/ets2panda/linter/test/main/debugger_statememt.ets.migrate.json b/ets2panda/linter/test/main/debugger_statememt.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/debugger_statememt.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 diff --git a/ets2panda/linter/test/main/default_required_args.ets b/ets2panda/linter/test/main/default_required_args.ets new file mode 100644 index 0000000000000000000000000000000000000000..cbccdb42cf31c8bdadd160e270814f14ec671829 --- /dev/null +++ b/ets2panda/linter/test/main/default_required_args.ets @@ -0,0 +1,60 @@ +/* + * 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(left: number = 0, right: number): number { + return left + right +} + +function foo3(a: number, b: number = 5, c: number): number { + return a + b + c; +} + +function foo4(a: number = 1, b: number = 2, c: number): number { + return a + b + c; +} + +function foo5(a: number = 1, b: number = 2, c: number = 3): number { //legal + return a + b + c; +} + +const bar = (x: boolean = true, y: boolean) => { + return x && y; +}; + +class MyClass { + myMethod(x: number = 0, y: number) { + return x + y; + } +} + +function fooLegal(a: number, b: number = 0): number { //legal + return a + b; +} + +function greetLegal(name: string, message: string = "Hi"): string { //legal + return message + ", " + name; +} + +const barLegal = (x: boolean, y: boolean = false) => { //legal + return x && y; +}; + +function log(level: string = 'info', some: string, message?: string): void { + console.log(`${some} [${level.toUpperCase()}] ${message ?? 'No message'}`); +} + +function config(debug: boolean = true, verbose?: boolean): string { //legal + return `Debug: ${debug ?? false}, Verbose: ${verbose ?? false}`; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/default_required_args.ets.args.json b/ets2panda/linter/test/main/default_required_args.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..9b16bb93a4605b3465a0f919cd2f678737401555 --- /dev/null +++ b/ets2panda/linter/test/main/default_required_args.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/worker_module.ts.arkts2.json b/ets2panda/linter/test/main/default_required_args.ets.arkts2.json similarity index 49% rename from ets2panda/linter/test/main/worker_module.ts.arkts2.json rename to ets2panda/linter/test/main/default_required_args.ets.arkts2.json index f6f6faec236ee87c01a7f5849a6a74f8cf841a9e..bbcdfcb08550783a6ee99afe23bf3147a0334e5f 100644 --- a/ets2panda/linter/test/main/worker_module.ts.arkts2.json +++ b/ets2panda/linter/test/main/default_required_args.ets.arkts2.json @@ -16,118 +16,108 @@ "result": [ { "line": 16, - "column": 10, + "column": 14, "endLine": 16, - "endColumn": 16, - "problem": "LimitedStdLibApi", + "endColumn": 18, + "problem": "DefaultArgsBehindRequiredArgs", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", "severity": "ERROR" }, { - "line": 18, - "column": 10, - "endLine": 18, - "endColumn": 16, - "problem": "LimitedStdLibApi", + "line": 16, + "column": 29, + "endLine": 16, + "endColumn": 30, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 18, - "column": 20, - "endLine": 18, - "endColumn": 31, - "problem": "LimitedStdLibApi", + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27, + "problem": "DefaultArgsBehindRequiredArgs", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", "severity": "ERROR" }, { "line": 20, - "column": 10, + "column": 38, "endLine": 20, - "endColumn": 16, - "problem": "LimitedStdLibApi", + "endColumn": 39, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 20, - "column": 20, - "endLine": 20, - "endColumn": 29, - "problem": "LimitedStdLibApi", + "line": 24, + "column": 30, + "endLine": 24, + "endColumn": 31, + "problem": "DefaultArgsBehindRequiredArgs", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", "severity": "ERROR" }, { "line": 24, - "column": 10, + "column": 15, "endLine": 24, "endColumn": 16, - "problem": "LimitedStdLibApi", + "problem": "DefaultArgsBehindRequiredArgs", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", "severity": "ERROR" }, { - "line": 28, - "column": 9, - "endLine": 28, - "endColumn": 76, + "line": 24, + "column": 27, + "endLine": 24, + "endColumn": 28, "problem": "NumericSemantics", "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 28, - "column": 18, - "endLine": 28, - "endColumn": 24, - "problem": "LimitedStdLibApi", + "line": 24, + "column": 42, + "endLine": 24, + "endColumn": 43, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { "line": 28, - "column": 44, + "column": 27, "endLine": 28, - "endColumn": 50, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 9, - "endLine": 30, - "endColumn": 60, + "endColumn": 28, "problem": "NumericSemantics", "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 30, - "column": 23, - "endLine": 30, - "endColumn": 34, - "problem": "LimitedStdLibApi", + "line": 28, + "column": 42, + "endLine": 28, + "endColumn": 43, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 32, - "column": 9, - "endLine": 32, + "line": 28, + "column": 57, + "endLine": 28, "endColumn": 58, "problem": "NumericSemantics", "suggest": "", @@ -136,72 +126,52 @@ }, { "line": 32, - "column": 23, + "column": 14, "endLine": 32, - "endColumn": 32, - "problem": "LimitedStdLibApi", + "endColumn": 15, + "problem": "DefaultArgsBehindRequiredArgs", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", "severity": "ERROR" }, { - "line": 34, - "column": 7, - "endLine": 34, - "endColumn": 40, - "problem": "NumericSemantics", + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 13, + "problem": "DefaultArgsBehindRequiredArgs", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", "severity": "ERROR" }, { - "line": 34, - "column": 16, - "endLine": 34, - "endColumn": 27, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 9, - "endLine": 36, - "endColumn": 86, + "line": 37, + "column": 24, + "endLine": 37, + "endColumn": 25, "problem": "NumericSemantics", "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 36, - "column": 18, - "endLine": 36, - "endColumn": 29, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 49, - "endLine": 36, - "endColumn": 60, - "problem": "LimitedStdLibApi", + "line": 42, + "column": 42, + "endLine": 42, + "endColumn": 43, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 38, - "column": 7, - "endLine": 38, - "endColumn": 42, - "problem": "NumericSemantics", + "line": 54, + "column": 14, + "endLine": 54, + "endColumn": 19, + "problem": "DefaultArgsBehindRequiredArgs", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Default parameters must be placed after mandatory parameters (arkts-default-args-behind-required-args)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/default_required_args.ets.json b/ets2panda/linter/test/main/default_required_args.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/main/default_required_args.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": [] +} diff --git a/ets2panda/linter/test/main/definite_assignment.ets.arkts2.json b/ets2panda/linter/test/main/definite_assignment.ets.arkts2.json index cd7c54679e12d6b274062c1e19e84b41ca2baa32..c08c8a3f993b48cdfb95a800c5d53caab98aee9c 100644 --- a/ets2panda/linter/test/main/definite_assignment.ets.arkts2.json +++ b/ets2panda/linter/test/main/definite_assignment.ets.arkts2.json @@ -24,6 +24,26 @@ "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "ERROR" }, + { + "line": 21, + "column": 7, + "endLine": 21, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 33, "column": 3, @@ -33,6 +53,36 @@ "suggest": "", "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "ERROR" + }, + { + "line": 37, + "column": 30, + "endLine": 37, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 17, + "endLine": 43, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 12, + "endLine": 51, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_assignments.ets.args.json b/ets2panda/linter/test/main/destructuring_assignments.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/destructuring_assignments.ets.args.json +++ b/ets2panda/linter/test/main/destructuring_assignments.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/destructuring_assignments.ets.autofix.json b/ets2panda/linter/test/main/destructuring_assignments.ets.autofix.json index 376b05b6dcc48b9a948d29b32cd6b15a99cebcd6..a9c281d2f38381ce20e29ef85d85963624f4add6 100644 --- a/ets2panda/linter/test/main/destructuring_assignments.ets.autofix.json +++ b/ets2panda/linter/test/main/destructuring_assignments.ets.autofix.json @@ -47,7 +47,7 @@ "end": 736 }, { - "replacementText": "a = GeneratedDestructObj_1.a;b = GeneratedDestructObj_1.b;s = GeneratedDestructObj_1.s;", + "replacementText": "\na = GeneratedDestructObj_1.a;\nb = GeneratedDestructObj_1.b;\ns = GeneratedDestructObj_1.s;\n", "start": 737, "end": 737 } @@ -119,7 +119,7 @@ "end": 892 }, { - "replacementText": "a = GeneratedDestructObj_2.a;({ c, d: s } = GeneratedDestructObj_2.b);", + "replacementText": "\na = GeneratedDestructObj_2.a;\n({ c, d: s } = GeneratedDestructObj_2.b);\n", "start": 893, "end": 893 } @@ -213,7 +213,7 @@ "end": 1047 }, { - "replacementText": "a = GeneratedDestructObj_3.a;b = GeneratedDestructObj_3.b;", + "replacementText": "\na = GeneratedDestructObj_3.a;\nb = GeneratedDestructObj_3.b;\n", "start": 1048, "end": 1048 } @@ -235,7 +235,7 @@ "end": 1092 }, { - "replacementText": "a = GeneratedDestructArray_1[0];b = GeneratedDestructArray_1[1];c = GeneratedDestructArray_1[2];", + "replacementText": "\na = GeneratedDestructArray_1[0];\nb = GeneratedDestructArray_1[1];\nc = GeneratedDestructArray_1[2];\n", "start": 1108, "end": 1108 } @@ -267,7 +267,7 @@ "end": 1155 }, { - "replacementText": "[a1, a2] = GeneratedDestructArray_2[0];[b1, b2] = GeneratedDestructArray_2[1];[c1, c2] = GeneratedDestructArray_2[2];", + "replacementText": "\n[a1, a2] = GeneratedDestructArray_2[0];\n[b1, b2] = GeneratedDestructArray_2[1];\n[c1, c2] = GeneratedDestructArray_2[2];\n", "start": 1183, "end": 1183 } @@ -289,7 +289,7 @@ "end": 1192 }, { - "replacementText": "a = GeneratedDestructArray_3[0];b = GeneratedDestructArray_3[1];", + "replacementText": "\na = GeneratedDestructArray_3[0];\nb = GeneratedDestructArray_3[1];\n", "start": 1202, "end": 1202 } @@ -391,7 +391,7 @@ "end": 1506 }, { - "replacementText": "a = GeneratedDestructArray_4[0];b = GeneratedDestructArray_4[1];", + "replacementText": "\na = GeneratedDestructArray_4[0];\nb = GeneratedDestructArray_4[1];\n", "start": 1520, "end": 1520 } @@ -565,7 +565,7 @@ "end": 1953 }, { - "replacementText": "a = GeneratedDestructObj_4.a;[c, d] = GeneratedDestructObj_4.b;", + "replacementText": "\na = GeneratedDestructObj_4.a;\n[c, d] = GeneratedDestructObj_4.b;\n", "start": 1954, "end": 1954 } @@ -597,7 +597,7 @@ "end": 2051 }, { - "replacementText": "a = GeneratedDestructObj_5.a;({\n s,\n c: [d, f],\n } = GeneratedDestructObj_5.b);", + "replacementText": "\na = GeneratedDestructObj_5.a;\n({\n s,\n c: [d, f],\n } = GeneratedDestructObj_5.b);\n", "start": 2052, "end": 2052 } @@ -739,7 +739,7 @@ "end": 2525 }, { - "replacementText": "a = GeneratedDestructObj_6.a;b = GeneratedDestructObj_6.b;s = GeneratedDestructObj_6.s;", + "replacementText": "\na = GeneratedDestructObj_6.a;\nb = GeneratedDestructObj_6.b;\ns = GeneratedDestructObj_6.s;\n", "start": 2526, "end": 2526 } diff --git a/ets2panda/linter/test/migrate/destructuring_assignments.sts b/ets2panda/linter/test/main/destructuring_assignments.ets.migrate.ets similarity index 41% rename from ets2panda/linter/test/migrate/destructuring_assignments.sts rename to ets2panda/linter/test/main/destructuring_assignments.ets.migrate.ets index e40bde0f0b0a549edd39b306d82eac6b9023019a..e3835ceaeb5a387819d4fc2906ff8c9b66e6a4dc 100644 --- a/ets2panda/linter/test/migrate/destructuring_assignments.sts +++ b/ets2panda/linter/test/main/destructuring_assignments.ets.migrate.ets @@ -16,22 +16,69 @@ // Object destructuring let a = 5, b = 10, c = 15, d = 20, s = 'foo'; let rest, rest2; -({ a, b, s } = { a: 100, b: 200, s: 'bar' }); // NOT OK +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: number; + s: string; +} +let GeneratedDestructObj_1: GeneratedObjectLiteralInterface_2 = { a: 100, b: 200, s: 'bar' }; +a = GeneratedDestructObj_1.a; +b = GeneratedDestructObj_1.b; +s = GeneratedDestructObj_1.s; + // NOT OK ({ a, b, s } = {}); // NOT OK, not fixable ({ a, ...rest } = { a: 1, b: 2 }); // NOT OK -({ a, b: { c, d: s } } = { a: 1, b: { c: 3, d: 'baz' }}); // NOT OK +interface GeneratedObjectLiteralInterface_3 { + c: number; + d: string; +} +interface GeneratedObjectLiteralInterface_6 { + a: number; + b: GeneratedObjectLiteralInterface_3; +} +let GeneratedDestructObj_2: GeneratedObjectLiteralInterface_6 = { a: 1, b: ({ c: 3, d: 'baz' } as GeneratedObjectLiteralInterface_3) }; +a = GeneratedDestructObj_2.a; +let GeneratedDestructObj_7 = GeneratedDestructObj_2.b; +c = GeneratedDestructObj_7.c; +s = GeneratedDestructObj_7.d; + + // NOT OK ({ a, b: { ...rest } } = { a: 1, b: { c: 3, d: 'bah' }}); // NOT OK +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: number; +} function getObject() { - return { a: 1, b: 2 }; + return ({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1); } -({ a, b } = getObject()); // NOT OK +let GeneratedDestructObj_3 = getObject(); +a = GeneratedDestructObj_3.a; +b = GeneratedDestructObj_3.b; + // NOT OK // Array destructuring -[a, b, c] = [10, 20, 30]; +let GeneratedDestructArray_1 = [10, 20, 30]; +a = GeneratedDestructArray_1[0]; +b = GeneratedDestructArray_1[1]; +c = GeneratedDestructArray_1[2]; + [a, b, c] = []; -[[a1, a2], [b1, b2], [c1, c2]] = [[1, 2], [3, 4], [5, 6]]; -[a, b] = [b, a]; +let GeneratedDestructArray_2 = [[1, 2], [3, 4], [5, 6]]; +a1 = GeneratedDestructArray_2[0][0]; +a2 = GeneratedDestructArray_2[0][1]; + +b1 = GeneratedDestructArray_2[1][0]; +b2 = GeneratedDestructArray_2[1][1]; + +c1 = GeneratedDestructArray_2[2][0]; +c2 = GeneratedDestructArray_2[2][1]; + + +let GeneratedDestructArray_3 = [b, a]; +a = GeneratedDestructArray_3[0]; +b = GeneratedDestructArray_3[1]; + [a, b, ...rest] = [10, 20, 30, 40, 50]; // NOT OK [a, b, [c, d]] = [10, 20, [300, 400], 50]; [a, b, [c, ...rest]] = [10, 20, [30, 40, 50]]; // NOT OK @@ -41,7 +88,10 @@ let tuple: [number, string, number] = [1, '2', 3]; [a, ...rest] = tuple; // NOT OK const getArray = (): number[] => [1, 2, 3]; -[a, b] = getArray(); +let GeneratedDestructArray_4 = getArray(); +a = GeneratedDestructArray_4[0]; +b = GeneratedDestructArray_4[1]; + const set: Set = new Set([1, 2, 3, 4]); [a, b, c] = set; // NOT OK @@ -50,19 +100,43 @@ const map: Map = new Map(); [[a, b], [c, d]] = map; // NOT OK // Mixed destructuring -let e: number, f: number, x: { e: number }, g; +interface GeneratedTypeLiteralInterface_1 { + e: number; +} +let e: number, f: number, x: GeneratedTypeLiteralInterface_1, g; [a, b, [x, { f }]] = [1, 2, [{ e: 20 }, { f: 5 }]]; // NOT OK [a, b, {e, e: f, ...g}] = [1, 2, {e: 10}]; // NOT OK [a, b, ...{length}] = [1, 2, {e: 10}]; // NOT OK -({ a, b : [c, d] } = { a: 1, b: [2, 3] }); // NOT OK -({ - a, - b: { - s, - c: [d, f], - }, -} = { a: 10, b: { s: 'foo', c: [30, 40] } }); // NOT OK +interface GeneratedObjectLiteralInterface_4 { + a: number; + b: number[]; +} +let GeneratedDestructObj_4: GeneratedObjectLiteralInterface_4 = { a: 1, b: [2, 3] }; +a = GeneratedDestructObj_4.a; +let GeneratedDestructArray_5 = GeneratedDestructObj_4.b; +c = GeneratedDestructArray_5[0]; +d = GeneratedDestructArray_5[1]; + + // NOT OK +interface GeneratedObjectLiteralInterface_5 { + s: string; + c: number[]; +} +interface GeneratedObjectLiteralInterface_7 { + a: number; + b: GeneratedObjectLiteralInterface_5; +} +let GeneratedDestructObj_5: GeneratedObjectLiteralInterface_7 = { a: 10, b: ({ s: 'foo', c: [30, 40] } as GeneratedObjectLiteralInterface_5) }; +a = GeneratedDestructObj_5.a; +let GeneratedDestructObj_8 = GeneratedDestructObj_5.b; +s = GeneratedDestructObj_8.s; +let GeneratedDestructArray_6 = GeneratedDestructObj_8.c; +d = GeneratedDestructArray_6[0]; +f = GeneratedDestructArray_6[1]; + + + // NOT OK // test for default value ({ a, b = 7, s } = { a: 100, b: 200, s: 'bar' }); // NOT OK @@ -84,5 +158,9 @@ class C { public s: string = "0000"; } -({ a, b, s } = new C()); // NOT OK +let GeneratedDestructObj_6 = new C(); +a = GeneratedDestructObj_6.a; +b = GeneratedDestructObj_6.b; +s = GeneratedDestructObj_6.s; + // NOT OK diff --git a/ets2panda/linter/test/migrate/destructuring_assignments.ts.json b/ets2panda/linter/test/main/destructuring_assignments.ets.migrate.json similarity index 60% rename from ets2panda/linter/test/migrate/destructuring_assignments.ts.json rename to ets2panda/linter/test/main/destructuring_assignments.ets.migrate.json index ed8cdee78e1e83178dd2042ac02b2e8ccdfa40a9..9627371dd3a363fc570da6be996be7096c2a38d5 100644 --- a/ets2panda/linter/test/migrate/destructuring_assignments.ts.json +++ b/ets2panda/linter/test/main/destructuring_assignments.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 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", @@ -35,29 +35,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 29, "column": 2, - "endLine": 19, - "endColumn": 44, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 16, - "endLine": 19, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 2, - "endLine": 20, + "endLine": 29, "endColumn": 18, "problem": "DestructuringAssignment", "suggest": "", @@ -65,9 +45,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 29, "column": 16, - "endLine": 20, + "endLine": 29, "endColumn": 17, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -75,9 +55,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 30, "column": 2, - "endLine": 21, + "endLine": 30, "endColumn": 33, "problem": "DestructuringAssignment", "suggest": "", @@ -85,9 +65,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 30, "column": 7, - "endLine": 21, + "endLine": 30, "endColumn": 14, "problem": "SpreadOperator", "suggest": "", @@ -95,9 +75,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 46, "column": 2, - "endLine": 22, + "endLine": 46, "endColumn": 56, "problem": "DestructuringAssignment", "suggest": "", @@ -105,39 +85,9 @@ "severity": "ERROR" }, { - "line": 22, - "column": 26, - "endLine": 22, - "endColumn": 27, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 37, - "endLine": 22, - "endColumn": 38, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 2, - "endLine": 23, - "endColumn": 56, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 23, + "line": 46, "column": 12, - "endLine": 23, + "endLine": 46, "endColumn": 19, "problem": "SpreadOperator", "suggest": "", @@ -145,9 +95,9 @@ "severity": "ERROR" }, { - "line": 23, + "line": 46, "column": 26, - "endLine": 23, + "endLine": 46, "endColumn": 27, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -155,39 +105,9 @@ "severity": "ERROR" }, { - "line": 26, - "column": 10, - "endLine": 26, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 2, - "endLine": 28, - "endColumn": 24, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 1, - "endLine": 31, - "endColumn": 25, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 32, + "line": 66, "column": 1, - "endLine": 32, + "endLine": 66, "endColumn": 15, "problem": "DestructuringAssignment", "suggest": "", @@ -195,29 +115,9 @@ "severity": "ERROR" }, { - "line": 33, - "column": 1, - "endLine": 33, - "endColumn": 58, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 16, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 35, + "line": 82, "column": 1, - "endLine": 35, + "endLine": 82, "endColumn": 39, "problem": "DestructuringAssignment", "suggest": "", @@ -225,9 +125,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 82, "column": 8, - "endLine": 35, + "endLine": 82, "endColumn": 15, "problem": "SpreadOperator", "suggest": "", @@ -235,9 +135,9 @@ "severity": "ERROR" }, { - "line": 36, + "line": 83, "column": 1, - "endLine": 36, + "endLine": 83, "endColumn": 42, "problem": "DestructuringAssignment", "suggest": "", @@ -245,9 +145,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 84, "column": 1, - "endLine": 37, + "endLine": 84, "endColumn": 46, "problem": "DestructuringAssignment", "suggest": "", @@ -255,9 +155,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 84, "column": 12, - "endLine": 37, + "endLine": 84, "endColumn": 19, "problem": "SpreadOperator", "suggest": "", @@ -265,9 +165,9 @@ "severity": "ERROR" }, { - "line": 40, + "line": 87, "column": 1, - "endLine": 40, + "endLine": 87, "endColumn": 17, "problem": "DestructuringAssignment", "suggest": "", @@ -275,9 +175,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 88, "column": 1, - "endLine": 41, + "endLine": 88, "endColumn": 21, "problem": "DestructuringAssignment", "suggest": "", @@ -285,9 +185,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 88, "column": 5, - "endLine": 41, + "endLine": 88, "endColumn": 12, "problem": "SpreadOperator", "suggest": "", @@ -295,19 +195,9 @@ "severity": "ERROR" }, { - "line": 44, - "column": 1, - "endLine": 44, - "endColumn": 20, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 47, + "line": 97, "column": 1, - "endLine": 47, + "endLine": 97, "endColumn": 16, "problem": "DestructuringAssignment", "suggest": "", @@ -315,9 +205,9 @@ "severity": "ERROR" }, { - "line": 50, + "line": 100, "column": 1, - "endLine": 50, + "endLine": 100, "endColumn": 23, "problem": "DestructuringAssignment", "suggest": "", @@ -325,29 +215,19 @@ "severity": "ERROR" }, { - "line": 53, - "column": 30, - "endLine": 53, - "endColumn": 31, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 45, - "endLine": 53, - "endColumn": 46, + "line": 106, + "column": 63, + "endLine": 106, + "endColumn": 64, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 54, + "line": 107, "column": 1, - "endLine": 54, + "endLine": 107, "endColumn": 51, "problem": "DestructuringAssignment", "suggest": "", @@ -355,9 +235,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 107, "column": 29, - "endLine": 54, + "endLine": 107, "endColumn": 50, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -365,19 +245,9 @@ "severity": "ERROR" }, { - "line": 54, - "column": 30, - "endLine": 54, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 54, + "line": 107, "column": 41, - "endLine": 54, + "endLine": 107, "endColumn": 42, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -385,9 +255,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 108, "column": 1, - "endLine": 55, + "endLine": 108, "endColumn": 42, "problem": "DestructuringAssignment", "suggest": "", @@ -395,9 +265,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 108, "column": 18, - "endLine": 55, + "endLine": 108, "endColumn": 22, "problem": "SpreadOperator", "suggest": "", @@ -405,9 +275,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 109, "column": 1, - "endLine": 56, + "endLine": 109, "endColumn": 38, "problem": "DestructuringAssignment", "suggest": "", @@ -415,9 +285,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 109, "column": 8, - "endLine": 56, + "endLine": 109, "endColumn": 19, "problem": "SpreadOperator", "suggest": "", @@ -425,9 +295,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 109, "column": 23, - "endLine": 56, + "endLine": 109, "endColumn": 38, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -435,9 +305,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 109, "column": 30, - "endLine": 56, + "endLine": 109, "endColumn": 31, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -445,59 +315,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 142, "column": 2, - "endLine": 58, - "endColumn": 41, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 22, - "endLine": 58, - "endColumn": 23, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 2, - "endLine": 65, - "endColumn": 44, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 5, - "endLine": 65, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 17, - "endLine": 65, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 2, - "endLine": 68, + "endLine": 142, "endColumn": 48, "problem": "DestructuringAssignment", "suggest": "", @@ -505,9 +325,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 142, "column": 20, - "endLine": 68, + "endLine": 142, "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -515,9 +335,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 143, "column": 2, - "endLine": 69, + "endLine": 143, "endColumn": 60, "problem": "DestructuringAssignment", "suggest": "", @@ -525,9 +345,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 143, "column": 30, - "endLine": 69, + "endLine": 143, "endColumn": 31, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -535,9 +355,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 143, "column": 41, - "endLine": 69, + "endLine": 143, "endColumn": 42, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -545,9 +365,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 144, "column": 2, - "endLine": 70, + "endLine": 144, "endColumn": 45, "problem": "DestructuringAssignment", "suggest": "", @@ -555,9 +375,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 144, "column": 26, - "endLine": 70, + "endLine": 144, "endColumn": 27, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -565,9 +385,9 @@ "severity": "ERROR" }, { - "line": 71, + "line": 145, "column": 2, - "endLine": 77, + "endLine": 151, "endColumn": 44, "problem": "DestructuringAssignment", "suggest": "", @@ -575,9 +395,9 @@ "severity": "ERROR" }, { - "line": 77, + "line": 151, "column": 5, - "endLine": 77, + "endLine": 151, "endColumn": 6, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -585,9 +405,9 @@ "severity": "ERROR" }, { - "line": 77, + "line": 151, "column": 17, - "endLine": 77, + "endLine": 151, "endColumn": 18, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -595,19 +415,9 @@ "severity": "ERROR" }, { - "line": 87, - "column": 2, - "endLine": 87, - "endColumn": 23, - "problem": "DestructuringAssignment", - "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", - "severity": "ERROR" - }, - { - "line": 32, + "line": 66, "column": 2, - "endLine": 32, + "endLine": 66, "endColumn": 3, "problem": "StrictDiagnostic", "suggest": "Type 'undefined' is not assignable to type 'number'.", @@ -615,9 +425,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 66, "column": 5, - "endLine": 32, + "endLine": 66, "endColumn": 6, "problem": "StrictDiagnostic", "suggest": "Type 'undefined' is not assignable to type 'number'.", @@ -625,9 +435,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 66, "column": 8, - "endLine": 32, + "endLine": 66, "endColumn": 9, "problem": "StrictDiagnostic", "suggest": "Type 'undefined' is not assignable to type 'number'.", diff --git a/ets2panda/linter/test/main/destructuring_declarations.ets.args.json b/ets2panda/linter/test/main/destructuring_declarations.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/destructuring_declarations.ets.args.json +++ b/ets2panda/linter/test/main/destructuring_declarations.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/destructuring_declarations.ets.autofix.json b/ets2panda/linter/test/main/destructuring_declarations.ets.autofix.json index a76a73dd10b390453eaa1b53f194f221ef49186a..d4bd32c57f76df7ce021a99f9d25acc816b8351e 100644 --- a/ets2panda/linter/test/main/destructuring_declarations.ets.autofix.json +++ b/ets2panda/linter/test/main/destructuring_declarations.ets.autofix.json @@ -27,7 +27,7 @@ "end": 644 }, { - "replacementText": "let a = GeneratedDestructObj_1.a;let b = GeneratedDestructObj_1.b;let c = GeneratedDestructObj_1.c;", + "replacementText": "\nlet a = GeneratedDestructObj_1.a;\nlet b = GeneratedDestructObj_1.b;\nlet c = GeneratedDestructObj_1.c;\n", "start": 676, "end": 676 } @@ -79,7 +79,7 @@ "end": 768 }, { - "replacementText": "let a3 = GeneratedDestructObj_2.a3;let { c3, d3: e3 } = GeneratedDestructObj_2.b3;", + "replacementText": "\nlet a3 = GeneratedDestructObj_2.a3;\nlet { c3, d3: e3 } = GeneratedDestructObj_2.b3;\n", "start": 806, "end": 806 } @@ -193,7 +193,7 @@ "end": 1007 }, { - "replacementText": "let a5 = GeneratedDestructObj_3.a5;let b5 = GeneratedDestructObj_3.b5;", + "replacementText": "\nlet a5 = GeneratedDestructObj_3.a5;\nlet b5 = GeneratedDestructObj_3.b5;\n", "start": 1022, "end": 1022 } @@ -215,7 +215,7 @@ "end": 1075 }, { - "replacementText": "const a6 = GeneratedDestructArray_1[0];const b6 = GeneratedDestructArray_1[1];const c6 = GeneratedDestructArray_1[2];", + "replacementText": "\nconst a6 = GeneratedDestructArray_1[0];\nconst b6 = GeneratedDestructArray_1[1];\nconst c6 = GeneratedDestructArray_1[2];\n", "start": 1091, "end": 1091 } @@ -267,7 +267,7 @@ "end": 1308 }, { - "replacementText": "const [a1, a2] = GeneratedDestructArray_2[0];const [b1, b2] = GeneratedDestructArray_2[1];const [c1, c2] = GeneratedDestructArray_2[2];", + "replacementText": "\nconst [a1, a2] = GeneratedDestructArray_2[0];\nconst [b1, b2] = GeneratedDestructArray_2[1];\nconst [c1, c2] = GeneratedDestructArray_2[2];\n", "start": 1336, "end": 1336 } @@ -289,7 +289,7 @@ "end": 1387 }, { - "replacementText": "const [a1, a2, a3] = GeneratedDestructArray_3[0];const [b1, b2, b3] = GeneratedDestructArray_3[1];const [c1, c2, c3] = GeneratedDestructArray_3[2];", + "replacementText": "\nconst [a1, a2, a3] = GeneratedDestructArray_3[0];\nconst [b1, b2, b3] = GeneratedDestructArray_3[1];\nconst [c1, c2, c3] = GeneratedDestructArray_3[2];\n", "start": 1424, "end": 1424 } @@ -331,7 +331,7 @@ "end": 1603 }, { - "replacementText": "let a12 = GeneratedDestructArray_4[0];let b12 = GeneratedDestructArray_4[1];", + "replacementText": "\nlet a12 = GeneratedDestructArray_4[0];\nlet b12 = GeneratedDestructArray_4[1];\n", "start": 1617, "end": 1617 } @@ -443,7 +443,7 @@ "end": 2055 }, { - "replacementText": "let a18 = GeneratedDestructObj_4.a18;let [c18, d18] = GeneratedDestructObj_4.b18;", + "replacementText": "\nlet a18 = GeneratedDestructObj_4.a18;\nlet [c18, d18] = GeneratedDestructObj_4.b18;\n", "start": 2082, "end": 2082 } @@ -475,7 +475,7 @@ "end": 2151 }, { - "replacementText": "let a19 = GeneratedDestructObj_5.a19;let {\n c19,\n d19: [e19, f19],\n } = GeneratedDestructObj_5.b19;", + "replacementText": "\nlet a19 = GeneratedDestructObj_5.a19;\nlet {\n c19,\n d19: [e19, f19],\n } = GeneratedDestructObj_5.b19;\n", "start": 2202, "end": 2202 } @@ -627,7 +627,7 @@ "end": 2760 }, { - "replacementText": "let a = GeneratedDestructObj_6.a;let b = GeneratedDestructObj_6.b;let s = GeneratedDestructObj_6.s;", + "replacementText": "\nlet a = GeneratedDestructObj_6.a;\nlet b = GeneratedDestructObj_6.b;\nlet s = GeneratedDestructObj_6.s;\n", "start": 2771, "end": 2771 } diff --git a/ets2panda/linter/test/migrate/destructuring_declarations.sts b/ets2panda/linter/test/main/destructuring_declarations.ets.migrate.ets similarity index 39% rename from ets2panda/linter/test/migrate/destructuring_declarations.sts rename to ets2panda/linter/test/main/destructuring_declarations.ets.migrate.ets index 0ee8cd35379733529fe19b9ed3020a994f28ba1d..709d135068231bf91f0bbf35e4fc4652cdecc2bc 100644 --- a/ets2panda/linter/test/migrate/destructuring_declarations.sts +++ b/ets2panda/linter/test/main/destructuring_declarations.ets.migrate.ets @@ -14,33 +14,93 @@ */ // Object destructuring -let { a, b, c } = { a: 100, b: 200, c: 'bar' }; // NOT OK +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: number; + c: string; +} +let GeneratedDestructObj_1: GeneratedObjectLiteralInterface_2 = { a: 100, b: 200, c: 'bar' }; +let a = GeneratedDestructObj_1.a; +let b = GeneratedDestructObj_1.b; +let c = GeneratedDestructObj_1.c; + // NOT OK let { a2, ...rest2 } = { a2: 1, b2: 2 }; // NOT OK -let { a3, b3: { c3, d3: e3 } } = { a3: 1, b3: { c3: 3, d3: 'baz' }}; // NOT OK +interface GeneratedObjectLiteralInterface_3 { + c3: number; + d3: string; +} +interface GeneratedObjectLiteralInterface_6 { + a3: number; + b3: GeneratedObjectLiteralInterface_3; +} +let GeneratedDestructObj_2: GeneratedObjectLiteralInterface_6 = { a3: 1, b3: ({ c3: 3, d3: 'baz' } as GeneratedObjectLiteralInterface_3)}; +let a3 = GeneratedDestructObj_2.a3; +let GeneratedDestructObj_7 = GeneratedDestructObj_2.b3; +let c3 = GeneratedDestructObj_7.c3; +let e3 = GeneratedDestructObj_7.d3; + + // NOT OK let { a4, b4: { ...rest4 } } = { a4: 1, b4: { c4: 3, d4: 'bah' }}; // NOT OK let { a, b, c } = {}; // NOT OK, not fixable +interface GeneratedObjectLiteralInterface_1 { + a5: number; + b5: number; +} function getObject() { - return { a5: 1, b5: 2 }; + return ({ a5: 1, b5: 2 } as GeneratedObjectLiteralInterface_1); } -let { a5, b5 } = getObject(); // NOT OK +let GeneratedDestructObj_3 = getObject(); +let a5 = GeneratedDestructObj_3.a5; +let b5 = GeneratedDestructObj_3.b5; + // NOT OK // Array destructuring -const [a6, b6, c6] = [10, 20, 30]; +const GeneratedDestructArray_1 = [10, 20, 30]; +const a6 = GeneratedDestructArray_1[0]; +const b6 = GeneratedDestructArray_1[1]; +const c6 = GeneratedDestructArray_1[2]; + const [a7, b7, ...rest7] = [10, 20, 30, 40, 50]; // NOT OK const [a8, b8, [c8, e8]] = [10, 20, [300, 400], 50]; const [a9, b9, [c9, ...rest9]] = [10, 20, [30, 40, 50]]; // NOT OK -const [[a1, a2], [b1, b2], [c1, c2]] = [[1, 2], [3, 4], [5, 6]]; -const [[a1, a2, a3], [b1, b2, b3], [c1, c2, c3]] = [[1, 2, 3], [3, 4, 5], [5, 6, 7]]; +const GeneratedDestructArray_2 = [[1, 2], [3, 4], [5, 6]]; +const a1 = GeneratedDestructArray_2[0][0]; +const a2 = GeneratedDestructArray_2[0][1]; + +const b1 = GeneratedDestructArray_2[1][0]; +const b2 = GeneratedDestructArray_2[1][1]; + +const c1 = GeneratedDestructArray_2[2][0]; +const c2 = GeneratedDestructArray_2[2][1]; + + +const GeneratedDestructArray_3 = [[1, 2, 3], [3, 4, 5], [5, 6, 7]]; +const a1 = GeneratedDestructArray_3[0][0]; +const a2 = GeneratedDestructArray_3[0][1]; +const a3 = GeneratedDestructArray_3[0][2]; + +const b1 = GeneratedDestructArray_3[1][0]; +const b2 = GeneratedDestructArray_3[1][1]; +const b3 = GeneratedDestructArray_3[1][2]; + +const c1 = GeneratedDestructArray_3[2][0]; +const c2 = GeneratedDestructArray_3[2][1]; +const c3 = GeneratedDestructArray_3[2][2]; + + let tuple: [number, string, number] = [1, '2', 3]; let [a10, , b10] = tuple; let [a11, ...rest11] = tuple; // NOT OK const getArray = (): number[] => [1, 2, 3]; -let [a12, b12] = getArray(); +let GeneratedDestructArray_4 = getArray(); +let a12 = GeneratedDestructArray_4[0]; +let b12 = GeneratedDestructArray_4[1]; + const set: Set = new Set([1, 2, 3, 4]); let [a13, b13, c13] = set; // NOT OK @@ -53,14 +113,35 @@ let [a15, b15, [x15, { f15 }]] = [1, 2, [{ e15: 20 }, { f15: 5 }]]; // NOT OK let [a16, b16, {e16, e16: f16, ...g16}] = [1, 2, {e16: 10}]; // NOT OK { let [a17, b17, ...{length}] = [1, 2, 3, 4]; } // NOT OK -let { a18, b18: [c18, d18] } = { a18: 1, b18: [2, 3] }; // NOT OK -let { - a19, - b19: { - c19, - d19: [e19, f19], - }, -} = { a19: 10, b19: { c19: 'foo', d19: [30, 40] } }; // NOT OK +interface GeneratedObjectLiteralInterface_4 { + a18: number; + b18: number[]; +} +let GeneratedDestructObj_4: GeneratedObjectLiteralInterface_4 = { a18: 1, b18: [2, 3] }; +let a18 = GeneratedDestructObj_4.a18; +let GeneratedDestructArray_5 = GeneratedDestructObj_4.b18; +let c18 = GeneratedDestructArray_5[0]; +let d18 = GeneratedDestructArray_5[1]; + + // NOT OK +interface GeneratedObjectLiteralInterface_5 { + c19: string; + d19: number[]; +} +interface GeneratedObjectLiteralInterface_7 { + a19: number; + b19: GeneratedObjectLiteralInterface_5; +} +let GeneratedDestructObj_5: GeneratedObjectLiteralInterface_7 = { a19: 10, b19: ({ c19: 'foo', d19: [30, 40] } as GeneratedObjectLiteralInterface_5) }; +let a19 = GeneratedDestructObj_5.a19; +let GeneratedDestructObj_8 = GeneratedDestructObj_5.b19; +let c19 = GeneratedDestructObj_8.c19; +let GeneratedDestructArray_6 = GeneratedDestructObj_8.d19; +let e19 = GeneratedDestructArray_6[0]; +let f19 = GeneratedDestructArray_6[1]; + + + // NOT OK // test for default value let { a, b, c = 9 } = { a: 100, b: 200, c: 'bar' }; // NOT OK @@ -82,4 +163,8 @@ class C { public s: string = "0000"; } -let { a, b, s } = new C(); // NOT OK \ No newline at end of file +let GeneratedDestructObj_6 = new C(); +let a = GeneratedDestructObj_6.a; +let b = GeneratedDestructObj_6.b; +let s = GeneratedDestructObj_6.s; + // NOT OK \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/destructuring_declarations.ts.json b/ets2panda/linter/test/main/destructuring_declarations.ets.migrate.json similarity index 58% rename from ets2panda/linter/test/migrate/destructuring_declarations.ts.json rename to ets2panda/linter/test/main/destructuring_declarations.ets.migrate.json index 2d0805cb0e52a24340c998044c01d4b1f28ed45c..825250c726041e35485f461b596bf9bf4b0d7b0c 100644 --- a/ets2panda/linter/test/migrate/destructuring_declarations.ts.json +++ b/ets2panda/linter/test/main/destructuring_declarations.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 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", @@ -15,29 +15,9 @@ ], "result": [ { - "line": 17, - "column": 5, - "endLine": 17, - "endColumn": 47, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 19, - "endLine": 17, - "endColumn": 20, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 18, + "line": 27, "column": 5, - "endLine": 18, + "endLine": 27, "endColumn": 40, "problem": "DestructuringDeclaration", "suggest": "", @@ -45,9 +25,9 @@ "severity": "ERROR" }, { - "line": 18, + "line": 27, "column": 24, - "endLine": 18, + "endLine": 27, "endColumn": 25, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -55,39 +35,9 @@ "severity": "ERROR" }, { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 68, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 34, - "endLine": 19, - "endColumn": 35, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 47, - "endLine": 19, - "endColumn": 48, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 20, + "line": 43, "column": 5, - "endLine": 20, + "endLine": 43, "endColumn": 66, "problem": "DestructuringDeclaration", "suggest": "", @@ -95,9 +45,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 43, "column": 32, - "endLine": 20, + "endLine": 43, "endColumn": 33, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -105,9 +55,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 43, "column": 45, - "endLine": 20, + "endLine": 43, "endColumn": 46, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -115,9 +65,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 45, "column": 5, - "endLine": 22, + "endLine": 45, "endColumn": 21, "problem": "DestructuringDeclaration", "suggest": "", @@ -125,9 +75,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 45, "column": 19, - "endLine": 22, + "endLine": 45, "endColumn": 20, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -135,39 +85,9 @@ "severity": "ERROR" }, { - "line": 25, - "column": 10, - "endLine": 25, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 27, - "column": 5, - "endLine": 27, - "endColumn": 29, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 30, + "line": 65, "column": 7, - "endLine": 30, - "endColumn": 34, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 7, - "endLine": 31, + "endLine": 65, "endColumn": 48, "problem": "DestructuringDeclaration", "suggest": "", @@ -175,9 +95,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 66, "column": 7, - "endLine": 32, + "endLine": 66, "endColumn": 52, "problem": "DestructuringDeclaration", "suggest": "", @@ -185,9 +105,9 @@ "severity": "ERROR" }, { - "line": 33, + "line": 67, "column": 7, - "endLine": 33, + "endLine": 67, "endColumn": 56, "problem": "DestructuringDeclaration", "suggest": "", @@ -195,29 +115,9 @@ "severity": "ERROR" }, { - "line": 35, - "column": 7, - "endLine": 35, - "endColumn": 64, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 7, - "endLine": 36, - "endColumn": 85, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 39, + "line": 96, "column": 5, - "endLine": 39, + "endLine": 96, "endColumn": 25, "problem": "DestructuringDeclaration", "suggest": "", @@ -225,9 +125,9 @@ "severity": "ERROR" }, { - "line": 40, + "line": 97, "column": 5, - "endLine": 40, + "endLine": 97, "endColumn": 29, "problem": "DestructuringDeclaration", "suggest": "", @@ -235,19 +135,9 @@ "severity": "ERROR" }, { - "line": 43, - "column": 5, - "endLine": 43, - "endColumn": 28, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 46, + "line": 106, "column": 5, - "endLine": 46, + "endLine": 106, "endColumn": 26, "problem": "DestructuringDeclaration", "suggest": "", @@ -255,9 +145,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 109, "column": 5, - "endLine": 49, + "endLine": 109, "endColumn": 35, "problem": "DestructuringDeclaration", "suggest": "", @@ -265,9 +155,9 @@ "severity": "ERROR" }, { - "line": 52, + "line": 112, "column": 5, - "endLine": 52, + "endLine": 112, "endColumn": 67, "problem": "DestructuringDeclaration", "suggest": "", @@ -275,9 +165,9 @@ "severity": "ERROR" }, { - "line": 52, + "line": 112, "column": 41, - "endLine": 52, + "endLine": 112, "endColumn": 66, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -285,9 +175,9 @@ "severity": "ERROR" }, { - "line": 52, + "line": 112, "column": 55, - "endLine": 52, + "endLine": 112, "endColumn": 56, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -295,9 +185,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 113, "column": 5, - "endLine": 53, + "endLine": 113, "endColumn": 60, "problem": "DestructuringDeclaration", "suggest": "", @@ -305,9 +195,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 113, "column": 43, - "endLine": 53, + "endLine": 113, "endColumn": 60, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -315,9 +205,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 113, "column": 50, - "endLine": 53, + "endLine": 113, "endColumn": 51, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -325,9 +215,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 114, "column": 7, - "endLine": 54, + "endLine": 114, "endColumn": 45, "problem": "DestructuringDeclaration", "suggest": "", @@ -335,59 +225,9 @@ "severity": "ERROR" }, { - "line": 56, - "column": 5, - "endLine": 56, - "endColumn": 55, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 32, - "endLine": 56, - "endColumn": 33, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 5, - "endLine": 63, - "endColumn": 52, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 5, - "endLine": 63, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 21, - "endLine": 63, - "endColumn": 22, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 66, + "line": 147, "column": 5, - "endLine": 66, + "endLine": 147, "endColumn": 51, "problem": "DestructuringDeclaration", "suggest": "", @@ -395,9 +235,9 @@ "severity": "ERROR" }, { - "line": 66, + "line": 147, "column": 23, - "endLine": 66, + "endLine": 147, "endColumn": 24, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -405,9 +245,9 @@ "severity": "ERROR" }, { - "line": 67, + "line": 148, "column": 5, - "endLine": 67, + "endLine": 148, "endColumn": 73, "problem": "DestructuringDeclaration", "suggest": "", @@ -415,9 +255,9 @@ "severity": "ERROR" }, { - "line": 67, + "line": 148, "column": 39, - "endLine": 67, + "endLine": 148, "endColumn": 40, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -425,9 +265,9 @@ "severity": "ERROR" }, { - "line": 67, + "line": 148, "column": 52, - "endLine": 67, + "endLine": 148, "endColumn": 53, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -435,9 +275,9 @@ "severity": "ERROR" }, { - "line": 68, + "line": 149, "column": 5, - "endLine": 68, + "endLine": 149, "endColumn": 33, "problem": "DestructuringDeclaration", "suggest": "", @@ -445,9 +285,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 150, "column": 5, - "endLine": 69, + "endLine": 150, "endColumn": 60, "problem": "DestructuringDeclaration", "suggest": "", @@ -455,9 +295,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 150, "column": 37, - "endLine": 69, + "endLine": 150, "endColumn": 38, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -465,9 +305,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 151, "column": 5, - "endLine": 76, + "endLine": 157, "endColumn": 52, "problem": "DestructuringDeclaration", "suggest": "", @@ -475,9 +315,9 @@ "severity": "ERROR" }, { - "line": 76, + "line": 157, "column": 5, - "endLine": 76, + "endLine": 157, "endColumn": 6, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -485,24 +325,14 @@ "severity": "ERROR" }, { - "line": 76, + "line": 157, "column": 21, - "endLine": 76, + "endLine": 157, "endColumn": 22, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" - }, - { - "line": 85, - "column": 5, - "endLine": 85, - "endColumn": 26, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_parameters.ets b/ets2panda/linter/test/main/destructuring_parameters.ets index 0c4fdc6492320a265053803f3ae5f48ea60b3f7d..fca184f73146bf77a2aefead9b15391eae93d7e0 100644 --- a/ets2panda/linter/test/main/destructuring_parameters.ets +++ b/ets2panda/linter/test/main/destructuring_parameters.ets @@ -13,6 +13,8 @@ * limitations under the License. */ +// issue: 24982: Enable 'autofix' mode for this test to ensure it finishes without crashing + function drawText({ text = '', position: [x, y] = [0, 0] }): void { // NOT OK // Draw text } diff --git a/ets2panda/linter/test/migrate/class_static_block.ts.args.json b/ets2panda/linter/test/main/destructuring_parameters.ets.args.json similarity index 90% rename from ets2panda/linter/test/migrate/class_static_block.ts.args.json rename to ets2panda/linter/test/main/destructuring_parameters.ets.args.json index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/migrate/class_static_block.ts.args.json +++ b/ets2panda/linter/test/main/destructuring_parameters.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { + "autofix": "", "migrate": "" } } diff --git a/ets2panda/linter/test/main/destructuring_parameters.ets.autofix.json b/ets2panda/linter/test/main/destructuring_parameters.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..3783eb31801f297b23fd344e02236f77e3696078 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_parameters.ets.autofix.json @@ -0,0 +1,304 @@ +{ + "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": 18, + "column": 19, + "endLine": 18, + "endColumn": 59, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 16, + "endLine": 29, + "endColumn": 2, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 4, + "endLine": 26, + "endColumn": 5, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 846, + "end": 846, + "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n firstName: string;\n lastName: string;\n}\n" + }, + { + "start": 901, + "end": 945, + "replacementText": "GeneratedTypeLiteralInterface_1" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 19, + "endLine": 30, + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 16, + "endLine": 32, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 1055, + "end": 1055, + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n firstName: string;\n lastName: string;\n}\n" + }, + { + "start": 1067, + "end": 1067, + "replacementText": ": GeneratedObjectLiteralInterface_1" + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 13, + "endLine": 39, + "endColumn": 23, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 33, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 22, + "endLine": 43, + "endColumn": 23, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 1219, + "end": 1219, + "replacementText": "interface GeneratedTypeLiteralInterface_2 {\n d: number;\n}\n" + }, + { + "start": 1240, + "end": 1251, + "replacementText": "GeneratedTypeLiteralInterface_2" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 4, + "endLine": 45, + "endColumn": 5, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 13, + "endLine": 47, + "endColumn": 22, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 46, + "endLine": 49, + "endColumn": 50, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 4, + "endLine": 51, + "endColumn": 5, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 13, + "endLine": 53, + "endColumn": 19, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 13, + "endLine": 58, + "endColumn": 29, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 13, + "endLine": 63, + "endColumn": 24, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 13, + "endLine": 68, + "endColumn": 25, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 13, + "endLine": 73, + "endColumn": 30, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 13, + "endLine": 78, + "endColumn": 24, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 4, + "endLine": 81, + "endColumn": 21, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 8, + "endLine": 81, + "endColumn": 9, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 14, + "endLine": 83, + "endColumn": 36, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 9, + "endLine": 86, + "endColumn": 27, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 13, + "endLine": 86, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 14, + "endLine": 88, + "endColumn": 33, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/destructuring_parameters.ets.json b/ets2panda/linter/test/main/destructuring_parameters.ets.json index ba3275b467a8994657e293b88218f1a6b9392afb..eadaa87a97ddc11b2f22715afd94b34f73557916 100644 --- a/ets2panda/linter/test/main/destructuring_parameters.ets.json +++ b/ets2panda/linter/test/main/destructuring_parameters.ets.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 16, + "line": 18, "column": 19, - "endLine": 16, + "endLine": 18, "endColumn": 59, "problem": "DestructuringParameter", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 21, "column": 10, - "endLine": 19, + "endLine": 21, "endColumn": 11, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 23, "column": 16, - "endLine": 27, + "endLine": 29, "endColumn": 2, "problem": "DestructuringParameter", "suggest": "", @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 24, + "line": 26, "column": 4, - "endLine": 24, + "endLine": 26, "endColumn": 5, "problem": "ObjectTypeLiteral", "suggest": "", @@ -55,9 +55,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 30, "column": 19, - "endLine": 28, + "endLine": 30, "endColumn": 20, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -65,9 +65,9 @@ "severity": "ERROR" }, { - "line": 30, + "line": 32, "column": 16, - "endLine": 30, + "endLine": 32, "endColumn": 17, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -75,9 +75,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 39, "column": 13, - "endLine": 37, + "endLine": 39, "endColumn": 23, "problem": "DestructuringParameter", "suggest": "", @@ -85,9 +85,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 43, "column": 13, - "endLine": 41, + "endLine": 43, "endColumn": 33, "problem": "DestructuringParameter", "suggest": "", @@ -95,9 +95,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 43, "column": 22, - "endLine": 41, + "endLine": 43, "endColumn": 23, "problem": "ObjectTypeLiteral", "suggest": "", @@ -105,9 +105,9 @@ "severity": "ERROR" }, { - "line": 43, + "line": 45, "column": 4, - "endLine": 43, + "endLine": 45, "endColumn": 5, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -115,9 +115,9 @@ "severity": "ERROR" }, { - "line": 45, + "line": 47, "column": 13, - "endLine": 45, + "endLine": 47, "endColumn": 22, "problem": "DestructuringParameter", "suggest": "", @@ -125,9 +125,9 @@ "severity": "ERROR" }, { - "line": 47, + "line": 49, "column": 46, - "endLine": 47, + "endLine": 49, "endColumn": 50, "problem": "PropertyAccessByIndex", "suggest": "", @@ -135,9 +135,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 51, "column": 4, - "endLine": 49, + "endLine": 51, "endColumn": 5, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -145,9 +145,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 53, "column": 13, - "endLine": 51, + "endLine": 53, "endColumn": 19, "problem": "DestructuringParameter", "suggest": "", @@ -155,9 +155,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 58, "column": 13, - "endLine": 56, + "endLine": 58, "endColumn": 29, "problem": "DestructuringParameter", "suggest": "", @@ -165,9 +165,9 @@ "severity": "ERROR" }, { - "line": 61, + "line": 63, "column": 13, - "endLine": 61, + "endLine": 63, "endColumn": 24, "problem": "DestructuringParameter", "suggest": "", @@ -175,9 +175,9 @@ "severity": "ERROR" }, { - "line": 66, + "line": 68, "column": 13, - "endLine": 66, + "endLine": 68, "endColumn": 25, "problem": "DestructuringParameter", "suggest": "", @@ -185,9 +185,9 @@ "severity": "ERROR" }, { - "line": 71, + "line": 73, "column": 13, - "endLine": 71, + "endLine": 73, "endColumn": 30, "problem": "DestructuringParameter", "suggest": "", @@ -195,9 +195,9 @@ "severity": "ERROR" }, { - "line": 76, + "line": 78, "column": 13, - "endLine": 76, + "endLine": 78, "endColumn": 24, "problem": "DestructuringParameter", "suggest": "", @@ -205,9 +205,9 @@ "severity": "ERROR" }, { - "line": 79, + "line": 81, "column": 4, - "endLine": 79, + "endLine": 81, "endColumn": 21, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -215,9 +215,9 @@ "severity": "ERROR" }, { - "line": 79, + "line": 81, "column": 8, - "endLine": 79, + "endLine": 81, "endColumn": 9, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -225,9 +225,9 @@ "severity": "ERROR" }, { - "line": 81, + "line": 83, "column": 14, - "endLine": 81, + "endLine": 83, "endColumn": 36, "problem": "DestructuringParameter", "suggest": "", @@ -235,9 +235,9 @@ "severity": "ERROR" }, { - "line": 84, + "line": 86, "column": 9, - "endLine": 84, + "endLine": 86, "endColumn": 27, "problem": "ArrayLiteralNoContextType", "suggest": "", @@ -245,9 +245,9 @@ "severity": "ERROR" }, { - "line": 84, + "line": 86, "column": 13, - "endLine": 84, + "endLine": 86, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -255,9 +255,9 @@ "severity": "ERROR" }, { - "line": 86, + "line": 88, "column": 14, - "endLine": 86, + "endLine": 88, "endColumn": 33, "problem": "DestructuringParameter", "suggest": "", diff --git a/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.ets b/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5c3acdce95dc7db6cc20be549fe097b2f92fe553 --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.ets @@ -0,0 +1,99 @@ +/* + * 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. + */ + +// issue: 24982: Enable 'autofix' mode for this test to ensure it finishes without crashing + +function drawText({ text = '', position: [x, y] = [0, 0] }): void { // NOT OK + // Draw text +} +drawText({ text: 'Figure 1', position: [10, 20] }); + +interface GeneratedTypeLiteralInterface_1 { + firstName: string; + lastName: string; +} +const hello = ({ // NOT OK + firstName, + lastName, +}: GeneratedTypeLiteralInterface_1): string => `Hello ${firstName} ${lastName}`; +console.log(hello({ firstName: 'Karl', lastName: 'Marks' })); + +interface GeneratedObjectLiteralInterface_1 { + firstName: string; + lastName: string; +} +const person: GeneratedObjectLiteralInterface_1 = { firstName: 'Adam', lastName: 'Smith' }; +console.log(hello(person)); + +interface I { + d: number +} + +function f1({d = 1}: I) { // NOT OK +} +f1({d:2}) + +interface GeneratedTypeLiteralInterface_2 { + d: number; +} +function f2({d = 1}: GeneratedTypeLiteralInterface_2) { // NOT OK +} +f2({d:2}) + +function f3({x, ...y}) { // NOT OK + console.log(x); + Object.keys(y).forEach(k => console.log(k, y[k])) +} +f3({x: 1, b: 2, c: 3}) + +function f4([a, b]): void { + console.log(a, b); +} +f4(['Hello', 'Wolrd']); + +function f5([a, b]: number[]): void { + console.log(a, b); +} +f5([1, 2, 3]); + +function f6([a, [b, c]]): void { + console.log(a, b, c); +} +f6([1, [2, 3]]); + +function f7([a, b, ...c]) { // NOT OK + console.log(a, b, c); +} +f7([1, 2, 3, 4]) + +function f8([a, b, [c, ...d]]) { // NOT OK + console.log(a, b, c, d); +} +f8([1, 2, [3, 4, 5]]) + +function f9([a, {b, c}]): void { // NOT OK + console.log(a, b, c); +} +f9([1, {b: 2, c: 3}]); + +function f10([a, [b, {c: d, e: f}]]): void { // NOT OK + console.log(a, b, d, f); +} +f10([1, [2, {c : 3, e: 4}]]); + +function f11([a, b]: Set): void { // NOT OK + console.log(a, b); +} +f11(new Set([1, 2, 3, 4])); diff --git a/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.json b/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca33c3f4997e9e606c510232135028e2e085f00a --- /dev/null +++ b/ets2panda/linter/test/main/destructuring_parameters.ets.migrate.json @@ -0,0 +1,228 @@ +{ + "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": 18, + "column": 19, + "endLine": 18, + "endColumn": 59, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 16, + "endLine": 30, + "endColumn": 35, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 19, + "endLine": 38, + "endColumn": 25, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 13, + "endLine": 44, + "endColumn": 23, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 13, + "endLine": 51, + "endColumn": 53, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 13, + "endLine": 55, + "endColumn": 22, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 46, + "endLine": 57, + "endColumn": 50, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 4, + "endLine": 59, + "endColumn": 5, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 13, + "endLine": 61, + "endColumn": 19, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 13, + "endLine": 66, + "endColumn": 29, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 13, + "endLine": 71, + "endColumn": 24, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 13, + "endLine": 76, + "endColumn": 25, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 13, + "endLine": 81, + "endColumn": 30, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 13, + "endLine": 86, + "endColumn": 24, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 4, + "endLine": 89, + "endColumn": 21, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 8, + "endLine": 89, + "endColumn": 9, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 14, + "endLine": 91, + "endColumn": 36, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 9, + "endLine": 94, + "endColumn": 27, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 13, + "endLine": 94, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 14, + "endLine": 96, + "endColumn": 33, + "problem": "DestructuringParameter", + "suggest": "", + "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets b/ets2panda/linter/test/main/dollar_binding_1.ets index dc21222d0f1f30e8e61f13be21a33b330e0c078e..e2b25273dab296827be248c4ec6c4558665f0ba3 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets +++ b/ets2panda/linter/test/main/dollar_binding_1.ets @@ -16,18 +16,24 @@ @Component struct MyComponent { @State count: number = 0 + @State $$: number = 0 + build() { Column() { MyCounter({ count: $count }) + MyCounter({ + count: $$$ + }) } } } @Component struct MyCounter { - @Link count: number; + @Link count: number + build() { Row() { Text(`${this.count}`) diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.args.json b/ets2panda/linter/test/main/dollar_binding_1.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets.args.json +++ b/ets2panda/linter/test/main/dollar_binding_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json b/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json index a182150903283296b2e33b01003cf32f2e3a4f33..674cd0d86840389cbd363d0f9601084eb9f32331 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/dollar_binding_1.ets.arkts2.json @@ -1,29 +1,59 @@ { "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 (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, + "line": 18, + "column": 26, + "endLine": 18, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 23, + "endLine": 19, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, "column": 9, - "endLine": 22, + "endLine": 24, "endColumn": 22, "problem": "DollarBindingNotSupported", "suggest": "", "rule": "\"${variable}\" for decorator binding is not supported (arkui-link-decorator-passing)", "severity": "ERROR" }, + { + "line": 27, + "column": 9, + "endLine": 27, + "endColumn": 19, + "problem": "DollarBindingNotSupported", + "suggest": "", + "rule": "\"${variable}\" for decorator binding is not supported (arkui-link-decorator-passing)", + "severity": "ERROR" + }, { "line": 16, "column": 2, @@ -45,9 +75,29 @@ "severity": "ERROR" }, { - "line": 20, + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, "column": 5, - "endLine": 20, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 2, + "endLine": 33, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -55,9 +105,9 @@ "severity": "ERROR" }, { - "line": 30, + "line": 35, "column": 4, - "endLine": 30, + "endLine": 35, "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", @@ -65,9 +115,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 38, "column": 5, - "endLine": 32, + "endLine": 38, "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", @@ -75,9 +125,9 @@ "severity": "ERROR" }, { - "line": 33, + "line": 39, "column": 7, - "endLine": 33, + "endLine": 39, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.autofix.json b/ets2panda/linter/test/main/dollar_binding_1.ets.autofix.json index 3f59e4315778c3057f714a16e02ad268e019ba28..3081866ef6d24a3931db204b35cdb51f8e98e37d 100644 --- a/ets2panda/linter/test/main/dollar_binding_1.ets.autofix.json +++ b/ets2panda/linter/test/main/dollar_binding_1.ets.autofix.json @@ -1,30 +1,97 @@ { "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 (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, + "line": 18, + "column": 26, + "endLine": 18, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 662, + "end": 663, + "replacementText": "0.0", + "line": 18, + "column": 26, + "endLine": 18, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 23, + "endLine": 19, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 686, + "end": 687, + "replacementText": "0.0", + "line": 19, + "column": 23, + "endLine": 19, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, "column": 9, - "endLine": 22, + "endLine": 24, "endColumn": 22, "problem": "DollarBindingNotSupported", "autofix": [ { - "start": 724, - "end": 730, - "replacementText": "this.count" + "start": 749, + "end": 755, + "replacementText": "this.count", + "line": 24, + "column": 9, + "endLine": 24, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "\"${variable}\" for decorator binding is not supported (arkui-link-decorator-passing)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 9, + "endLine": 27, + "endColumn": 19, + "problem": "DollarBindingNotSupported", + "autofix": [ + { + "start": 798, + "end": 801, + "replacementText": "this.$$", + "line": 27, + "column": 9, + "endLine": 27, + "endColumn": 19 } ], "suggest": "", @@ -37,6 +104,17 @@ "endLine": 16, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -47,51 +125,141 @@ "endLine": 18, "endColumn": 9, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 20, + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, "column": 5, - "endLine": 20, + "endLine": 22, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 30, + "line": 33, + "column": 2, + "endLine": 33, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, "column": 4, - "endLine": 30, + "endLine": 35, "endColumn": 8, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 32, + "line": 38, "column": 5, - "endLine": 32, + "endLine": 38, "endColumn": 8, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 33, + "line": 39, "column": 7, - "endLine": 33, + "endLine": 39, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kits.ArkUI';" + "replacementText": "\n\nimport { Component, State, Column, Link, Row, Text } from '@kit.ArkUI';", + "line": 39, + "column": 7, + "endLine": 39, + "endColumn": 11 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets b/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..aa775da121c3210d3ed6bc36d0baf3c98307ef12 --- /dev/null +++ b/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.ets @@ -0,0 +1,44 @@ +/* + * 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 { Component, State, Column, Link, Row, Text } from '@kit.ArkUI'; + +@Component +struct MyComponent { + @State count: number = 0.0 + @State $$: number = 0.0 + + build() { + Column() { + MyCounter({ + count: this.count + }) + MyCounter({ + count: this.$$ + }) + } + } +} + +@Component +struct MyCounter { + @Link count: number + + build() { + Row() { + Text(`${this.count}`) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.json b/ets2panda/linter/test/main/dollar_binding_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/dollar_binding_1.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 diff --git a/ets2panda/linter/test/main/dollar_binding_2.ets b/ets2panda/linter/test/main/dollar_binding_2.ets index 022416bfb94153ce5f2858e13ae66b0c9489a035..244e4156a9e756c896fa0c9356ae003bee616597 100644 --- a/ets2panda/linter/test/main/dollar_binding_2.ets +++ b/ets2panda/linter/test/main/dollar_binding_2.ets @@ -13,23 +13,29 @@ * limitations under the License. */ -import { Component, State, Column, Link, Row, Text } from '@kits.ArkUI'; +import { Component, State, Column, Link, Row, Text } from '@kit.ArkUI'; @Component struct MyComponent { @State count: number = 0 + @State $$: number = 0 + build() { Column() { MyCounter({ count: this.count }) + MyCounter({ + count: this.$$ + }) } } } @Component struct MyCounter { - @Link count: number; + @Link count: number + build() { Row() { Text(`${this.count}`) diff --git a/ets2panda/linter/test/main/dollar_binding_2.ets.args.json b/ets2panda/linter/test/main/dollar_binding_2.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/dollar_binding_2.ets.args.json +++ b/ets2panda/linter/test/main/dollar_binding_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_2.ets.arkts2.json b/ets2panda/linter/test/main/dollar_binding_2.ets.arkts2.json index ca88f857e960b437dcf767c0ac40be998c8f1236..1ac9993dfe8c6eafc3692ac0dcc695a8dffd4bbd 100644 --- a/ets2panda/linter/test/main/dollar_binding_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/dollar_binding_2.ets.arkts2.json @@ -13,5 +13,26 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 23, + "endLine": 21, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_2.ets.autofix.json b/ets2panda/linter/test/main/dollar_binding_2.ets.autofix.json index ca88f857e960b437dcf767c0ac40be998c8f1236..89c63ca3e5c602e88ccf13990048ecd4ec0fbaca 100644 --- a/ets2panda/linter/test/main/dollar_binding_2.ets.autofix.json +++ b/ets2panda/linter/test/main/dollar_binding_2.ets.autofix.json @@ -13,5 +13,48 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 735, + "end": 736, + "replacementText": "0.0", + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 23, + "endLine": 21, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 759, + "end": 760, + "replacementText": "0.0", + "line": 21, + "column": 23, + "endLine": 21, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_2.ets.migrate.ets b/ets2panda/linter/test/main/dollar_binding_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..aa775da121c3210d3ed6bc36d0baf3c98307ef12 --- /dev/null +++ b/ets2panda/linter/test/main/dollar_binding_2.ets.migrate.ets @@ -0,0 +1,44 @@ +/* + * 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 { Component, State, Column, Link, Row, Text } from '@kit.ArkUI'; + +@Component +struct MyComponent { + @State count: number = 0.0 + @State $$: number = 0.0 + + build() { + Column() { + MyCounter({ + count: this.count + }) + MyCounter({ + count: this.$$ + }) + } + } +} + +@Component +struct MyCounter { + @Link count: number + + build() { + Row() { + Text(`${this.count}`) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/dollar_binding_2.ets.migrate.json b/ets2panda/linter/test/main/dollar_binding_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/dollar_binding_2.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 diff --git a/ets2panda/linter/test/main/double_dollar_binding_1.ets b/ets2panda/linter/test/main/double_dollar_binding_1.ets index 53dce1a70c06e06cb2ee4e030f13f29bb60f935f..37be34c3bf138a9820ebab82e6eb849c281df2bd 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_1.ets +++ b/ets2panda/linter/test/main/double_dollar_binding_1.ets @@ -14,8 +14,9 @@ */ @Component -struct Myomponent { - @State value: number = 0; +struct MyComponent { + @State value: number = 0 + build() { Row() { Slider({ @@ -28,6 +29,7 @@ struct Myomponent { @Component struct Test { @State checked: boolean = false + build() { Row() { Checkbox().select($$this.checked) diff --git a/ets2panda/linter/test/main/double_dollar_binding_1.ets.args.json b/ets2panda/linter/test/main/double_dollar_binding_1.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_1.ets.args.json +++ b/ets2panda/linter/test/main/double_dollar_binding_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_dollar_binding_1.ets.arkts2.json b/ets2panda/linter/test/main/double_dollar_binding_1.ets.arkts2.json index 280b7fd22f8f030217bb903198efed006ae6067c..f62cf13942a130fbec139962a797ac8a2c2be275 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/double_dollar_binding_1.ets.arkts2.json @@ -15,9 +15,19 @@ ], "result": [ { - "line": 22, + "line": 18, + "column": 26, + "endLine": 18, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, "column": 16, - "endLine": 22, + "endLine": 23, "endColumn": 28, "problem": "DoubleDollarBindingNotSupported", "suggest": "", @@ -25,9 +35,9 @@ "severity": "ERROR" }, { - "line": 33, + "line": 35, "column": 25, - "endLine": 33, + "endLine": 35, "endColumn": 39, "problem": "DoubleDollarBindingNotSupported", "suggest": "", @@ -55,9 +65,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 5, - "endLine": 20, + "endLine": 21, "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", @@ -65,9 +75,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 22, "column": 7, - "endLine": 21, + "endLine": 22, "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", @@ -75,10 +85,20 @@ "severity": "ERROR" }, { - "line": 33, - "column": 7, - "endLine": 33, - "endColumn": 15, + "line": 29, + "column": 2, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 4, + "endLine": 31, + "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", @@ -86,9 +106,9 @@ }, { "line": 34, - "column": 7, + "column": 5, "endLine": 34, - "endColumn": 12, + "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", @@ -98,6 +118,26 @@ "line": 35, "column": 7, "endLine": 35, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 7, + "endLine": 36, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", diff --git a/ets2panda/linter/test/main/double_dollar_binding_1.ets.autofix.json b/ets2panda/linter/test/main/double_dollar_binding_1.ets.autofix.json index 9dee2674f0e7e45460dfd66c8a94f577805c4ef6..7a7748866b57036663b876c85f319174f3ad95ed 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_1.ets.autofix.json +++ b/ets2panda/linter/test/main/double_dollar_binding_1.ets.autofix.json @@ -15,16 +15,41 @@ ], "result": [ { - "line": 22, + "line": 18, + "column": 26, + "endLine": 18, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 662, + "end": 663, + "replacementText": "0.0", + "line": 18, + "column": 26, + "endLine": 18, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, "column": 16, - "endLine": 22, + "endLine": 23, "endColumn": 28, "problem": "DoubleDollarBindingNotSupported", "autofix": [ { - "start": 718, - "end": 730, - "replacementText": "$$(this.value)" + "start": 719, + "end": 731, + "replacementText": "$$(this.value)", + "line": 23, + "column": 16, + "endLine": 23, + "endColumn": 28 } ], "suggest": "", @@ -32,16 +57,20 @@ "severity": "ERROR" }, { - "line": 33, + "line": 35, "column": 25, - "endLine": 33, + "endLine": 35, "endColumn": 39, "problem": "DoubleDollarBindingNotSupported", "autofix": [ { - "start": 860, - "end": 874, - "replacementText": "$$(this.checked)" + "start": 862, + "end": 876, + "replacementText": "$$(this.checked)", + "line": 35, + "column": 25, + "endLine": 35, + "endColumn": 39 } ], "suggest": "", @@ -54,6 +83,17 @@ "endLine": 16, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -64,46 +104,122 @@ "endLine": 18, "endColumn": 9, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 5, - "endLine": 20, + "endLine": 21, "endColumn": 8, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 21, + "line": 22, "column": 7, - "endLine": 21, + "endLine": 22, "endColumn": 13, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 33, - "column": 7, - "endLine": 33, - "endColumn": 15, + "line": 29, + "column": 2, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 4, + "endLine": 31, + "endColumn": 9, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { "line": 34, - "column": 7, + "column": 5, "endLine": 34, - "endColumn": 12, + "endColumn": 8, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -112,13 +228,59 @@ "line": 35, "column": 7, "endLine": 35, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 7, + "endLine": 36, + "endColumn": 12, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kits.ArkUI';" + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI';", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 11 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.ets b/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb6147cf5b4ed1f5c754bb49f95266668c993489 --- /dev/null +++ b/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.ets @@ -0,0 +1,42 @@ +/* + * 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 { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI'; + +@Component +struct MyComponent { + @State value: number = 0.0 + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +@Component +struct Test { + @State checked: boolean = false + + build() { + Row() { + Checkbox().select($$(this.checked)) + Blank() + Text(this.checked ? '开启': '关闭') + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.json b/ets2panda/linter/test/main/double_dollar_binding_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/double_dollar_binding_1.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 diff --git a/ets2panda/linter/test/main/double_dollar_binding_2.ets b/ets2panda/linter/test/main/double_dollar_binding_2.ets index 84b8d5448ea35b18371dc5090fd94e339eefc280..e598afe1a5c9ef6cc608c902b7bade026786bfd8 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_2.ets +++ b/ets2panda/linter/test/main/double_dollar_binding_2.ets @@ -13,11 +13,12 @@ * limitations under the License. */ -import { Component, State, Row, Slider, Checkbox, Blank, Text } from '@kits.ArkUI'; +import { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI'; @Component -struct Myomponent { - @State value: number = 0; +struct MyComponent { + @State value: number = 0 + build() { Row() { Slider({ @@ -30,6 +31,7 @@ struct Myomponent { @Component struct Test { @State checked: boolean = false + build() { Row() { Checkbox().select($$(this.checked)) diff --git a/ets2panda/linter/test/main/double_dollar_binding_2.ets.args.json b/ets2panda/linter/test/main/double_dollar_binding_2.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_2.ets.args.json +++ b/ets2panda/linter/test/main/double_dollar_binding_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_dollar_binding_2.ets.arkts2.json b/ets2panda/linter/test/main/double_dollar_binding_2.ets.arkts2.json index ca88f857e960b437dcf767c0ac40be998c8f1236..63543b96ff729073225b0d28ff1f4087e1a314f4 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/double_dollar_binding_2.ets.arkts2.json @@ -13,5 +13,16 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_dollar_binding_2.ets.autofix.json b/ets2panda/linter/test/main/double_dollar_binding_2.ets.autofix.json index ca88f857e960b437dcf767c0ac40be998c8f1236..51a33cbdbf04be9f302dd3a3033b9893d4e45b43 100644 --- a/ets2panda/linter/test/main/double_dollar_binding_2.ets.autofix.json +++ b/ets2panda/linter/test/main/double_dollar_binding_2.ets.autofix.json @@ -13,5 +13,27 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 750, + "end": 751, + "replacementText": "0.0", + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.ets b/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb6147cf5b4ed1f5c754bb49f95266668c993489 --- /dev/null +++ b/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.ets @@ -0,0 +1,42 @@ +/* + * 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 { Component, State, Row, Slider, $$, Checkbox, Blank, Text } from '@kit.ArkUI'; + +@Component +struct MyComponent { + @State value: number = 0.0 + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +@Component +struct Test { + @State checked: boolean = false + + build() { + Row() { + Checkbox().select($$(this.checked)) + Blank() + Text(this.checked ? '开启': '关闭') + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.json b/ets2panda/linter/test/main/double_dollar_binding_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/double_dollar_binding_2.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 diff --git a/ets2panda/linter/test/main/double_excla_binding_1.ets b/ets2panda/linter/test/main/double_excla_binding_1.ets index 91a26fca7c3ae71a063c4e86325a5c735e07d932..2026351a801f99c0adc75e04de136334f0ef3da9 100644 --- a/ets2panda/linter/test/main/double_excla_binding_1.ets +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets @@ -16,8 +16,9 @@ import { MyCard } from './' @Component -struct Myomponent { - @State value: number = 0; +struct MyComponent1 { + @State value: number = 0 + build() { Row() { Slider({ @@ -30,6 +31,7 @@ struct Myomponent { @Component struct Test { @State checked: boolean = false + build() { Row() { Checkbox().select(this.checked!!) @@ -40,7 +42,7 @@ struct Test { } @Component -struct Myomponent { +struct MyComponent2 { @State value: number = 0; build() { Row() { @@ -52,7 +54,7 @@ struct Myomponent { } @Component -struct Myomponent { +struct MyComponent3 { @State value: number = 0; build() { Row() { @@ -64,7 +66,7 @@ struct Myomponent { } @Component -struct Myomponent { +struct MyComponent4 { @State value: number = 0; build() { Row() { diff --git a/ets2panda/linter/test/main/double_excla_binding_1.ets.args.json b/ets2panda/linter/test/main/double_excla_binding_1.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/double_excla_binding_1.ets.args.json +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_1.ets.arkts2.json b/ets2panda/linter/test/main/double_excla_binding_1.ets.arkts2.json index ba417616711c6329099d34138402fb4a10809a39..1049eb7c5c4dee94d8d7d448974569ee75c9a99a 100644 --- a/ets2panda/linter/test/main/double_excla_binding_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.arkts2.json @@ -1,23 +1,33 @@ { "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 (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": 24, + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, "column": 16, - "endLine": 24, + "endLine": 25, "endColumn": 28, "problem": "DoubleExclaBindingNotSupported", "suggest": "", @@ -25,9 +35,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 37, "column": 25, - "endLine": 35, + "endLine": 37, "endColumn": 39, "problem": "DoubleExclaBindingNotSupported", "suggest": "", @@ -35,9 +45,49 @@ "severity": "ERROR" }, { - "line": 90, + "line": 46, + "column": 26, + "endLine": 46, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 26, + "endLine": 58, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 26, + "endLine": 70, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 26, + "endLine": 83, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, "column": 21, - "endLine": 90, + "endLine": 92, "endColumn": 33, "problem": "DoubleExclaBindingNotSupported", "suggest": "", @@ -45,15 +95,35 @@ "severity": "ERROR" }, { - "line": 91, + "line": 93, "column": 21, - "endLine": 91, + "endLine": 93, "endColumn": 31, "problem": "DoubleExclaBindingNotSupported", "suggest": "", "rule": "\"!!\" for bidirectional data binding is not supported (arkui-no-!!-bidirectional-data-binding)", "severity": "ERROR" }, + { + "line": 101, + "column": 26, + "endLine": 101, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 21, + "endLine": 108, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 18, "column": 2, @@ -75,9 +145,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 23, "column": 5, - "endLine": 22, + "endLine": 23, "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", @@ -85,9 +155,9 @@ "severity": "ERROR" }, { - "line": 23, + "line": 24, "column": 7, - "endLine": 23, + "endLine": 24, "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", @@ -95,10 +165,20 @@ "severity": "ERROR" }, { - "line": 35, - "column": 7, - "endLine": 35, - "endColumn": 15, + "line": 31, + "column": 2, + "endLine": 31, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 4, + "endLine": 33, + "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", @@ -106,9 +186,9 @@ }, { "line": 36, - "column": 7, + "column": 5, "endLine": 36, - "endColumn": 12, + "endColumn": 8, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", @@ -118,6 +198,26 @@ "line": 37, "column": 7, "endLine": 37, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 7, + "endLine": 38, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 7, + "endLine": 39, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -125,19 +225,79 @@ "severity": "ERROR" }, { - "line": 78, + "line": 44, "column": 2, - "endLine": 78, - "endColumn": 7, + "endLine": 44, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 4, + "endLine": 46, + "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 79, + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 7, + "endLine": 49, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 56, "column": 2, - "endLine": 79, + "endLine": 56, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 4, + "endLine": 58, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 7, + "endLine": 61, "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", @@ -145,9 +305,79 @@ "severity": "ERROR" }, { - "line": 81, + "line": 68, + "column": 2, + "endLine": 68, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 70, "column": 4, + "endLine": 70, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 7, + "endLine": 73, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 2, + "endLine": 80, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 2, "endLine": 81, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 4, + "endLine": 83, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 4, + "endLine": 84, "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", @@ -155,9 +385,9 @@ "severity": "ERROR" }, { - "line": 85, + "line": 87, "column": 5, - "endLine": 85, + "endLine": 87, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -165,9 +395,19 @@ "severity": "ERROR" }, { - "line": 87, + "line": 88, "column": 7, - "endLine": 87, + "endLine": 88, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 7, + "endLine": 89, "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", @@ -176,8 +416,18 @@ }, { "line": 99, - "column": 4, + "column": 2, "endLine": 99, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 4, + "endLine": 101, "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", @@ -185,14 +435,44 @@ "severity": "ERROR" }, { - "line": 100, + "line": 102, "column": 4, - "endLine": 100, + "endLine": 102, "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 7, + "endLine": 106, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_1.ets.autofix.json b/ets2panda/linter/test/main/double_excla_binding_1.ets.autofix.json index 4fe1155c873a375fc59c0714c3731e480bcc9d88..b10e76da6e07d88ad1b89779564a1527805f2cf7 100644 --- a/ets2panda/linter/test/main/double_excla_binding_1.ets.autofix.json +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.autofix.json @@ -1,30 +1,55 @@ { "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 (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": 24, + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 692, + "end": 693, + "replacementText": "0.0", + "line": 20, + "column": 26, + "endLine": 20, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, "column": 16, - "endLine": 24, + "endLine": 25, "endColumn": 28, "problem": "DoubleExclaBindingNotSupported", "autofix": [ { - "start": 747, - "end": 759, - "replacementText": "$$(this.value)" + "start": 749, + "end": 761, + "replacementText": "$$(this.value)", + "line": 25, + "column": 16, + "endLine": 25, + "endColumn": 28 } ], "suggest": "", @@ -32,16 +57,20 @@ "severity": "ERROR" }, { - "line": 35, + "line": 37, "column": 25, - "endLine": 35, + "endLine": 37, "endColumn": 39, "problem": "DoubleExclaBindingNotSupported", "autofix": [ { - "start": 889, - "end": 903, - "replacementText": "$$(this.checked)" + "start": 892, + "end": 906, + "replacementText": "$$(this.checked)", + "line": 37, + "column": 25, + "endLine": 37, + "endColumn": 39 } ], "suggest": "", @@ -49,16 +78,104 @@ "severity": "ERROR" }, { - "line": 90, + "line": 46, + "column": 26, + "endLine": 46, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1031, + "end": 1032, + "replacementText": "0.0", + "line": 46, + "column": 26, + "endLine": 46, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 26, + "endLine": 58, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1182, + "end": 1183, + "replacementText": "0.0", + "line": 58, + "column": 26, + "endLine": 58, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 26, + "endLine": 70, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1334, + "end": 1335, + "replacementText": "0.0", + "line": 70, + "column": 26, + "endLine": 70, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 26, + "endLine": 83, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1489, + "end": 1490, + "replacementText": "0.0", + "line": 83, + "column": 26, + "endLine": 83, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, "column": 21, - "endLine": 90, + "endLine": 92, "endColumn": 33, "problem": "DoubleExclaBindingNotSupported", "autofix": [ { - "start": 1653, - "end": 1676, - "replacementText": "{\n value: this.value,\n $value: value => {\n this.value = value;\n }\n}" + "start": 1662, + "end": 1685, + "replacementText": "{\n value: this.value,\n $value: value => {\n this.value = value;\n }\n }", + "line": 92, + "column": 21, + "endLine": 92, + "endColumn": 33 } ], "suggest": "", @@ -66,28 +183,85 @@ "severity": "ERROR" }, { - "line": 91, + "line": 93, "column": 21, - "endLine": 91, + "endLine": 93, "endColumn": 31, "problem": "DoubleExclaBindingNotSupported", "autofix": [ { - "start": 1691, - "end": 1710, - "replacementText": "{\n str: this.str,\n $str: value => {\n this.str = value;\n }\n}" + "start": 1700, + "end": 1719, + "replacementText": "{\n str: this.str,\n $str: value => {\n this.str = value;\n }\n }", + "line": 93, + "column": 21, + "endLine": 93, + "endColumn": 31 } ], "suggest": "", "rule": "\"!!\" for bidirectional data binding is not supported (arkui-no-!!-bidirectional-data-binding)", "severity": "ERROR" }, + { + "line": 101, + "column": 26, + "endLine": 101, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1787, + "end": 1788, + "replacementText": "0.0", + "line": 101, + "column": 26, + "endLine": 101, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 21, + "endLine": 108, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1974, + "end": 1976, + "replacementText": "10.0", + "line": 108, + "column": 21, + "endLine": 108, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 18, "column": 2, "endLine": 18, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -98,46 +272,122 @@ "endLine": 20, "endColumn": 9, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 22, + "line": 23, "column": 5, - "endLine": 22, + "endLine": 23, "endColumn": 8, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 23, + "line": 24, "column": 7, - "endLine": 23, + "endLine": 24, "endColumn": 13, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 35, - "column": 7, - "endLine": 35, - "endColumn": 15, + "line": 31, + "column": 2, + "endLine": 31, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 4, + "endLine": 33, + "endColumn": 9, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { "line": 36, - "column": 7, + "column": 5, "endLine": 36, - "endColumn": 12, + "endColumn": 8, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -146,83 +396,584 @@ "line": 37, "column": 7, "endLine": 37, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 7, + "endLine": 38, + "endColumn": 12, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 7, + "endLine": 39, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 78, + "line": 44, "column": 2, - "endLine": 78, - "endColumn": 7, + "endLine": 44, + "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 79, + "line": 46, + "column": 4, + "endLine": 46, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 7, + "endLine": 49, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 56, "column": 2, - "endLine": 79, + "endLine": 56, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 4, + "endLine": 58, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 7, + "endLine": 61, "endColumn": 13, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 2, + "endLine": 68, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 81, + "line": 70, "column": 4, + "endLine": 70, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 7, + "endLine": 73, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 2, + "endLine": 80, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 2, "endLine": 81, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 4, + "endLine": 83, "endColumn": 9, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 85, + "line": 84, + "column": 4, + "endLine": 84, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 87, "column": 5, - "endLine": 85, + "endLine": 87, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 87, + "line": 88, "column": 7, - "endLine": 87, + "endLine": 88, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 7, + "endLine": 89, "endColumn": 13, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { "line": 99, - "column": 4, + "column": 2, "endLine": 99, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 4, + "endLine": 101, "endColumn": 9, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 100, + "line": 102, "column": 4, - "endLine": 100, + "endLine": 102, "endColumn": 9, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kits.ArkUI';" + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 7, + "endLine": 106, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI';", + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 13 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.ets b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6f1805da3f3f051a322f824e498366219cbe16db --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.ets @@ -0,0 +1,124 @@ +/* + * 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 { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI'; + +import { MyCard } from './' + +@Component +struct MyComponent1 { + @State value: number = 0.0 + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +@Component +struct Test { + @State checked: boolean = false + + build() { + Row() { + Checkbox().select($$(this.checked)) + Blank() + Text(this.checked ? '开启': '关闭') + } + } +} + +@Component +struct MyComponent2 { + @State value: number = 0.0; + build() { + Row() { + Slider({ + value: this.value!!! + }) + } + } +} + +@Component +struct MyComponent3 { + @State value: number = 0.0; + build() { + Row() { + Slider({ + value: this.value!!!! + }) + } + } +} + +@Component +struct MyComponent4 { + @State value: number = 0.0; + build() { + Row() { + Slider({ + value: this.value!!!!! + }) + } + } +} + +@Entry +@ComponentV2 +struct Index { + @Local value: number = 0.0; + @Local str: string = ''; + + build() { + Column() { + Text(`${this.value}`) + Button(`change value`).onClick(() => { + this.value++; + }) + Star({ + value: this.value, + $value: value => { + this.value = value; + } + }) + MyCard({ + str: this.str, + $str: value => { + this.str = value; + } + }) + } + } +} + + +@ComponentV2 +struct Star { + @Param value: number = 0.0; + @Event $value: (val: number) => void = (val: number) => {}; + + build() { + Column() { + Text(`${this.value}`) + Button(`change value `).onClick(() => { + this.$value(10.0); + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.json b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c697fe6484ca72352bfc6b04ba5b73eade8a1961 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_1.ets.migrate.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": 102, + "column": 15, + "endLine": 102, + "endColumn": 20, + "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/main/double_excla_binding_2.ets b/ets2panda/linter/test/main/double_excla_binding_2.ets index c8526bdd61b44dcb57591798bd3a5f886cb4b326..3f5d8563a9e48b35c0d1fe7d20c2a743ba48438e 100644 --- a/ets2panda/linter/test/main/double_excla_binding_2.ets +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets @@ -13,13 +13,14 @@ * limitations under the License. */ -import { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kits.ArkUI'; +import { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI'; import { MyCard } from './' @Component -struct Myomponent { - @State value: number = 0; +struct MyComponent { + @State value: number = 0 + build() { Row() { Slider({ @@ -32,6 +33,7 @@ struct Myomponent { @Component struct Test { @State checked: boolean = false + build() { Row() { Checkbox().select($$(this.checked)) @@ -41,6 +43,42 @@ struct Test { } } +@Component +struct MyComponent2 { + @State value: number = 0; + build() { + Row() { + Slider({ + value: this.value!!! + }) + } + } +} + +@Component +struct MyComponent3 { + @State value: number = 0; + build() { + Row() { + Slider({ + value: this.value!!!! + }) + } + } +} + +@Component +struct MyComponent4 { + @State value: number = 0; + build() { + Row() { + Slider({ + value: this.value!!!!! + }) + } + } +} + @Entry @ComponentV2 struct Index { diff --git a/ets2panda/linter/test/main/double_excla_binding_2.ets.args.json b/ets2panda/linter/test/main/double_excla_binding_2.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/double_excla_binding_2.ets.args.json +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_2.ets.arkts2.json b/ets2panda/linter/test/main/double_excla_binding_2.ets.arkts2.json index 9077c4db994b2f27c3ebc8e3d2fbddd7ae891d58..2931b3b9f080b8f40e2ef40bf5614f3a023f39f4 100644 --- a/ets2panda/linter/test/main/double_excla_binding_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets.arkts2.json @@ -1,28 +1,98 @@ { "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 (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": 63, + "line": 22, + "column": 26, + "endLine": 22, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 26, + "endLine": 48, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 26, + "endLine": 60, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 26, + "endLine": 72, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 26, + "endLine": 85, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 101, "column": 15, - "endLine": 63, + "endLine": 101, "endColumn": 20, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 112, + "column": 26, + "endLine": 112, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 21, + "endLine": 119, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_2.ets.autofix.json b/ets2panda/linter/test/main/double_excla_binding_2.ets.autofix.json index 9077c4db994b2f27c3ebc8e3d2fbddd7ae891d58..1bf244df8f665d06bbb01080ccdcab36f3bf03e5 100644 --- a/ets2panda/linter/test/main/double_excla_binding_2.ets.autofix.json +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets.autofix.json @@ -1,28 +1,175 @@ { "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 (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": 63, + "line": 22, + "column": 26, + "endLine": 22, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 836, + "end": 837, + "replacementText": "0.0", + "line": 22, + "column": 26, + "endLine": 22, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 26, + "endLine": 48, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1179, + "end": 1180, + "replacementText": "0.0", + "line": 48, + "column": 26, + "endLine": 48, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 26, + "endLine": 60, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1330, + "end": 1331, + "replacementText": "0.0", + "line": 60, + "column": 26, + "endLine": 60, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 26, + "endLine": 72, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1482, + "end": 1483, + "replacementText": "0.0", + "line": 72, + "column": 26, + "endLine": 72, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 26, + "endLine": 85, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1637, + "end": 1638, + "replacementText": "0.0", + "line": 85, + "column": 26, + "endLine": 85, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 101, "column": 15, - "endLine": 63, + "endLine": 101, "endColumn": 20, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 112, + "column": 26, + "endLine": 112, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2064, + "end": 2065, + "replacementText": "0.0", + "line": 112, + "column": 26, + "endLine": 112, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 21, + "endLine": 119, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2251, + "end": 2253, + "replacementText": "10.0", + "line": 119, + "column": 21, + "endLine": 119, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_2.ets.json b/ets2panda/linter/test/main/double_excla_binding_2.ets.json index 9077c4db994b2f27c3ebc8e3d2fbddd7ae891d58..56397bece3039a1107847f2f79538a15b8a80ae1 100644 --- a/ets2panda/linter/test/main/double_excla_binding_2.ets.json +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets.json @@ -15,9 +15,9 @@ ], "result": [ { - "line": 63, + "line": 101, "column": 15, - "endLine": 63, + "endLine": 101, "endColumn": 20, "problem": "AnyType", "suggest": "", diff --git a/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.ets b/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5b4c234d0b10bf3515247585631d5265b738dc35 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.ets @@ -0,0 +1,123 @@ +/* + * 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 { Component, State, Row, Slider, $$, Checkbox, Blank, Text, Entry, ComponentV2, Local, Column, Button, Param, Event } from '@kit.ArkUI'; + +import { MyCard } from './' + +@Component +struct MyComponent { + @State value: number = 0.0 + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +@Component +struct Test { + @State checked: boolean = false + + build() { + Row() { + Checkbox().select($$(this.checked)) + Blank() + Text(this.checked ? '开启': '关闭') + } + } +} + +@Component +struct MyComponent2 { + @State value: number = 0.0; + build() { + Row() { + Slider({ + value: this.value!!! + }) + } + } +} + +@Component +struct MyComponent3 { + @State value: number = 0.0; + build() { + Row() { + Slider({ + value: this.value!!!! + }) + } + } +} + +@Component +struct MyComponent4 { + @State value: number = 0.0; + build() { + Row() { + Slider({ + value: this.value!!!!! + }) + } + } +} + +@Entry +@ComponentV2 +struct Index { + @Local value: number = 0.0; + + build() { + Column() { + Text(`${this.value}`) + Button(`change value`).onClick(() => { + this.value++; + }) + Star({ + value: this.value, + $value: value => { + this.value = value; + } + }) + MyCard({ + str: this.str, + $str: value => { + this.str = value; + } + }) + } + } +} + + +@ComponentV2 +struct Star { + @Param value: number = 0.0; + @Event $value: (val: number) => void = (val: number) => {}; + + build() { + Column() { + Text(`${this.value}`) + Button(`change value `).onClick(() => { + this.$value(10.0); + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.json b/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..9ce7a7e1390eb1866c6616e64e3c99b788cda1e4 --- /dev/null +++ b/ets2panda/linter/test/main/double_excla_binding_2.ets.migrate.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": 101, + "column": 15, + "endLine": 101, + "endColumn": 20, + "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/main/dynamic_ctor_call.ets.arkts2.json b/ets2panda/linter/test/main/dynamic_ctor_call.ets.arkts2.json index 2e06ab8e482041ee04ea0d231078bf7a42509e16..0ef26c352d653b6c6e8fd73f0070ea28f6847bbe 100644 --- a/ets2panda/linter/test/main/dynamic_ctor_call.ets.arkts2.json +++ b/ets2panda/linter/test/main/dynamic_ctor_call.ets.arkts2.json @@ -54,6 +54,26 @@ "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, + { + "line": 26, + "column": 19, + "endLine": 26, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 22, + "endLine": 26, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 30, "column": 9, @@ -74,6 +94,26 @@ "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, + { + "line": 32, + "column": 19, + "endLine": 32, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 36, "column": 3, diff --git a/ets2panda/linter/test/main/entry_annotation_test10_1.ets b/ets2panda/linter/test/main/entry_annotation_test10_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..1e06295870c7af4aed816109c2f2f1827f1c270e --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; +import { getLocalStorage } from './storage-manager'; + +@Entry({storage: getLocalStorage(1)}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.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/entry_annotation_test10_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..0e990c1b4b1ec6ea7bc542311f0ed96209ef47b4 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 19, + "column": 1, + "endLine": 19, + "endColumn": 38, + "problem": "EntryAnnotation", + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 34, + "endLine": 19, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..842bfd57b07576e219438f36907a96b7dd85d110 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.autofix.json @@ -0,0 +1,60 @@ +{ + "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": 19, + "column": 1, + "endLine": 19, + "endColumn": 38, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 738, + "end": 775, + "replacementText": "const __get_local_storage__ = (): LocalStorage => getLocalStorage(1);\n@Entry({ storage: \"__get_local_storage__\" })", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 34, + "endLine": 19, + "endColumn": 35, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 771, + "end": 772, + "replacementText": "1.0", + "line": 19, + "column": 34, + "endLine": 19, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.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/entry_annotation_test10_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..cd8cec09b98c42d29e581dd6ca474b1429861dfe --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; +import { getLocalStorage } from './storage-manager'; + +const __get_local_storage__ = (): LocalStorage => getLocalStorage(1.0); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test10_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_1.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 diff --git a/ets2panda/linter/test/main/entry_annotation_test10_2.ets b/ets2panda/linter/test/main/entry_annotation_test10_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..59984ecfef0c835cfe7b08bf4d66fafa54667db5 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; +import { getLocalStorage } from './storage-manager'; + +const __get_local_storage__ = (): LocalStorage => getLocalStorage(1); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.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/entry_annotation_test10_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..51f70c2d7785733f2de131de151191e77e51a0ab --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.arkts2.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": 19, + "column": 67, + "endLine": 19, + "endColumn": 68, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..bc7b6ccc6aa3e8cca81fa41040e064f2ebbc816b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.autofix.json @@ -0,0 +1,39 @@ +{ + "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": 19, + "column": 67, + "endLine": 19, + "endColumn": 68, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 804, + "end": 805, + "replacementText": "1.0", + "line": 19, + "column": 67, + "endLine": 19, + "endColumn": 68 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_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/entry_annotation_test10_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..c7f8f3c02e1b91bc5b3a0637714ff3bb4f6d858b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; +import { getLocalStorage } from './storage-manager'; + +const __get_local_storage__ = (): LocalStorage => getLocalStorage(1.0); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test10_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test10_2.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 diff --git a/ets2panda/linter/test/main/entry_annotation_test1_1.ets b/ets2panda/linter/test/main/entry_annotation_test1_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..1d6b599d2471d61ac22a08af2e12f00ca0b43da6 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.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. + */ + +import { Entry, Component, Text } from '@ohos.arkui.components'; + +@Entry +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.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/entry_annotation_test1_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.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/entry_annotation_test1_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.autofix.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/entry_annotation_test1_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.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/entry_annotation_test1_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e62f535cac447db61b2257170bdb17f5107ad331 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.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. + */ + +import { Entry, Component, Text } from '@ohos.arkui.components'; + +@Entry +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test1_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_1.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 diff --git a/ets2panda/linter/test/main/entry_annotation_test1_2.ets b/ets2panda/linter/test/main/entry_annotation_test1_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..1d6b599d2471d61ac22a08af2e12f00ca0b43da6 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.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. + */ + +import { Entry, Component, Text } from '@ohos.arkui.components'; + +@Entry +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.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/entry_annotation_test1_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.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/entry_annotation_test1_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.autofix.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/entry_annotation_test1_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_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/entry_annotation_test1_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e62f535cac447db61b2257170bdb17f5107ad331 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.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. + */ + +import { Entry, Component, Text } from '@ohos.arkui.components'; + +@Entry +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test1_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test1_2.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 diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets b/ets2panda/linter/test/main/entry_annotation_test2_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..8a6b6e367a224b8b1e6cd29897dbca714a8cad65 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +@Entry(storage) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.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/entry_annotation_test2_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..350f552e391cda46b39c79385a493e67ebf49020 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 16, + "problem": "EntryAnnotation", + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..5430117ee12997f35363c2316f3da0a11496b6ac --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.autofix.json @@ -0,0 +1,55 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 16, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 721, + "end": 736, + "replacementText": "const __get_local_storage__ = (): LocalStorage => storage;\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..a39b2863ef150ce31f7df235b2c0dd2d0f00d64f --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "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/main/entry_annotation_test2_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a7d2611b8743dcf4578b79a292ee60370555d11 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d9d95f393735b0e2928f47ea11b82f3d93353268 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_1.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_2.ets b/ets2panda/linter/test/main/entry_annotation_test2_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..b188329f6f2c30a64849e116822b6258b7a77319 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({storage: "__get_local_storage__"}) +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.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/entry_annotation_test2_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..bc6a0db58e87d2dbe42552066a4d4d4b673ece84 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..bc6a0db58e87d2dbe42552066a4d4d4b673ece84 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.autofix.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..a39b2863ef150ce31f7df235b2c0dd2d0f00d64f --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "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/main/entry_annotation_test2_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..52bd3e4f789c6d73bd0a5d04017b29a790c4be6d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({storage: "__get_local_storage__"}) +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d9d95f393735b0e2928f47ea11b82f3d93353268 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test2_2.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets b/ets2panda/linter/test/main/entry_annotation_test3_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..adae2542f2ac9494a4bfecf0090ced768370f9c1 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry(new LocalStorage()) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.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/entry_annotation_test3_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..aa442606c5259412ea7d3bc0247857f326d735b7 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 27, + "problem": "EntryAnnotation", + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 12, + "endLine": 18, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..177c74ca80e95e1bdb023147eee803520d49d368 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.autofix.json @@ -0,0 +1,45 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 27, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 711, + "replacementText": "const __get_local_storage__ = (): LocalStorage => new LocalStorage();\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 12, + "endLine": 18, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.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/data_observation_2.ets b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.ets similarity index 68% rename from ets2panda/linter/test/main/data_observation_2.ets rename to ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.ets index 7ce00c004c79c5fcbd0766bffa3bcbcc1b6cd083..3d30dad8c7689ec649f4be551916268c5ec1e5f0 100644 --- a/ets2panda/linter/test/main/data_observation_2.ets +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.ets @@ -1,35 +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 { MyClassB, MyClassD } from './' - -@Entry -@Component -struct Test { - @State data1: number = 0 - @State data2: MyClassA = 0 - @State data3: MyClassB | string = 0 - @State data3: undefined | string | MyClassC | MyClassD = 0 -} - -@Observed -class MyClassA { - -} - -@Observed -class MyClassC { - +/* + * 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, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8ecb23f92c00e0e43cd69914e10283866b396780 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_1.ets.migrate.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": 18, + "column": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_2.ets b/ets2panda/linter/test/main/entry_annotation_test3_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..14d0661094d30187826c74309b69d7397c5cd740 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.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/entry_annotation_test3_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..daadd31517f1013e52240af36696a8aa79e9833b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.arkts2.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": 18, + "column": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..daadd31517f1013e52240af36696a8aa79e9833b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.autofix.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": 18, + "column": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_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/entry_annotation_test3_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5d9cf9c567f9629ad3f8806ef02536fca3233163 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8ecb23f92c00e0e43cd69914e10283866b396780 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test3_2.ets.migrate.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": 18, + "column": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets b/ets2panda/linter/test/main/entry_annotation_test4_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..b0e972cd29805948ad48eaf1746ba31022f6e740 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry(LocalStorage.getShared()) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.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/entry_annotation_test4_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..6055f15b89bc2c3a9a7594c5c499100f0897dab2 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.arkts2.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": 18, + "column": 1, + "endLine": 18, + "endColumn": 33, + "problem": "EntryAnnotation", + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..845f1133f9da9dcdad5d6167041ccac0aa989fe4 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.autofix.json @@ -0,0 +1,35 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 33, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 717, + "replacementText": "const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared();\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.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/entry_annotation_test4_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe0711cbc54f5d6fa47bbc98c912af01e7225269 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test4_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_1.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 diff --git a/ets2panda/linter/test/main/entry_annotation_test4_2.ets b/ets2panda/linter/test/main/entry_annotation_test4_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..33c63bb35c7022f650b528687666580ae85afee3 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.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/entry_annotation_test4_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.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/entry_annotation_test4_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.autofix.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/entry_annotation_test4_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_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/entry_annotation_test4_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6638d8b755d3c79ea395770df0ef629b21d44e1b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test4_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test4_2.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 diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets b/ets2panda/linter/test/main/entry_annotation_test5_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..b5a754f0e2daa676d59fc80af3d51d3f31c1af89 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +@Entry({storage: storage}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.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/entry_annotation_test5_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..723aac826a54d8834c4899b5b3449b25256da7c0 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 27, + "problem": "EntryAnnotation", + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..ee459b5f4abb7bc6d559ef47311e74df4e0d646f --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.autofix.json @@ -0,0 +1,55 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 27, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 721, + "end": 747, + "replacementText": "const __get_local_storage__ = (): LocalStorage => storage;\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..a39b2863ef150ce31f7df235b2c0dd2d0f00d64f --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "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/main/entry_annotation_test5_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a7d2611b8743dcf4578b79a292ee60370555d11 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d9d95f393735b0e2928f47ea11b82f3d93353268 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_1.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_2.ets b/ets2panda/linter/test/main/entry_annotation_test5_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..b188329f6f2c30a64849e116822b6258b7a77319 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({storage: "__get_local_storage__"}) +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.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/entry_annotation_test5_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..bc6a0db58e87d2dbe42552066a4d4d4b673ece84 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..bc6a0db58e87d2dbe42552066a4d4d4b673ece84 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.autofix.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..a39b2863ef150ce31f7df235b2c0dd2d0f00d64f --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "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/main/entry_annotation_test5_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..52bd3e4f789c6d73bd0a5d04017b29a790c4be6d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const storage = new LocalStorage(); +const __get_local_storage__ = (): LocalStorage => storage; +@Entry({storage: "__get_local_storage__"}) +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..d9d95f393735b0e2928f47ea11b82f3d93353268 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test5_2.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 7, + "endLine": 18, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 33, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets b/ets2panda/linter/test/main/entry_annotation_test6_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..570e2082a99c8b9c872f19faec9a6be7674601e1 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry({storage: new LocalStorage()}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.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/entry_annotation_test6_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ad567bc81c8ae063b8b04f1da4927f9dbc8869e9 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 38, + "problem": "EntryAnnotation", + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 22, + "endLine": 18, + "endColumn": 34, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..838b1b21a4d33f0578dd32e103d9380e49308469 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.autofix.json @@ -0,0 +1,45 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 38, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 722, + "replacementText": "const __get_local_storage__ = (): LocalStorage => new LocalStorage();\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 22, + "endLine": 18, + "endColumn": 34, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.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/entry_annotation_test6_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d30dad8c7689ec649f4be551916268c5ec1e5f0 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8ecb23f92c00e0e43cd69914e10283866b396780 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_1.ets.migrate.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": 18, + "column": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_2.ets b/ets2panda/linter/test/main/entry_annotation_test6_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..14d0661094d30187826c74309b69d7397c5cd740 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.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/entry_annotation_test6_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..daadd31517f1013e52240af36696a8aa79e9833b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.arkts2.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": 18, + "column": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..daadd31517f1013e52240af36696a8aa79e9833b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.autofix.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": 18, + "column": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_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/entry_annotation_test6_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..5d9cf9c567f9629ad3f8806ef02536fca3233163 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => new LocalStorage(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8ecb23f92c00e0e43cd69914e10283866b396780 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test6_2.ets.migrate.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": 18, + "column": 55, + "endLine": 18, + "endColumn": 67, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets b/ets2panda/linter/test/main/entry_annotation_test7_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..b246bb838178afd64d62dd5a8baacd405f31a61d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry({storage: LocalStorage.getShared()}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.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/entry_annotation_test7_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..2b7950ceb872deec8a0d268d4cfa99723d402297 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.arkts2.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": 18, + "column": 1, + "endLine": 18, + "endColumn": 44, + "problem": "EntryAnnotation", + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..45c5a879bc8dc241b3f7e755fb8c3a8775029da8 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.autofix.json @@ -0,0 +1,35 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 44, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 728, + "replacementText": "const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared();\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.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/entry_annotation_test7_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe0711cbc54f5d6fa47bbc98c912af01e7225269 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test7_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_1.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 diff --git a/ets2panda/linter/test/main/entry_annotation_test7_2.ets b/ets2panda/linter/test/main/entry_annotation_test7_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..33c63bb35c7022f650b528687666580ae85afee3 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.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/entry_annotation_test7_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.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/entry_annotation_test7_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.autofix.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/entry_annotation_test7_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..8227167def1b271819ea01c30d8adbb1022b3b20 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_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/entry_annotation_test7_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6638d8b755d3c79ea395770df0ef629b21d44e1b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => LocalStorage.getShared(); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test7_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test7_2.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 diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets b/ets2panda/linter/test/main/entry_annotation_test8_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..2db526a74087ba340a2c9f83764da8dcbe364967 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const source = globalThis.localStorage; +@Entry({storage: source}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.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/entry_annotation_test8_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..184525610491889d08e607a967ed98e327be55fa --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 16, + "endLine": 18, + "endColumn": 39, + "problem": "GlobalThisError", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 26, + "problem": "EntryAnnotation", + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..c1e82092cbc8411d1014db7524fa9e02b3151d6c --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.autofix.json @@ -0,0 +1,52 @@ +{ + "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": 18, + "column": 16, + "endLine": 18, + "endColumn": 39, + "problem": "GlobalThisError", + "autofix": [ + { + "start": 700, + "end": 723, + "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" + } + ], + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 26, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 725, + "end": 750, + "replacementText": "const __get_local_storage__ = (): LocalStorage => source;\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..b9bcd106e59df2e1bb6fe5f81ca68c0039b7ecf2 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.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": 18, + "column": 16, + "endLine": 18, + "endColumn": 26, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "WARNING" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1159381e1c3c5eae9a51f58e38fae68cb7e2e27a --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const source = specialAutofixLib.globalThis.get("localStorage"); +const __get_local_storage__ = (): LocalStorage => source; +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..045feeac1b91ac7e0aaa3fc613760478fdcaa478 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_1.ets.migrate.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": 18, + "column": 7, + "endLine": 18, + "endColumn": 64, + "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/main/entry_annotation_test8_2.ets b/ets2panda/linter/test/main/entry_annotation_test8_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..435ff1addfd0011813aea9cebc03da93d0b9107f --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const source = globalThis.localStorage; +const __get_local_storage__ = (): LocalStorage => source; +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.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/entry_annotation_test8_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..9dc9dd7879bd99b79a63f6c42dd45dd20d517411 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.arkts2.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": 18, + "column": 16, + "endLine": 18, + "endColumn": 39, + "problem": "GlobalThisError", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..f73277ba2c6e5588e6920e22bfe177ab72d3790a --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.autofix.json @@ -0,0 +1,35 @@ +{ + "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": 18, + "column": 16, + "endLine": 18, + "endColumn": 39, + "problem": "GlobalThisError", + "autofix": [ + { + "start": 700, + "end": 723, + "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" + } + ], + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..b9bcd106e59df2e1bb6fe5f81ca68c0039b7ecf2 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.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": 18, + "column": 16, + "endLine": 18, + "endColumn": 26, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "WARNING" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..0c20666abffa48687f2ec8cd3bd6587609d30ff2 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const source = specialAutofixLib.globalThis.get("localStorage"); +const __get_local_storage__ = (): LocalStorage => source; +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..045feeac1b91ac7e0aaa3fc613760478fdcaa478 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test8_2.ets.migrate.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": 18, + "column": 7, + "endLine": 18, + "endColumn": 64, + "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/main/entry_annotation_test9_1.ets b/ets2panda/linter/test/main/entry_annotation_test9_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..24563d7f73aa6ccbaafef9316a128b6f3aa37c03 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +@Entry({storage: globalThis.localStorage}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.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/entry_annotation_test9_1.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..13bf25157103c1e1a7e0301d95348dc19d4db002 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 43, + "problem": "EntryAnnotation", + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 18, + "endLine": 18, + "endColumn": 41, + "problem": "GlobalThisError", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..f8e2a1ef6c88975cdd9dfddc0d5cd8451a81ca3b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.autofix.json @@ -0,0 +1,52 @@ +{ + "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": 18, + "column": 1, + "endLine": 18, + "endColumn": 43, + "problem": "EntryAnnotation", + "autofix": [ + { + "start": 685, + "end": 727, + "replacementText": "const __get_local_storage__ = (): LocalStorage => globalThis.localStorage;\n@Entry({ storage: \"__get_local_storage__\" })" + } + ], + "suggest": "", + "rule": "The \"@Entry\" annotation does not support dynamic parameters (arkui-entry-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 18, + "endLine": 18, + "endColumn": 41, + "problem": "GlobalThisError", + "autofix": [ + { + "start": 702, + "end": 725, + "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" + } + ], + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.json b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..87514dc7ed9ac4e07389e2595af06489fbcf97fe --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.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": 18, + "column": 18, + "endLine": 18, + "endColumn": 28, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "WARNING" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..8c9d2b20122520a1036755a7aab58b9807fc626f --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => specialAutofixLib.globalThis.get("localStorage"); +@Entry({ storage: "__get_local_storage__" }) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test9_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_1.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 diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets b/ets2panda/linter/test/main/entry_annotation_test9_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..20d1b06bd96f166f9a5ead5c6cade2e6e30f043b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => globalThis.localStorage; +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.args.json b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..95b475ab3ce2f06558faffcd414f7e6ad9766f0d --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.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/entry_annotation_test9_2.ets.arkts2.json b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..08d96edc08960615ce560841cee23f7c071b45cf --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.arkts2.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": 18, + "column": 51, + "endLine": 18, + "endColumn": 74, + "problem": "GlobalThisError", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.autofix.json b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..17f6fcde033bbf37a56d9c1ce4d514a029e8e332 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.autofix.json @@ -0,0 +1,35 @@ +{ + "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": 18, + "column": 51, + "endLine": 18, + "endColumn": 74, + "problem": "GlobalThisError", + "autofix": [ + { + "start": 735, + "end": 758, + "replacementText": "specialAutofixLib.globalThis.get(\"localStorage\")" + } + ], + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.json b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..c259d2121eb9621050dfb40b3e151ff1900583ed --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.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": 18, + "column": 51, + "endLine": 18, + "endColumn": 61, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "WARNING" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.ets b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..9f1162ccfd9b4bd32b22eda12ce9773232e37e9b --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.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. + */ + +import { Entry, Component, Text, LocalStorage } from '@ohos.arkui.components'; + +const __get_local_storage__ = (): LocalStorage => specialAutofixLib.globalThis.get("localStorage"); +@Entry({storage: "__get_local_storage__"}) +@Component +struct MyPage { + build() { + Text("Hello World") + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.json b/ets2panda/linter/test/main/entry_annotation_test9_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/entry_annotation_test9_2.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 diff --git a/ets2panda/linter/test/main/enum_not_support_float.ets.arkts2.json b/ets2panda/linter/test/main/enum_not_support_float.ets.arkts2.json index d4ffa9eb19c5048cf8f47e78c548f6b55cee5048..ff258d6c128395ffaa10c3a1f32fcde5e9e2f7cb 100644 --- a/ets2panda/linter/test/main/enum_not_support_float.ets.arkts2.json +++ b/ets2panda/linter/test/main/enum_not_support_float.ets.arkts2.json @@ -34,6 +34,46 @@ "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", "severity": "ERROR" }, + { + "line": 39, + "column": 10, + "endLine": 39, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 15, + "endLine": 39, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 11, + "endLine": 40, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 16, + "endLine": 40, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 44, "column": 7, @@ -44,6 +84,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 44, + "column": 18, + "endLine": 44, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 45, "column": 5, @@ -54,6 +104,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 45, + "column": 14, + "endLine": 45, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 49, "column": 3, @@ -73,6 +133,26 @@ "suggest": "", "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", "severity": "ERROR" + }, + { + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 12, + "endLine": 54, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/equals_token_option.ets b/ets2panda/linter/test/main/equals_token_option.ets new file mode 100755 index 0000000000000000000000000000000000000000..0c3da5b2574ea6fc0c52e7b53ec280a0f25472c4 --- /dev/null +++ b/ets2panda/linter/test/main/equals_token_option.ets @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022-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; +a &&=2; +a ||=2; +a ??=2; +typeof (a ||=2); +let person = { name: "Alice", age: 30 }; + +function setAge(){ + person.age &&= - 1; +} +person.age = 0; +person.age &&= 5; + +let count: number | null = null; +count ??= 10; + +count = 0; +count ??= 5; +console.log((count ??= 5)+'') +function getCount(){ + return (count ??= 5); +} +let message: string | null = null; + +message ||= "msg"; +console.log(message); + +message = "msg1"; +message ||= "newMsg"; +console.log(message); +class Demo{ + constructor() { + message ||= "defaultMsg"; + } + setMes(){ + message ||= "defaultMsg"; + } + getMes(){ + return message ??= "newMsg"; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/void_operator.ts.args.json b/ets2panda/linter/test/main/equals_token_option.ets.args.json old mode 100644 new mode 100755 similarity index 97% rename from ets2panda/linter/test/migrate/void_operator.ts.args.json rename to ets2panda/linter/test/main/equals_token_option.ets.args.json index 18bd09a6663ad5c031113d0e9c112c2407277375..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- a/ets2panda/linter/test/migrate/void_operator.ts.args.json +++ b/ets2panda/linter/test/main/equals_token_option.ets.args.json @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "migrate": "" + "arkts2": "" } } diff --git a/ets2panda/linter/test/migrate/function_expression.ts.json b/ets2panda/linter/test/main/equals_token_option.ets.arkts2.json old mode 100644 new mode 100755 similarity index 34% rename from ets2panda/linter/test/migrate/function_expression.ts.json rename to ets2panda/linter/test/main/equals_token_option.ets.arkts2.json index cd0c60aca76683778d948101f392bacba88dffbd..d63680f14923686d4652bfe79995b34ac69ec50a --- a/ets2panda/linter/test/migrate/function_expression.ts.json +++ b/ets2panda/linter/test/main/equals_token_option.ets.arkts2.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2022-2024 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", @@ -15,333 +15,323 @@ ], "result": [ { - "line": 16, - "column": 15, - "endLine": 16, - "endColumn": 29, - "problem": "FunctionExpression", + "line": 15, + "column": 5, + "endLine": 15, + "endColumn": 9, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 18, - "column": 18, - "endLine": 20, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 15, + "column": 8, + "endLine": 15, + "endColumn": 9, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 18, - "column": 39, - "endLine": 18, - "endColumn": 40, - "problem": "AnyType", + "line": 16, + "column": 3, + "endLine": 16, + "endColumn": 6, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 23, - "column": 10, - "endLine": 25, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 16, + "column": 6, + "endLine": 16, + "endColumn": 7, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 28, - "column": 17, - "endLine": 30, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 17, + "column": 3, + "endLine": 17, + "endColumn": 6, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 32, - "column": 2, - "endLine": 34, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 17, + "column": 6, + "endLine": 17, + "endColumn": 7, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 36, - "column": 7, - "endLine": 38, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 6, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 41, - "column": 26, - "endLine": 43, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 18, + "column": 6, + "endLine": 18, + "endColumn": 7, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 44, - "column": 27, - "endLine": 46, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 19, + "column": 12, + "endLine": 19, + "endColumn": 15, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 48, - "column": 22, - "endLine": 50, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 19, + "column": 15, + "endLine": 19, + "endColumn": 16, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 48, - "column": 22, - "endLine": 50, - "endColumn": 2, - "problem": "LimitedReturnTypeInference", + "line": 20, + "column": 14, + "endLine": 20, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 48, - "column": 35, - "endLine": 48, + "line": 20, + "column": 36, + "endLine": 20, "endColumn": 38, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 19, - "endLine": 54, - "endColumn": 2, - "problem": "FunctionExpression", + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 52, - "column": 19, - "endLine": 54, - "endColumn": 2, - "problem": "GeneratorFunction", + "line": 23, + "column": 14, + "endLine": 23, + "endColumn": 17, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Generator functions are not supported (arkts-no-generators)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 53, - "column": 3, - "endLine": 53, - "endColumn": 10, - "problem": "YieldExpression", + "line": 23, + "column": 20, + "endLine": 23, + "endColumn": 21, + "problem": "NumericSemantics", "suggest": "", - "rule": "Generator functions are not supported (arkts-no-generators)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 56, - "column": 17, - "endLine": 58, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 25, + "column": 14, + "endLine": 25, + "endColumn": 15, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 60, - "column": 18, - "endLine": 62, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 26, + "column": 12, + "endLine": 26, + "endColumn": 15, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 64, - "column": 19, - "endLine": 66, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 26, + "column": 16, + "endLine": 26, + "endColumn": 17, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 71, - "column": 25, - "endLine": 76, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 10, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 78, - "column": 12, - "endLine": 80, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 29, + "column": 11, + "endLine": 29, + "endColumn": 13, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 82, - "column": 5, - "endLine": 84, - "endColumn": 5, - "problem": "AnyType", + "line": 31, + "column": 9, + "endLine": 31, + "endColumn": 10, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 82, - "column": 19, - "endLine": 84, - "endColumn": 5, - "problem": "PropertyAccessByIndex", + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 10, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 82, - "column": 19, - "endLine": 84, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 32, + "column": 11, + "endLine": 32, + "endColumn": 12, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 86, - "column": 6, - "endLine": 88, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 33, + "column": 20, + "endLine": 33, + "endColumn": 23, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 91, - "column": 9, - "endLine": 93, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 33, + "column": 24, + "endLine": 33, + "endColumn": 25, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 96, - "column": 25, - "endLine": 98, + "line": 34, + "column": 1, + "endLine": 36, "endColumn": 2, - "problem": "FunctionExpression", + "problem": "NumericSemantics", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 102, - "column": 9, - "endLine": 104, - "endColumn": 17, - "problem": "AnyType", + "line": 35, + "column": 17, + "endLine": 35, + "endColumn": 20, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 104, - "column": 7, - "endLine": 104, - "endColumn": 17, - "problem": "FunctionBind", + "line": 35, + "column": 21, + "endLine": 35, + "endColumn": 22, + "problem": "NumericSemantics", "suggest": "", - "rule": "'Function.bind' is not supported (arkts-no-func-bind)", - "severity": "WARNING" + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" }, { - "line": 102, - "column": 15, - "endLine": 104, - "endColumn": 6, - "problem": "FunctionExpression", + "line": 39, + "column": 9, + "endLine": 39, + "endColumn": 12, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 108, - "column": 16, - "endLine": 108, - "endColumn": 55, - "problem": "FunctionExpression", + "line": 43, + "column": 9, + "endLine": 43, + "endColumn": 12, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 109, - "column": 24, - "endLine": 109, - "endColumn": 75, - "problem": "FunctionExpression", + "line": 47, + "column": 13, + "endLine": 47, + "endColumn": 16, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 112, - "column": 5, - "endLine": 112, - "endColumn": 45, - "problem": "FunctionExpression", + "line": 50, + "column": 13, + "endLine": 50, + "endColumn": 16, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" }, { - "line": 113, - "column": 10, - "endLine": 113, - "endColumn": 50, - "problem": "FunctionExpression", + "line": 53, + "column": 20, + "endLine": 53, + "endColumn": 23, + "problem": "UnsupportOperator", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Operator is not support (arkts-unsupport-operator)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/equals_token_option.ets.json b/ets2panda/linter/test/main/equals_token_option.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..4dccd5bab8034ecea69fdd2c1339d88827958515 --- /dev/null +++ b/ets2panda/linter/test/main/equals_token_option.ets.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": 20, + "column": 14, + "endLine": 20, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/es_object.ets b/ets2panda/linter/test/main/es_object.ets index 573c6a523a8f4324ac87ca9460a87897b11f3c56..61241cdf08795eda3006ac574e35c78201cd3f3c 100644 --- a/ets2panda/linter/test/main/es_object.ets +++ b/ets2panda/linter/test/main/es_object.ets @@ -13,47 +13,47 @@ * limitations under the License. */ import { fooOh, barOh } from './oh_modules/ohos_lib' -type ESObject = any +type ESValue = any class A {} -let g1: ESObject -let g2: ESObject[] -let g3: A +let g1: ESValue +let g2: ESValue[] +let g3: A class B { - f1: ESObject - f2: ESObject[] - f3: A + f1: ESValue + f2: ESValue[] + f3: A - constructor(p1: ESObject, p2: ESObject[], p3: A) { + constructor(p1: ESValue, p2: ESValue[], p3: A) { this.f1 = p1 this.f2 = p2 this.f3 = p3 } - foo1(p1: ESObject, p2: ESObject[], p3: A): ESObject { + foo1(p1: ESValue, p2: ESValue[], p3: A): ESValue { return p1 } - foo2(p1: ESObject, p2: ESObject[], p3: A): ESObject[] { + foo2(p1: ESValue, p2: ESValue[], p3: A): ESValue[] { return p2 } - foo3(p1: ESObject, p2: ESObject[], p3: A): A { + foo3(p1: ESValue, p2: ESValue[], p3: A): A { return p3 } } -function bar1(p1: ESObject, p2: ESObject[], p3: A): ESObject { +function bar1(p1: ESValue, p2: ESValue[], p3: A): ESValue { return p1 } -function bar2(p1: ESObject, p2: ESObject[], p3: A): ESObject[] { +function bar2(p1: ESValue, p2: ESValue[], p3: A): ESValue[] { return p2 } -function bar3(p1: ESObject, p2: ESObject[], p3: A): A { +function bar3(p1: ESValue, p2: ESValue[], p3: A): A { return p3 } @@ -61,14 +61,14 @@ function ff(): {x: number} { return {x: 10} } -function baz(p1: ESObject, p2: ESObject[], p3: A): void { - const c1: ESObject = p1; - const c2: ESObject[] = p2 - const c3: A = p3 +function baz(p1: ESValue, p2: ESValue[], p3: A): void { + const c1: ESValue = p1; + const c2: ESValue[] = p2 + const c3: A = p3 - let v1: ESObject = p1 - let v2: ESObject[] = p2 - let v3: A = p3 + let v1: ESValue = p1 + let v2: ESValue[] = p2 + let v3: A = p3 v1 = c1 v2 = c2 @@ -87,36 +87,36 @@ function baz(p1: ESObject, p2: ESObject[], p3: A): void { v1 = [p1, c1, "abc"] v1 = new A() - let v11: ESObject = {} - let v12: ESObject = "abc" - let v13: ESObject = ff() - let v14: ESObject = [1, 2] - let v15: ESObject = [p1, c1] - let v16: ESObject = [p1, c1, "abc"] - let v17: ESObject = new A() + let v11: ESValue = {} + let v12: ESValue = "abc" + let v13: ESValue = ff() + let v14: ESValue = [1, 2] + let v15: ESValue = [p1, c1] + let v16: ESValue = [p1, c1, "abc"] + let v17: ESValue = new A() let n1: number = v1 n1 = v1 let n2: number = p1 as number } -export let obj = new ESObject(); +export let obj = new ESValue(); -type t1 = ESObject -type t2 = ESObject[] +type t1 = ESValue +type t2 = ESValue[] -export type t3 = ESObject -export type t4 = ESObject[] +export type t3 = ESValue +export type t4 = ESValue[] export type t5 = t3 export type t6 = t4[] export function foo1(): any { - let a: ESObject = "STRING"; + let a: ESValue = "STRING"; return a } -export function foo2(a: ESObject): ESObject { +export function foo2(a: ESValue): ESValue { return a; } @@ -133,7 +133,7 @@ foo3(null) foo2(undefined) foo3(undefined) -export function foo4(a: ESObject[]): ESObject { +export function foo4(a: ESValue[]): ESValue { return a; } @@ -145,13 +145,13 @@ foo4([2, 3]) foo5([2, 3]) foo4(["str1", "str2"]) foo5(["str1", "str2"]) -let n: ESObject +let n: ESValue n = null foo4(n) foo5(n) -export function foo6(a: ESObject[]): ESObject { +export function foo6(a: ESValue[]): ESValue { return a; } @@ -159,7 +159,7 @@ export function foo7(a: t3[]): t3 { return a; } -export function foo8(a: ESObject[]): ESObject { +export function foo8(a: ESValue[]): ESValue { return a; } @@ -167,27 +167,27 @@ export function foo9(a: t3[]): t3 { return a; } -export class Cls {} +export class Cls {} -interface CL extends ESObject {} +interface CL extends ESValue {} -export interface CLS extends ESObject {} +export interface CLS extends ESValue {} foo2({ k: 'k', h: {t: 1}}) // we can assign anything to the esobject, even untyped literal -let q1: ESObject = 1; // CTE - ``ESObject`` typed variable can only be local -let q2: ESObject = fooOh(); // CTE - ``ESObject`` typed variable can only be local -let q3: ESObject = q2; // CTE - ``ESObject`` typed variable can only be local +let q1: ESValue = 1; // CTE - ``ESValue`` typed variable can only be local +let q2: ESValue = fooOh(); // CTE - ``ESValue`` typed variable can only be local +let q3: ESValue = q2; // CTE - ``ESValue`` typed variable can only be local function f() { let e1 = fooOh(); // CTE - type of e1 is `any` - let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values - let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values - let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values - let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values - let e6: ESObject = fooOh(); // OK - explicitly annotaded as ESObject - let e7: ESObject = e6; // OK - initialize ESObject with ESObject - e6['prop'] // CTE - can't access dynamic properties of ESObject - e6[1] // CTE - can't access dynamic properties of ESObject - e6.prop // CTE - can't access dynamic properties of ESObject - barOh(e6) // OK - ESObject is passed to interop call - e6 = e7 // OK - ESObject is assigned to ESObject + let e2: ESValue = 1; // CTE - can't initialize ESValue with not dynamic values + let e3: ESValue = {}; // CTE - can't initialize ESValue with not dynamic values + let e4: ESValue = []; // CTE - can't initialize ESValue with not dynamic values + let e5: ESValue = ""; // CTE - can't initialize ESValue with not dynamic values + let e6: ESValue = fooOh(); // OK - explicitly annotaded as ESValue + let e7: ESValue = e6; // OK - initialize ESValue with ESValue + e6['prop'] // CTE - can't access dynamic properties of ESValue + e6[1] // CTE - can't access dynamic properties of ESValue + e6.prop // CTE - can't access dynamic properties of ESValue + barOh(e6) // OK - ESValue is passed to interop call + e6 = e7 // OK - ESValue is assigned to ESValue } diff --git a/ets2panda/linter/test/main/es_object.ets.args.json b/ets2panda/linter/test/main/es_object.ets.args.json index c82e9090b14efa2b6677fac8f410b039972ff7be..4c5ee75ae13eb33a07ef6b198f7fdb637c8d84fc 100644 --- a/ets2panda/linter/test/main/es_object.ets.args.json +++ b/ets2panda/linter/test/main/es_object.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", diff --git a/ets2panda/linter/test/main/es_object.ets.arkts2.json b/ets2panda/linter/test/main/es_object.ets.arkts2.json index 68eef9e72dc046a8764c25cce9f63811c7128f6c..79c951c0d912a7ac671a4b8f6c39da9ad1a785c4 100644 --- a/ets2panda/linter/test/main/es_object.ets.arkts2.json +++ b/ets2panda/linter/test/main/es_object.ets.arkts2.json @@ -1,24 +1,24 @@ { "copyright": [ - "Copyright (c) 2024 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 (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." ], "result": [ { "line": 16, - "column": 17, + "column": 16, "endLine": 16, - "endColumn": 20, + "endColumn": 19, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,330 +28,330 @@ "line": 20, "column": 5, "endLine": 20, - "endColumn": 17, - "problem": "EsObjectTypeError", + "endColumn": 16, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 21, "column": 9, "endLine": 21, - "endColumn": 17, - "problem": "EsObjectTypeError", + "endColumn": 16, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 22, "column": 11, "endLine": 22, - "endColumn": 19, - "problem": "EsObjectTypeError", + "endColumn": 18, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 25, "column": 9, "endLine": 25, - "endColumn": 17, - "problem": "EsObjectTypeError", + "endColumn": 16, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 26, "column": 9, "endLine": 26, - "endColumn": 17, - "problem": "EsObjectTypeError", + "endColumn": 16, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 27, "column": 11, "endLine": 27, - "endColumn": 19, - "problem": "EsObjectTypeError", + "endColumn": 18, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 29, "column": 21, "endLine": 29, - "endColumn": 29, - "problem": "EsObjectTypeError", + "endColumn": 28, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 29, - "column": 35, + "column": 34, "endLine": 29, - "endColumn": 43, - "problem": "EsObjectTypeError", + "endColumn": 41, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 29, - "column": 53, + "column": 51, "endLine": 29, - "endColumn": 61, - "problem": "EsObjectTypeError", + "endColumn": 58, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 35, "column": 14, "endLine": 35, - "endColumn": 22, - "problem": "EsObjectTypeError", + "endColumn": 21, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 35, - "column": 28, + "column": 27, "endLine": 35, - "endColumn": 36, - "problem": "EsObjectTypeError", + "endColumn": 34, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 35, - "column": 46, + "column": 44, "endLine": 35, - "endColumn": 54, - "problem": "EsObjectTypeError", + "endColumn": 51, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 35, - "column": 58, + "column": 55, "endLine": 35, - "endColumn": 66, - "problem": "EsObjectTypeError", + "endColumn": 62, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 39, "column": 14, "endLine": 39, - "endColumn": 22, - "problem": "EsObjectTypeError", + "endColumn": 21, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 39, - "column": 28, + "column": 27, "endLine": 39, - "endColumn": 36, - "problem": "EsObjectTypeError", + "endColumn": 34, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 39, - "column": 46, + "column": 44, "endLine": 39, - "endColumn": 54, - "problem": "EsObjectTypeError", + "endColumn": 51, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 39, - "column": 58, + "column": 55, "endLine": 39, - "endColumn": 66, - "problem": "EsObjectTypeError", + "endColumn": 62, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 43, "column": 14, "endLine": 43, - "endColumn": 22, - "problem": "EsObjectTypeError", + "endColumn": 21, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 43, - "column": 28, + "column": 27, "endLine": 43, - "endColumn": 36, - "problem": "EsObjectTypeError", + "endColumn": 34, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 43, - "column": 46, + "column": 44, "endLine": 43, - "endColumn": 54, - "problem": "EsObjectTypeError", + "endColumn": 51, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 43, - "column": 60, + "column": 57, "endLine": 43, - "endColumn": 68, - "problem": "EsObjectTypeError", + "endColumn": 64, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 48, "column": 19, "endLine": 48, - "endColumn": 27, - "problem": "EsObjectTypeError", + "endColumn": 26, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 48, - "column": 33, + "column": 32, "endLine": 48, - "endColumn": 41, - "problem": "EsObjectTypeError", + "endColumn": 39, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 48, - "column": 51, + "column": 49, "endLine": 48, - "endColumn": 59, - "problem": "EsObjectTypeError", + "endColumn": 56, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 48, - "column": 63, + "column": 60, "endLine": 48, - "endColumn": 71, - "problem": "EsObjectTypeError", + "endColumn": 67, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 52, "column": 19, "endLine": 52, - "endColumn": 27, - "problem": "EsObjectTypeError", + "endColumn": 26, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 52, - "column": 33, + "column": 32, "endLine": 52, - "endColumn": 41, - "problem": "EsObjectTypeError", + "endColumn": 39, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 52, - "column": 51, + "column": 49, "endLine": 52, - "endColumn": 59, - "problem": "EsObjectTypeError", + "endColumn": 56, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 52, - "column": 63, + "column": 60, "endLine": 52, - "endColumn": 71, - "problem": "EsObjectTypeError", + "endColumn": 67, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 56, "column": 19, "endLine": 56, - "endColumn": 27, - "problem": "EsObjectTypeError", + "endColumn": 26, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 56, - "column": 33, + "column": 32, "endLine": 56, - "endColumn": 41, - "problem": "EsObjectTypeError", + "endColumn": 39, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 56, - "column": 51, + "column": 49, "endLine": 56, - "endColumn": 59, - "problem": "EsObjectTypeError", + "endColumn": 56, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 56, - "column": 65, + "column": 62, "endLine": 56, - "endColumn": 73, - "problem": "EsObjectTypeError", + "endColumn": 69, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -374,74 +374,84 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 61, + "column": 16, + "endLine": 61, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 64, "column": 18, "endLine": 64, - "endColumn": 26, - "problem": "EsObjectTypeError", + "endColumn": 25, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 64, - "column": 32, + "column": 31, "endLine": 64, - "endColumn": 40, - "problem": "EsObjectTypeError", + "endColumn": 38, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 64, - "column": 50, + "column": 48, "endLine": 64, - "endColumn": 58, - "problem": "EsObjectTypeError", + "endColumn": 55, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 66, "column": 15, "endLine": 66, - "endColumn": 23, - "problem": "EsObjectTypeError", + "endColumn": 22, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 67, "column": 17, "endLine": 67, - "endColumn": 25, - "problem": "EsObjectTypeError", + "endColumn": 24, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 70, "column": 13, "endLine": 70, - "endColumn": 21, - "problem": "EsObjectTypeError", + "endColumn": 20, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 71, "column": 15, "endLine": 71, - "endColumn": 23, - "problem": "EsObjectTypeError", + "endColumn": 22, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -449,9 +459,19 @@ "column": 5, "endLine": 77, "endColumn": 9, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 12, + "endLine": 77, + "endColumn": 14, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -459,9 +479,9 @@ "column": 5, "endLine": 78, "endColumn": 13, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -469,9 +489,19 @@ "column": 5, "endLine": 79, "endColumn": 11, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 14, + "endLine": 79, + "endColumn": 16, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -479,9 +509,19 @@ "column": 5, "endLine": 80, "endColumn": 11, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 8, + "endLine": 80, + "endColumn": 10, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -489,9 +529,9 @@ "column": 5, "endLine": 82, "endColumn": 12, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -499,9 +539,9 @@ "column": 5, "endLine": 83, "endColumn": 15, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -509,9 +549,29 @@ "column": 5, "endLine": 85, "endColumn": 16, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 11, + "endLine": 85, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 14, + "endLine": 85, + "endColumn": 15, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -519,9 +579,9 @@ "column": 5, "endLine": 86, "endColumn": 18, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -529,9 +589,9 @@ "column": 5, "endLine": 87, "endColumn": 25, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -539,69 +599,89 @@ "column": 5, "endLine": 88, "endColumn": 25, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 90, "column": 9, "endLine": 90, - "endColumn": 27, - "problem": "EsObjectTypeError", + "endColumn": 26, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 91, "column": 9, "endLine": 91, - "endColumn": 30, - "problem": "EsObjectTypeError", + "endColumn": 29, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 93, "column": 9, "endLine": 93, - "endColumn": 31, - "problem": "EsObjectTypeError", + "endColumn": 30, + "problem": "EsValueTypeError", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 25, + "endLine": 93, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 28, + "endLine": 93, + "endColumn": 29, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { "line": 94, "column": 9, "endLine": 94, - "endColumn": 33, - "problem": "EsObjectTypeError", + "endColumn": 32, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 95, "column": 9, "endLine": 95, - "endColumn": 40, - "problem": "EsObjectTypeError", + "endColumn": 39, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 96, "column": 9, "endLine": 96, - "endColumn": 40, - "problem": "EsObjectTypeError", + "endColumn": 39, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -609,9 +689,9 @@ "column": 9, "endLine": 98, "endColumn": 24, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -619,16 +699,16 @@ "column": 5, "endLine": 99, "endColumn": 12, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 103, "column": 12, "endLine": 103, - "endColumn": 32, + "endColumn": 31, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -638,7 +718,7 @@ "line": 103, "column": 22, "endLine": 103, - "endColumn": 30, + "endColumn": 29, "problem": "DynamicCtorCall", "suggest": "", "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", @@ -648,40 +728,40 @@ "line": 105, "column": 11, "endLine": 105, - "endColumn": 19, - "problem": "EsObjectTypeError", + "endColumn": 18, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 106, "column": 11, "endLine": 106, - "endColumn": 19, - "problem": "EsObjectTypeError", + "endColumn": 18, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 108, "column": 18, "endLine": 108, - "endColumn": 26, - "problem": "EsObjectTypeError", + "endColumn": 25, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 109, "column": 18, "endLine": 109, - "endColumn": 26, - "problem": "EsObjectTypeError", + "endColumn": 25, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -698,60 +778,120 @@ "line": 115, "column": 9, "endLine": 115, - "endColumn": 31, - "problem": "EsObjectTypeError", + "endColumn": 30, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 119, "column": 25, "endLine": 119, - "endColumn": 33, - "problem": "EsObjectTypeError", + "endColumn": 32, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 119, - "column": 36, + "column": 35, "endLine": 119, - "endColumn": 44, - "problem": "EsObjectTypeError", + "endColumn": 42, + "problem": "EsValueTypeError", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 6, + "endLine": 127, + "endColumn": 7, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 6, + "endLine": 128, + "endColumn": 7, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { "line": 136, "column": 25, "endLine": 136, - "endColumn": 33, - "problem": "EsObjectTypeError", + "endColumn": 32, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 136, - "column": 38, + "column": 37, "endLine": 136, - "endColumn": 46, - "problem": "EsObjectTypeError", + "endColumn": 44, + "problem": "EsValueTypeError", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 7, + "endLine": 144, + "endColumn": 8, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 10, + "endLine": 144, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 7, + "endLine": 145, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 10, + "endLine": 145, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { "line": 148, "column": 5, "endLine": 148, - "endColumn": 16, - "problem": "EsObjectTypeError", + "endColumn": 15, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -759,99 +899,99 @@ "column": 1, "endLine": 149, "endColumn": 9, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 154, "column": 32, "endLine": 154, - "endColumn": 40, - "problem": "EsObjectTypeError", + "endColumn": 39, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 154, - "column": 45, + "column": 44, "endLine": 154, - "endColumn": 53, - "problem": "EsObjectTypeError", + "endColumn": 51, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 154, - "column": 58, + "column": 56, "endLine": 154, - "endColumn": 66, - "problem": "EsObjectTypeError", + "endColumn": 63, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 162, "column": 32, "endLine": 162, - "endColumn": 40, - "problem": "EsObjectTypeError", + "endColumn": 39, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 162, - "column": 47, + "column": 46, "endLine": 162, - "endColumn": 55, - "problem": "EsObjectTypeError", + "endColumn": 53, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 162, - "column": 60, + "column": 58, "endLine": 162, - "endColumn": 68, - "problem": "EsObjectTypeError", + "endColumn": 65, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 170, "column": 28, "endLine": 170, - "endColumn": 36, - "problem": "EsObjectTypeError", + "endColumn": 35, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 172, "column": 22, "endLine": 172, - "endColumn": 30, - "problem": "EsObjectTypeError", + "endColumn": 29, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 174, "column": 30, "endLine": 174, - "endColumn": 38, - "problem": "EsObjectTypeError", + "endColumn": 37, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -864,34 +1004,54 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 176, + "column": 23, + "endLine": 176, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 177, "column": 5, "endLine": 177, - "endColumn": 21, - "problem": "EsObjectTypeError", + "endColumn": 20, + "problem": "EsValueTypeError", + "suggest": "", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 19, + "endLine": 177, + "endColumn": 20, + "problem": "NumericSemantics", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { "line": 178, "column": 5, "endLine": 178, - "endColumn": 27, - "problem": "EsObjectTypeError", + "endColumn": 26, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 179, "column": 5, "endLine": 179, - "endColumn": 22, - "problem": "EsObjectTypeError", + "endColumn": 21, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -908,40 +1068,50 @@ "line": 182, "column": 9, "endLine": 182, - "endColumn": 25, - "problem": "EsObjectTypeError", + "endColumn": 24, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 23, + "endLine": 182, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { "line": 183, "column": 9, "endLine": 183, - "endColumn": 26, - "problem": "EsObjectTypeError", + "endColumn": 25, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 184, "column": 9, "endLine": 184, - "endColumn": 26, - "problem": "EsObjectTypeError", + "endColumn": 25, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { "line": 185, "column": 9, "endLine": 185, - "endColumn": 26, - "problem": "EsObjectTypeError", + "endColumn": 25, + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -949,9 +1119,9 @@ "column": 5, "endLine": 188, "endColumn": 15, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -959,9 +1129,9 @@ "column": 5, "endLine": 189, "endColumn": 10, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" }, { @@ -969,10 +1139,10 @@ "column": 5, "endLine": 190, "endColumn": 12, - "problem": "EsObjectTypeError", + "problem": "EsValueTypeError", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "ERROR" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/es_object.ets.json b/ets2panda/linter/test/main/es_object.ets.json index f4bf11de9b0c5aed2acb63721287dd8c6fff19da..536dc90f885170757c01f40a3484b0fee5c61938 100644 --- a/ets2panda/linter/test/main/es_object.ets.json +++ b/ets2panda/linter/test/main/es_object.ets.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "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", @@ -16,9 +16,9 @@ "result": [ { "line": 16, - "column": 17, + "column": 16, "endLine": 16, - "endColumn": 20, + "endColumn": 19, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,330 +28,330 @@ "line": 20, "column": 5, "endLine": 20, - "endColumn": 17, - "problem": "EsObjectType", + "endColumn": 16, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 21, "column": 9, "endLine": 21, - "endColumn": 17, - "problem": "EsObjectType", + "endColumn": 16, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 22, "column": 11, "endLine": 22, - "endColumn": 19, - "problem": "EsObjectType", + "endColumn": 18, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 25, "column": 9, "endLine": 25, - "endColumn": 17, - "problem": "EsObjectType", + "endColumn": 16, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 26, "column": 9, "endLine": 26, - "endColumn": 17, - "problem": "EsObjectType", + "endColumn": 16, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 27, "column": 11, "endLine": 27, - "endColumn": 19, - "problem": "EsObjectType", + "endColumn": 18, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 29, "column": 21, "endLine": 29, - "endColumn": 29, - "problem": "EsObjectType", + "endColumn": 28, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 29, - "column": 35, + "column": 34, "endLine": 29, - "endColumn": 43, - "problem": "EsObjectType", + "endColumn": 41, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 29, - "column": 53, + "column": 51, "endLine": 29, - "endColumn": 61, - "problem": "EsObjectType", + "endColumn": 58, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 35, "column": 14, "endLine": 35, - "endColumn": 22, - "problem": "EsObjectType", + "endColumn": 21, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 35, - "column": 28, + "column": 27, "endLine": 35, - "endColumn": 36, - "problem": "EsObjectType", + "endColumn": 34, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 35, - "column": 46, + "column": 44, "endLine": 35, - "endColumn": 54, - "problem": "EsObjectType", + "endColumn": 51, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 35, - "column": 58, + "column": 55, "endLine": 35, - "endColumn": 66, - "problem": "EsObjectType", + "endColumn": 62, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 39, "column": 14, "endLine": 39, - "endColumn": 22, - "problem": "EsObjectType", + "endColumn": 21, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 39, - "column": 28, + "column": 27, "endLine": 39, - "endColumn": 36, - "problem": "EsObjectType", + "endColumn": 34, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 39, - "column": 46, + "column": 44, "endLine": 39, - "endColumn": 54, - "problem": "EsObjectType", + "endColumn": 51, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 39, - "column": 58, + "column": 55, "endLine": 39, - "endColumn": 66, - "problem": "EsObjectType", + "endColumn": 62, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 43, "column": 14, "endLine": 43, - "endColumn": 22, - "problem": "EsObjectType", + "endColumn": 21, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 43, - "column": 28, + "column": 27, "endLine": 43, - "endColumn": 36, - "problem": "EsObjectType", + "endColumn": 34, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 43, - "column": 46, + "column": 44, "endLine": 43, - "endColumn": 54, - "problem": "EsObjectType", + "endColumn": 51, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 43, - "column": 60, + "column": 57, "endLine": 43, - "endColumn": 68, - "problem": "EsObjectType", + "endColumn": 64, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 48, "column": 19, "endLine": 48, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 48, - "column": 33, + "column": 32, "endLine": 48, - "endColumn": 41, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 48, - "column": 51, + "column": 49, "endLine": 48, - "endColumn": 59, - "problem": "EsObjectType", + "endColumn": 56, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 48, - "column": 63, + "column": 60, "endLine": 48, - "endColumn": 71, - "problem": "EsObjectType", + "endColumn": 67, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 52, "column": 19, "endLine": 52, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 52, - "column": 33, + "column": 32, "endLine": 52, - "endColumn": 41, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 52, - "column": 51, + "column": 49, "endLine": 52, - "endColumn": 59, - "problem": "EsObjectType", + "endColumn": 56, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 52, - "column": 63, + "column": 60, "endLine": 52, - "endColumn": 71, - "problem": "EsObjectType", + "endColumn": 67, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 56, "column": 19, "endLine": 56, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 56, - "column": 33, + "column": 32, "endLine": 56, - "endColumn": 41, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 56, - "column": 51, + "column": 49, "endLine": 56, - "endColumn": 59, - "problem": "EsObjectType", + "endColumn": 56, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 56, - "column": 65, + "column": 62, "endLine": 56, - "endColumn": 73, - "problem": "EsObjectType", + "endColumn": 69, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -378,70 +378,70 @@ "line": 64, "column": 18, "endLine": 64, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 64, - "column": 32, + "column": 31, "endLine": 64, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 38, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 64, - "column": 50, + "column": 48, "endLine": 64, - "endColumn": 58, - "problem": "EsObjectType", + "endColumn": 55, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 66, "column": 15, "endLine": 66, - "endColumn": 23, - "problem": "EsObjectType", + "endColumn": 22, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 67, "column": 17, "endLine": 67, - "endColumn": 25, - "problem": "EsObjectType", + "endColumn": 24, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 70, "column": 13, "endLine": 70, - "endColumn": 21, - "problem": "EsObjectType", + "endColumn": 20, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 71, "column": 15, "endLine": 71, - "endColumn": 23, - "problem": "EsObjectType", + "endColumn": 22, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -449,9 +449,9 @@ "column": 5, "endLine": 77, "endColumn": 9, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -459,9 +459,9 @@ "column": 5, "endLine": 78, "endColumn": 13, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -469,9 +469,9 @@ "column": 5, "endLine": 79, "endColumn": 11, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -479,9 +479,9 @@ "column": 5, "endLine": 80, "endColumn": 11, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -489,9 +489,9 @@ "column": 5, "endLine": 82, "endColumn": 12, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -499,9 +499,9 @@ "column": 5, "endLine": 83, "endColumn": 15, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -509,9 +509,9 @@ "column": 5, "endLine": 85, "endColumn": 16, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -519,9 +519,9 @@ "column": 5, "endLine": 86, "endColumn": 18, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -529,9 +529,9 @@ "column": 5, "endLine": 87, "endColumn": 25, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -539,69 +539,69 @@ "column": 5, "endLine": 88, "endColumn": 25, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 90, "column": 9, "endLine": 90, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 91, "column": 9, "endLine": 91, - "endColumn": 30, - "problem": "EsObjectType", + "endColumn": 29, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 93, "column": 9, "endLine": 93, - "endColumn": 31, - "problem": "EsObjectType", + "endColumn": 30, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 94, "column": 9, "endLine": 94, - "endColumn": 33, - "problem": "EsObjectType", + "endColumn": 32, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 95, "column": 9, "endLine": 95, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 96, "column": 9, "endLine": 96, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -609,9 +609,9 @@ "column": 9, "endLine": 98, "endColumn": 24, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -619,16 +619,16 @@ "column": 5, "endLine": 99, "endColumn": 12, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 103, "column": 12, "endLine": 103, - "endColumn": 32, + "endColumn": 31, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -638,40 +638,40 @@ "line": 105, "column": 11, "endLine": 105, - "endColumn": 19, - "problem": "EsObjectType", + "endColumn": 18, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 106, "column": 11, "endLine": 106, - "endColumn": 19, - "problem": "EsObjectType", + "endColumn": 18, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 108, "column": 18, "endLine": 108, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 109, "column": 18, "endLine": 109, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -688,60 +688,60 @@ "line": 115, "column": 9, "endLine": 115, - "endColumn": 31, - "problem": "EsObjectType", + "endColumn": 30, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 119, "column": 25, "endLine": 119, - "endColumn": 33, - "problem": "EsObjectType", + "endColumn": 32, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 119, - "column": 36, + "column": 35, "endLine": 119, - "endColumn": 44, - "problem": "EsObjectType", + "endColumn": 42, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 136, "column": 25, "endLine": 136, - "endColumn": 33, - "problem": "EsObjectType", + "endColumn": 32, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 136, - "column": 38, + "column": 37, "endLine": 136, - "endColumn": 46, - "problem": "EsObjectType", + "endColumn": 44, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 148, "column": 5, "endLine": 148, - "endColumn": 16, - "problem": "EsObjectType", + "endColumn": 15, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -749,99 +749,99 @@ "column": 1, "endLine": 149, "endColumn": 9, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 154, "column": 32, "endLine": 154, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 154, - "column": 45, + "column": 44, "endLine": 154, - "endColumn": 53, - "problem": "EsObjectType", + "endColumn": 51, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 154, - "column": 58, + "column": 56, "endLine": 154, - "endColumn": 66, - "problem": "EsObjectType", + "endColumn": 63, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 162, "column": 32, "endLine": 162, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 162, - "column": 47, + "column": 46, "endLine": 162, - "endColumn": 55, - "problem": "EsObjectType", + "endColumn": 53, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 162, - "column": 60, + "column": 58, "endLine": 162, - "endColumn": 68, - "problem": "EsObjectType", + "endColumn": 65, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 170, "column": 28, "endLine": 170, - "endColumn": 36, - "problem": "EsObjectType", + "endColumn": 35, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 172, "column": 22, "endLine": 172, - "endColumn": 30, - "problem": "EsObjectType", + "endColumn": 29, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 174, "column": 30, "endLine": 174, - "endColumn": 38, - "problem": "EsObjectType", + "endColumn": 37, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -858,30 +858,30 @@ "line": 177, "column": 5, "endLine": 177, - "endColumn": 21, - "problem": "EsObjectType", + "endColumn": 20, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 178, "column": 5, "endLine": 178, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 179, "column": 5, "endLine": 179, - "endColumn": 22, - "problem": "EsObjectType", + "endColumn": 21, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -898,40 +898,40 @@ "line": 182, "column": 9, "endLine": 182, - "endColumn": 25, - "problem": "EsObjectType", + "endColumn": 24, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 183, "column": 9, "endLine": 183, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 184, "column": 9, "endLine": 184, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 185, "column": 9, "endLine": 185, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -939,9 +939,9 @@ "column": 5, "endLine": 188, "endColumn": 15, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -949,9 +949,9 @@ "column": 5, "endLine": 189, "endColumn": 10, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -959,10 +959,10 @@ "column": 5, "endLine": 190, "endColumn": 12, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/main/explicit_function_type.ets b/ets2panda/linter/test/main/explicit_function_type.ets index ee7f99ecd5df56663b926ed8aba9585243d88464..9b440521971be16a2666905393f3b541f642d724 100755 --- a/ets2panda/linter/test/main/explicit_function_type.ets +++ b/ets2panda/linter/test/main/explicit_function_type.ets @@ -161,4 +161,15 @@ function compose45(...fns: Function[]): Function { } export let add: (a: number, b: number) => number; -export let add1: (a: string) => object; \ No newline at end of file +export let add1: (a: string) => object; + +f1(); + +class AB3 { + fn3: Function = () => {}; +} +let ab3 = new AB3(); +ab3.fn3(); + +const fn29: Function[] = []; +fn29[1](); \ No newline at end of file diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.args.json b/ets2panda/linter/test/main/explicit_function_type.ets.args.json index 4d93062f69db6d74420adeb506e0ca28c5580728..a89d885810708ad03d96e3e14bb6590efd1a7547 100755 --- a/ets2panda/linter/test/main/explicit_function_type.ets.args.json +++ b/ets2panda/linter/test/main/explicit_function_type.ets.args.json @@ -14,6 +14,8 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json b/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json index 36763e4d93109aec801215cfd6e821319b436556..6c7ca94b922852b39dbb8edf11e8a67856b34ea0 100755 --- a/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/explicit_function_type.ets.arkts2.json @@ -1,538 +1,328 @@ { - "copyright": [ - "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." - ], - "result": [ - { - "line": 15, - "column": 9, - "endLine": 15, - "endColumn": 17, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 9, - "endLine": 16, - "endColumn": 17, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 20, - "endLine": 16, - "endColumn": 33, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 9, - "endLine": 17, - "endColumn": 17, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 24, - "endLine": 17, - "endColumn": 32, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 10, - "endLine": 18, - "endColumn": 23, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 14, - "endLine": 19, - "endColumn": 22, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 7, - "endLine": 37, - "endColumn": 15, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 10, - "endLine": 41, - "endColumn": 18, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 7, - "endLine": 45, - "endColumn": 15, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 7, - "endLine": 53, - "endColumn": 15, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 19, - "endLine": 56, - "endColumn": 27, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 60, - "column": 26, - "endLine": 60, - "endColumn": 34, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 17, - "endLine": 65, - "endColumn": 25, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 25, - "endLine": 69, - "endColumn": 33, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 12, - "endLine": 70, - "endColumn": 20, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 12, - "endLine": 70, - "endColumn": 20, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 75, - "column": 20, - "endLine": 75, - "endColumn": 28, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 79, - "column": 11, - "endLine": 79, - "endColumn": 19, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 79, - "column": 11, - "endLine": 79, - "endColumn": 19, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 87, - "column": 12, - "endLine": 87, - "endColumn": 20, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 21, - "endLine": 96, - "endColumn": 29, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 101, - "column": 22, - "endLine": 101, - "endColumn": 30, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 101, - "column": 38, - "endLine": 101, - "endColumn": 46, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 101, - "column": 56, - "endLine": 101, - "endColumn": 64, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 105, - "column": 23, - "endLine": 105, - "endColumn": 31, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 109, - "column": 27, - "endLine": 109, - "endColumn": 35, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 114, - "column": 80, - "endLine": 114, - "endColumn": 88, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 16, - "endLine": 118, - "endColumn": 24, - "problem": "ClassAsObjectError", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 16, - "endLine": 118, - "endColumn": 24, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 121, - "column": 3, - "endLine": 121, - "endColumn": 10, - "problem": "TsOverload", - "suggest": "", - "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", - "severity": "ERROR" - }, - { - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 35, - "problem": "TsOverload", - "suggest": "", - "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", - "severity": "ERROR" - }, - { - "line": 122, - "column": 12, - "endLine": 122, - "endColumn": 20, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 123, - "column": 3, - "endLine": 125, - "endColumn": 4, - "problem": "TsOverload", - "suggest": "", - "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", - "severity": "ERROR" - }, - { - "line": 123, - "column": 13, - "endLine": 123, - "endColumn": 21, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 21, - "endLine": 128, - "endColumn": 29, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 31, - "endLine": 128, - "endColumn": 32, - "problem": "LimitedLiteralType", - "suggest": "", - "rule": "Literal types are restricted(arkts-limited-literal-types)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 33, - "endLine": 128, - "endColumn": 37, - "problem": "LimitedLiteralType", - "suggest": "", - "rule": "Literal types are restricted(arkts-limited-literal-types)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 39, - "endLine": 128, - "endColumn": 44, - "problem": "LimitedLiteralType", - "suggest": "", - "rule": "Literal types are restricted(arkts-limited-literal-types)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 57, - "endLine": 128, - "endColumn": 65, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 138, - "column": 34, - "endLine": 138, - "endColumn": 42, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 142, - "column": 11, - "endLine": 142, - "endColumn": 19, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 143, - "column": 36, - "endLine": 143, - "endColumn": 44, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 150, - "column": 16, - "endLine": 150, - "endColumn": 21, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 151, - "column": 14, - "endLine": 151, - "endColumn": 22, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 153, - "column": 20, - "endLine": 153, - "endColumn": 28, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 154, - "column": 9, - "endLine": 154, - "endColumn": 31, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 155, - "column": 17, - "endLine": 155, - "endColumn": 25, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 159, - "column": 28, - "endLine": 159, - "endColumn": 36, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 159, - "column": 41, - "endLine": 159, - "endColumn": 49, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 160, - "column": 47, - "endLine": 160, - "endColumn": 55, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 160, - "column": 85, - "endLine": 160, - "endColumn": 93, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - } - ] -} + "copyright": [ + "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." + ], + "result": [ + { + "line": 16, + "column": 20, + "endLine": 16, + "endColumn": 33, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 23, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 29, + "endLine": 21, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 27, + "endLine": 29, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 20, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 19, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 11, + "endLine": 93, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 16, + "endLine": 118, + "endColumn": 24, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 26, + "endLine": 118, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 29, + "endLine": 118, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 32, + "endLine": 118, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 10, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 35, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 3, + "endLine": 125, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 31, + "endLine": 128, + "endColumn": 32, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 31, + "endLine": 128, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 33, + "endLine": 128, + "endColumn": 37, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 39, + "endLine": 128, + "endColumn": 44, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 80, + "endLine": 128, + "endColumn": 81, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 3, + "endLine": 132, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 3, + "endLine": 139, + "endColumn": 11, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 41, + "endLine": 142, + "endColumn": 42, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 16, + "endLine": 150, + "endColumn": 21, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 14, + "endLine": 151, + "endColumn": 22, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 9, + "endLine": 154, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 62, + "endLine": 160, + "endColumn": 66, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 67, + "endLine": 160, + "endColumn": 71, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 1, + "endLine": 166, + "endColumn": 3, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 172, + "column": 1, + "endLine": 172, + "endColumn": 8, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 1, + "endLine": 175, + "endColumn": 8, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.autofix.json b/ets2panda/linter/test/main/explicit_function_type.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..6f0f0a04818feb1bc8998c01eb4f2dae5cefcabc --- /dev/null +++ b/ets2panda/linter/test/main/explicit_function_type.ets.autofix.json @@ -0,0 +1,526 @@ +{ + "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": 20, + "endLine": 16, + "endColumn": 33, + "problem": "FunctionExpression", + "autofix": [ + { + "start": 668, + "end": 681, + "replacementText": "() => { }", + "line": 16, + "column": 20, + "endLine": 16, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 23, + "problem": "FunctionExpression", + "autofix": [ + { + "start": 760, + "end": 773, + "replacementText": "() => { }", + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 29, + "endLine": 21, + "endColumn": 30, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 881, + "end": 882, + "replacementText": "1.0", + "line": 21, + "column": 29, + "endLine": 21, + "endColumn": 30 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 27, + "endLine": 29, + "endColumn": 29, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1047, + "end": 1049, + "replacementText": "42.0", + "line": 29, + "column": 27, + "endLine": 29, + "endColumn": 29 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "fn.unSafeCall", + "start": 1572, + "end": 1574, + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5 + } + ], + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 20, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 19, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 11, + "endLine": 93, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2073, + "end": 2074, + "replacementText": "2.0", + "line": 93, + "column": 11, + "endLine": 93, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 16, + "endLine": 118, + "endColumn": 24, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 26, + "endLine": 118, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2550, + "end": 2551, + "replacementText": "1.0", + "line": 118, + "column": 26, + "endLine": 118, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 29, + "endLine": 118, + "endColumn": 30, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2553, + "end": 2554, + "replacementText": "2.0", + "line": 118, + "column": 29, + "endLine": 118, + "endColumn": 30 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 32, + "endLine": 118, + "endColumn": 33, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2556, + "end": 2557, + "replacementText": "3.0", + "line": 118, + "column": 32, + "endLine": 118, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 10, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 35, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 3, + "endLine": 125, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 31, + "endLine": 128, + "endColumn": 32, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 31, + "endLine": 128, + "endColumn": 32, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2719, + "end": 2720, + "replacementText": "1.0", + "line": 128, + "column": 31, + "endLine": 128, + "endColumn": 32 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 33, + "endLine": 128, + "endColumn": 37, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 39, + "endLine": 128, + "endColumn": 44, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 80, + "endLine": 128, + "endColumn": 81, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2768, + "end": 2769, + "replacementText": "1.0", + "line": 128, + "column": 80, + "endLine": 128, + "endColumn": 81 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 3, + "endLine": 132, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 3, + "endLine": 139, + "endColumn": 11, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "callback.unSafeCall", + "start": 2921, + "end": 2929, + "line": 139, + "column": 3, + "endLine": 139, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 41, + "endLine": 142, + "endColumn": 42, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2995, + "end": 2996, + "replacementText": "1.0", + "line": 142, + "column": 41, + "endLine": 142, + "endColumn": 42 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 16, + "endLine": 150, + "endColumn": 21, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 14, + "endLine": 151, + "endColumn": 22, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 9, + "endLine": 154, + "endColumn": 31, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 62, + "endLine": 160, + "endColumn": 66, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "curr.unSafeCall", + "start": 3458, + "end": 3462, + "line": 160, + "column": 62, + "endLine": 160, + "endColumn": 66 + } + ], + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 67, + "endLine": 160, + "endColumn": 71, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "prev.unSafeCall", + "start": 3463, + "end": 3467, + "line": 160, + "column": 67, + "endLine": 160, + "endColumn": 71 + } + ], + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 1, + "endLine": 166, + "endColumn": 3, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "f1.unSafeCall", + "start": 3586, + "end": 3588, + "line": 166, + "column": 1, + "endLine": 166, + "endColumn": 3 + } + ], + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 172, + "column": 1, + "endLine": 172, + "endColumn": 8, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "ab3.fn3.unSafeCall", + "start": 3656, + "end": 3663, + "line": 172, + "column": 1, + "endLine": 172, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 1, + "endLine": 175, + "endColumn": 8, + "problem": "ExplicitFunctionType", + "autofix": [ + { + "replacementText": "fn29[1].unSafeCall", + "start": 3697, + "end": 3704, + "line": 175, + "column": 1, + "endLine": 175, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.json b/ets2panda/linter/test/main/explicit_function_type.ets.json index 8620bd2581d66656322fd9ab27e56444ce4137b6..d1381869898d689771df539f100eaacd386998a0 100755 --- a/ets2panda/linter/test/main/explicit_function_type.ets.json +++ b/ets2panda/linter/test/main/explicit_function_type.ets.json @@ -14,35 +14,65 @@ "limitations under the License." ], "result": [ - { - "line": 16, - "column": 20, - "endLine": 16, - "endColumn": 33, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 10, - "endLine": 18, - "endColumn": 23, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 154, - "column": 9, - "endLine": 154, - "endColumn": 31, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - } - ] -} + { + "line": 16, + "column": 20, + "endLine": 16, + "endColumn": 33, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 23, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 20, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 19, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 118, + "column": 16, + "endLine": 118, + "endColumn": 24, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 154, + "column": 9, + "endLine": 154, + "endColumn": 31, + "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/main/explicit_function_type.ets.migrate.ets b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a5b1a221f4ff54dbded7d2b2c587748901b508a --- /dev/null +++ b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.ets @@ -0,0 +1,175 @@ +/* + * 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. + */ +let f1: Function = () => {}; // NOT OK +let g1: Function = () => { }; // NOT OK +let h1: Function = new Function('return 42'); // NOT OK +let g2 = () => { }; // OK +let h2 = new Function('return 42'); // NOT OK +let j1 = () => {}; // OK +let f2 = (x: number) => x + 1.0; // OK + + +type F = () => R; +type F1 = (p: P) => R; +type F2 = (p1: P1, p2: P2) => R; + +let f3: F = () => {}; // OK +let g3: F = () => 42.0; // OK +let h3: F1 = (s: string) => s.length; // OK +let i: F2 = (n: number, s: string) => s.length > n; // OK + +export let add: (a: number, b: number) => number; // OK +export let add1: (a: string) => object; // OK + +interface C2 { + f2: Function // NOK +} + +class A3 { + func3: Function = () => {} // NOK +} + +class A4 extends A3 { + f4: Function = () => {} // NOK +} + +interface C5 { + a5; +} + +class D5 implements C5 { + a5: Function = () => {} // NOK +} + +function run6(fn: Function) { + fn.unSafeCall(); +} + +function getFunction8(): Function { + return () => {}; +} + +abstract class F17 { + abstract f17: Function; +} + +class H23 { + async foo1(): Promise { + return Function; + } +} + +class I24 { + constructor(par: Function, par1?: string) {} +} +class I24_1 extends I24 { + constructor() { + super(Function) + } +} + + +class I25 { + constructor(par: number, par1?: string) {} + + foo3(fn: Function) { + console.log("this is Arkts1") + } +} +class I25_1 extends I25 { + constructor() { + super(2.0) + } + + override foo3(fn: Function): void { + console.log("this is Arkts2") + } +} + +function foo30(par1: Function, par2: Function[], par3: Function) { + console.log("ArkTs foo30") +} + +function foo31(par1?: Function) { + console.log("ArkTs foo31") +} + +function push32(...items: Function[]) { + items.forEach(item => { + }); +} + +function foo33(par1: number, par2: boolean, par3: string, par4: [string, Array]) { + console.log("ArkTs foo33") +} + +let array34 = [Function, 1.0, 2.0, 3.0]; + +class L36 { + foo1(); + foo1(par:Function, par1:string); + foo1(par?:Function, par1?:string){ + console.log('arkts36') + } +} + +let tup38:[['arkts'|Function, 1.0|true, false], string[], Function] = [['arkts', 1.0, false], ['arkts1', 'arkts2'], tup38_1]; + +//枚举 +enum E39 { + Function, + BLUE = 1, + YELLOW +} + +//回调参数不明确 +function handleEvent41(callback: Function) { + callback.unSafeCall("event", Date.now()); +} + +let fn43: Function = (x: number) => x + 1.0; +function process43(input: number): Function { + if (typeof input === "string") return fn43; + if (typeof input === "number") return fn43; + return fn43; +} + +//as +async function fetch(url: string) { + return new Animal42(); +} +const fetchData44: Function = async (url: string) => { + const res = await fetch(url); + return res as Function; +}; + +//高阶函数 +function compose45(...fns: Function[]): Function { + return fns.reduce((prev, curr) => (...args: Function[]) => curr.unSafeCall(prev.unSafeCall(...args)) as Function); +} + +export let add: (a: number, b: number) => number; +export let add1: (a: string) => object; + +f1.unSafeCall(); + +class AB3 { + fn3: Function = () => {}; +} +let ab3 = new AB3(); +ab3.fn3.unSafeCall(); + +const fn29: Function[] = []; +fn29[1].unSafeCall(); \ No newline at end of file diff --git a/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca5758bca29ec3547fa2ecf15a3320655747c97b --- /dev/null +++ b/ets2panda/linter/test/main/explicit_function_type.ets.migrate.json @@ -0,0 +1,148 @@ +{ + "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": 70, + "column": 12, + "endLine": 70, + "endColumn": 20, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 19, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 16, + "endLine": 118, + "endColumn": 24, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 10, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 35, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 3, + "endLine": 125, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 31, + "endLine": 128, + "endColumn": 34, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 35, + "endLine": 128, + "endColumn": 39, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 41, + "endLine": 128, + "endColumn": 46, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 3, + "endLine": 132, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 16, + "endLine": 150, + "endColumn": 21, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 14, + "endLine": 151, + "endColumn": 22, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 9, + "endLine": 154, + "endColumn": 31, + "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/main/exponent.ets.args.json b/ets2panda/linter/test/main/exponent.ets.args.json index c0636ac689f243039f0ead525df4e6ba5763d93d..0476e60c0bb38d48ebb1411ba3249c22948eb658 100644 --- a/ets2panda/linter/test/main/exponent.ets.args.json +++ b/ets2panda/linter/test/main/exponent.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "autofix": "--arkts-2", - "arkts2": "" + "arkts2": "", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/exponent.ets.arkts2.json b/ets2panda/linter/test/main/exponent.ets.arkts2.json index 642e7e5dcb664b564ef12d8c02fe4feab1fa075b..5f36685a32cf77e62ec94aa8f07a753fa51e6a1c 100644 --- a/ets2panda/linter/test/main/exponent.ets.arkts2.json +++ b/ets2panda/linter/test/main/exponent.ets.arkts2.json @@ -34,6 +34,26 @@ "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", "severity": "ERROR" }, + { + "line": 16, + "column": 19, + "endLine": 16, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 22, + "endLine": 16, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 19, "column": 5, @@ -44,6 +64,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 19, + "column": 9, + "endLine": 19, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 19, "column": 11, @@ -54,6 +84,16 @@ "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", "severity": "ERROR" }, + { + "line": 19, + "column": 14, + "endLine": 19, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 22, "column": 3, @@ -64,6 +104,16 @@ "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", "severity": "ERROR" }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 25, "column": 5, @@ -73,6 +123,16 @@ "suggest": "", "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", "severity": "ERROR" + }, + { + "line": 25, + "column": 15, + "endLine": 25, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/exponent.ets.autofix.json b/ets2panda/linter/test/main/exponent.ets.autofix.json index ba7b6664897b5ec58a87fa0e87df466c06e3849b..ee4e3b46625385ea9fb4c16f906bf1005963b961 100644 --- a/ets2panda/linter/test/main/exponent.ets.autofix.json +++ b/ets2panda/linter/test/main/exponent.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 609, "end": 628, - "replacementText": "kk: number = Math.pow(6, 3)" + "replacementText": "kk: number = Math.pow(6, 3)", + "line": 16, + "column": 5, + "endLine": 16, + "endColumn": 24 } ], "suggest": "", @@ -41,6 +45,48 @@ "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", "severity": "ERROR" }, + { + "line": 16, + "column": 19, + "endLine": 16, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 623, + "end": 624, + "replacementText": "6.0", + "line": 16, + "column": 19, + "endLine": 16, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 22, + "endLine": 16, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 626, + "end": 627, + "replacementText": "3.0", + "line": 16, + "column": 22, + "endLine": 16, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 19, "column": 5, @@ -51,7 +97,32 @@ { "start": 652, "end": 662, - "replacementText": "k: number = 5 ** 2" + "replacementText": "k: number = 5 ** 2", + "line": 19, + "column": 5, + "endLine": 19, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 9, + "endLine": 19, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 656, + "end": 657, + "replacementText": "5.0", + "line": 19, + "column": 9, + "endLine": 19, + "endColumn": 10 } ], "suggest": "", @@ -68,13 +139,38 @@ { "replacementText": "Math.pow(5, 2)", "start": 656, - "end": 662 + "end": 662, + "line": 19, + "column": 11, + "endLine": 19, + "endColumn": 13 } ], "suggest": "", "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", "severity": "ERROR" }, + { + "line": 19, + "column": 14, + "endLine": 19, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 661, + "end": 662, + "replacementText": "2.0", + "line": 19, + "column": 14, + "endLine": 19, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 22, "column": 3, @@ -85,13 +181,38 @@ { "replacementText": "k = Math.pow(k, 2)", "start": 681, - "end": 688 + "end": 688, + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 6 } ], "suggest": "", "rule": "exponent opartions \"**\" and \"**=\" are disabled (arkts-no-exponent-op)", "severity": "ERROR" }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 8, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 687, + "end": 688, + "replacementText": "2.0", + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 25, "column": 5, @@ -101,6 +222,27 @@ "suggest": "", "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", "severity": "ERROR" + }, + { + "line": 25, + "column": 15, + "endLine": 25, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 721, + "end": 722, + "replacementText": "1.0", + "line": 25, + "column": 15, + "endLine": 25, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/exponent.ets.migrate.ets b/ets2panda/linter/test/main/exponent.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..b4124ce72df2db1fe1d7d99e7c39d20e9fab8747 --- /dev/null +++ b/ets2panda/linter/test/main/exponent.ets.migrate.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. + */ + +let kk: number = Math.pow(6.0, 3.0); +console.log(kk); + +let k: number = Math.pow(5.0, 2.0); +console.log(k); + +k = Math.pow(k, 2.0); +console.log(k); + +k = Math.pow(-1.0, Infinity); +console.log(k); diff --git a/ets2panda/linter/test/main/exponent.ets.migrate.json b/ets2panda/linter/test/main/exponent.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c4a7f4ec82bfbda812dcbdfe139c0b222552cd08 --- /dev/null +++ b/ets2panda/linter/test/main/exponent.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 18, + "endLine": 16, + "endColumn": 36, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 17, + "endLine": 19, + "endColumn": 35, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 21, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 29, + "problem": "MathPow", + "suggest": "", + "rule": "function \"Math.pow()\" behavior for ArkTS differs from Typescript version (arkts-math-pow-standard-diff)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets b/ets2panda/linter/test/main/extend_decorator_1.ets index 7bd3d3ffd72e50c0f8e57f901dcf9e2f7034035a..b4051c0d3d63c5744c0c711b713930057f5c7457 100644 --- a/ets2panda/linter/test/main/extend_decorator_1.ets +++ b/ets2panda/linter/test/main/extend_decorator_1.ets @@ -25,7 +25,7 @@ struct MyCard { const mycolor: string = "#ffffff" -@Extend(Row) +@Extend(Column) function cardStyle() { .backgroundColor("#ffff00") diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.args.json b/ets2panda/linter/test/main/extend_decorator_1.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/extend_decorator_1.ets.args.json +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.arkts2.json b/ets2panda/linter/test/main/extend_decorator_1.ets.arkts2.json index d27decfbfe111393acd96d12964bd7b9dd68c2c2..d35d9872c4271ad275d034cda0702aae22e5b33e 100644 --- a/ets2panda/linter/test/main/extend_decorator_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.arkts2.json @@ -1,17 +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." + "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": [ { @@ -24,6 +24,46 @@ "rule": "\"@Extend\" decorator is not supported (arkui-no-extend-decorator)", "severity": "ERROR" }, + { + "line": 36, + "column": 17, + "endLine": 36, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 8, + "endLine": 39, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 44, "column": 1, @@ -35,13 +75,13 @@ "severity": "ERROR" }, { - "line": 47, - "column": 4, - "endLine": 47, - "endColumn": 15, - "problem": "LimitedVoidType", + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 14, + "problem": "NumericSemantics", "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.autofix.json b/ets2panda/linter/test/main/extend_decorator_1.ets.autofix.json index 04ab68490b00fcedb43f391fee84fb8f77b6e7aa..6f96180e67fa6209a20ab9ec6749d26b7b64f0a5 100644 --- a/ets2panda/linter/test/main/extend_decorator_1.ets.autofix.json +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.autofix.json @@ -1,17 +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." + "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": [ { @@ -23,14 +23,102 @@ "autofix": [ { "start": 743, - "end": 1015, - "replacementText": "@Memo\nfunction cardStyle(this: RowAttribute): this {\n this.backgroundColor(\"#ffff00\");\n this.backgroundColor(\"#00ffff\");\n this.backgroundColor(\"#ff00ff\");\n this.backgroundColor(mycolor);\n this.backgroundColor(Color.Red);\n this.borderRadius(8);\n this.padding(8);\n this.backgroundImagePosition({\n x: 0,\n y: 0\n });\n return this;\n}" + "end": 1018, + "replacementText": "function cardStyle(this: ColumnAttribute): this {\n this.backgroundColor(\"#ffff00\");\n this.backgroundColor(\"#00ffff\");\n this.backgroundColor(\"#ff00ff\");\n this.backgroundColor(mycolor);\n this.backgroundColor(Color.Red);\n this.borderRadius(8);\n this.padding(8);\n this.backgroundImagePosition({\n x: 0,\n y: 0\n });\n return this;\n}", + "line": 28, + "column": 1, + "endLine": 42, + "endColumn": 2 } ], "suggest": "", "rule": "\"@Extend\" decorator is not supported (arkui-no-extend-decorator)", "severity": "ERROR" }, + { + "line": 36, + "column": 17, + "endLine": 36, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 946, + "end": 947, + "replacementText": "8.0", + "line": 36, + "column": 17, + "endLine": 36, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 960, + "end": 961, + "replacementText": "8.0", + "line": 37, + "column": 12, + "endLine": 37, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 8, + "endLine": 39, + "endColumn": 9, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 999, + "end": 1000, + "replacementText": "0.0", + "line": 39, + "column": 8, + "endLine": 39, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 9, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1009, + "end": 1010, + "replacementText": "0.0", + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 44, "column": 1, @@ -39,9 +127,13 @@ "problem": "ExtendDecoratorNotSupported", "autofix": [ { - "start": 1017, - "end": 1102, - "replacementText": "@Memo\nfunction superCard(this: ColumnAttribute, padding: number): this {\n this.cardStyle();\n this.padding(10);\n return this;\n}" + "start": 1020, + "end": 1105, + "replacementText": "function superCard(this: ColumnAttribute, padding: number): this {\n this.cardStyle();\n this.padding(10);\n return this;\n}", + "line": 44, + "column": 1, + "endLine": 49, + "endColumn": 2 } ], "suggest": "", @@ -49,13 +141,24 @@ "severity": "ERROR" }, { - "line": 47, - "column": 4, - "endLine": 47, - "endColumn": 15, - "problem": "LimitedVoidType", + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1100, + "end": 1102, + "replacementText": "10.0", + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 14 + } + ], "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -64,6 +167,17 @@ "endLine": 16, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI';", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 25 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -74,6 +188,17 @@ "endLine": 19, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI';", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 25 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -84,6 +209,17 @@ "endLine": 20, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI';", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 25 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -98,7 +234,11 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, Column, Text, RowAttribute, Memo, Color, ColumnAttribute } from '@kits.ArkUI';" + "replacementText": "\n\nimport { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI';", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 25 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..da62cffcb5a96926f3db3ae064235799cceed319 --- /dev/null +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.ets @@ -0,0 +1,49 @@ +/* + * 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 { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI'; + +@Component +struct MyCard { + build() { + Column() { + Text('Card') + } + .cardStyle() + } +} + +const mycolor: string = "#ffffff" + +function cardStyle(this: ColumnAttribute): this { + this.backgroundColor("#ffff00"); + this.backgroundColor("#00ffff"); + this.backgroundColor("#ff00ff"); + this.backgroundColor(mycolor); + this.backgroundColor(Color.Red); + this.borderRadius(8.0); + this.padding(8.0); + this.backgroundImagePosition({ + x: 0.0, + y: 0.0 + }); + return this; +} + +function superCard(this: ColumnAttribute, padding: number): this { + this.cardStyle(); + this.padding(10.0); + return this; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..be60c934865f47fd861687847b25781c212573e6 --- /dev/null +++ b/ets2panda/linter/test/main/extend_decorator_1.ets.migrate.json @@ -0,0 +1,178 @@ +{ + "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": 31, + "column": 5, + "endLine": 31, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 5, + "endLine": 37, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 12, + "endLine": 42, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 44, + "endLine": 30, + "endColumn": 48, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 20, + "endLine": 45, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 61, + "endLine": 45, + "endColumn": 65, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets b/ets2panda/linter/test/main/extend_decorator_2.ets index 28c72c619fbb0932cbe73ea8c62ca08a45fb626c..c53497da05239bbde8ecdfb75b4ec103560e15e8 100644 --- a/ets2panda/linter/test/main/extend_decorator_2.ets +++ b/ets2panda/linter/test/main/extend_decorator_2.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { Component, Column, Text, Memo, ColumnAttribute, Color } from '@kits.ArkUI'; +import { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI'; @Component struct MyCard { @@ -27,7 +27,6 @@ struct MyCard { const mycolor: string = "#ffffff" -@Memo function cardStyle(this: ColumnAttribute): this { this.backgroundColor("#ffff00"); this.backgroundColor("#00ffff"); @@ -43,7 +42,6 @@ function cardStyle(this: ColumnAttribute): this { return this; } -@Memo function superCard(this: ColumnAttribute, padding: number): this { .cardStyle() .padding(10) diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets.args.json b/ets2panda/linter/test/main/extend_decorator_2.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/main/extend_decorator_2.ets.args.json +++ b/ets2panda/linter/test/main/extend_decorator_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets.arkts2.json b/ets2panda/linter/test/main/extend_decorator_2.ets.arkts2.json index 00d0e7c4b261c297f24e72f6165de16432deb797..4ba965df1a5d470c3107657edff288748cedfe7b 100644 --- a/ets2panda/linter/test/main/extend_decorator_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/extend_decorator_2.ets.arkts2.json @@ -1,19 +1,29 @@ { "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 (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": 31, + "column": 3, + "endLine": 31, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, { "line": 32, "column": 3, @@ -85,19 +95,9 @@ "severity": "ERROR" }, { - "line": 39, - "column": 3, - "endLine": 39, - "endColumn": 7, - "problem": "FunctionContainsThis", - "suggest": "", - "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", - "severity": "ERROR" - }, - { - "line": 43, + "line": 42, "column": 10, - "endLine": 43, + "endLine": 42, "endColumn": 14, "problem": "FunctionContainsThis", "suggest": "", @@ -106,18 +106,8 @@ }, { "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 6, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 31, "column": 20, - "endLine": 31, + "endLine": 30, "endColumn": 24, "problem": "InvalidIdentifier", "suggest": "", @@ -125,9 +115,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 30, "column": 44, - "endLine": 31, + "endLine": 30, "endColumn": 48, "problem": "ThisType", "suggest": "", @@ -135,19 +125,49 @@ "severity": "ERROR" }, { - "line": 46, - "column": 1, - "endLine": 46, - "endColumn": 6, - "problem": "DecoratorsNotSupported", + "line": 36, + "column": 21, + "endLine": 36, + "endColumn": 22, + "problem": "NumericSemantics", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 47, + "line": 37, + "column": 16, + "endLine": 37, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 8, + "endLine": 39, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, "column": 20, - "endLine": 47, + "endLine": 45, "endColumn": 24, "problem": "InvalidIdentifier", "suggest": "", @@ -155,14 +175,24 @@ "severity": "ERROR" }, { - "line": 47, + "line": 45, "column": 61, - "endLine": 47, + "endLine": 45, "endColumn": 65, "problem": "ThisType", "suggest": "", "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", "severity": "ERROR" + }, + { + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets.autofix.json b/ets2panda/linter/test/main/extend_decorator_2.ets.autofix.json index 00d0e7c4b261c297f24e72f6165de16432deb797..80d063967a266ace25340cbbfc130f2e72338af1 100644 --- a/ets2panda/linter/test/main/extend_decorator_2.ets.autofix.json +++ b/ets2panda/linter/test/main/extend_decorator_2.ets.autofix.json @@ -1,19 +1,29 @@ { "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 (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": 31, + "column": 3, + "endLine": 31, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, { "line": 32, "column": 3, @@ -85,19 +95,9 @@ "severity": "ERROR" }, { - "line": 39, - "column": 3, - "endLine": 39, - "endColumn": 7, - "problem": "FunctionContainsThis", - "suggest": "", - "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", - "severity": "ERROR" - }, - { - "line": 43, + "line": 42, "column": 10, - "endLine": 43, + "endLine": 42, "endColumn": 14, "problem": "FunctionContainsThis", "suggest": "", @@ -106,18 +106,8 @@ }, { "line": 30, - "column": 1, - "endLine": 30, - "endColumn": 6, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 31, "column": 20, - "endLine": 31, + "endLine": 30, "endColumn": 24, "problem": "InvalidIdentifier", "suggest": "", @@ -125,9 +115,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 30, "column": 44, - "endLine": 31, + "endLine": 30, "endColumn": 48, "problem": "ThisType", "suggest": "", @@ -135,19 +125,93 @@ "severity": "ERROR" }, { - "line": 46, - "column": 1, - "endLine": 46, - "endColumn": 6, - "problem": "DecoratorsNotSupported", + "line": 36, + "column": 21, + "endLine": 36, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1065, + "end": 1066, + "replacementText": "8.0", + "line": 36, + "column": 21, + "endLine": 36, + "endColumn": 22 + } + ], "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 47, + "line": 37, + "column": 16, + "endLine": 37, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1084, + "end": 1085, + "replacementText": "8.0", + "line": 37, + "column": 16, + "endLine": 37, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 8, + "endLine": 39, + "endColumn": 9, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1128, + "end": 1129, + "replacementText": "0.0", + "line": 39, + "column": 8, + "endLine": 39, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 9, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1138, + "end": 1139, + "replacementText": "0.0", + "line": 40, + "column": 8, + "endLine": 40, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, "column": 20, - "endLine": 47, + "endLine": 45, "endColumn": 24, "problem": "InvalidIdentifier", "suggest": "", @@ -155,14 +219,35 @@ "severity": "ERROR" }, { - "line": 47, + "line": 45, "column": 61, - "endLine": 47, + "endLine": 45, "endColumn": 65, "problem": "ThisType", "suggest": "", "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", "severity": "ERROR" + }, + { + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1257, + "end": 1259, + "replacementText": "10.0", + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets.json b/ets2panda/linter/test/main/extend_decorator_2.ets.json index 6c81fee307c44a6d753b259ea7ceecf52b7f4b49..791091b1d7a63a16972cef7c8dcc62f5183556ab 100644 --- a/ets2panda/linter/test/main/extend_decorator_2.ets.json +++ b/ets2panda/linter/test/main/extend_decorator_2.ets.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, { "line": 32, "column": 3, @@ -85,19 +95,9 @@ "severity": "ERROR" }, { - "line": 39, - "column": 3, - "endLine": 39, - "endColumn": 7, - "problem": "FunctionContainsThis", - "suggest": "", - "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", - "severity": "ERROR" - }, - { - "line": 43, + "line": 42, "column": 10, - "endLine": 43, + "endLine": 42, "endColumn": 14, "problem": "FunctionContainsThis", "suggest": "", @@ -105,9 +105,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 30, "column": 44, - "endLine": 31, + "endLine": 30, "endColumn": 48, "problem": "ThisType", "suggest": "", @@ -115,9 +115,9 @@ "severity": "ERROR" }, { - "line": 47, + "line": 45, "column": 61, - "endLine": 47, + "endLine": 45, "endColumn": 65, "problem": "ThisType", "suggest": "", diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.ets b/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..009dc2d912b3ee0ff5b55dfa62595111f82ac3a4 --- /dev/null +++ b/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.ets @@ -0,0 +1,48 @@ +/* + * 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 { Component, Column, Text, ColumnAttribute, Color } from '@kit.ArkUI'; + +@Component +struct MyCard { + build() { + Column() { + Text('Card') + } + .cardStyle() + } +} + +const mycolor: string = "#ffffff" + +function cardStyle(this: ColumnAttribute): this { + this.backgroundColor("#ffff00"); + this.backgroundColor("#00ffff"); + this.backgroundColor("#ff00ff"); + this.backgroundColor(mycolor); + this.backgroundColor(Color.Red); + this.borderRadius(8.0); + this.padding(8.0); + this.backgroundImagePosition({ + x: 0.0, + y: 0.0 + }); + return this; +} + +function superCard(this: ColumnAttribute, padding: number): this { + .cardStyle() + .padding(10.0) +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.json b/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..0f332deca642333fc8f530a70ee3252badc85eef --- /dev/null +++ b/ets2panda/linter/test/main/extend_decorator_2.ets.migrate.json @@ -0,0 +1,148 @@ +{ + "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": 31, + "column": 3, + "endLine": 31, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 32, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 3, + "endLine": 33, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 3, + "endLine": 36, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 3, + "endLine": 37, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 7, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 10, + "endLine": 42, + "endColumn": 14, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 44, + "endLine": 30, + "endColumn": 48, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 20, + "endLine": 45, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 61, + "endLine": 45, + "endColumn": 65, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/extends_expression.ets b/ets2panda/linter/test/main/extends_expression.ets index b7236fae81ac80e423f318ed9abaee3114add4eb..fde6f5729d4b0322841a8770a80b1b512deaa41f 100755 --- a/ets2panda/linter/test/main/extends_expression.ets +++ b/ets2panda/linter/test/main/extends_expression.ets @@ -12,6 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' + class A { v: number = 0 } @@ -54,4 +56,34 @@ class C4 implements E { export declare class Bar { constructor(arg: { new(): T }); -} \ No newline at end of file +} + +function getBaseClass(isAdmin: boolean) { + class A{ + adminMethod() { + console.log('这是管理员方法'); + } + } + class B{ + adminMethod() { + console.log('这是用户方法'); + } + } + if (isAdmin) { + return A; + } else { + return B; + } +} + +class User extends getBaseClass(false) { + commonMethod() { + console.log('这是通用方法'); + } +} + +class Admin extends getBaseClass(true) { + commonMethod() { + console.log('这是通用方法'); + } +} diff --git a/ets2panda/linter/test/main/extends_expression.ets.arkts2.json b/ets2panda/linter/test/main/extends_expression.ets.arkts2.json index 408c287bcd38d74ba9b9d24a6bbf29ed2a1400ad..789b06a0ffe191c1ae7660cd7667a0712b4a9274 100755 --- a/ets2panda/linter/test/main/extends_expression.ets.arkts2.json +++ b/ets2panda/linter/test/main/extends_expression.ets.arkts2.json @@ -15,9 +15,19 @@ ], "result": [ { - "line": 19, + "line": 18, + "column": 15, + "endLine": 18, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, "column": 9, - "endLine": 19, + "endLine": 21, "endColumn": 10, "problem": "ClassAsObjectError", "suggest": "", @@ -25,19 +35,39 @@ "severity": "ERROR" }, { - "line": 21, + "line": 23, "column": 17, - "endLine": 21, + "endLine": 23, "endColumn": 18, "problem": "ExtendsExpression", "suggest": "", - "rule": "Extends or implemetns expression are not supported(arkts-no-extends-expression)", + "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", "severity": "ERROR" }, { - "line": 29, + "line": 24, + "column": 15, + "endLine": 24, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 21, + "endLine": 28, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, "column": 37, - "endLine": 29, + "endLine": 31, "endColumn": 44, "problem": "InterfaceExtendsClass", "suggest": "", @@ -45,9 +75,9 @@ "severity": "ERROR" }, { - "line": 45, + "line": 47, "column": 5, - "endLine": 45, + "endLine": 47, "endColumn": 10, "problem": "AnyType", "suggest": "", @@ -55,9 +85,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 58, "column": 22, - "endLine": 56, + "endLine": 58, "endColumn": 23, "problem": "ObjectTypeLiteral", "suggest": "", @@ -65,14 +95,64 @@ "severity": "ERROR" }, { - "line": 56, + "line": 58, "column": 24, - "endLine": 56, + "endLine": 58, "endColumn": 32, "problem": "ConstructorType", "suggest": "", "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", "severity": "ERROR" + }, + { + "line": 61, + "column": 10, + "endLine": 61, + "endColumn": 22, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 12, + "endLine": 73, + "endColumn": 13, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 12, + "endLine": 75, + "endColumn": 13, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 20, + "endLine": 79, + "endColumn": 39, + "problem": "ExtendsExpression", + "suggest": "", + "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 21, + "endLine": 85, + "endColumn": 39, + "problem": "ExtendsExpression", + "suggest": "", + "rule": "Extends or implements expression are not supported(arkts-no-extends-expression)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/extends_expression.ets.json b/ets2panda/linter/test/main/extends_expression.ets.json index c1f183fffbce64d68160b2ec8ff0604a09a0b3cb..390e52b7818f4c3f731b3deb7b96c5afc04e0855 100644 --- a/ets2panda/linter/test/main/extends_expression.ets.json +++ b/ets2panda/linter/test/main/extends_expression.ets.json @@ -13,56 +13,76 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ - { - "line": 19, - "column": 9, - "endLine": 19, - "endColumn": 10, - "problem": "ClassAsObject", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "WARNING" - }, - { - "line": 29, - "column": 37, - "endLine": 29, - "endColumn": 44, - "problem": "InterfaceExtendsClass", - "suggest": "", - "rule": "Interfaces cannot extend classes (arkts-extends-only-class)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 10, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 22, - "endLine": 56, - "endColumn": 23, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 24, - "endLine": 56, - "endColumn": 32, - "problem": "ConstructorType", - "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", - "severity": "ERROR" - } - ] -} \ No newline at end of file + "result": [ + { + "line": 21, + "column": 9, + "endLine": 21, + "endColumn": 10, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 31, + "column": 37, + "endLine": 31, + "endColumn": 44, + "problem": "InterfaceExtendsClass", + "suggest": "", + "rule": "Interfaces cannot extend classes (arkts-extends-only-class)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 10, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 22, + "endLine": 58, + "endColumn": 23, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 24, + "endLine": 58, + "endColumn": 32, + "problem": "ConstructorType", + "suggest": "", + "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 12, + "endLine": 73, + "endColumn": 13, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 75, + "column": 12, + "endLine": 75, + "endColumn": 13, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + } + ] +} diff --git a/ets2panda/linter/test/main/func_inferred_type_args.ets b/ets2panda/linter/test/main/func_inferred_type_args.ets index 91bf75c577039236224ac5fd14f487a62b795bb3..f5bcd5b762e5ffd23272d3eecad9d9de1438b931 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args.ets +++ b/ets2panda/linter/test/main/func_inferred_type_args.ets @@ -14,7 +14,17 @@ */ import { bad_func } from "./dynamic_lib" - +import { Deque } from '@kit.ArkTS'; +import ArrayList from '@ohos.util.ArrayList'; +import Deque from '@ohos.util.Deque'; +import HashMap from '@ohos.util.HashMap'; +import HashSet from '@ohos.util.HashSet'; +import LinkedList from '@ohos.util.LinkedList'; +import PlainArray from '@ohos.util.PlainArray'; +import Queue from '@ohos.util.Queue'; +import TreeMap from '@ohos.util.TreeMap'; +import TreeSet from '@ohos.util.TreeSet'; +import { LinkedList } from '@kit.ArkTS'; function choose(x: T, y: T): T { return Math.random() < 0.5 ? x : y } @@ -89,3 +99,36 @@ const stringBox1: Box1 = new Box1(); // NOK const stringBox2: Box1 = new Box1(); // OK const stringBox3: Box1 = new Box1(); // OK const stringBox4 = new Box1(); // NOK + +let de: Deque = new Deque(); //error +function newDeque():Deque{ + return new Deque(); //error +} +class D{ + dd: Deque; + constructor(){ + new Deque(); //error + } + + initDD(){ + dd = new Deque(); + } +} + +class Base{} +class NewClass extends Base{} +export let obj = new NewClass(); +class NewClass2 extends Base{} +export let obj2 = new NewClass2(); + +let test_arrayList_e: ArrayList = new ArrayList(); // +let test_deque_e: Deque = new Deque(); // +let test_hashMap_e: HashMap = new HashMap(); // +let test_hashSet_e: HashSet = new HashSet(); // +let test_linkedList_e: LinkedList = new LinkedList(); // +let test_plainArray_e: PlainArray = new PlainArray(); // +let test_queue_e: Queue = new Queue(); // +let test_treeMap_e: TreeMap = new TreeMap(); // +let test_treeSet_e: TreeSet = new TreeSet(); // +let test_treeSet_set_e: TreeSet> = new TreeSet(); +let listenerList: LinkedList = new LinkedList(); \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args.ets.arkts2.json b/ets2panda/linter/test/main/func_inferred_type_args.ets.arkts2.json index ac441596b11ce2074c853c6a3039f5106d250e35..c7c9c047cb79bf3fe6e17e75068d42cba906fc2c 100755 --- a/ets2panda/linter/test/main/func_inferred_type_args.ets.arkts2.json +++ b/ets2panda/linter/test/main/func_inferred_type_args.ets.arkts2.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2025 Huawei Device Co., Ltd.", + "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", @@ -15,9 +15,9 @@ ], "result": [ { - "line": 21, + "line": 31, "column": 5, - "endLine": 21, + "endLine": 31, "endColumn": 23, "problem": "NumericSemantics", "suggest": "", @@ -25,9 +25,29 @@ "severity": "ERROR" }, { - "line": 26, + "line": 31, + "column": 16, + "endLine": 31, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 20, + "endLine": 31, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, "column": 5, - "endLine": 26, + "endLine": 36, "endColumn": 16, "problem": "UnknownType", "suggest": "", @@ -35,9 +55,9 @@ "severity": "ERROR" }, { - "line": 26, + "line": 36, "column": 9, - "endLine": 26, + "endLine": 36, "endColumn": 16, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -45,9 +65,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 38, "column": 1, - "endLine": 30, + "endLine": 40, "endColumn": 2, "problem": "NumericSemantics", "suggest": "", @@ -55,9 +75,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 38, "column": 21, - "endLine": 28, + "endLine": 38, "endColumn": 24, "problem": "AnyType", "suggest": "", @@ -65,9 +85,19 @@ "severity": "ERROR" }, { - "line": 31, + "line": 39, + "column": 10, + "endLine": 39, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 41, "column": 1, - "endLine": 31, + "endLine": 41, "endColumn": 6, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -75,9 +105,9 @@ "severity": "ERROR" }, { - "line": 38, + "line": 48, "column": 1, - "endLine": 38, + "endLine": 48, "endColumn": 6, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -85,9 +115,9 @@ "severity": "ERROR" }, { - "line": 42, + "line": 52, "column": 5, - "endLine": 42, + "endLine": 52, "endColumn": 14, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -95,19 +125,9 @@ "severity": "ERROR" }, { - "line": 43, - "column": 1, - "endLine": 43, - "endColumn": 31, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 46, + "line": 56, "column": 8, - "endLine": 46, + "endLine": 56, "endColumn": 11, "problem": "AnyType", "suggest": "", @@ -115,9 +135,9 @@ "severity": "ERROR" }, { - "line": 47, + "line": 57, "column": 16, - "endLine": 47, + "endLine": 57, "endColumn": 19, "problem": "AnyType", "suggest": "", @@ -125,9 +145,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 59, "column": 8, - "endLine": 49, + "endLine": 59, "endColumn": 9, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -135,9 +155,29 @@ "severity": "ERROR" }, { - "line": 51, + "line": 59, + "column": 12, + "endLine": 59, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 18, + "endLine": 59, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, "column": 5, - "endLine": 51, + "endLine": 61, "endColumn": 20, "problem": "UnknownType", "suggest": "", @@ -145,9 +185,9 @@ "severity": "ERROR" }, { - "line": 51, + "line": 61, "column": 11, - "endLine": 51, + "endLine": 61, "endColumn": 20, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -155,9 +195,9 @@ "severity": "ERROR" }, { - "line": 53, + "line": 63, "column": 3, - "endLine": 53, + "endLine": 63, "endColumn": 22, "problem": "TsOverload", "suggest": "", @@ -165,9 +205,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 64, "column": 3, - "endLine": 54, + "endLine": 64, "endColumn": 19, "problem": "TsOverload", "suggest": "", @@ -175,9 +215,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 66, "column": 5, - "endLine": 56, + "endLine": 66, "endColumn": 16, "problem": "UnknownType", "suggest": "", @@ -185,9 +225,9 @@ "severity": "ERROR" }, { - "line": 56, + "line": 66, "column": 9, - "endLine": 56, + "endLine": 66, "endColumn": 16, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -195,9 +235,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 68, "column": 5, - "endLine": 58, + "endLine": 68, "endColumn": 17, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -205,9 +245,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 68, "column": 11, - "endLine": 58, + "endLine": 68, "endColumn": 16, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -215,9 +255,9 @@ "severity": "ERROR" }, { - "line": 59, + "line": 69, "column": 5, - "endLine": 59, + "endLine": 69, "endColumn": 15, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -225,9 +265,9 @@ "severity": "ERROR" }, { - "line": 60, + "line": 70, "column": 5, - "endLine": 60, + "endLine": 70, "endColumn": 26, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -235,9 +275,9 @@ "severity": "ERROR" }, { - "line": 60, + "line": 70, "column": 19, - "endLine": 60, + "endLine": 70, "endColumn": 22, "problem": "AnyType", "suggest": "", @@ -245,9 +285,9 @@ "severity": "ERROR" }, { - "line": 62, + "line": 72, "column": 10, - "endLine": 62, + "endLine": 72, "endColumn": 11, "problem": "ObjectTypeLiteral", "suggest": "", @@ -255,9 +295,19 @@ "severity": "ERROR" }, { - "line": 69, + "line": 78, + "column": 37, + "endLine": 78, + "endColumn": 38, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, "column": 11, - "endLine": 69, + "endLine": 79, "endColumn": 14, "problem": "AnyType", "suggest": "", @@ -266,8 +316,28 @@ }, { "line": 79, - "column": 5, + "column": 27, + "endLine": 79, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 31, "endLine": 79, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 5, + "endLine": 89, "endColumn": 23, "problem": "AnyType", "suggest": "", @@ -275,9 +345,9 @@ "severity": "ERROR" }, { - "line": 79, + "line": 89, "column": 12, - "endLine": 79, + "endLine": 89, "endColumn": 23, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -285,9 +355,9 @@ "severity": "ERROR" }, { - "line": 80, + "line": 90, "column": 5, - "endLine": 80, + "endLine": 90, "endColumn": 21, "problem": "AnyType", "suggest": "", @@ -295,9 +365,9 @@ "severity": "ERROR" }, { - "line": 80, + "line": 90, "column": 5, - "endLine": 80, + "endLine": 90, "endColumn": 21, "problem": "AnyType", "suggest": "", @@ -305,9 +375,9 @@ "severity": "ERROR" }, { - "line": 80, + "line": 90, "column": 12, - "endLine": 80, + "endLine": 90, "endColumn": 21, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -315,9 +385,9 @@ "severity": "ERROR" }, { - "line": 81, + "line": 91, "column": 5, - "endLine": 81, + "endLine": 91, "endColumn": 39, "problem": "AnyType", "suggest": "", @@ -325,9 +395,9 @@ "severity": "ERROR" }, { - "line": 81, + "line": 91, "column": 24, - "endLine": 81, + "endLine": 91, "endColumn": 37, "problem": "DynamicCtorCall", "suggest": "", @@ -335,9 +405,9 @@ "severity": "ERROR" }, { - "line": 81, + "line": 91, "column": 20, - "endLine": 81, + "endLine": 91, "endColumn": 39, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -345,9 +415,9 @@ "severity": "ERROR" }, { - "line": 82, + "line": 92, "column": 5, - "endLine": 82, + "endLine": 92, "endColumn": 52, "problem": "UnknownType", "suggest": "", @@ -355,9 +425,9 @@ "severity": "ERROR" }, { - "line": 82, + "line": 92, "column": 16, - "endLine": 82, + "endLine": 92, "endColumn": 52, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -365,9 +435,9 @@ "severity": "ERROR" }, { - "line": 83, + "line": 93, "column": 5, - "endLine": 83, + "endLine": 93, "endColumn": 29, "problem": "AnyType", "suggest": "", @@ -375,9 +445,9 @@ "severity": "ERROR" }, { - "line": 83, + "line": 93, "column": 16, - "endLine": 83, + "endLine": 93, "endColumn": 29, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -385,9 +455,9 @@ "severity": "ERROR" }, { - "line": 84, + "line": 94, "column": 16, - "endLine": 84, + "endLine": 94, "endColumn": 29, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -395,9 +465,9 @@ "severity": "ERROR" }, { - "line": 88, + "line": 98, "column": 34, - "endLine": 88, + "endLine": 98, "endColumn": 44, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -405,9 +475,9 @@ "severity": "ERROR" }, { - "line": 91, + "line": 101, "column": 7, - "endLine": 91, + "endLine": 101, "endColumn": 30, "problem": "UnknownType", "suggest": "", @@ -415,9 +485,9 @@ "severity": "ERROR" }, { - "line": 91, + "line": 101, "column": 20, - "endLine": 91, + "endLine": 101, "endColumn": 30, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -425,9 +495,299 @@ "severity": "ERROR" }, { - "line": 63, + "line": 103, + "column": 21, + "endLine": 103, + "endColumn": 26, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 17, + "endLine": 103, + "endColumn": 28, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 14, + "endLine": 105, + "endColumn": 19, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 10, + "endLine": 105, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 9, + "endLine": 110, + "endColumn": 14, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 5, + "endLine": 110, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 14, + "endLine": 114, + "endColumn": 19, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 47, + "endLine": 124, + "endColumn": 56, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 43, + "endLine": 124, + "endColumn": 58, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 39, + "endLine": 125, + "endColumn": 44, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 35, + "endLine": 125, + "endColumn": 46, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 51, + "endLine": 126, + "endColumn": 58, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 47, + "endLine": 126, + "endColumn": 60, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 43, + "endLine": 127, + "endColumn": 50, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 39, + "endLine": 127, + "endColumn": 52, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 49, + "endLine": 128, + "endColumn": 59, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 45, + "endLine": 128, + "endColumn": 61, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 49, + "endLine": 129, + "endColumn": 59, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 45, + "endLine": 129, + "endColumn": 61, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 39, + "endLine": 130, + "endColumn": 44, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 35, + "endLine": 130, + "endColumn": 46, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 131, + "column": 51, + "endLine": 131, + "endColumn": 58, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 131, + "column": 47, + "endLine": 131, + "endColumn": 60, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 43, + "endLine": 132, + "endColumn": 50, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 39, + "endLine": 132, + "endColumn": 52, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 56, + "endLine": 133, + "endColumn": 63, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 52, + "endLine": 133, + "endColumn": 65, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 44, + "endLine": 134, + "endColumn": 54, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 40, + "endLine": 134, + "endColumn": 56, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 73, "column": 1, - "endLine": 63, + "endLine": 73, "endColumn": 2, "problem": "StrictDiagnostic", "suggest": "Variable 'd' is used before being assigned.", diff --git a/ets2panda/linter/test/main/func_inferred_type_args.ets.json b/ets2panda/linter/test/main/func_inferred_type_args.ets.json index bd681a3a67351b5089da4854c094a3a52fac490d..2d86c954b2772f916aefe6ee54dbcd73100e9674 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args.ets.json +++ b/ets2panda/linter/test/main/func_inferred_type_args.ets.json @@ -1,278 +1,278 @@ { - "copyright": [ - "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." - ], - "result": [ - { - "line": 26, - "column": 5, - "endLine": 26, - "endColumn": 16, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 9, - "endLine": 26, - "endColumn": 16, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 21, - "endLine": 28, - "endColumn": 24, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 1, - "endLine": 31, - "endColumn": 6, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 1, - "endLine": 38, - "endColumn": 6, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 8, - "endLine": 46, - "endColumn": 11, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 16, - "endLine": 47, - "endColumn": 19, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 49, - "column": 8, - "endLine": 49, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 5, - "endLine": 51, - "endColumn": 20, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 11, - "endLine": 51, - "endColumn": 20, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 5, - "endLine": 56, - "endColumn": 16, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 56, - "column": 9, - "endLine": 56, - "endColumn": 16, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 11, - "endLine": 58, - "endColumn": 16, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 60, - "column": 19, - "endLine": 60, - "endColumn": 22, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 62, - "column": 10, - "endLine": 62, - "endColumn": 11, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 11, - "endLine": 69, - "endColumn": 14, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 79, - "column": 5, - "endLine": 79, - "endColumn": 23, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 5, - "endLine": 80, - "endColumn": 21, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 5, - "endLine": 80, - "endColumn": 21, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 5, - "endLine": 81, - "endColumn": 39, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 82, - "column": 5, - "endLine": 82, - "endColumn": 52, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 82, - "column": 16, - "endLine": 82, - "endColumn": 52, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 83, - "column": 5, - "endLine": 83, - "endColumn": 29, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 91, - "column": 7, - "endLine": 91, - "endColumn": 30, - "problem": "UnknownType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 91, - "column": 20, - "endLine": 91, - "endColumn": 30, - "problem": "GenericCallNoTypeArgs", - "suggest": "", - "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 1, - "endLine": 63, - "endColumn": 2, - "problem": "StrictDiagnostic", - "suggest": "Variable 'd' is used before being assigned.", - "rule": "Variable 'd' is used before being assigned.", - "severity": "ERROR" - } - ] -} + "copyright": [ + "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." + ], + "result": [ + { + "line": 36, + "column": 5, + "endLine": 36, + "endColumn": 16, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 9, + "endLine": 36, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 21, + "endLine": 38, + "endColumn": 24, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 1, + "endLine": 41, + "endColumn": 6, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 1, + "endLine": 48, + "endColumn": 6, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 8, + "endLine": 56, + "endColumn": 11, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 16, + "endLine": 57, + "endColumn": 19, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 8, + "endLine": 59, + "endColumn": 9, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 20, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 11, + "endLine": 61, + "endColumn": 20, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 16, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 9, + "endLine": 66, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 11, + "endLine": 68, + "endColumn": 16, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 19, + "endLine": 70, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 10, + "endLine": 72, + "endColumn": 11, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 11, + "endLine": 79, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 5, + "endLine": 90, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 5, + "endLine": 90, + "endColumn": 21, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 5, + "endLine": 91, + "endColumn": 39, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 5, + "endLine": 92, + "endColumn": 52, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 16, + "endLine": 92, + "endColumn": 52, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 5, + "endLine": 93, + "endColumn": 29, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 7, + "endLine": 101, + "endColumn": 30, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 20, + "endLine": 101, + "endColumn": 30, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 1, + "endLine": 73, + "endColumn": 2, + "problem": "StrictDiagnostic", + "suggest": "Variable 'd' is used before being assigned.", + "rule": "Variable 'd' is used before being assigned.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets b/ets2panda/linter/test/main/func_inferred_type_args_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..636e016aeadd253445251567c7f09fa7da3bd996 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.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. + */ + +const irreparableArr = new Array(); +let repairableArr: Array = new Array(); +repairableArr = new Array(); + +const irreparableMap = new Map(); +const repairableMap: Map = new Map(); +repairableMap = new Map(); + +class MyClass { + public irreparableMap = new Map(); + public repairableSet: Set = new Map(); + public repairableMap: Map string[]> = new Map(); + static repairableStaticMap: Map string[]> = new Map(); + constructor() {} +} + +const irreparableA = new MyClass(); +const irreparableB = new MyClass(); +const repairableC: MyClass = new MyClass(); +repairableC.irreparableMap = new Map(); +repairableC.repairableSet = new Set(); +repairableC.repairableMap = new Map(); +MyClass.repairableStaticMap = new Map(); + +const promise: Promise = new Promise(()=> {return ''}); + +function testA(): Map { + return new Map(); +} + +async function testB(): Promise> { + return new Map(); +} + +function testC(): Map { + return new Set(); +} + +async function testD(): Promise> { + return new Set(); +} + +class MyClassB { + testA(): Map { + return new Map(); + } + + async testB(): Promise> { + return new Map(); + } + + testC(): Map { + return new Set(); + } + + async testD(): Promise> { + return new Set(); + } +} diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.args.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..30973c00a22aa0a072616f644b02c89a4a4dd4fa --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.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/func_inferred_type_args_2.ets.arkts2.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..8332379fa7ccc19ab8c5ff0b28b5ca38417e962e --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json @@ -0,0 +1,378 @@ +{ + "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": 7, + "endLine": 16, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 24, + "endLine": 16, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 36, + "endLine": 17, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 17, + "endLine": 18, + "endColumn": 28, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 24, + "endLine": 20, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 44, + "endLine": 21, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 26, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 36, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 10, + "endLine": 26, + "endColumn": 23, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 39, + "endLine": 26, + "endColumn": 48, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 55, + "endLine": 27, + "endColumn": 64, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 61, + "endLine": 28, + "endColumn": 70, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 35, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 38, + "endLine": 34, + "endColumn": 51, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 30, + "endLine": 35, + "endColumn": 39, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 29, + "endLine": 36, + "endColumn": 38, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 29, + "endLine": 37, + "endColumn": 38, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 31, + "endLine": 38, + "endColumn": 40, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 34, + "endLine": 40, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 10, + "endLine": 43, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 10, + "endLine": 47, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 12, + "endLine": 60, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..773fea5ff8c4e90cfc4e962f87f7eb24ea4edf71 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json @@ -0,0 +1,483 @@ +{ + "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": 7, + "endLine": 16, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 24, + "endLine": 16, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 36, + "endLine": 17, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 676, + "end": 687, + "replacementText": "new Array()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 17, + "endLine": 18, + "endColumn": 28, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 705, + "end": 716, + "replacementText": "new Array()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 24, + "endLine": 20, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 44, + "endLine": 21, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 796, + "end": 805, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 26, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 823, + "end": 832, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 36, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 10, + "endLine": 26, + "endColumn": 23, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 39, + "endLine": 26, + "endColumn": 48, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 55, + "endLine": 27, + "endColumn": 64, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 994, + "end": 1003, + "replacementText": "new Map string[]>()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 61, + "endLine": 28, + "endColumn": 70, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1065, + "end": 1074, + "replacementText": "new Map string[]>()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 35, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 38, + "endLine": 34, + "endColumn": 51, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1215, + "end": 1228, + "replacementText": "new MyClass()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 30, + "endLine": 35, + "endColumn": 39, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 29, + "endLine": 36, + "endColumn": 38, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1298, + "end": 1307, + "replacementText": "new Set()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 29, + "endLine": 37, + "endColumn": 38, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1337, + "end": 1346, + "replacementText": "new Map string[]>()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 31, + "endLine": 38, + "endColumn": 40, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1378, + "end": 1387, + "replacementText": "new Map string[]>()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 34, + "endLine": 40, + "endColumn": 63, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1423, + "end": 1452, + "replacementText": "new Promise(() => { return ''; })" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 10, + "endLine": 43, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1504, + "end": 1513, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 10, + "endLine": 47, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1582, + "end": 1591, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 12, + "endLine": 60, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1798, + "end": 1807, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "autofix": [ + { + "start": 1873, + "end": 1882, + "replacementText": "new Map()" + } + ], + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..1f00081d43be7bede54b70559d1f112d1b9b47ab --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.json @@ -0,0 +1,128 @@ +{ + "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": 7, + "endLine": 16, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 35, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..01a5d89f97c06ce79226ada89136f658d4d19bdb --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.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. + */ + +const irreparableArr = new Array(); +let repairableArr: Array = new Array(); +repairableArr = new Array(); + +const irreparableMap = new Map(); +const repairableMap: Map = new Map(); +repairableMap = new Map(); + +class MyClass { + public irreparableMap = new Map(); + public repairableSet: Set = new Map(); + public repairableMap: Map string[]> = new Map string[]>(); + static repairableStaticMap: Map string[]> = new Map string[]>(); + constructor() {} +} + +const irreparableA = new MyClass(); +const irreparableB = new MyClass(); +const repairableC: MyClass = new MyClass(); +repairableC.irreparableMap = new Map(); +repairableC.repairableSet = new Set(); +repairableC.repairableMap = new Map string[]>(); +MyClass.repairableStaticMap = new Map string[]>(); + +const promise: Promise = new Promise(() => { return ''; }); + +function testA(): Map { + return new Map(); +} + +async function testB(): Promise> { + return new Map(); +} + +function testC(): Map { + return new Set(); +} + +async function testD(): Promise> { + return new Set(); +} + +class MyClassB { + testA(): Map { + return new Map(); + } + + async testB(): Promise> { + return new Map(); + } + + testC(): Map { + return new Set(); + } + + async testD(): Promise> { + return new Set(); + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..a3d92d0d965596b23b8e137b426e01275b3f7847 --- /dev/null +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json @@ -0,0 +1,228 @@ +{ + "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": 7, + "endLine": 16, + "endColumn": 35, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 24, + "endLine": 16, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 33, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 24, + "endLine": 20, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 27, + "endLine": 25, + "endColumn": 36, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 10, + "endLine": 26, + "endColumn": 23, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 39, + "endLine": 26, + "endColumn": 48, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 7, + "endLine": 32, + "endColumn": 35, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 35, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 30, + "endLine": 35, + "endColumn": 39, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 19, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 12, + "endLine": 68, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 12, + "endLine": 72, + "endColumn": 21, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/func_return_type.ets.args.json b/ets2panda/linter/test/main/func_return_type.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/func_return_type.ets.args.json +++ b/ets2panda/linter/test/main/func_return_type.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/migrate/func_return_type.sts b/ets2panda/linter/test/main/func_return_type.ets.migrate.ets similarity index 77% rename from ets2panda/linter/test/migrate/func_return_type.sts rename to ets2panda/linter/test/main/func_return_type.ets.migrate.ets index c2167e6373157ff748ad9ee044c39b09e3f2c36e..cbcf3e1fb8ea652207ff978c7368b50927b98173 100644 --- a/ets2panda/linter/test/migrate/func_return_type.sts +++ b/ets2panda/linter/test/main/func_return_type.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -13,14 +13,14 @@ * limitations under the License. */ -function q(x: number) { // Need fix +function q(x: number): number { // Need fix return w(x) } function w(x: number) { - return x; + return x; } -function e(x: string) { // Need fix +function e(x: string): string { // Need fix return r(x) } function r(x: string) { @@ -30,7 +30,7 @@ function t(x: string): string { return x; } -function y() { // Need fix +function y(): number[] { // Need fix return u(); } function u() { @@ -59,23 +59,23 @@ function z(a: any) { // Not fixable } function functionExpressions() { - let f1 = function (c: C) { // Need fix + let f1 = (c: C): C => { return f2(c); - }; - let f2 = function (c: C) { +}; + let f2 = (c: C) => { return new C(); - }; - - let f3 = function (x: number, y: number) { +}; + + let f3 = (x: number, y: number) => { return x + y; - }; +}; - let f4 = function () { // Need fix + let f4 = (): Map => { return f5(); - }; - let f5 = function () { +}; + let f5 = () => { return new Map(); - }; +}; let f6 = function () { // Not fixable return z(0); @@ -83,20 +83,20 @@ function functionExpressions() { } function lambdas() { - let l1 = (t: T) => { // Need fix + let l1 = (t: T): T => { return l2(t); - }; +}; let l2 = (t: T) => { return t; }; - + let l3 = (x: number, y: number) => { return x + y; }; - let l4 = () => { // Need fix + let l4 = (): (x: number) => string => { return l5(); - }; +}; let l5 = () => { return (x: number) => x.toString(); }; @@ -107,19 +107,19 @@ function lambdas() { } class C { - m(x: number) { // Need fix + m(x: number): number { // Need fix return q(x) } - - m2(x: number) { // Need fix + + m2(x: number): number { // Need fix return this.m(x) } m3(x: number) { return 10; } - - m4() { // Need fix + + m4(): number { // Need fix return this.m2(20); } @@ -128,7 +128,7 @@ class C { } } -function no_space_before_body(x: number){ // Need fix +function no_space_before_body(x: number): number{ // Need fix return w(x) } diff --git a/ets2panda/linter/test/migrate/func_return_type.ts.json b/ets2panda/linter/test/main/func_return_type.ets.migrate.json similarity index 49% rename from ets2panda/linter/test/migrate/func_return_type.ts.json rename to ets2panda/linter/test/main/func_return_type.ets.migrate.json index 00be5f244b8ce3b6ab16fa954aa0368a9bc39cf2..4d8789634f9daf40ac0655cd549af1ee9a74946d 100644 --- a/ets2panda/linter/test/migrate/func_return_type.ts.json +++ b/ets2panda/linter/test/main/func_return_type.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 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", @@ -14,36 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 16, - "column": 10, - "endLine": 16, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 10, - "endLine": 23, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 10, - "endLine": 33, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, { "line": 40, "column": 10, @@ -94,56 +64,6 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, - { - "line": 62, - "column": 12, - "endLine": 64, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 12, - "endLine": 67, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 12, - "endLine": 71, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 12, - "endLine": 75, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 76, - "column": 12, - "endLine": 78, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, { "line": 80, "column": 12, @@ -164,26 +84,6 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, - { - "line": 86, - "column": 12, - "endLine": 88, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 97, - "column": 12, - "endLine": 99, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, { "line": 104, "column": 12, @@ -194,36 +94,6 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, - { - "line": 110, - "column": 3, - "endLine": 110, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 114, - "column": 3, - "endLine": 114, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, { "line": 126, "column": 3, @@ -234,16 +104,6 @@ "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, - { - "line": 131, - "column": 10, - "endLine": 131, - "endColumn": 30, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, { "line": 135, "column": 18, diff --git a/ets2panda/linter/test/main/function_expression.ets.args.json b/ets2panda/linter/test/main/function_expression.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/function_expression.ets.args.json +++ b/ets2panda/linter/test/main/function_expression.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/migrate/function_expression.sts b/ets2panda/linter/test/main/function_expression.ets.migrate.ets similarity index 42% rename from ets2panda/linter/test/migrate/function_expression.sts rename to ets2panda/linter/test/main/function_expression.ets.migrate.ets index 0806c249b8cc5275b5e03f8acc15df5d16e49e18..5e0cd324c204719bae12bd2340e58d3dbd7bad5e 100644 --- a/ets2panda/linter/test/migrate/function_expression.sts +++ b/ets2panda/linter/test/main/function_expression.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -13,36 +13,36 @@ * limitations under the License. */ -const empty = function () {}; +const empty = () => { }; -const multiply = function (x: number, y): number { - return x * y; +const multiply = (x: number, y): number => { + return x * y; }; function createFunc(): () => number { - return function () { + return () => { return 100; - }; +}; } -const foobar = (function () { - return 'get result immediately'; +const foobar = (() => { + return 'get result immediately'; })(); -(function () { - console.log('foo!'); +(() => { + console.log('foo!'); })(); -void (function () { - console.log('bar!'); +void (() => { + console.log('bar!'); })(); const array = [1, 2, 3, 4, 5, 6]; -const double = array.map(function (e) { - return e * 2; +const double = array.map((e) => { + return e * 2; }); -const even = array.filter(function (x) { - return x % 2 === 0; +const even = array.filter((x) => { + return x % 2 === 0; }); const retTypeInfer = function (p: any) { @@ -53,12 +53,12 @@ const generator = function * () { yield 1; }; -const generic = function (t: T, e: E) { - return t; +const generic = (t: T, e: E) => { + return t; }; -const asyncFun = async function() { - console.log('baz!'); +const asyncFun = async () => { + console.log('baz!'); }; const factorial = function f(n: number): number { @@ -68,46 +68,46 @@ const factorial = function f(n: number): number { class C { m() {} } -const noRecursiveCall = function f(p: () => number): void { // Doesn't have recursive call, should be autofixable - let a = factorial(3); - let b = p(); - let c = new C() - c.m(); +const noRecursiveCall = (p: () => number): void => { + let a = factorial(3); + let b = p(); + let c = new C(); + c.m(); }; -let iife = function() { - console.log('called immediately'); -}(); +let iife = (() => { + console.log('called immediately'); +})(); -let indexAccess = function() { - console.log('index access'); -}[0]; +let indexAccess = (() => { + console.log('index access'); +})[0]; -void function() { - console.log('void'); -}; +void (() => { + console.log('void'); +}); -async function awaitFun() { - await function() { +async function awaitFun() { + await (() => { console.log('async'); - }; +}); } -let typeofFunc = typeof function() { - console.log('typeof'); -} +let typeofFunc = typeof (() => { + console.log('typeof'); +}) class BindFuncExpr { foo() { - let bar = function(p: boolean) { - console.log('Function.bind(this)'); - }.bind(this); + let bar = ((p: boolean) => { + console.log('Function.bind(this)'); +}).bind(this); } } -let callback = function() { console.log('callback'); } -callback = callback || function() { console.log('expr || function(){}'); }; +let callback = () => { console.log('callback'); } +callback = callback || (() => { console.log('expr || function(){}'); }); let ternaryExpr = !!callback - ? function() { console.log('ternary 1'); } || 2 - : 3 && function() { console.log('ternary 2'); }; \ No newline at end of file + ? (() => { console.log('ternary 1'); }) || 2 + : 3 && (() => { console.log('ternary 2'); }); \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/void_operator.ts.json b/ets2panda/linter/test/main/function_expression.ets.migrate.json similarity index 46% rename from ets2panda/linter/test/migrate/void_operator.ts.json rename to ets2panda/linter/test/main/function_expression.ets.migrate.json index 4903dda8202cfce0bcc049087d1c68051e76f8cf..71e6ea80028dbae025ae4ace5f6a34693ed279f0 100644 --- a/ets2panda/linter/test/migrate/void_operator.ts.json +++ b/ets2panda/linter/test/main/function_expression.ets.migrate.json @@ -15,19 +15,19 @@ ], "result": [ { - "line": 22, - "column": 6, - "endLine": 22, - "endColumn": 7, - "problem": "ObjectLiteralNoContextType", + "line": 18, + "column": 30, + "endLine": 18, + "endColumn": 31, + "problem": "AnyType", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 36, - "column": 6, - "endLine": 38, + "line": 48, + "column": 22, + "endLine": 50, "endColumn": 2, "problem": "FunctionExpression", "suggest": "", @@ -35,19 +35,29 @@ "severity": "ERROR" }, { - "line": 40, - "column": 6, - "endLine": 42, + "line": 48, + "column": 22, + "endLine": 50, "endColumn": 2, - "problem": "FunctionExpression", + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 35, + "endLine": 48, + "endColumn": 38, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 44, - "column": 7, - "endLine": 46, + "line": 52, + "column": 19, + "endLine": 54, "endColumn": 2, "problem": "FunctionExpression", "suggest": "", @@ -55,64 +65,74 @@ "severity": "ERROR" }, { - "line": 48, - "column": 6, - "endLine": 48, - "endColumn": 11, - "problem": "ClassExpression", + "line": 52, + "column": 19, + "endLine": 54, + "endColumn": 2, + "problem": "GeneratorFunction", "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", + "rule": "Generator functions are not supported (arkts-no-generators)", "severity": "ERROR" }, { - "line": 50, - "column": 7, - "endLine": 50, - "endColumn": 12, - "problem": "ClassExpression", + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 10, + "problem": "YieldExpression", "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", + "rule": "Generator functions are not supported (arkts-no-generators)", "severity": "ERROR" }, { - "line": 61, - "column": 8, - "endLine": 63, - "endColumn": 4, + "line": 64, + "column": 19, + "endLine": 66, + "endColumn": 2, "problem": "FunctionExpression", "suggest": "", "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", "severity": "ERROR" }, { - "line": 65, - "column": 8, - "endLine": 67, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 82, + "column": 5, + "endLine": 84, + "endColumn": 6, + "problem": "AnyType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 69, - "column": 8, - "endLine": 69, - "endColumn": 13, - "problem": "ClassExpression", + "line": 82, + "column": 19, + "endLine": 84, + "endColumn": 6, + "problem": "PropertyAccessByIndex", "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, { - "line": 71, - "column": 8, - "endLine": 71, - "endColumn": 13, - "problem": "ClassExpression", + "line": 102, + "column": 9, + "endLine": 104, + "endColumn": 14, + "problem": "AnyType", "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" + }, + { + "line": 104, + "column": 4, + "endLine": 104, + "endColumn": 14, + "problem": "FunctionBind", + "suggest": "", + "rule": "'Function.bind' is not supported (arkts-no-func-bind)", + "severity": "WARNING" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/function_object_methods.ets.arkts2.json b/ets2panda/linter/test/main/function_object_methods.ets.arkts2.json index b4340103615c77dd8413bf3f8cffb809aa85140b..adb91f9c46eff8b5ca22a4d0d66f2180d5637b30 100644 --- a/ets2panda/linter/test/main/function_object_methods.ets.arkts2.json +++ b/ets2panda/linter/test/main/function_object_methods.ets.arkts2.json @@ -14,26 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 19, - "column": 16, - "endLine": 19, - "endColumn": 24, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 14, - "endLine": 20, - "endColumn": 22, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 29, "column": 5, @@ -134,16 +114,6 @@ "rule": "'Function.bind' is not supported (arkts-no-func-bind)", "severity": "ERROR" }, - { - "line": 75, - "column": 15, - "endLine": 75, - "endColumn": 23, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 75, "column": 48, @@ -155,13 +125,13 @@ "severity": "ERROR" }, { - "line": 78, - "column": 15, - "endLine": 78, - "endColumn": 23, + "line": 76, + "column": 9, + "endLine": 76, + "endColumn": 13, "problem": "ExplicitFunctionType", "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { @@ -174,6 +144,16 @@ "rule": "'Function.bind' is not supported (arkts-no-func-bind)", "severity": "ERROR" }, + { + "line": 79, + "column": 9, + "endLine": 79, + "endColumn": 13, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, { "line": 81, "column": 31, @@ -244,16 +224,6 @@ "rule": "'Function.bind' is not supported (arkts-no-func-bind)", "severity": "ERROR" }, - { - "line": 101, - "column": 14, - "endLine": 101, - "endColumn": 22, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 101, "column": 42, @@ -265,13 +235,13 @@ "severity": "ERROR" }, { - "line": 104, - "column": 14, - "endLine": 104, - "endColumn": 22, + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 6, "problem": "ExplicitFunctionType", "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", "severity": "ERROR" }, { @@ -284,6 +254,16 @@ "rule": "'Function.bind' is not supported (arkts-no-func-bind)", "severity": "ERROR" }, + { + "line": 105, + "column": 3, + "endLine": 105, + "endColumn": 6, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, { "line": 107, "column": 20, diff --git a/ets2panda/linter/test/main/global_this.ets.args.json b/ets2panda/linter/test/main/global_this.ets.args.json index db044a3dff705d84beabaa2d833b7cf1b2debd01..a89d885810708ad03d96e3e14bb6590efd1a7547 100644 --- a/ets2panda/linter/test/main/global_this.ets.args.json +++ b/ets2panda/linter/test/main/global_this.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/global_this.ets.arkts2.json b/ets2panda/linter/test/main/global_this.ets.arkts2.json index 34bcda6b2d2414dd2e9bf4d9e05f9a556ee0a4b7..447570a136871eb55c8a0a2f2ae64cc13a5651c3 100644 --- a/ets2panda/linter/test/main/global_this.ets.arkts2.json +++ b/ets2panda/linter/test/main/global_this.ets.arkts2.json @@ -64,6 +64,16 @@ "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", "severity": "ERROR" }, + { + "line": 28, + "column": 18, + "endLine": 28, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 30, "column": 7, @@ -103,6 +113,16 @@ "suggest": "", "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", "severity": "ERROR" + }, + { + "line": 34, + "column": 18, + "endLine": 34, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/global_this.ets.autofix.json b/ets2panda/linter/test/main/global_this.ets.autofix.json index 5d8cc4d2dee047bb9d926d44f590afd9775ccbb0..95eda816e5d4ddfe3cc3a99b095f66fbd32d7e31 100755 --- a/ets2panda/linter/test/main/global_this.ets.autofix.json +++ b/ets2panda/linter/test/main/global_this.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 616, "end": 627, - "replacementText": "pi: number = 3.1416" + "replacementText": "pi: number = 3.1416", + "line": 16, + "column": 7, + "endLine": 16, + "endColumn": 18 } ], "suggest": "", @@ -51,7 +55,11 @@ { "start": 700, "end": 713, - "replacementText": "specialAutofixLib.globalThis.get(\"pi\")" + "replacementText": "specialAutofixLib.globalThis.get(\"pi\")", + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 23 } ], "suggest": "", @@ -78,13 +86,38 @@ { "start": 779, "end": 799, - "replacementText": "specialAutofixLib.globalThis.set(\"abc\", 200)" + "replacementText": "specialAutofixLib.globalThis.set(\"abc\", 200)", + "line": 28, + "column": 1, + "endLine": 28, + "endColumn": 21 } ], "suggest": "", "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", "severity": "ERROR" }, + { + "line": 28, + "column": 18, + "endLine": 28, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 796, + "end": 799, + "replacementText": "200.0", + "line": 28, + "column": 18, + "endLine": 28, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 30, "column": 7, @@ -105,7 +138,11 @@ { "start": 816, "end": 830, - "replacementText": "specialAutofixLib.globalThis.get(\"obj\")" + "replacementText": "specialAutofixLib.globalThis.get(\"obj\")", + "line": 30, + "column": 15, + "endLine": 30, + "endColumn": 29 } ], "suggest": "", @@ -132,12 +169,37 @@ { "start": 845, "end": 864, - "replacementText": "specialAutofixLib.globalThis.get(\"property\")" + "replacementText": "specialAutofixLib.globalThis.get(\"property\")", + "line": 32, + "column": 8, + "endLine": 32, + "endColumn": 27 } ], "suggest": "", "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", "severity": "ERROR" + }, + { + "line": 34, + "column": 18, + "endLine": 34, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 884, + "end": 887, + "replacementText": "100.0", + "line": 34, + "column": 18, + "endLine": 34, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/global_this.ets.migrate.ets b/ets2panda/linter/test/main/global_this.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..aaafd6ebd11b8534e2cd97530cafd75685758d31 --- /dev/null +++ b/ets2panda/linter/test/main/global_this.ets.migrate.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022-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 pi: number = 3.1416; + +function circleArea(r: number): number { + foo(globalThis); + + return specialAutofixLib.globalThis.get("pi") * r * r; +} + +function foo(x: any): void { + console.log(x.pi); +} + +specialAutofixLib.globalThis.set("abc", 200.0); + +const value = specialAutofixLib.globalThis.get("obj").prop; + +delete specialAutofixLib.globalThis.get("property"); + +globalThisprop = 100.0; + +specialAutofixLib.globalThis.get("pi"); + +specialAutofixLib.globalThis.set("pi",3.1416); + +specialAutofixLib.globalThis; + diff --git a/ets2panda/linter/test/main/global_this.ets.migrate.json b/ets2panda/linter/test/main/global_this.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..cdc3cef837269d89e24bee549595845bda5cc72b --- /dev/null +++ b/ets2panda/linter/test/main/global_this.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 19, + "column": 7, + "endLine": 19, + "endColumn": 17, + "problem": "GlobalThisError", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 17, + "endLine": 24, + "endColumn": 20, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 7, + "endLine": 30, + "endColumn": 59, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 7, + "problem": "DeleteOperator", + "suggest": "", + "rule": "\"delete\" operator is not supported (arkts-no-delete)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json b/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json index 5fe322754714c75722b28c50322a2ab6afcb1164..da908095d3d48a520457fd8c8455423a513ff7ff 100644 --- a/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json +++ b/ets2panda/linter/test/main/incompatible_function.ets.arkts2.json @@ -24,6 +24,26 @@ "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", "severity": "ERROR" }, + { + "line": 19, + "column": 12, + "endLine": 19, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 16, + "endLine": 24, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 28, "column": 8, @@ -34,6 +54,36 @@ "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", "severity": "ERROR" }, + { + "line": 29, + "column": 12, + "endLine": 29, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 16, + "endLine": 34, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 12, + "endLine": 39, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 42, "column": 7, @@ -44,6 +94,16 @@ "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", "severity": "ERROR" }, + { + "line": 51, + "column": 12, + "endLine": 51, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 56, "column": 23, @@ -54,6 +114,16 @@ "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", "severity": "ERROR" }, + { + "line": 57, + "column": 12, + "endLine": 57, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 60, "column": 8, @@ -64,6 +134,26 @@ "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", "severity": "ERROR" }, + { + "line": 61, + "column": 12, + "endLine": 61, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 59, + "endLine": 64, + "endColumn": 60, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 66, "column": 38, @@ -74,6 +164,26 @@ "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", "severity": "ERROR" }, + { + "line": 67, + "column": 12, + "endLine": 67, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 12, + "endLine": 75, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 80, "column": 35, @@ -83,6 +193,16 @@ "suggest": "", "rule": "Stricter assignments into variables of function type (arkts-incompatible-function-types)", "severity": "ERROR" + }, + { + "line": 81, + "column": 12, + "endLine": 81, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/index_negative.ets.arkts2.json b/ets2panda/linter/test/main/index_negative.ets.arkts2.json index 8c2d2b6a35d5ce0cc59465da582e18b4b3fa6ca3..d1daebd5f8a021b6d2daa1afa892f0a62a28f0c9 100755 --- a/ets2panda/linter/test/main/index_negative.ets.arkts2.json +++ b/ets2panda/linter/test/main/index_negative.ets.arkts2.json @@ -24,6 +24,36 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 16, + "column": 17, + "endLine": 16, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 19, + "endLine": 16, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 21, + "endLine": 16, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 17, "column": 5, @@ -64,6 +94,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 21, + "column": 10, + "endLine": 21, + "endColumn": 12, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 22, "column": 10, @@ -74,6 +114,36 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 24, + "column": 18, + "endLine": 24, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 30, + "endLine": 27, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 33, + "endLine": 27, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 28, "column": 9, @@ -94,6 +164,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 33, + "column": 11, + "endLine": 33, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 37, "column": 1, @@ -124,6 +204,26 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 13, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 20, + "endLine": 41, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 42, "column": 1, @@ -134,6 +234,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 42, + "column": 5, + "endLine": 42, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 8, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 45, "column": 5, @@ -144,6 +264,26 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 10, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 13, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 50, "column": 1, @@ -154,6 +294,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 9, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 52, "column": 1, @@ -164,6 +314,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 5, + "endLine": 53, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 54, "column": 1, @@ -174,6 +344,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 6, + "endLine": 56, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 57, "column": 1, @@ -194,6 +384,26 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 58, + "column": 5, + "endLine": 58, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 5, + "endLine": 59, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 60, "column": 1, @@ -204,6 +414,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 16, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 61, "column": 1, @@ -234,6 +454,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 63, + "column": 6, + "endLine": 63, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 65, "column": 1, @@ -244,6 +474,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 66, "column": 1, @@ -254,6 +494,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 9, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 68, "column": 1, @@ -264,6 +514,36 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 68, + "column": 5, + "endLine": 68, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 71, "column": 7, @@ -274,6 +554,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 30, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 73, "column": 1, @@ -284,6 +574,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 6, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 74, "column": 7, @@ -294,6 +594,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 74, + "column": 12, + "endLine": 74, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 75, "column": 7, @@ -304,6 +614,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 75, + "column": 13, + "endLine": 75, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 76, "column": 7, @@ -314,6 +634,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 76, + "column": 13, + "endLine": 76, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 77, "column": 7, @@ -326,7 +656,17 @@ }, { "line": 77, - "column": 12, + "column": 13, + "endLine": 77, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 15, "endLine": 77, "endColumn": 16, "problem": "NumericSemantics", @@ -344,6 +684,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 78, + "column": 13, + "endLine": 78, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 79, "column": 7, @@ -354,6 +704,46 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 79, + "column": 13, + "endLine": 79, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 15, + "endLine": 79, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 82, "column": 1, @@ -364,6 +754,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 82, + "column": 5, + "endLine": 82, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 83, "column": 1, @@ -374,6 +774,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 5, + "endLine": 84, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 85, "column": 1, @@ -384,6 +804,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 86, "column": 7, @@ -394,6 +824,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 86, + "column": 15, + "endLine": 86, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 87, "column": 1, @@ -404,6 +844,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 88, "column": 5, @@ -424,6 +874,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 7, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 90, "column": 1, @@ -484,6 +944,26 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 92, + "column": 5, + "endLine": 92, + "endColumn": 9, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 11, + "endLine": 94, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 96, "column": 11, @@ -494,6 +974,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 97, + "column": 15, + "endLine": 97, + "endColumn": 24, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 98, "column": 7, @@ -504,6 +994,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 98, + "column": 14, + "endLine": 98, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 99, "column": 1, @@ -514,6 +1014,16 @@ "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" }, + { + "line": 99, + "column": 5, + "endLine": 99, + "endColumn": 14, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, { "line": 100, "column": 1, @@ -523,6 +1033,16 @@ "suggest": "", "rule": "The index expression must be zero or positive value.(arkts-array-index-negative)", "severity": "ERROR" + }, + { + "line": 100, + "column": 5, + "endLine": 100, + "endColumn": 8, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_1.ets b/ets2panda/linter/test/main/interface_import_1.ets index fdf8aa458c974c90e8e628dfc16ec648a80ce181..a6cf768c0b7e48216895bbd3acd4f9b6365dd82f 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets +++ b/ets2panda/linter/test/main/interface_import_1.ets @@ -13,15 +13,13 @@ * limitations under the License. */ -import { Row, Slider } from '@kits.ArkUI'; +import { Slider } from '@kit.ArkUI'; @Entry @Component struct Test { - - @State num: number = 0; - - @State a: MyClassA = new MyClassA(); + @State num: number = 0 + @State a: MyClassA = new MyClassA() build() { Column() { @@ -30,11 +28,8 @@ struct Test { Circle() { } - .stateStyles({ - }) - - MyComponent() { + MyComponent1() { } @@ -52,8 +47,9 @@ function Circle() { } @Component -struct MyComponent { +struct MyComponent1 { @State count: number = 0; + build() { Row() { Slider(){} @@ -64,7 +60,7 @@ struct MyComponent { @Extend(Text) function cardStyle() { - .backgroundColor1(Color.Green) + .backgroundColor(Color.Green) } @AnimatableExtend(Column) @@ -73,8 +69,9 @@ function animatableWidth(width: number) { } @Component -struct Myomponent { +struct MyComponent2 { @State value: number = 0; + build() { Row() { Slider({ @@ -84,11 +81,9 @@ struct Myomponent { } } -function processImageFit(imageFit: ImageFit): void { -} - -class MyClassA { +class MyClassA {} +function processImageFit(imageFit: ImageFit): void { } function Calendar() { diff --git a/ets2panda/linter/test/main/interface_import_1.ets.args.json b/ets2panda/linter/test/main/interface_import_1.ets.args.json index f6c6b88ccf1c4f584046e33982847cab303736a4..631484dfeb6566327bedf2e0eaf8ba98e5589e2e 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.args.json +++ b/ets2panda/linter/test/main/interface_import_1.ets.args.json @@ -15,7 +15,8 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_1.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_1.ets.arkts2.json index a056e273be99b2338846d381f417ea807e98ad39..953e84542d0fa2136b8adb75eec1e5f7974fcda1 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/interface_import_1.ets.arkts2.json @@ -1,33 +1,43 @@ { "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 (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": 24, - "column": 13, - "endLine": 24, - "endColumn": 21, - "problem": "DataObservation", + "line": 21, + "column": 24, + "endLine": 21, + "endColumn": 25, + "problem": "NumericSemantics", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 64, + "line": 51, + "column": 26, + "endLine": 51, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 60, "column": 1, - "endLine": 68, + "endLine": 64, "endColumn": 2, "problem": "ExtendDecoratorNotSupported", "suggest": "", @@ -35,9 +45,9 @@ "severity": "ERROR" }, { - "line": 70, + "line": 66, "column": 1, - "endLine": 73, + "endLine": 69, "endColumn": 2, "problem": "AnimatableExtendDecoratorTransform", "suggest": "", @@ -45,9 +55,19 @@ "severity": "ERROR" }, { - "line": 81, + "line": 73, + "column": 26, + "endLine": 73, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 78, "column": 16, - "endLine": 81, + "endLine": 78, "endColumn": 28, "problem": "DoubleDollarBindingNotSupported", "suggest": "", @@ -74,6 +94,16 @@ "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, { "line": 22, "column": 4, @@ -85,9 +115,9 @@ "severity": "ERROR" }, { - "line": 27, + "line": 25, "column": 5, - "endLine": 27, + "endLine": 25, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -95,9 +125,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 26, "column": 7, - "endLine": 28, + "endLine": 26, "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", @@ -105,9 +135,9 @@ "severity": "ERROR" }, { - "line": 41, + "line": 36, "column": 7, - "endLine": 41, + "endLine": 36, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -115,9 +145,39 @@ "severity": "ERROR" }, { - "line": 70, + "line": 49, "column": 2, - "endLine": 70, + "endLine": 49, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 4, + "endLine": 51, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 2, + "endLine": 66, "endColumn": 18, "problem": "UIInterfaceImport", "suggest": "", @@ -125,9 +185,39 @@ "severity": "ERROR" }, { - "line": 87, + "line": 71, + "column": 2, + "endLine": 71, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 4, + "endLine": 73, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 5, + "endLine": 76, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 86, "column": 36, - "endLine": 87, + "endLine": 86, "endColumn": 44, "problem": "UIInterfaceImport", "suggest": "", diff --git a/ets2panda/linter/test/main/interface_import_1.ets.autofix.json b/ets2panda/linter/test/main/interface_import_1.ets.autofix.json index 6d9552cc1b25bc6a4c3f1a922022b6fb4f78944f..deacf76eb3cf7a24628c3329f028d3b5e52e9fdd 100644 --- a/ets2panda/linter/test/main/interface_import_1.ets.autofix.json +++ b/ets2panda/linter/test/main/interface_import_1.ets.autofix.json @@ -1,47 +1,76 @@ { "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 (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": 24, - "column": 13, - "endLine": 24, - "endColumn": 21, - "problem": "DataObservation", + "line": 21, + "column": 24, + "endLine": 21, + "endColumn": 25, + "problem": "NumericSemantics", "autofix": [ { - "start": 1501, - "end": 1501, - "replacementText": "@Observed\n" + "start": 698, + "end": 699, + "replacementText": "0.0", + "line": 21, + "column": 24, + "endLine": 21, + "endColumn": 25 } ], "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 64, + "line": 51, + "column": 26, + "endLine": 51, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1041, + "end": 1042, + "replacementText": "0.0", + "line": 51, + "column": 26, + "endLine": 51, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 60, "column": 1, - "endLine": 68, + "endLine": 64, "endColumn": 2, "problem": "ExtendDecoratorNotSupported", "autofix": [ { - "start": 1137, - "end": 1208, - "replacementText": "@Memo\nfunction cardStyle(this: TextAttribute): this {\n this.backgroundColor1(Color.Green);\n return this;\n}" + "start": 1099, + "end": 1169, + "replacementText": "function cardStyle(this: TextAttribute): this {\n this.backgroundColor(Color.Green);\n return this;\n}", + "line": 60, + "column": 1, + "endLine": 64, + "endColumn": 2 } ], "suggest": "", @@ -49,16 +78,20 @@ "severity": "ERROR" }, { - "line": 70, + "line": 66, "column": 1, - "endLine": 73, + "endLine": 69, "endColumn": 2, "problem": "AnimatableExtendDecoratorTransform", "autofix": [ { - "start": 1210, - "end": 1295, - "replacementText": "@AnimatableExtend\n@Memo\nfunction animatableWidth(this: ColumnAttribute, width: number): this {\n this.width(width);\n return this;\n}" + "start": 1171, + "end": 1256, + "replacementText": "@AnimatableExtend\nfunction animatableWidth(this: ColumnAttribute, width: number): this {\n this.width(width);\n return this;\n}", + "line": 66, + "column": 1, + "endLine": 69, + "endColumn": 2 } ], "suggest": "", @@ -66,16 +99,41 @@ "severity": "ERROR" }, { - "line": 81, + "line": 73, + "column": 26, + "endLine": 73, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1316, + "end": 1317, + "replacementText": "0.0", + "line": 73, + "column": 26, + "endLine": 73, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 78, "column": 16, - "endLine": 81, + "endLine": 78, "endColumn": 28, "problem": "DoubleDollarBindingNotSupported", "autofix": [ { - "start": 1410, - "end": 1422, - "replacementText": "$$(this.value)" + "start": 1374, + "end": 1386, + "replacementText": "$$(this.value)", + "line": 78, + "column": 16, + "endLine": 78, + "endColumn": 28 } ], "suggest": "", @@ -88,6 +146,17 @@ "endLine": 18, "endColumn": 7, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -98,6 +167,38 @@ "endLine": 19, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 4, + "endLine": 21, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -108,61 +209,246 @@ "endLine": 22, "endColumn": 9, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 27, + "line": 25, "column": 5, - "endLine": 27, + "endLine": 25, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 28, + "line": 26, "column": 7, - "endLine": 28, + "endLine": 26, "endColumn": 13, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 41, + "line": 36, "column": 7, - "endLine": 41, + "endLine": 36, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 70, + "line": 49, "column": 2, - "endLine": 70, + "endLine": 49, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 4, + "endLine": 51, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 2, + "endLine": 66, "endColumn": 18, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 2, + "endLine": 71, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 4, + "endLine": 73, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 5, + "endLine": 76, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 87, + "line": 86, "column": 36, - "endLine": 87, + "endLine": 86, "endColumn": 44, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, TextAttribute, Memo, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kits.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI';", + "line": 86, + "column": 36, + "endLine": 86, + "endColumn": 44 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/interface_import_1.ets.migrate.ets b/ets2panda/linter/test/main/interface_import_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..97155fd1a2a10d56545fe3ca589ff0fef5b73834 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_1.ets.migrate.ets @@ -0,0 +1,93 @@ +/* + * 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, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI'; + +import { Slider } from '@kit.ArkUI'; + +@Entry +@Component +struct Test { + @State num: number = 0.0 + @State a: MyClassA = new MyClassA() + + build() { + Column() { + Button('按钮') + .backgroundColor('#ffffff') + Circle() { + + } + + MyComponent1() { + + } + + Text("Test") + }.width("100%") + } +} + +enum Color { + Green +} + +function Circle() { + +} + +@Component +struct MyComponent1 { + @State count: number = 0.0; + + build() { + Row() { + Slider(){} + } + } +} + +function cardStyle(this: TextAttribute): this { + this.backgroundColor(Color.Green); + return this; +} + +@AnimatableExtend +function animatableWidth(this: ColumnAttribute, width: number): this { + this.width(width); + return this; +} + +@Component +struct MyComponent2 { + @State value: number = 0.0; + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +class MyClassA {} + +function processImageFit(imageFit: ImageFit): void { +} + +function Calendar() { + +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_1.ets.migrate.json b/ets2panda/linter/test/main/interface_import_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..400a3c703388b6e748b41fa890330385a7a325eb --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_1.ets.migrate.json @@ -0,0 +1,98 @@ +{ + "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": 63, + "column": 5, + "endLine": 63, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 20, + "endLine": 62, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 42, + "endLine": 62, + "endColumn": 46, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 26, + "endLine": 68, + "endColumn": 30, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 65, + "endLine": 68, + "endColumn": 69, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_2.ets b/ets2panda/linter/test/main/interface_import_2.ets index e3b20c0e764ecaff82fd574520933e02c854337e..231baa7371468bade2ef853c22cb7a7ec5896f61 100644 --- a/ets2panda/linter/test/main/interface_import_2.ets +++ b/ets2panda/linter/test/main/interface_import_2.ets @@ -13,13 +13,15 @@ * limitations under the License. */ -import { Row, Slider, Entry, Component, State, Column, Button, Text, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kits.ArkUI'; +import { Entry, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI'; + +import { Slider } from '@kit.ArkUI'; @Entry @Component struct Test { - - @State col: number = 0; + @State num: number = 0 + @State a: MyClassA = new MyClassA() build() { Column() { @@ -28,11 +30,8 @@ struct Test { Circle() { } - .stateStyles({ - - }) - MyComponent() { + MyComponent1() { } @@ -50,8 +49,9 @@ function Circle() { } @Component -struct MyComponent { +struct MyComponent1 { @State count: number = 0; + build() { Row() { Slider(){} @@ -59,21 +59,21 @@ struct MyComponent { } } -function cardStyle(this: TextAttribute): TextAttribute -{ - this.backgroundColor1('#ffffff'); - return this; +function cardStyle(this: TextAttribute): this { + this.backgroundColor(Color.Green); + return this; } @AnimatableExtend -function animatableWidth(this: ColumnAttribute, width: number) { - this.width(width) - return this; +function animatableWidth(this: ColumnAttribute, width: number): this { + this.width(width); + return this; } @Component -struct Myomponent { +struct MyComponent2 { @State value: number = 0; + build() { Row() { Slider({ @@ -81,4 +81,13 @@ struct Myomponent { }) } } +} + +class MyClassA {} + +function processImageFit(imageFit: ImageFit): void { +} + +function Calendar() { + } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_2.ets.args.json b/ets2panda/linter/test/main/interface_import_2.ets.args.json index f6c6b88ccf1c4f584046e33982847cab303736a4..631484dfeb6566327bedf2e0eaf8ba98e5589e2e 100644 --- a/ets2panda/linter/test/main/interface_import_2.ets.args.json +++ b/ets2panda/linter/test/main/interface_import_2.ets.args.json @@ -15,7 +15,8 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_2.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_2.ets.arkts2.json index 984baa68d4ee53e38516fbc7d17233787cb58f2c..8a9106960101a4f9a7f6f6f62bc570ae9b840699 100644 --- a/ets2panda/linter/test/main/interface_import_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/interface_import_2.ets.arkts2.json @@ -1,34 +1,54 @@ { "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 (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": 64, - "column": 3, - "endLine": 64, - "endColumn": 7, + "line": 23, + "column": 24, + "endLine": 23, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 26, + "endLine": 53, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 5, + "endLine": 63, + "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, { - "line": 65, - "column": 10, - "endLine": 65, - "endColumn": 14, + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", @@ -45,34 +65,64 @@ "severity": "ERROR" }, { - "line": 70, - "column": 3, - "endLine": 70, - "endColumn": 7, + "line": 62, + "column": 42, + "endLine": 62, + "endColumn": 46, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, { - "line": 71, - "column": 10, - "endLine": 71, - "endColumn": 14, + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, { - "line": 69, + "line": 68, "column": 26, - "endLine": 69, + "endLine": 68, "endColumn": 30, "problem": "InvalidIdentifier", "suggest": "", "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" + }, + { + "line": 68, + "column": 65, + "endLine": 68, + "endColumn": 69, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 26, + "endLine": 75, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_2.ets.autofix.json b/ets2panda/linter/test/main/interface_import_2.ets.autofix.json index 984baa68d4ee53e38516fbc7d17233787cb58f2c..2a99eb2500963467b1d274a17a3f3ed3fd94eb4c 100644 --- a/ets2panda/linter/test/main/interface_import_2.ets.autofix.json +++ b/ets2panda/linter/test/main/interface_import_2.ets.autofix.json @@ -1,34 +1,76 @@ { "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 (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": 64, - "column": 3, - "endLine": 64, - "endColumn": 7, + "line": 23, + "column": 24, + "endLine": 23, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 844, + "end": 845, + "replacementText": "0.0", + "line": 23, + "column": 24, + "endLine": 23, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 26, + "endLine": 53, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1187, + "end": 1188, + "replacementText": "0.0", + "line": 53, + "column": 26, + "endLine": 53, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 5, + "endLine": 63, + "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, { - "line": 65, - "column": 10, - "endLine": 65, - "endColumn": 14, + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", @@ -45,34 +87,75 @@ "severity": "ERROR" }, { - "line": 70, - "column": 3, - "endLine": 70, - "endColumn": 7, + "line": 62, + "column": 42, + "endLine": 62, + "endColumn": 46, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, { - "line": 71, - "column": 10, - "endLine": 71, - "endColumn": 14, + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, { - "line": 69, + "line": 68, "column": 26, - "endLine": 69, + "endLine": 68, "endColumn": 30, "problem": "InvalidIdentifier", "suggest": "", "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" + }, + { + "line": 68, + "column": 65, + "endLine": 68, + "endColumn": 69, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 26, + "endLine": 75, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1542, + "end": 1543, + "replacementText": "0.0", + "line": 75, + "column": 26, + "endLine": 75, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_2.ets.json b/ets2panda/linter/test/main/interface_import_2.ets.json index 99809749e715baf822badf87b65e9e672f9e8a7a..161c753493a5a310e9070b9111969694b8512474 100644 --- a/ets2panda/linter/test/main/interface_import_2.ets.json +++ b/ets2panda/linter/test/main/interface_import_2.ets.json @@ -15,53 +15,63 @@ ], "result": [ { - "line": 64, - "column": 3, - "endLine": 64, - "endColumn": 7, + "line": 63, + "column": 5, + "endLine": 63, + "endColumn": 9, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, { - "line": 65, - "column": 10, - "endLine": 65, - "endColumn": 14, + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, + { + "line": 62, + "column": 42, + "endLine": 62, + "endColumn": 46, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, { "line": 69, - "column": 10, + "column": 5, "endLine": 69, - "endColumn": 25, - "problem": "LimitedReturnTypeInference", + "endColumn": 9, + "problem": "FunctionContainsThis", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, { "line": 70, - "column": 3, + "column": 12, "endLine": 70, - "endColumn": 7, + "endColumn": 16, "problem": "FunctionContainsThis", "suggest": "", "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", "severity": "ERROR" }, { - "line": 71, - "column": 10, - "endLine": 71, - "endColumn": 14, - "problem": "FunctionContainsThis", + "line": 68, + "column": 65, + "endLine": 68, + "endColumn": 69, + "problem": "ThisType", "suggest": "", - "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/interface_import_2.ets.migrate.ets b/ets2panda/linter/test/main/interface_import_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..97155fd1a2a10d56545fe3ca589ff0fef5b73834 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_2.ets.migrate.ets @@ -0,0 +1,93 @@ +/* + * 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, Component, State, Column, Button, Text, Row, TextAttribute, ColumnAttribute, AnimatableExtend, $$, ImageFit } from '@kit.ArkUI'; + +import { Slider } from '@kit.ArkUI'; + +@Entry +@Component +struct Test { + @State num: number = 0.0 + @State a: MyClassA = new MyClassA() + + build() { + Column() { + Button('按钮') + .backgroundColor('#ffffff') + Circle() { + + } + + MyComponent1() { + + } + + Text("Test") + }.width("100%") + } +} + +enum Color { + Green +} + +function Circle() { + +} + +@Component +struct MyComponent1 { + @State count: number = 0.0; + + build() { + Row() { + Slider(){} + } + } +} + +function cardStyle(this: TextAttribute): this { + this.backgroundColor(Color.Green); + return this; +} + +@AnimatableExtend +function animatableWidth(this: ColumnAttribute, width: number): this { + this.width(width); + return this; +} + +@Component +struct MyComponent2 { + @State value: number = 0.0; + + build() { + Row() { + Slider({ + value: $$(this.value) + }) + } + } +} + +class MyClassA {} + +function processImageFit(imageFit: ImageFit): void { +} + +function Calendar() { + +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_2.ets.migrate.json b/ets2panda/linter/test/main/interface_import_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..400a3c703388b6e748b41fa890330385a7a325eb --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_2.ets.migrate.json @@ -0,0 +1,98 @@ +{ + "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": 63, + "column": 5, + "endLine": 63, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 12, + "endLine": 64, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 20, + "endLine": 62, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 42, + "endLine": 62, + "endColumn": 46, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 9, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 12, + "endLine": 70, + "endColumn": 16, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 26, + "endLine": 68, + "endColumn": 30, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 65, + "endLine": 68, + "endColumn": 69, + "problem": "ThisType", + "suggest": "", + "rule": "Type notation using \"this\" is not supported (arkts-no-typing-with-this)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_3.ets b/ets2panda/linter/test/main/interface_import_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d2d4f018cf24aa58c55a5c794412259eed75dc1 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_3.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. + */ + +import { A } from './har' + +A.getContext() + +A.b.getContext() + +let a: A = new A() +a.c.getContext() + +let c = a.c +c.getContext() + + +@Entry +@Component +struct importTest { + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_3.ets.args.json b/ets2panda/linter/test/main/interface_import_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_3.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/data_observation_2.ets.arkts2.json b/ets2panda/linter/test/main/interface_import_3.ets.arkts2.json similarity index 54% rename from ets2panda/linter/test/main/data_observation_2.ets.arkts2.json rename to ets2panda/linter/test/main/interface_import_3.ets.arkts2.json index e1facf88125a790b69914604eaa917e870d5cfb8..680b868bc155d9c6b2db73667b34a67b26b2fb8f 100644 --- a/ets2panda/linter/test/main/data_observation_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/interface_import_3.ets.arkts2.json @@ -15,29 +15,29 @@ ], "result": [ { - "line": 23, - "column": 19, - "endLine": 23, - "endColumn": 27, - "problem": "DataObservation", + "line": 22, + "column": 16, + "endLine": 22, + "endColumn": 17, + "problem": "DynamicCtorCall", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, { - "line": 24, - "column": 51, - "endLine": 24, - "endColumn": 59, - "problem": "DataObservation", + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 12, + "problem": "AnyType", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 18, + "line": 29, "column": 2, - "endLine": 18, + "endLine": 29, "endColumn": 7, "problem": "UIInterfaceImport", "suggest": "", @@ -45,34 +45,14 @@ "severity": "ERROR" }, { - "line": 19, + "line": 30, "column": 2, - "endLine": 19, + "endLine": 30, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" - }, - { - "line": 21, - "column": 6, - "endLine": 21, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 27, - "column": 2, - "endLine": 27, - "endColumn": 10, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_3.ets.autofix.json b/ets2panda/linter/test/main/interface_import_3.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..8bb68631570a7b49838734f2cd9b8a92e992e78e --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_3.ets.autofix.json @@ -0,0 +1,80 @@ +{ + "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": 16, + "endLine": 22, + "endColumn": 17, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 2, + "endLine": 29, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component } from '@kit.ArkUI';", + "line": 30, + "column": 2, + "endLine": 30, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 2, + "endLine": 30, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component } from '@kit.ArkUI';", + "line": 30, + "column": 2, + "endLine": 30, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/data_observation_1.ets.json b/ets2panda/linter/test/main/interface_import_3.ets.json similarity index 92% rename from ets2panda/linter/test/main/data_observation_1.ets.json rename to ets2panda/linter/test/main/interface_import_3.ets.json index c6dcaec09ee919e051db8ff10bc7f0a517a92362..e3cf8e3dff21a77173bd20420497e1e2f18ad670 100644 --- a/ets2panda/linter/test/main/data_observation_1.ets.json +++ b/ets2panda/linter/test/main/interface_import_3.ets.json @@ -15,10 +15,10 @@ ], "result": [ { - "line": 30, + "line": 25, "column": 5, - "endLine": 30, - "endColumn": 33, + "endLine": 25, + "endColumn": 12, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", diff --git a/ets2panda/linter/test/main/interface_import_3.ets.migrate.ets b/ets2panda/linter/test/main/interface_import_3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..437303702c6e107c16f736ec101add43705256b7 --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_3.ets.migrate.ets @@ -0,0 +1,36 @@ +/* + * 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, Component } from '@kit.ArkUI'; + +import { A } from './har' + +A.getContext() + +A.b.getContext() + +let a: A = new A() +a.c.getContext() + +let c = a.c +c.getContext() + + +@Entry +@Component +struct importTest { + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/interface_import_3.ets.migrate.json b/ets2panda/linter/test/main/interface_import_3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..97261a31bec464c39b11b661997115a04581803a --- /dev/null +++ b/ets2panda/linter/test/main/interface_import_3.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 24, + "column": 16, + "endLine": 24, + "endColumn": 17, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 12, + "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/main/interface_literal_prop_name.ets.json b/ets2panda/linter/test/main/interface_literal_prop_name.ets.json index 9df6f8b541e9eacb5608c595b973d5b3d8858580..6f68e19f773c93b033612ff79f18344ec936e933 100644 --- a/ets2panda/linter/test/main/interface_literal_prop_name.ets.json +++ b/ets2panda/linter/test/main/interface_literal_prop_name.ets.json @@ -14,16 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 23, - "column": 3, - "endLine": 23, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 23, "column": 3, @@ -64,16 +54,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 43, - "column": 10, - "endLine": 43, - "endColumn": 11, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 50, "column": 3, diff --git a/ets2panda/linter/test/main/invalid_identifier.ets b/ets2panda/linter/test/main/invalid_identifier.ets index 839b70c295a4f33093d6e91f4beb79d0eeb2f839..ade4397a201e9ff3aded49ca7fd2e9fdad73c859 100755 --- a/ets2panda/linter/test/main/invalid_identifier.ets +++ b/ets2panda/linter/test/main/invalid_identifier.ets @@ -198,4 +198,24 @@ struct Long { Text(this.message) } } +} + +enum char { + short, + number = 2, + int = 3, +} + +namespace char { + let number : number +} + +namespace quarantine { + interface int { + test: short + } + + interface test { + int: int + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json b/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json old mode 100755 new mode 100644 index fc35a0e44a7ac7a772670aa1e064605034bd00ac..2999205f9565c7610abab7a3471711f09e29ea9f --- a/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json +++ b/ets2panda/linter/test/main/invalid_identifier.ets.arkts2.json @@ -1,708 +1,918 @@ { - "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": 10, - "endLine": 16, - "endColumn": 16, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 8, - "endLine": 18, - "endColumn": 16, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 7, - "endLine": 22, - "endColumn": 15, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 7, - "endLine": 24, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 7, - "endLine": 26, - "endColumn": 9, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 7, - "endLine": 30, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 13, - "endLine": 32, - "endColumn": 13, - "problem": "SwitchExpression", - "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 7, - "endLine": 34, - "endColumn": 12, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 7, - "endLine": 36, - "endColumn": 10, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 7, - "endLine": 40, - "endColumn": 12, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 42, - "column": 7, - "endLine": 42, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 50, - "column": 10, - "endLine": 50, - "endColumn": 10, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 7, - "endLine": 52, - "endColumn": 12, - "problem": "ThrowStatement", - "suggest": "", - "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", - "severity": "ERROR" - }, - { - "line": 54, - "column": 7, - "endLine": 54, - "endColumn": 12, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 64, - "column": 7, - "endLine": 64, - "endColumn": 15, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 70, - "column": 7, - "endLine": 70, - "endColumn": 14, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 7, - "endLine": 72, - "endColumn": 16, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 74, - "column": 7, - "endLine": 74, - "endColumn": 18, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 7, - "endLine": 78, - "endColumn": 14, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 84, - "column": 7, - "endLine": 84, - "endColumn": 17, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 86, - "column": 7, - "endLine": 86, - "endColumn": 16, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 88, - "column": 7, - "endLine": 88, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 92, - "column": 7, - "endLine": 92, - "endColumn": 16, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 7, - "endLine": 96, - "endColumn": 14, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 98, - "column": 7, - "endLine": 98, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 100, - "column": 7, - "endLine": 100, - "endColumn": 14, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 7, - "endLine": 102, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 104, - "column": 7, - "endLine": 104, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 106, - "column": 7, - "endLine": 106, - "endColumn": 11, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 108, - "column": 7, - "endLine": 108, - "endColumn": 12, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 110, - "column": 7, - "endLine": 110, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 110, - "column": 24, - "endLine": 110, - "endColumn": 25, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 112, - "column": 7, - "endLine": 112, - "endColumn": 11, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 114, - "column": 7, - "endLine": 114, - "endColumn": 12, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 116, - "column": 7, - "endLine": 116, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 116, - "column": 24, - "endLine": 116, - "endColumn": 25, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 7, - "endLine": 118, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 120, - "column": 7, - "endLine": 120, - "endColumn": 10, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 122, - "column": 7, - "endLine": 122, - "endColumn": 12, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 124, - "column": 7, - "endLine": 124, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 126, - "column": 7, - "endLine": 126, - "endColumn": 10, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 128, - "column": 7, - "endLine": 128, - "endColumn": 12, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 130, - "column": 7, - "endLine": 130, - "endColumn": 11, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 132, - "column": 7, - "endLine": 132, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 134, - "column": 7, - "endLine": 134, - "endColumn": 11, - "problem": "VoidOperator", - "suggest": "", - "rule": "\"void\" operator is not supported (arkts-no-void-operator)", - "severity": "ERROR" - }, - { - "line": 134, - "column": 13, - "endLine": 134, - "endColumn": 17, - "problem": "VoidOperator", - "suggest": "", - "rule": "\"void\" operator is not supported (arkts-no-void-operator)", - "severity": "ERROR" - }, - { - "line": 136, - "column": 7, - "endLine": 136, - "endColumn": 13, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 138, - "column": 13, - "endLine": 138, - "endColumn": 18, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 140, - "column": 5, - "endLine": 140, - "endColumn": 11, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 142, - "column": 17, - "endLine": 142, - "endColumn": 23, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 145, - "column": 20, - "endLine": 145, - "endColumn": 24, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 148, - "column": 12, - "endLine": 148, - "endColumn": 16, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 151, - "column": 10, - "endLine": 151, - "endColumn": 16, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 156, - "column": 16, - "endLine": 156, - "endColumn": 22, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 160, - "column": 24, - "endLine": 160, - "endColumn": 30, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 164, - "column": 10, - "endLine": 164, - "endColumn": 14, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 164, - "column": 15, - "endLine": 164, - "endColumn": 21, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 169, - "column": 5, - "endLine": 169, - "endColumn": 11, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 174, - "column": 8, - "endLine": 174, - "endColumn": 12, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 176, - "column": 3, - "endLine": 176, - "endColumn": 11, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 177, - "column": 3, - "endLine": 177, - "endColumn": 8, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 178, - "column": 3, - "endLine": 178, - "endColumn": 11, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 187, - "column": 3, - "endLine": 187, - "endColumn": 7, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 193, - "column": 8, - "endLine": 193, - "endColumn": 12, - "problem": "InvalidIdentifier", - "suggest": "", - "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", - "severity": "ERROR" - }, - { - "line": 172, - "column": 2, - "endLine": 172, - "endColumn": 7, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 173, - "column": 2, - "endLine": 173, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 175, - "column": 4, - "endLine": 175, - "endColumn": 9, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 181, - "column": 5, - "endLine": 181, - "endColumn": 22, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 182, - "column": 7, - "endLine": 182, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - } - ] -} + "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": 10, + "endLine": 16, + "endColumn": 16, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 8, + "endLine": 18, + "endColumn": 16, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 7, + "endLine": 22, + "endColumn": 15, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 7, + "endLine": 26, + "endColumn": 9, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 7, + "endLine": 30, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 13, + "endLine": 32, + "endColumn": 13, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 7, + "endLine": 36, + "endColumn": 10, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 7, + "endLine": 42, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 10, + "endLine": 50, + "endColumn": 10, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 7, + "endLine": 52, + "endColumn": 12, + "problem": "ThrowStatement", + "suggest": "", + "rule": "\"throw\" statements cannot accept values of arbitrary types (arkts-limited-throw)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 7, + "endLine": 64, + "endColumn": 15, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 7, + "endLine": 70, + "endColumn": 14, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 7, + "endLine": 72, + "endColumn": 16, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 7, + "endLine": 74, + "endColumn": 18, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 7, + "endLine": 78, + "endColumn": 14, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 7, + "endLine": 84, + "endColumn": 17, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 7, + "endLine": 86, + "endColumn": 16, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 7, + "endLine": 88, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 7, + "endLine": 92, + "endColumn": 16, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 7, + "endLine": 96, + "endColumn": 14, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 7, + "endLine": 98, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 7, + "endLine": 100, + "endColumn": 14, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 7, + "endLine": 102, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 7, + "endLine": 104, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 24, + "endLine": 104, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 7, + "endLine": 106, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 22, + "endLine": 106, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 7, + "endLine": 108, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 7, + "endLine": 110, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 24, + "endLine": 110, + "endColumn": 25, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 7, + "endLine": 112, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 22, + "endLine": 112, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 7, + "endLine": 114, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 7, + "endLine": 116, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 24, + "endLine": 116, + "endColumn": 25, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 7, + "endLine": 118, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 7, + "endLine": 120, + "endColumn": 10, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 21, + "endLine": 120, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 7, + "endLine": 122, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 23, + "endLine": 122, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 7, + "endLine": 124, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 7, + "endLine": 126, + "endColumn": 10, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 21, + "endLine": 126, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 7, + "endLine": 128, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 23, + "endLine": 128, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 7, + "endLine": 130, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 7, + "endLine": 132, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 7, + "endLine": 134, + "endColumn": 11, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 134, + "column": 13, + "endLine": 134, + "endColumn": 17, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 7, + "endLine": 136, + "endColumn": 13, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 13, + "endLine": 138, + "endColumn": 18, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 5, + "endLine": 140, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 17, + "endLine": 142, + "endColumn": 23, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 20, + "endLine": 145, + "endColumn": 24, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 12, + "endLine": 148, + "endColumn": 16, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 10, + "endLine": 151, + "endColumn": 16, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 156, + "column": 16, + "endLine": 156, + "endColumn": 22, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 24, + "endLine": 160, + "endColumn": 30, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 10, + "endLine": 164, + "endColumn": 14, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 15, + "endLine": 164, + "endColumn": 21, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 5, + "endLine": 169, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 174, + "column": 8, + "endLine": 174, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 3, + "endLine": 176, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 21, + "endLine": 176, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 3, + "endLine": 177, + "endColumn": 8, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 18, + "endLine": 177, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 178, + "column": 3, + "endLine": 178, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 178, + "column": 21, + "endLine": 178, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 3, + "endLine": 187, + "endColumn": 7, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 8, + "endLine": 193, + "endColumn": 12, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 6, + "endLine": 203, + "endColumn": 10, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 204, + "column": 3, + "endLine": 204, + "endColumn": 8, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 3, + "endLine": 205, + "endColumn": 9, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 3, + "endLine": 206, + "endColumn": 6, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 11, + "endLine": 209, + "endColumn": 15, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 210, + "column": 9, + "endLine": 210, + "endColumn": 15, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 214, + "column": 13, + "endLine": 214, + "endColumn": 16, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 219, + "column": 7, + "endLine": 219, + "endColumn": 10, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 172, + "column": 2, + "endLine": 172, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 2, + "endLine": 173, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 4, + "endLine": 175, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 181, + "column": 5, + "endLine": 181, + "endColumn": 22, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 7, + "endLine": 182, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 4, + "endLine": 194, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 5, + "endLine": 197, + "endColumn": 22, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 7, + "endLine": 198, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/lazy_import.ets b/ets2panda/linter/test/main/lazy_import.ets index baea8b80e4a84b1cf03642560f5122792cc83bd7..a40b832b4fe0f040cf84a16ef13b9c7c58dc08a3 100755 --- a/ets2panda/linter/test/main/lazy_import.ets +++ b/ets2panda/linter/test/main/lazy_import.ets @@ -14,3 +14,6 @@ */ import lazy { m } from 'module' + +import lazy { a, b } from 'module1' +import { c } from 'module2' diff --git a/ets2panda/linter/test/main/lazy_import.ets.args.json b/ets2panda/linter/test/main/lazy_import.ets.args.json index 948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c..aaabef1e0a30f23f303a3fcf12ad9bd1973f6aa0 100755 --- a/ets2panda/linter/test/main/lazy_import.ets.args.json +++ b/ets2panda/linter/test/main/lazy_import.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--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 a55c1929eca32eecfd01eddc825276144a1e6687..bd0dee6544ca1c7f589ba627e4b38524d50d5777 100755 --- a/ets2panda/linter/test/main/lazy_import.ets.arkts2.json +++ b/ets2panda/linter/test/main/lazy_import.ets.arkts2.json @@ -23,6 +23,16 @@ "suggest": "", "rule": "Lazy import is not supported(arkts-no-lazy-import)", "severity": "ERROR" + }, + { + "line": 18, + "column": 8, + "endLine": 18, + "endColumn": 12, + "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 new file mode 100644 index 0000000000000000000000000000000000000000..765ce394d875c17c4ad49fe096ea073a84d6f57f --- /dev/null +++ b/ets2panda/linter/test/main/lazy_import.ets.autofix.json @@ -0,0 +1,52 @@ +{ + "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": 8, + "endLine": 16, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 612, + "end": 622, + "replacementText": "{ m }" + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 8, + "endLine": 18, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 645, + "end": 658, + "replacementText": "{ a, b }" + } + ], + "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/limit_void_type.ets b/ets2panda/linter/test/main/limit_void_type.ets index 603154118f31d1617a83cb23004224326f6a3818..d6ae5d427f0946f89ddb7962cda23e30a91be021 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets +++ b/ets2panda/linter/test/main/limit_void_type.ets @@ -189,3 +189,17 @@ class C { return; } } + +function foo(): void {} +function bar(): void {} + +let aa = '1'; +let bb = aa === '1' ? foo() : bar(); // Error + +aa === '1' ? foo() : bar(); // No error +let dd; +dd = aa === '1' ? foo() : bar(); // Error +interface testB{ + u:void; // Error + fooIf():void; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json b/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json index b72341140b98057bd78add917905a1a4caba4c9a..39d24845a6e49fd2f89e45c2a5ef8279dc72e0b6 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.arkts2.json @@ -154,6 +154,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 41, + "column": 28, + "endLine": 41, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 42, "column": 8, @@ -164,6 +174,16 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 42, + "column": 36, + "endLine": 42, + "endColumn": 40, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 45, "column": 8, @@ -414,6 +434,36 @@ "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" }, + { + "line": 83, + "column": 19, + "endLine": 83, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 22, + "endLine": 83, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 25, + "endLine": 83, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 85, "column": 19, @@ -965,13 +1015,63 @@ "severity": "ERROR" }, { - "line": 177, - "column": 8, - "endLine": 177, - "endColumn": 16, - "problem": "ExplicitFunctionType", + "line": 197, + "column": 23, + "endLine": 197, + "endColumn": 28, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 31, + "endLine": 197, + "endColumn": 36, + "problem": "LimitedVoidType", "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 5, + "endLine": 200, + "endColumn": 7, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 19, + "endLine": 201, + "endColumn": 24, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 27, + "endLine": 201, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 5, + "endLine": 203, + "endColumn": 9, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/limit_void_type.ets.json b/ets2panda/linter/test/main/limit_void_type.ets.json index f095579e86c95ea104c69095d4ecaf0bc86e4745..c23430e5d2f182b83a08ba6b9c9c8445030b3948 100644 --- a/ets2panda/linter/test/main/limit_void_type.ets.json +++ b/ets2panda/linter/test/main/limit_void_type.ets.json @@ -183,6 +183,16 @@ "suggest": "", "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", "severity": "WARNING" + }, + { + "line": 200, + "column": 5, + "endLine": 200, + "endColumn": 7, + "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/main/limited_literal_type.ets b/ets2panda/linter/test/main/limited_literal_type.ets index eeb8ea827551afd4479dc0e653755723e74ba1fb..d44a76204c8a155569581637e733f27dedbe5b7a 100644 --- a/ets2panda/linter/test/main/limited_literal_type.ets +++ b/ets2panda/linter/test/main/limited_literal_type.ets @@ -34,3 +34,18 @@ class A{ } let x: number; let persons : Record; + +let s = "123"; +let c1 = s.length as number & 1; +let c2 = s.length & 1 + +function foo(p: 1) {} // CTE + +let arr: 1[]; // CTE + +let a = 1 as 1; // CTE + +let c1 = s.length as (number & 1); // error +let tup: [['arkts' | boolean, 1 | true, false], string[], number] = [['arkts', 1, false], ['arkts1', 'arkts2'], 1.5]; +let a : 1| boolean = 1; +let b : [1] = [1] \ No newline at end of file diff --git a/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json b/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json index 36751780874481751a6d9c81b0c470faff15abe2..bac768d6989a17a428165cacec894dbafa092f14 100644 --- a/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json +++ b/ets2panda/linter/test/main/limited_literal_type.ets.arkts2.json @@ -24,6 +24,26 @@ "rule": "Literal types are restricted(arkts-limited-literal-types)", "severity": "ERROR" }, + { + "line": 16, + "column": 9, + "endLine": 16, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 13, + "endLine": 16, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 17, "column": 9, @@ -44,6 +64,26 @@ "rule": "Literal types are restricted(arkts-limited-literal-types)", "severity": "ERROR" }, + { + "line": 23, + "column": 14, + "endLine": 23, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 13, + "endLine": 28, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 30, "column": 7, @@ -53,6 +93,316 @@ "suggest": "", "rule": "Literal types are restricted(arkts-limited-literal-types)", "severity": "ERROR" + }, + { + "line": 30, + "column": 7, + "endLine": 30, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 11, + "endLine": 30, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 22, + "endLine": 39, + "endColumn": 32, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 31, + "endLine": 39, + "endColumn": 32, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 31, + "endLine": 39, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 21, + "endLine": 40, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 17, + "endLine": 42, + "endColumn": 18, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 17, + "endLine": 42, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 11, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 9, + "endLine": 46, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 14, + "endLine": 46, + "endColumn": 15, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 14, + "endLine": 46, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 23, + "endLine": 48, + "endColumn": 33, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 32, + "endLine": 48, + "endColumn": 33, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 32, + "endLine": 48, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 31, + "endLine": 49, + "endColumn": 32, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 31, + "endLine": 49, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 35, + "endLine": 49, + "endColumn": 39, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 41, + "endLine": 49, + "endColumn": 46, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 80, + "endLine": 49, + "endColumn": 81, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 9, + "endLine": 50, + "endColumn": 10, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 9, + "endLine": 50, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 22, + "endLine": 50, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 11, + "problem": "LimitedLiteralType", + "suggest": "", + "rule": "Literal types are restricted(arkts-limited-literal-types)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 10, + "endLine": 51, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 16, + "endLine": 51, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/limited_literal_type.ets.json b/ets2panda/linter/test/main/limited_literal_type.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..cc9bfbefca257da40202a9bde418239e0d673ada 100644 --- a/ets2panda/linter/test/main/limited_literal_type.ets.json +++ b/ets2panda/linter/test/main/limited_literal_type.ets.json @@ -13,5 +13,26 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 39, + "column": 22, + "endLine": 39, + "endColumn": 32, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 23, + "endLine": 48, + "endColumn": 33, + "problem": "IntersectionType", + "suggest": "", + "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json b/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json index 2c05e0ccbc2ed9e68875c6b1ad460c78bdc989f5..affb940597e111dc0e82345f4353752bafc14639 100644 --- a/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json +++ b/ets2panda/linter/test/main/limited_stdlib_api.ets.arkts2.json @@ -44,6 +44,36 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "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": 21, + "column": 7, + "endLine": 21, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 15, + "endLine": 23, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 31, "column": 8, @@ -85,14 +115,24 @@ "severity": "ERROR" }, { - "line": 34, - "column": 19, - "endLine": 34, - "endColumn": 27, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" + "line": 34, + "column": 19, + "endLine": 34, + "endColumn": 32, + "problem": "ExplicitFunctionType", + "suggest": "", + "rule": "The function type should be explicit (arkts-no-ts-like-function-call)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 8, + "endLine": 46, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" }, { "line": 56, @@ -304,6 +344,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 77, + "column": 13, + "endLine": 77, + "endColumn": 39, + "problem": "BuiltinGetOwnPropertyNames", + "suggest": "", + "rule": "Using \"Object.getOwnPropertyNames\" is not allowed in this API (arkts-builtin-object-getOwnPropertyNames))", + "severity": "ERROR" + }, { "line": 85, "column": 9, @@ -414,11 +464,21 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 100, + "column": 27, + "endLine": 100, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 101, - "column": 1, + "column": 19, "endLine": 101, - "endColumn": 28, + "endColumn": 20, "problem": "NumericSemantics", "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", @@ -684,6 +744,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 116, + "column": 41, + "endLine": 116, + "endColumn": 42, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 117, "column": 13, @@ -704,6 +774,16 @@ "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", "severity": "ERROR" }, + { + "line": 122, + "column": 25, + "endLine": 122, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 127, "column": 12, @@ -714,6 +794,26 @@ "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", "severity": "ERROR" }, + { + "line": 128, + "column": 43, + "endLine": 128, + "endColumn": 44, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 51, + "endLine": 128, + "endColumn": 52, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 130, "column": 25, diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets b/ets2panda/linter/test/main/literals_as_prop_names.ets index 53d450b13a9becf077427416265e845fe152c4ee..c9947181022ed196981fdc51a7673894bcd1d8e3 100755 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets @@ -97,3 +97,42 @@ const enum Direction16 { "\\" = 1, "__x5c" = 1, } + +const enum Direction17 { + "\\" = 1, + "__x5c" = 1, +} +let case17 = Direction17["\\"] +let case172 = Direction17["__x5c"] + +const enum Direction11 { +"!!" = 1, +} +const enum Direction23 { +"aaa" = 1, +} +// ArkUI +@Component +struct Index { +@State message: string = 'Hello World'; +private case11 = Direction11["!!"] +build() { +} +} + + +class A{ + public age:number = 1; +} + +let a:A = { "age": 30} + + +class B{ + public 'age': number = 1 // error in arkts2 +} + +let obj11: Record = { +['value']: 1, // 误扫 +'value2': 1 // ok +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets.args.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.args.json index 52b03ab984f1a8230dfc79caadc6a0f2debbe85c..ff8738ddc9c94be0accd0958c036d94d30ce1764 100644 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.args.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json index 8520a5f1b6bdb982ea5d035f0c2b302091089219..286fd756ff7265880cbb18d4dfc3e7848bae06e8 100755 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.arkts2.json @@ -34,26 +34,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 26, - "column": 11, - "endLine": 26, - "endColumn": 12, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 27, - "column": 3, - "endLine": 27, - "endColumn": 8, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 27, "column": 3, @@ -69,9 +49,9 @@ "column": 3, "endLine": 32, "endColumn": 4, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { @@ -79,19 +59,19 @@ "column": 3, "endLine": 33, "endColumn": 8, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 32, - "column": 3, - "endLine": 32, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 11, + "problem": "NumericSemantics", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -124,6 +104,16 @@ "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, + { + "line": 49, + "column": 8, + "endLine": 49, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 57, "column": 9, @@ -139,19 +129,19 @@ "column": 10, "endLine": 57, "endColumn": 16, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { "line": 57, - "column": 22, + "column": 18, "endLine": 57, - "endColumn": 23, - "problem": "ObjectLiteralProperty", + "endColumn": 20, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -164,6 +154,16 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 57, + "column": 25, + "endLine": 57, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 59, "column": 13, @@ -195,30 +195,30 @@ "severity": "ERROR" }, { - "line": 75, - "column": 3, - "endLine": 75, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 67, + "column": 20, + "endLine": 67, + "endColumn": 22, + "problem": "NumericSemantics", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 75, - "column": 3, - "endLine": 75, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 67, + "column": 28, + "endLine": 67, + "endColumn": 30, + "problem": "NumericSemantics", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 76, + "line": 75, "column": 3, - "endLine": 76, - "endColumn": 8, + "endLine": 75, + "endColumn": 4, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", @@ -249,9 +249,9 @@ "column": 3, "endLine": 80, "endColumn": 4, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { @@ -259,19 +259,19 @@ "column": 3, "endLine": 81, "endColumn": 8, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 80, - "column": 3, - "endLine": 80, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 81, + "column": 10, + "endLine": 81, + "endColumn": 13, + "problem": "NumericSemantics", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -279,19 +279,19 @@ "column": 36, "endLine": 84, "endColumn": 37, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { "line": 84, - "column": 36, + "column": 39, "endLine": 84, - "endColumn": 37, - "problem": "LiteralAsPropertyName", + "endColumn": 42, + "problem": "NumericSemantics", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -324,6 +324,156 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 11, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 14, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 5, + "endLine": 106, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 1, + "endLine": 109, + "endColumn": 9, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 1, + "endLine": 112, + "endColumn": 10, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 22, + "endLine": 125, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 13, + "endLine": 128, + "endColumn": 18, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 20, + "endLine": 128, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 10, + "endLine": 132, + "endColumn": 15, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 26, + "endLine": 132, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 12, + "endLine": 136, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 11, + "endLine": 137, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 2, + "endLine": 115, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 2, + "endLine": 117, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, { "line": 42, "column": 11, diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets.autofix.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.autofix.json index 0eabd752ac23b4fa68c6e18704877d195715b6cf..282458e4e5bf09a939b7369e09cc839049e7466c 100644 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.autofix.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.autofix.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 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", @@ -24,12 +24,20 @@ { "replacementText": "PrivateTwo", "start": 721, - "end": 733 + "end": 733, + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 22 }, { "replacementText": "LiteralAsPropertyNameEnum.PrivateTwo", "start": 1919, - "end": 1958 + "end": 1958, + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 22 } ], "suggest": "", @@ -46,17 +54,29 @@ { "replacementText": "__2", "start": 836, - "end": 837 + "end": 837, + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 29 }, { "replacementText": "__2", "start": 928, - "end": 929 + "end": 929, + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 29 }, { "replacementText": "litAsPropName.__2", "start": 1001, - "end": 1017 + "end": 1017, + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 29 } ], "suggest": "", @@ -64,26 +84,38 @@ "severity": "ERROR" }, { - "line": 26, - "column": 11, - "endLine": 26, - "endColumn": 12, + "line": 27, + "column": 3, + "endLine": 27, + "endColumn": 8, "problem": "LiteralAsPropertyName", "autofix": [ { - "replacementText": "__2", - "start": 836, - "end": 837 + "replacementText": "Two", + "start": 849, + "end": 854, + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 33 }, { - "replacementText": "__2", - "start": 928, - "end": 929 + "replacementText": "Two", + "start": 940, + "end": 945, + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 33 }, { - "replacementText": "litAsPropName.__2", - "start": 1001, - "end": 1017 + "replacementText": "litAsPropName.Two", + "start": 1032, + "end": 1052, + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 33 } ], "suggest": "", @@ -91,26 +123,38 @@ "severity": "ERROR" }, { - "line": 27, + "line": 32, "column": 3, - "endLine": 27, - "endColumn": 8, + "endLine": 32, + "endColumn": 4, "problem": "LiteralAsPropertyName", "autofix": [ { - "replacementText": "Two", - "start": 849, - "end": 854 + "replacementText": "__2", + "start": 836, + "end": 837, + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 29 }, { - "replacementText": "Two", - "start": 940, - "end": 945 + "replacementText": "__2", + "start": 928, + "end": 929, + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 29 }, { - "replacementText": "litAsPropName.Two", - "start": 1032, - "end": 1052 + "replacementText": "litAsPropName.__2", + "start": 1001, + "end": 1017, + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 29 } ], "suggest": "", @@ -118,77 +162,63 @@ "severity": "ERROR" }, { - "line": 27, + "line": 33, "column": 3, - "endLine": 27, + "endLine": 33, "endColumn": 8, "problem": "LiteralAsPropertyName", "autofix": [ { "replacementText": "Two", "start": 849, - "end": 854 + "end": 854, + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 33 }, { "replacementText": "Two", "start": 940, - "end": 945 + "end": 945, + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 33 }, { "replacementText": "litAsPropName.Two", "start": 1032, - "end": 1052 + "end": 1052, + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 33 } ], "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 32, - "column": 3, - "endLine": 32, - "endColumn": 4, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, { "line": 33, - "column": 3, + "column": 10, "endLine": 33, - "endColumn": 8, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 3, - "endLine": 32, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "endColumn": 11, + "problem": "NumericSemantics", "autofix": [ { - "replacementText": "__2", - "start": 836, - "end": 837 - }, - { - "replacementText": "__2", - "start": 928, - "end": 929 - }, - { - "replacementText": "litAsPropName.__2", - "start": 1001, - "end": 1017 + "start": 947, + "end": 948, + "replacementText": "2.0", + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 11 } ], "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -201,7 +231,11 @@ { "replacementText": "litAsPropName.one", "start": 966, - "end": 986 + "end": 986, + "line": 36, + "column": 13, + "endLine": 36, + "endColumn": 33 } ], "suggest": "", @@ -218,17 +252,29 @@ { "replacementText": "__2", "start": 836, - "end": 837 + "end": 837, + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 29 }, { "replacementText": "__2", "start": 928, - "end": 929 + "end": 929, + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 29 }, { "replacementText": "litAsPropName.__2", "start": 1001, - "end": 1017 + "end": 1017, + "line": 37, + "column": 13, + "endLine": 37, + "endColumn": 29 } ], "suggest": "", @@ -245,41 +291,62 @@ { "replacementText": "Two", "start": 849, - "end": 854 + "end": 854, + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 33 }, { "replacementText": "Two", "start": 940, - "end": 945 + "end": 945, + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 33 }, { "replacementText": "litAsPropName.Two", "start": 1032, - "end": 1052 + "end": 1052, + "line": 38, + "column": 13, + "endLine": 38, + "endColumn": 33 } ], "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, + { + "line": 49, + "column": 8, + "endLine": 49, + "endColumn": 9, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1263, + "end": 1264, + "replacementText": "2.0", + "line": 49, + "column": 8, + "endLine": 49, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 57, "column": 9, "endLine": 57, "endColumn": 10, "problem": "ObjectLiteralNoContextType", - "autofix": [ - { - "start": 1416, - "end": 1416, - "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n \"name\": number;\n 2: number;\n}\n" - }, - { - "start": 1421, - "end": 1421, - "replacementText": ": GeneratedObjectLiteralInterface_1" - } - ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" @@ -289,19 +356,30 @@ "column": 10, "endLine": 57, "endColumn": 16, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { "line": 57, - "column": 22, + "column": 18, "endLine": 57, - "endColumn": 23, - "problem": "ObjectLiteralProperty", + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1433, + "end": 1435, + "replacementText": "20.0", + "line": 57, + "column": 18, + "endLine": 57, + "endColumn": 20 + } + ], "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -314,6 +392,27 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 57, + "column": 25, + "endLine": 57, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1440, + "end": 1442, + "replacementText": "30.0", + "line": 57, + "column": 25, + "endLine": 57, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 59, "column": 13, @@ -344,12 +443,20 @@ { "start": 1556, "end": 1556, - "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n name: number;\n _2: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n name: number;\n _2: number;\n}\n", + "line": 67, + "column": 13, + "endLine": 67, + "endColumn": 14 }, { "start": 1565, "end": 1565, - "replacementText": ": GeneratedObjectLiteralInterface_2" + "replacementText": ": GeneratedObjectLiteralInterface_1", + "line": 67, + "column": 13, + "endLine": 67, + "endColumn": 14 } ], "suggest": "", @@ -357,65 +464,71 @@ "severity": "ERROR" }, { - "line": 75, - "column": 3, - "endLine": 75, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 67, + "column": 20, + "endLine": 67, + "endColumn": 22, + "problem": "NumericSemantics", "autofix": [ { - "replacementText": "___2", - "start": 1726, - "end": 1727 - }, - { - "replacementText": "___2", - "start": 1808, - "end": 1809 + "start": 1575, + "end": 1577, + "replacementText": "20.0", + "line": 67, + "column": 20, + "endLine": 67, + "endColumn": 22 } ], "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 75, - "column": 3, - "endLine": 75, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 67, + "column": 28, + "endLine": 67, + "endColumn": 30, + "problem": "NumericSemantics", "autofix": [ { - "replacementText": "___2", - "start": 1726, - "end": 1727 - }, - { - "replacementText": "___2", - "start": 1808, - "end": 1809 + "start": 1583, + "end": 1585, + "replacementText": "20.0", + "line": 67, + "column": 28, + "endLine": 67, + "endColumn": 30 } ], "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 76, + "line": 75, "column": 3, - "endLine": 76, - "endColumn": 8, + "endLine": 75, + "endColumn": 4, "problem": "LiteralAsPropertyName", "autofix": [ { - "replacementText": "__2", - "start": 1739, - "end": 1744 + "replacementText": "___2", + "start": 1726, + "end": 1727, + "line": 80, + "column": 3, + "endLine": 80, + "endColumn": 4 }, { - "replacementText": "__2", - "start": 1824, - "end": 1829 + "replacementText": "___2", + "start": 1808, + "end": 1809, + "line": 80, + "column": 3, + "endLine": 80, + "endColumn": 4 } ], "suggest": "", @@ -432,12 +545,20 @@ { "replacementText": "__2", "start": 1739, - "end": 1744 + "end": 1744, + "line": 81, + "column": 3, + "endLine": 81, + "endColumn": 8 }, { "replacementText": "__2", "start": 1824, - "end": 1829 + "end": 1829, + "line": 81, + "column": 3, + "endLine": 81, + "endColumn": 8 } ], "suggest": "", @@ -459,9 +580,29 @@ "column": 3, "endLine": 80, "endColumn": 4, - "problem": "ObjectLiteralProperty", + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "___2", + "start": 1726, + "end": 1727, + "line": 80, + "column": 3, + "endLine": 80, + "endColumn": 4 + }, + { + "replacementText": "___2", + "start": 1808, + "end": 1809, + "line": 80, + "column": 3, + "endLine": 80, + "endColumn": 4 + } + ], "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { @@ -469,27 +610,25 @@ "column": 3, "endLine": 81, "endColumn": 8, - "problem": "ObjectLiteralProperty", - "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 3, - "endLine": 80, - "endColumn": 4, "problem": "LiteralAsPropertyName", "autofix": [ { - "replacementText": "___2", - "start": 1726, - "end": 1727 + "replacementText": "__2", + "start": 1739, + "end": 1744, + "line": 81, + "column": 3, + "endLine": 81, + "endColumn": 8 }, { - "replacementText": "___2", - "start": 1808, - "end": 1809 + "replacementText": "__2", + "start": 1824, + "end": 1829, + "line": 81, + "column": 3, + "endLine": 81, + "endColumn": 8 } ], "suggest": "", @@ -497,13 +636,24 @@ "severity": "ERROR" }, { - "line": 84, - "column": 36, - "endLine": 84, - "endColumn": 37, - "problem": "ObjectLiteralProperty", + "line": 81, + "column": 10, + "endLine": 81, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1831, + "end": 1834, + "replacementText": "123.0", + "line": 81, + "column": 10, + "endLine": 81, + "endColumn": 13 + } + ], "suggest": "", - "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -516,6 +666,27 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 84, + "column": 39, + "endLine": 84, + "endColumn": 42, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1877, + "end": 1880, + "replacementText": "234.0", + "line": 84, + "column": 39, + "endLine": 84, + "endColumn": 42 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 92, "column": 4, @@ -526,7 +697,11 @@ { "replacementText": "__empty", "start": 1991, - "end": 1993 + "end": 1993, + "line": 92, + "column": 4, + "endLine": 92, + "endColumn": 10 } ], "suggest": "", @@ -541,9 +716,13 @@ "problem": "LiteralAsPropertyName", "autofix": [ { - "replacementText": "__x5c_1", + "replacementText": "___x5c", "start": 2033, - "end": 2037 + "end": 2037, + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 11 } ], "suggest": "", @@ -560,13 +739,359 @@ { "replacementText": "__x5c", "start": 2045, - "end": 2052 + "end": 2052, + "line": 98, + "column": 3, + "endLine": 98, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 11, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "___x5c", + "start": 2088, + "end": 2092, + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 11 + }, + { + "replacementText": "Direction17.___x5c", + "start": 2128, + "end": 2145, + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 14, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "__x5c", + "start": 2100, + "end": 2107, + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 14 + }, + { + "replacementText": "Direction17.__x5c", + "start": 2160, + "end": 2180, + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 31, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2119, + "end": 2145, + "replacementText": "case17: number = Direction17[\"\\\\\"]", + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 31 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 5, + "endLine": 106, + "endColumn": 35, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2150, + "end": 2180, + "replacementText": "case172: number = Direction17[\"__x5c\"]", + "line": 106, + "column": 5, + "endLine": 106, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 1, + "endLine": 109, + "endColumn": 9, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "__x21x21", + "start": 2207, + "end": 2211, + "line": 109, + "column": 1, + "endLine": 109, + "endColumn": 9 + }, + { + "replacementText": "Direction11.__x21x21", + "start": 2349, + "end": 2366, + "line": 109, + "column": 1, + "endLine": 109, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 1, + "endLine": 112, + "endColumn": 10, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "aaa", + "start": 2244, + "end": 2249, + "line": 112, + "column": 1, + "endLine": 112, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 22, + "endLine": 125, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2413, + "end": 2414, + "replacementText": "1.0", + "line": 125, + "column": 22, + "endLine": 125, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 13, + "endLine": 128, + "endColumn": 18, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "age", + "start": 2432, + "end": 2437, + "line": 128, + "column": 13, + "endLine": 128, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 20, + "endLine": 128, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2439, + "end": 2441, + "replacementText": "30.0", + "line": 128, + "column": 20, + "endLine": 128, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 10, + "endLine": 132, + "endColumn": 15, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "age", + "start": 2465, + "end": 2470, + "line": 132, + "column": 10, + "endLine": 132, + "endColumn": 15 } ], "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, + { + "line": 132, + "column": 26, + "endLine": 132, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2481, + "end": 2482, + "replacementText": "1.0", + "line": 132, + "column": 26, + "endLine": 132, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 12, + "endLine": 136, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2554, + "end": 2555, + "replacementText": "1.0", + "line": 136, + "column": 12, + "endLine": 136, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 11, + "endLine": 137, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2573, + "end": 2574, + "replacementText": "1.0", + "line": 137, + "column": 11, + "endLine": 137, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 2, + "endLine": 115, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 608, + "end": 608, + "replacementText": "\n\nimport { Component, State } from '@kit.ArkUI';", + "line": 117, + "column": 2, + "endLine": 117, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 2, + "endLine": 117, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 608, + "end": 608, + "replacementText": "\n\nimport { Component, State } from '@kit.ArkUI';", + "line": 117, + "column": 2, + "endLine": 117, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, { "line": 42, "column": 11, diff --git a/ets2panda/linter/test/main/literals_as_prop_names.ets.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.json index bf6df5f5a308e91a1af58a57e9b253da53cd02ed..7e721f74f1a1f51c82e35dff5046839e4d2c21de 100644 --- a/ets2panda/linter/test/main/literals_as_prop_names.ets.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "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", @@ -14,16 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 26, - "column": 11, - "endLine": 26, - "endColumn": 12, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 26, "column": 11, @@ -134,16 +124,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 75, - "column": 3, - "endLine": 75, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 80, "column": 3, diff --git a/ets2panda/linter/test/migrate/literals_as_prop_names.sts b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets similarity index 50% rename from ets2panda/linter/test/migrate/literals_as_prop_names.sts rename to ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets index 7d4da7fcddf56c6d4a937244e744d6e3c8d5fe50..54ed22aed80c78711c9c222e7fbe5dc5085f0979 100644 --- a/ets2panda/linter/test/migrate/literals_as_prop_names.sts +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -13,23 +13,31 @@ * limitations under the License. */ +import { Component, State } from '@kit.ArkUI'; + import { ExportLitAsPropName } from './ignore_files/good'; +enum LiteralAsPropertyNameEnum { + One = "one", + PrivateTwo = "_2", + Two = "Two" +} + class LiteralAsPropertyName { public one: string = "1111111111"; - private 2: string; - 'Two': number; + private __2: string; + Two: number; } const litAsPropName: LiteralAsPropertyName = { one: "1", - 2: 'two', - 'Two': 2, + __2: 'two', + Two: 2.0, }; -console.log(litAsPropName["one"]); -console.log(litAsPropName[2]); -console.log(litAsPropName["Two"]); +console.log(litAsPropName.one); +console.log(litAsPropName.__2); +console.log(litAsPropName.Two); class LiteralAsPropertyName_fix { public one: string = "1111111111"; @@ -40,7 +48,7 @@ class LiteralAsPropertyName_fix { const litAsPropName_fix: LiteralAsPropertyName_fix = { one: "1111111111", _2: 'two', - Two: 2, + Two: 2.0, }; console.log("Fixed listAsPropName:"); @@ -48,7 +56,7 @@ console.log(litAsPropName_fix.one); console.log(litAsPropName_fix._2); console.log(litAsPropName_fix.Two); -let x = {"name": 20, 2: 30} +let x = {"name": 20.0, 2: 30.0} console.log(x["name"]); console.log(x[2]); @@ -58,7 +66,11 @@ class X_class { public _2: number; } -let x_fix = {name: 20, _2: 20}; +interface GeneratedObjectLiteralInterface_1 { + name: number; + _2: number; +} +let x_fix: GeneratedObjectLiteralInterface_1 = {name: 20.0, _2: 20.0}; console.log("Fixed x object literal:"); console.log(x_fix.name); @@ -66,13 +78,67 @@ console.log(x_fix._2); interface litAsPropNameIface { one: string; - 2: string; - '__2': number; + ___2: string; + __2: number; } const int: litAsPropNameIface = { one: '12321', - 2: 'weqwewq', - '__2': 123 + ___2: 'weqwewq', + __2: 123.0 }; -const imp: ExportLitAsPropName = { 1: 234 }; +const imp: ExportLitAsPropName = { 1: 234.0 }; + +LiteralAsPropertyNameEnum['One'] + +LiteralAsPropertyNameEnum.PrivateTwo; + +{ + const enum Direction { + __empty = 1, + } +} + +const enum Direction16 { + ___x5c = 1, + __x5c = 1, +} + +const enum Direction17 { + ___x5c = 1, + __x5c = 1, +} +let case17: number = Direction17.___x5c +let case172: number = Direction17.__x5c + +const enum Direction11 { +__x21x21 = 1, +} +const enum Direction23 { +aaa = 1, +} +// ArkUI +@Component +struct Index { +@State message: string = 'Hello World'; +private case11 = Direction11.__x21x21 +build() { +} +} + + +class A{ + public age:number = 1.0; +} + +let a:A = { age: 30.0} + + +class B{ + public age: number = 1.0 // error in arkts2 +} + +let obj11: Record = { +['value']: 1.0, // 误扫 +'value2': 1.0 // ok +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.json b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json similarity index 59% rename from ets2panda/linter/test/migrate/literals_as_prop_names.ts.json rename to ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json index 5a6fd813fa3ade1f04aaf73f12ab8151d662826e..7756bd53973f3ae465790f9582ab044fb5879ed4 100644 --- a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.json +++ b/ets2panda/linter/test/main/literals_as_prop_names.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 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", @@ -15,79 +15,39 @@ ], "result": [ { - "line": 20, - "column": 11, - "endLine": 20, - "endColumn": 12, - "problem": "LiteralAsPropertyName", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 10, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 26, - "column": 3, - "endLine": 26, - "endColumn": 4, + "line": 59, + "column": 10, + "endLine": 59, + "endColumn": 16, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 30, - "column": 13, - "endLine": 30, - "endColumn": 33, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 13, - "endLine": 31, - "endColumn": 29, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 13, - "endLine": 32, - "endColumn": 33, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 9, - "endLine": 51, - "endColumn": 10, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 22, - "endLine": 51, - "endColumn": 23, + "line": 59, + "column": 24, + "endLine": 59, + "endColumn": 25, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 53, + "line": 61, "column": 13, - "endLine": 53, + "endLine": 61, "endColumn": 22, "problem": "PropertyAccessByIndex", "suggest": "", @@ -95,9 +55,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 62, "column": 13, - "endLine": 54, + "endLine": 62, "endColumn": 17, "problem": "PropertyAccessByIndex", "suggest": "", @@ -105,49 +65,49 @@ "severity": "ERROR" }, { - "line": 61, - "column": 13, - "endLine": 61, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 84, + "column": 7, + "endLine": 84, + "endColumn": 10, + "problem": "InvalidIdentifier", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", "severity": "ERROR" }, { - "line": 69, - "column": 3, - "endLine": 69, - "endColumn": 4, + "line": 90, + "column": 36, + "endLine": 90, + "endColumn": 37, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 74, - "column": 3, - "endLine": 74, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "line": 28, + "column": 11, + "endLine": 28, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Property '__2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '__2' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" }, { - "line": 78, - "column": 36, - "endLine": 78, - "endColumn": 37, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" }, { - "line": 36, + "line": 44, "column": 11, - "endLine": 36, + "endLine": 44, "endColumn": 13, "problem": "StrictDiagnostic", "suggest": "Property '_2' has no initializer and is not definitely assigned in the constructor.", @@ -155,9 +115,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 45, "column": 3, - "endLine": 37, + "endLine": 45, "endColumn": 6, "problem": "StrictDiagnostic", "suggest": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", @@ -165,9 +125,9 @@ "severity": "ERROR" }, { - "line": 57, + "line": 65, "column": 12, - "endLine": 57, + "endLine": 65, "endColumn": 16, "problem": "StrictDiagnostic", "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", @@ -175,9 +135,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 66, "column": 12, - "endLine": 58, + "endLine": 66, "endColumn": 14, "problem": "StrictDiagnostic", "suggest": "Property '_2' has no initializer and is not definitely assigned in the constructor.", diff --git a/ets2panda/linter/test/main/localBuilder_1.ets b/ets2panda/linter/test/main/localBuilder_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..cdf32f53d6c695e2ba21ef8dd607af72c43c5d3d --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.ets @@ -0,0 +1,33 @@ +/* + * 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 +@Component +struct Parent { + @State label: string = 'Hello'; + + @LocalBuilder + citeLocalBuilder(paramA1: string) { + Row() { + Text(`UseStateVarByValue: ${paramA1}`) + } + } + + build() { + Column() { + this.citeLocalBuilder(this.label) + } + } +} diff --git a/ets2panda/linter/test/main/localBuilder_1.ets.args.json b/ets2panda/linter/test/main/localBuilder_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..e7a5dbc614c695778265e9fb7d345a304a601675 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.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/data_observation_2.ets.autofix.json b/ets2panda/linter/test/main/localBuilder_1.ets.arkts2.json similarity index 69% rename from ets2panda/linter/test/main/data_observation_2.ets.autofix.json rename to ets2panda/linter/test/main/localBuilder_1.ets.arkts2.json index 9779e282937b66cb767c3f108d7053679acfc831..d25d1a3cb3e628d2e1c93e5d29b19d430e622fed 100644 --- a/ets2panda/linter/test/main/data_observation_2.ets.autofix.json +++ b/ets2panda/linter/test/main/localBuilder_1.ets.arkts2.json @@ -15,30 +15,30 @@ ], "result": [ { - "line": 23, - "column": 19, - "endLine": 23, - "endColumn": 27, - "problem": "DataObservation", + "line": 21, + "column": 3, + "endLine": 21, + "endColumn": 16, + "problem": "LocalBuilderDecoratorNotSupported", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "\"@LocalBuilder\" Decorator is not supported (arkui-no-localbuilder-decorator)", "severity": "ERROR" }, { - "line": 24, - "column": 51, - "endLine": 24, - "endColumn": 59, - "problem": "DataObservation", + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 18, + "line": 17, "column": 2, - "endLine": 18, - "endColumn": 7, + "endLine": 17, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", @@ -46,18 +46,28 @@ }, { "line": 19, - "column": 2, + "column": 4, "endLine": 19, - "endColumn": 11, + "endColumn": 9, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 21, - "column": 6, - "endLine": 21, + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -65,18 +75,11 @@ "severity": "ERROR" }, { - "line": 27, - "column": 2, - "endLine": 27, - "endColumn": 10, + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11, "problem": "UIInterfaceImport", - "autofix": [ - { - "start": 603, - "end": 603, - "replacementText": "\n\nimport { Entry, Component, State, Observed } from '@kits.ArkUI';" - } - ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" diff --git a/ets2panda/linter/test/main/localBuilder_1.ets.autofix.json b/ets2panda/linter/test/main/localBuilder_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..03374a941ac15fbb8447ff5882f0c9b24f25192e --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.ets.autofix.json @@ -0,0 +1,137 @@ +{ + "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": 21, + "column": 3, + "endLine": 21, + "endColumn": 16, + "problem": "LocalBuilderDecoratorNotSupported", + "autofix": [ + { + "start": 676, + "end": 689, + "replacementText": "@Builder" + } + ], + "suggest": "", + "rule": "\"@LocalBuilder\" Decorator is not supported (arkui-no-localbuilder-decorator)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 8, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/localBuilder_1.ets.json b/ets2panda/linter/test/main/localBuilder_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.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/localBuilder_1.ets.migrate.ets b/ets2panda/linter/test/main/localBuilder_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d9a2b55ebe936e012207a55d2db5de2634f3e8f7 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.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 { Builder } from '@kit.ArkUI'; + +import { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI'; + +@Entry +@Component +struct Parent { + @State label: string = 'Hello'; + + @Builder + citeLocalBuilder(paramA1: string) { + Row() { + Text(`UseStateVarByValue: ${paramA1}`) + } + } + + build() { + Column() { + this.citeLocalBuilder(this.label) + } + } +} diff --git a/ets2panda/linter/test/main/localBuilder_1.ets.migrate.json b/ets2panda/linter/test/main/localBuilder_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_1.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 diff --git a/ets2panda/linter/test/main/localBuilder_2.ets b/ets2panda/linter/test/main/localBuilder_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..d9a2b55ebe936e012207a55d2db5de2634f3e8f7 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.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 { Builder } from '@kit.ArkUI'; + +import { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI'; + +@Entry +@Component +struct Parent { + @State label: string = 'Hello'; + + @Builder + citeLocalBuilder(paramA1: string) { + Row() { + Text(`UseStateVarByValue: ${paramA1}`) + } + } + + build() { + Column() { + this.citeLocalBuilder(this.label) + } + } +} diff --git a/ets2panda/linter/test/main/localBuilder_2.ets.args.json b/ets2panda/linter/test/main/localBuilder_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..e7a5dbc614c695778265e9fb7d345a304a601675 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.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/localBuilder_2.ets.arkts2.json b/ets2panda/linter/test/main/localBuilder_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.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/localBuilder_2.ets.autofix.json b/ets2panda/linter/test/main/localBuilder_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.ets.autofix.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/localBuilder_2.ets.json b/ets2panda/linter/test/main/localBuilder_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_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/localBuilder_2.ets.migrate.ets b/ets2panda/linter/test/main/localBuilder_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d9a2b55ebe936e012207a55d2db5de2634f3e8f7 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.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 { Builder } from '@kit.ArkUI'; + +import { Entry, Component, State, Row, Text, Column } from '@kit.ArkUI'; + +@Entry +@Component +struct Parent { + @State label: string = 'Hello'; + + @Builder + citeLocalBuilder(paramA1: string) { + Row() { + Text(`UseStateVarByValue: ${paramA1}`) + } + } + + build() { + Column() { + this.citeLocalBuilder(this.label) + } + } +} diff --git a/ets2panda/linter/test/main/localBuilder_2.ets.migrate.json b/ets2panda/linter/test/main/localBuilder_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/localBuilder_2.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 diff --git a/ets2panda/linter/test/main/make_observed_1.ets b/ets2panda/linter/test/main/make_observed_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..f85d77d9960d0cb043032595d27746b05072c615 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_1.ets @@ -0,0 +1,42 @@ +/* + * 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 { UIUtils } from '@kit.ArkUI'; + +class Info { + id: number = 0; + constructor(id: number) { + this.id = id; + } +} + +@Entry +@ComponentV2 +struct Index { + @Local message: Info = UIUtils.makeObserved(new Info(20)); + build() { + Column() { + Button(`change id`).onClick(() => { + this.message.id++; + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = new Info(30); + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = UIUtils.makeObserved(new Info(30)); + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_1.ets.args.json b/ets2panda/linter/test/main/make_observed_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_1.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_1.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..10dbf86c4885419f1a59d2391a152f1bc7f7d9b8 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_1.ets.arkts2.json @@ -0,0 +1,148 @@ +{ + "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": 19, + "column": 16, + "endLine": 19, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 26, + "endLine": 28, + "endColumn": 46, + "problem": "MakeObservedIsNotSupported", + "suggest": "", + "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 56, + "endLine": 28, + "endColumn": 58, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 33, + "endLine": 35, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 24, + "endLine": 38, + "endColumn": 44, + "problem": "MakeObservedIsNotSupported", + "suggest": "", + "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 54, + "endLine": 38, + "endColumn": 56, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 2, + "endLine": 25, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 2, + "endLine": 26, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 4, + "endLine": 28, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_1.ets.json b/ets2panda/linter/test/main/make_observed_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_1.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/make_observed_2.ets b/ets2panda/linter/test/main/make_observed_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..f6f99b903f3c5c9f04e17c21b559f961f20e2077 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_2.ets @@ -0,0 +1,42 @@ +/* + * 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 { UIUtils as utils } from '@ohos.arkui.StateManagement'; + +class Info { + id: number = 0; + constructor(id: number) { + this.id = id; + } +} + +@Entry +@ComponentV2 +struct Index { + @Local message: Info = utils.makeObserved(new Info(20)); + build() { + Column() { + Button(`change id`).onClick(() => { + this.message.id++; + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = new Info(30); + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = utils.makeObserved(new Info(30)); + }) + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_2.ets.args.json b/ets2panda/linter/test/main/make_observed_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..acf1d0da2e4b1e72ca4827a4bb2b5ee836b9b6dc --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_2.ets.arkts2.json @@ -0,0 +1,148 @@ +{ + "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": 19, + "column": 16, + "endLine": 19, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 26, + "endLine": 28, + "endColumn": 44, + "problem": "MakeObservedIsNotSupported", + "suggest": "", + "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 54, + "endLine": 28, + "endColumn": 56, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 33, + "endLine": 35, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 24, + "endLine": 38, + "endColumn": 42, + "problem": "MakeObservedIsNotSupported", + "suggest": "", + "rule": "The makeObserved function is not supported (arkui-no-makeobserved-function)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 52, + "endLine": 38, + "endColumn": 54, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 2, + "endLine": 25, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 2, + "endLine": 26, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 4, + "endLine": 28, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_2.ets.json b/ets2panda/linter/test/main/make_observed_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_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/make_observed_3.ets b/ets2panda/linter/test/main/make_observed_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..1c9c6dcc19828207c5d2fc747d3f975d0aac8e2a --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_3.ets @@ -0,0 +1,49 @@ +/* + * 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 { UIUtils } from './utils'; + +class Info { + id: number = 0; + constructor(id: number) { + this.id = id; + } +} + +@Entry +@ComponentV2 +struct Index { + @Local message: Info = UIUtils.makeObserved(new Info(20)); + build() { + Column() { + Button(`change id`).onClick(() => { + this.message.id++; + }) + Button(`change Info ${this.message.id}`).onClick(() => { + this.message = new Info(30); + }) + Button(`change Info1 ${this.message.id}`).onClick(() => { + this.message = UIUtils.makeObserved(new Info(30)); + }) + Button(`change Info1 ${this.message.id}`).onClick(() => { + this.message = makeObserved(new Info(30)); + }) + } + } +} + +function makeObserved(source: T): T { + return source; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_3.ets.args.json b/ets2panda/linter/test/main/make_observed_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_3.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json b/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..7323b8589d7c86eab354575d7fe50005bae89b20 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_3.ets.arkts2.json @@ -0,0 +1,148 @@ +{ + "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": 19, + "column": 16, + "endLine": 19, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 56, + "endLine": 28, + "endColumn": 58, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 33, + "endLine": 35, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 54, + "endLine": 38, + "endColumn": 56, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 46, + "endLine": 41, + "endColumn": 48, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 2, + "endLine": 25, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 2, + "endLine": 26, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 4, + "endLine": 28, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 7, + "endLine": 31, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 7, + "endLine": 40, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/make_observed_3.ets.json b/ets2panda/linter/test/main/make_observed_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/make_observed_3.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/method_inheritance.ets b/ets2panda/linter/test/main/method_inheritance.ets new file mode 100644 index 0000000000000000000000000000000000000000..ff1895fc91560a5662f08d3eb401caa34da364e0 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance.ets @@ -0,0 +1,99 @@ +/* + * 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. + */ + +abstract class Y { + abstract getDataByName(name: string | number, albumUri: string): Promise; +} + +class X extends Y { + async getDataByName(name: string, albumUri: string): Promise { + return; + } +} + +abstract class B { + abstract getDataByName(name: string | number, albumUri: string): Promise | Promise; +} + +class A extends B { + async getDataByName(name: string | number | boolean, albumUri: string): Promise { //Legal + return undefined; + } +} + +abstract class W { + abstract getDataByName(name: string | number, albumUri: string): Promise; +} + +class Q extends W { + async getDataByName(name: string | number, albumUri: string | number): Promise { + return; + }; +} + +abstract class BaseClass3 { + abstract compute(value: string): string; +} + +class IncorrectWiderReturn extends BaseClass3 { + compute(value: string): string | number { + return value.length > 5 ? value : 0; + } +} + +abstract class BaseClass4 { + abstract setValues(x: string | number, y: boolean | number): void; +} + +class IncorrectMultipleParamMismatch extends BaseClass4 { + setValues(x: string, y: boolean): void { + console.log(x, y); + } +} + +abstract class BaseClass5 { + abstract transform(data: number | string): number; +} + +class IncorrectBothMismatch extends BaseClass5 { + transform(data: number): number | string { + return data > 10 ? data : "too small"; + } +} + +//legal +abstract class BaseClass { + abstract getData(a: string | number): string | number; +} + +class CorrectWiderParam extends BaseClass { + getData(a: string | number | boolean): string | number { + return typeof a === 'boolean' ? 0 : a; + } +} + +class CorrectNarrowerReturn extends BaseClass { + getData(a: string | number): string { + return typeof a === 'number' ? a.toString() : a; + } +} + +class CorrectBothWiderParamNarrowReturn extends BaseClass { + getData(a: string | number | boolean): string { + return String(a); + } +} + + diff --git a/ets2panda/linter/test/main/method_inheritance.ets.args.json b/ets2panda/linter/test/main/method_inheritance.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance.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": "" + } +} \ 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 new file mode 100644 index 0000000000000000000000000000000000000000..717bb1ec00ad2857434448b626a61f51c958acfd --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json @@ -0,0 +1,138 @@ +{ + "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": 21, + "column": 25, + "endLine": 21, + "endColumn": 37, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 58, + "endLine": 21, + "endColumn": 76, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 76, + "endLine": 41, + "endColumn": 94, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 29, + "endLine": 51, + "endColumn": 44, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 31, + "endLine": 52, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 43, + "endLine": 52, + "endColumn": 44, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 15, + "endLine": 61, + "endColumn": 24, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 26, + "endLine": 61, + "endColumn": 36, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 15, + "endLine": 71, + "endColumn": 27, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 30, + "endLine": 71, + "endColumn": 45, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 23, + "endLine": 72, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 41, + "endLine": 83, + "endColumn": 42, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "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 new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance.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/method_overriding.ets b/ets2panda/linter/test/main/method_overriding.ets index f4f2e72de98b2ce5ea8160a2a6d92a3f3b70dcf4..d2c268492790b2404aab7a074565d7d6885b540b 100755 --- a/ets2panda/linter/test/main/method_overriding.ets +++ b/ets2panda/linter/test/main/method_overriding.ets @@ -54,3 +54,11 @@ interface Person8 { interface Person8_1 extends Person8 { fun: () => void } + +interface Person9 { + fun: () => void +} + +interface Person9_1 extends Person9 { + fun():void +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_overriding.ets.arkts2.json b/ets2panda/linter/test/main/method_overriding.ets.arkts2.json index 6353ca54f23734dac1ed7326a90ccf7745c9071f..4d9808c7f7409ff9c8cf051e3d44098b21c1fd97 100755 --- a/ets2panda/linter/test/main/method_overriding.ets.arkts2.json +++ b/ets2panda/linter/test/main/method_overriding.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 10, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 12, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 31, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 30, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 13, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" }, { @@ -71,8 +71,18 @@ "endColumn": 18, "problem": "MethodOverridingField", "suggest": "", - "rule": "Method cant't override filed in interface implemented (arkts-no-method-overriding-field)", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", "severity": "ERROR" - } + }, + { + "line": 63, + "column": 3, + "endLine": 63, + "endColumn": 13, + "problem": "MethodOverridingField", + "suggest": "", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", + "severity": "ERROR" + } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/modules.ets.json b/ets2panda/linter/test/main/modules.ets.json index 108257f764a26a3cca97df5700b5be8724a4c819..d952c6ff27534cd20f2cadb7b67f8b56aed3f6ba 100644 --- a/ets2panda/linter/test/main/modules.ets.json +++ b/ets2panda/linter/test/main/modules.ets.json @@ -24,6 +24,16 @@ "rule": "\"with\" statement is not supported (arkts-no-with)", "severity": "ERROR" }, + { + "line": 22, + "column": 9, + "endLine": 22, + "endColumn": 13, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, { "line": 23, "column": 11, diff --git a/ets2panda/linter/test/main/no_enum_prop_as_type.ets b/ets2panda/linter/test/main/no_enum_prop_as_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..531ba328060333268e1f9b950802bedbb22cd419 --- /dev/null +++ b/ets2panda/linter/test/main/no_enum_prop_as_type.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. + */ + + +enum A { E = 'A' } +function foo(a: A.E) {} // ERROR + +let b: A.E = ''; \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_enum_prop_as_type.ets.args.json b/ets2panda/linter/test/main/no_enum_prop_as_type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/no_enum_prop_as_type.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_enum_prop_as_type.ets.arkts2.json b/ets2panda/linter/test/main/no_enum_prop_as_type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..be0d1b9493001b13e588a2405cc082e6429ec87e --- /dev/null +++ b/ets2panda/linter/test/main/no_enum_prop_as_type.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 18, + "column": 17, + "endLine": 18, + "endColumn": 20, + "problem": "NoEnumPropAsType", + "suggest": "", + "rule": "Enum elements cannot be types in ArkTS1.2 (arkts-no-enum-prop-as-type)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 11, + "problem": "NoEnumPropAsType", + "suggest": "", + "rule": "Enum elements cannot be types in ArkTS1.2 (arkts-no-enum-prop-as-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_enum_prop_as_type.ets.json b/ets2panda/linter/test/main/no_enum_prop_as_type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/no_enum_prop_as_type.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/no_import_concurrency.ets b/ets2panda/linter/test/main/no_import_concurrency.ets new file mode 100644 index 0000000000000000000000000000000000000000..d6f173602ac9b97d67ee5a86e8c873a096fc19ad --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022-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 { foo, util, taskpool as tpp } from '@ohos.taskpool'; +import { anyClass } from '@kit.ArkTS'; //legal +import foo2, { fooClass } from '@ohos.taskpool'; //legal +import taskpool, { ArkTSUtils as Atu, roo } from '@kit.ArkTS'; +import koo, { ArkTSUtils as Ark, process as pr } from '@kit.ArkTS'; +import doo, { ArkTSUtils as Ats, too } from '@kit.ArkTS'; +import fooke from '@ohos.process'; //legal +import { process as ps } from '@ohos.process'; +import process from '@ohos.process'; +import ArkTSUtils, { taskpool as tsk, process as prs } from '@kit.ArkTS'; \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.args.json b/ets2panda/linter/test/main/no_import_concurrency.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ef3938e967322a0c7551d84c7b6d280de94144c8 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.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/no_import_concurrency.ets.arkts2.json b/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..7d90da63697aff2fcbf4ea04318ef9be41fd6d1a --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.arkts2.json @@ -0,0 +1,108 @@ +{ + "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": 17, + "column": 21, + "endLine": 17, + "endColumn": 36, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 16, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 37, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 15, + "endLine": 21, + "endColumn": 32, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 34, + "endLine": 21, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 15, + "endLine": 22, + "endColumn": 32, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 37, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 74, + "problem": "LimitedStdLibNoImportConcurrency", + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.autofix.json b/ets2panda/linter/test/main/no_import_concurrency.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..2a756c0a4edcbb1429418311fc03b308492aa42e --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.autofix.json @@ -0,0 +1,171 @@ +{ + "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": 17, + "column": 21, + "endLine": 17, + "endColumn": 36, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 629, + "end": 646, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 8, + "endLine": 20, + "endColumn": 16, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 783, + "end": 793, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 37, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 795, + "end": 814, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 15, + "endLine": 21, + "endColumn": 32, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 853, + "end": 872, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 34, + "endLine": 21, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 870, + "end": 885, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 15, + "endLine": 22, + "endColumn": 32, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 921, + "end": 940, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 47, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1008, + "end": 1054, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 37, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1055, + "end": 1091, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 74, + "problem": "LimitedStdLibNoImportConcurrency", + "autofix": [ + { + "start": 1092, + "end": 1165, + "replacementText": "" + } + ], + "suggest": "", + "rule": "Import Concurrency is not required (arkts-limited-stdlib-no-import-concurrency)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.json b/ets2panda/linter/test/main/no_import_concurrency.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.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/no_import_concurrency.ets.migrate.ets b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a7dc1cccd1e7d3efc28ac56813a2342e849546cc --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022-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 { foo, util } from '@ohos.taskpool'; +import { anyClass } from '@kit.ArkTS'; //legal +import foo2, { fooClass } from '@ohos.taskpool'; //legal +import { roo } from '@kit.ArkTS'; +import koo from '@kit.ArkTS'; +import doo, { too } from '@kit.ArkTS'; +import fooke from '@ohos.process'; //legal + + diff --git a/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.json b/ets2panda/linter/test/main/no_import_concurrency.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/no_import_concurrency.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 diff --git a/ets2panda/linter/test/main/no_sparse_array.ets b/ets2panda/linter/test/main/no_sparse_array.ets new file mode 100644 index 0000000000000000000000000000000000000000..3298c36c9294e9ca7c6a20a5a0b06add4789a2d5 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array.ets @@ -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. + */ + +let a = [1, , , 3]; +let b = []; \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array.ets.args.json b/ets2panda/linter/test/main/no_sparse_array.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ddcd120faf3e98361f3f7d57d51d0137c8c25fe0 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array.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_array.ets.arkts2.json b/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..2a8c937e9f90ac9a473715b3abeaa83c114917ad --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json @@ -0,0 +1,58 @@ +{ + "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": 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, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 17, + "endLine": 16, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array.ets.json b/ets2panda/linter/test/main/no_sparse_array.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array.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/no_ts_like_smart_type.ets b/ets2panda/linter/test/main/no_ts_like_smart_type.ets new file mode 100755 index 0000000000000000000000000000000000000000..3a4d7ee28d66e130c6375b18bfdc3baa0a308241 --- /dev/null +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.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. + */ +// static +class AA1 { + public static instance : number | string; + getInstance(): number { + if (AA1.instance instanceof string) { + return 0; + } + return AA1.instance; // Error + } +} + +class AA2 { + public instance : number | string; + getInstance(): number { + if (this.instance instanceof string) { + return 0; + } + return this.instance; // Error + } +} +class A { + private static instance:A = new A(); + static get():A { + return A.instance; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets.args.json b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..aac366be5e8658d7672f4da2855a3c4740c7bcd3 --- /dev/null +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.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/no_ts_like_smart_type.ets.arkts2.json b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..45fcc934258a3b05da4885094e7c46c3f8ed2475 --- /dev/null +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.arkts2.json @@ -0,0 +1,78 @@ +{ + "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": 9, + "endLine": 22, + "endColumn": 29, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 5, + "endLine": 17, + "endColumn": 46, + "problem": "ClassstaticInitialization", + "suggest": "", + "rule": "The static property has no initializer (arkts-class-static-initialization)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 9, + "endLine": 32, + "endColumn": 30, + "problem": "NoTsLikeSmartType", + "suggest": "", + "rule": "Smart type differences (arkts-no-ts-like-smart-type)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 20, + "endLine": 30, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Property 'instance' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'instance' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..b9d40bdd285aa64170a36db11902a97e7d2644a9 --- /dev/null +++ b/ets2panda/linter/test/main/no_ts_like_smart_type.ets.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": 27, + "column": 12, + "endLine": 27, + "endColumn": 20, + "problem": "StrictDiagnostic", + "suggest": "Property 'instance' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'instance' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_tuples_arrays.ets b/ets2panda/linter/test/main/no_tuples_arrays.ets index feddaf52a0dabfc95ca929fd3142a8935f10be3f..93ab572c518a56e3ecb59350ba3da3ffacd46945 100644 --- a/ets2panda/linter/test/main/no_tuples_arrays.ets +++ b/ets2panda/linter/test/main/no_tuples_arrays.ets @@ -72,4 +72,19 @@ let gg: (boolean | number | boolean)[] = new A().ee() let ff = new A().ff() let hh: (boolean | number | boolean)[] =ff let mm: (boolean | number | boolean)[] = a.gg(); -let test: (boolean | string | A)[] = this.test3() \ No newline at end of file +let test: (boolean | string | A)[] = this.test3() + +let tuple14: [number, boolean] = [3.14, true] +let array13: (number|boolean)[] = tuple as (number|boolean)[] //error +let array14: (number|boolean)[] = tuple14 as (number|boolean)[] //error +let array15: (number|boolean)[] = array as (number|boolean)[] +let array16: (boolean | number | boolean)[] = a.gg() as (boolean | number | boolean)[] //error +let tuple15: [string, number, boolean] = this.test2() as [string, number, boolean] +let tuple16: [number, number, boolean] = array as [number, number, boolean] +let tuple17: [number, string, boolean] = ['s', 3.14, true] as [number, string, boolean] +const array17 = Array.from({ length: 5 }, (_, index) => index % 2 === 0 ? index : index % 3 === 0); +let tuple19: [number, boolean] = array17 as [number, boolean] //error +const originalArray: [number] = [1, 2, 3, 4, 5]; +const array18 = originalArray.map((value) => value % 2 === 0 ? true : value * 2); +let tuple20: [number, boolean] = array18 as [number, boolean] //error +let array20: (number)[] = originalArray as (number)[] //error \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json b/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json index 38136a1694264b410ea9a1bdfae2e2980146f97d..f4753e594f424b6cdff8b4dbd33f47f0819ae200 100644 --- a/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_tuples_arrays.ets.arkts2.json @@ -14,6 +14,36 @@ "limitations under the License." ], "result": [ + { + "line": 17, + "column": 18, + "endLine": 17, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 41, + "endLine": 18, + "endColumn": 42, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "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": 22, "column": 5, @@ -34,6 +64,46 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 25, + "column": 13, + "endLine": 25, + "endColumn": 59, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 30, + "endLine": 29, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 34, + "endLine": 29, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 23, + "endLine": 33, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 39, "column": 13, @@ -44,6 +114,36 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 39, + "column": 13, + "endLine": 39, + "endColumn": 62, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 43, + "endLine": 63, + "endColumn": 44, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 44, + "endLine": 64, + "endColumn": 45, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 65, "column": 7, @@ -54,11 +154,41 @@ "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", "severity": "ERROR" }, + { + "line": 65, + "column": 7, + "endLine": 65, + "endColumn": 42, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 7, + "endLine": 67, + "endColumn": 53, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, { "line": 67, "column": 7, "endLine": 67, "endColumn": 53, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 7, + "endLine": 68, + "endColumn": 53, "problem": "NoTuplesArrays", "suggest": "", "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", @@ -69,6 +199,16 @@ "column": 7, "endLine": 68, "endColumn": 53, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 53, "problem": "NoTuplesArrays", "suggest": "", "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", @@ -79,6 +219,16 @@ "column": 5, "endLine": 70, "endColumn": 53, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 43, "problem": "NoTuplesArrays", "suggest": "", "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", @@ -89,6 +239,16 @@ "column": 5, "endLine": 73, "endColumn": 43, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 5, + "endLine": 74, + "endColumn": 48, "problem": "NoTuplesArrays", "suggest": "", "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", @@ -99,6 +259,16 @@ "column": 5, "endLine": 74, "endColumn": 48, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 5, + "endLine": 75, + "endColumn": 50, "problem": "NoTuplesArrays", "suggest": "", "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", @@ -109,6 +279,226 @@ "column": 5, "endLine": 75, "endColumn": 50, + "problem": "ArrayTypeImmutable", + "suggest": "", + "rule": "Array type is immutable in ArkTS1.2 (arkts-array-type-immutable)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 35, + "endLine": 78, + "endColumn": 62, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 35, + "endLine": 79, + "endColumn": 64, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 47, + "endLine": 81, + "endColumn": 87, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 42, + "endLine": 83, + "endColumn": 76, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 17, + "endLine": 85, + "endColumn": 99, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 38, + "endLine": 85, + "endColumn": 39, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 44, + "endLine": 85, + "endColumn": 45, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 65, + "endLine": 85, + "endColumn": 66, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 71, + "endLine": 85, + "endColumn": 72, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 91, + "endLine": 85, + "endColumn": 92, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 97, + "endLine": 85, + "endColumn": 98, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 34, + "endLine": 86, + "endColumn": 62, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 34, + "endLine": 87, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 37, + "endLine": 87, + "endColumn": 38, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 40, + "endLine": 87, + "endColumn": 41, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 43, + "endLine": 87, + "endColumn": 44, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 46, + "endLine": 87, + "endColumn": 47, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 54, + "endLine": 88, + "endColumn": 55, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 60, + "endLine": 88, + "endColumn": 61, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 79, + "endLine": 88, + "endColumn": 80, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 34, + "endLine": 89, + "endColumn": 62, + "problem": "NoTuplesArrays", + "suggest": "", + "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 27, + "endLine": 90, + "endColumn": 54, "problem": "NoTuplesArrays", "suggest": "", "rule": "Array and tuple are different type(arkts-no-tuples-arrays)", diff --git a/ets2panda/linter/test/main/no_tuples_arrays.ets.json b/ets2panda/linter/test/main/no_tuples_arrays.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..f08af476724b403902b709a00b32a2edac1791bb 100644 --- a/ets2panda/linter/test/main/no_tuples_arrays.ets.json +++ b/ets2panda/linter/test/main/no_tuples_arrays.ets.json @@ -13,5 +13,26 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 85, + "column": 17, + "endLine": 85, + "endColumn": 99, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 44, + "endLine": 85, + "endColumn": 45, + "problem": "UnknownType", + "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/main/nondecimal-bigint.ets b/ets2panda/linter/test/main/nondecimal-bigint.ets new file mode 100755 index 0000000000000000000000000000000000000000..6ba019d0e5525a4b7d5e066c42b1bd6bbe631e59 --- /dev/null +++ b/ets2panda/linter/test/main/nondecimal-bigint.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. + */ + +let a1: bigint = 0xBAD3n +let a2: bigint = 0o777n +let a3: bigint = 0b101n +let a3: bigint = 123n diff --git a/ets2panda/linter/test/main/nondecimal-bigint.ets.args.json b/ets2panda/linter/test/main/nondecimal-bigint.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/nondecimal-bigint.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/nondecimal-bigint.ets.arkts2.json b/ets2panda/linter/test/main/nondecimal-bigint.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..e23fd1b155f4be4f2187261ff320003e28b51deb --- /dev/null +++ b/ets2panda/linter/test/main/nondecimal-bigint.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": 16, + "column": 18, + "endLine": 16, + "endColumn": 25, + "problem": "NondecimalBigint", + "suggest": "", + "rule": "Non-decimal BigInt literals (0x/0o/0b) are not supported. Use decimal format instead (arkts-only-support-decimal-bigint-literal)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 18, + "endLine": 17, + "endColumn": 24, + "problem": "NondecimalBigint", + "suggest": "", + "rule": "Non-decimal BigInt literals (0x/0o/0b) are not supported. Use decimal format instead (arkts-only-support-decimal-bigint-literal)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 18, + "endLine": 18, + "endColumn": 24, + "problem": "NondecimalBigint", + "suggest": "", + "rule": "Non-decimal BigInt literals (0x/0o/0b) are not supported. Use decimal format instead (arkts-only-support-decimal-bigint-literal)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/nondecimal-bigint.ets.json b/ets2panda/linter/test/main/nondecimal-bigint.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/nondecimal-bigint.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/numeric_bigint_compare.ets b/ets2panda/linter/test/main/numeric_bigint_compare.ets new file mode 100755 index 0000000000000000000000000000000000000000..a8479c4635e10285b980707d889cd92f6e7f0088 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_bigint_compare.ets @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022-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 n1:number = 123; +let n2:bigint = 456n; + +n1 <= n2 +n1 == n2 +n1 >= n2 + +n1 != n2 +n1 !== n2 +n1 === n2 +n1 > n2 +n1 < n2 + +n1 = n2 +n1 + n2 +n1 - n2 +n1 * n2 +n1 / n2 +n1 % n2 + +function parFunPar(params: boolean) {} +parFunPar(1n > 1.0); +parFunPar(1n < 1.0); +parFunPar(1n >= 1.0); +parFunPar(1n <= 1.0); +parFunPar(1n == 1.0); + +function parFunReturn() : boolean { + return 1n > 1.0; +} +function parFunReturn1() : boolean { + return 1n < 1.0; +} +function parFunReturn2() : boolean { + return 1n >= 1.0; +} +function parFunReturn3() : boolean { + return 1n <= 1.0; +} +function parFunReturn4() : boolean { + return 1n == 1.0; +} + +if (1n > 1.0) { + console.log('1n > 1.0'); +} +if (1n < 1.0) { + console.log('1n < 1.0'); +} +if (1n >= 1.0) { + console.log('1n >= 1.0'); +} +if (1n <= 1.0) { + console.log('1n <= 1.0'); +} +if (1n == 1.0) { + console.log('1n == 1.0'); +} + +let compareA6:boolean = true; +compareA6 = 2n > 1.0 && 1n > 1.5 || 2n >= 2.0; + +const condition = true +compareA6 = ((1n > 1.0) ? (1n < 1.0) : (1n >= 1.0)); +compareA6 = ((1n <= 1.0) ? (1n == 1.0) : (1n > 1.5)); +function comparePar2() { + return 5n > 5.0 || 5n < 5.0 || 5n >= 5.0 || 5n <= 5.0 || 5n == 5.0; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_bigint_compare.ets.args.json b/ets2panda/linter/test/main/numeric_bigint_compare.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..b9d72da1744d61b8b6c738b008adb28a4b9bee3a --- /dev/null +++ b/ets2panda/linter/test/main/numeric_bigint_compare.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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_bigint_compare.ets.arkts2.json b/ets2panda/linter/test/main/numeric_bigint_compare.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..9368614ceed5b359c8064110287393341f32a23b --- /dev/null +++ b/ets2panda/linter/test/main/numeric_bigint_compare.ets.arkts2.json @@ -0,0 +1,458 @@ +{ + "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": 18, + "endLine": 16, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 9, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 9, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 9, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 1, + "endLine": 23, + "endColumn": 9, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 10, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 1, + "endLine": 25, + "endColumn": 10, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 1, + "endLine": 27, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 1, + "endLine": 30, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 1, + "endLine": 31, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 1, + "endLine": 33, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 1, + "endLine": 34, + "endColumn": 8, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 11, + "endLine": 37, + "endColumn": 19, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 11, + "endLine": 38, + "endColumn": 19, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 11, + "endLine": 39, + "endColumn": 20, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 11, + "endLine": 40, + "endColumn": 20, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 11, + "endLine": 41, + "endColumn": 20, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 18, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 10, + "endLine": 47, + "endColumn": 18, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 10, + "endLine": 50, + "endColumn": 19, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 10, + "endLine": 53, + "endColumn": 19, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 10, + "endLine": 56, + "endColumn": 19, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 5, + "endLine": 59, + "endColumn": 13, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 5, + "endLine": 62, + "endColumn": 13, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 14, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 5, + "endLine": 68, + "endColumn": 14, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 14, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 13, + "endLine": 76, + "endColumn": 21, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 25, + "endLine": 76, + "endColumn": 33, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 37, + "endLine": 76, + "endColumn": 46, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 15, + "endLine": 79, + "endColumn": 23, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 28, + "endLine": 79, + "endColumn": 36, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 41, + "endLine": 79, + "endColumn": 50, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 15, + "endLine": 80, + "endColumn": 24, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 29, + "endLine": 80, + "endColumn": 38, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 43, + "endLine": 80, + "endColumn": 51, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 10, + "endLine": 82, + "endColumn": 18, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 22, + "endLine": 82, + "endColumn": 30, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 34, + "endLine": 82, + "endColumn": 43, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 47, + "endLine": 82, + "endColumn": 56, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 60, + "endLine": 82, + "endColumn": 69, + "problem": "NumericBigintCompare", + "suggest": "", + "rule": "Not supporting comparison between number type and bigint type (arkts-numeric-bigint-compare)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_bigint_compare.ets.json b/ets2panda/linter/test/main/numeric_bigint_compare.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_bigint_compare.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/numeric_semantics.ets b/ets2panda/linter/test/main/numeric_semantics.ets index fc52f50758fcd744043571f47e7921ee29479e84..e09d8b47cf7c1fe4bde0f446600b80eaa943059f 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets +++ b/ets2panda/linter/test/main/numeric_semantics.ets @@ -139,3 +139,67 @@ const c1 = 1; export class G{ readonly a5 = 4; } + +const fingerprintPositionY = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 0; + +private doCloseFolderBackgroundAnimation(): void { + openFolderLayout.getGridSwiperLayout().bgHeight = openFolderLayout.getBackgroundLayout().closedHeight; + openFolderLayout.getGridSwiperLayout().bgWidth = openFolderLayout.getBackgroundLayout().closedWidth; + + let pos = [-1, -1]; + pos = folderLayoutUtil.getFolderComponentCenterPosition(FolderData.getInstance().getOpenedFolder()); + let editModeTranslateY = this.getEditModeTranslateY(pos); + if (pos.length > 1) { + let translateXForScreenSplit: number = AppStorage.get('translateXForScreenSplit') ?? 0 as number; + let screenWidth: number = AppStorage.get('screenWidth') as number; + let screenHeight: number = AppStorage.get('screenHeight') as number; + if (screenWidth > screenHeight) { + log.showInfo('doCloseFolderBackgroundAnimation screenWidth: ' + screenWidth + ', height: ' + screenHeight); + screenWidth = screenHeight; + } + openFolderLayout.getGridSwiperLayout().bgTranslateX = pos[0] - screenWidth / 2 + translateXForScreenSplit; + openFolderLayout.getGridSwiperLayout().bgTranslateY = pos[1] + editModeTranslateY - + openFolderLayout.getBackgroundLayout().closedHeight * 0.5 - openFolderLayout.getBackgroundLayout().openedMargin; + } +} + +let f = 0.0; +let b5: number = 0; +f = b5; // OK + +let e = 0.0; +let g1: number = 0; + +e += g1; // OK +e -= g1; // OK +e *= g1; // OK +e /= g1; // OK +e <<= g1; // OK +e >>= g1; // OK +e &= g1; // OK +e = e & 3; // OK +e = e | 3; // OK +let arr1 = [1,2,3] +e += arr1[0]; // OK + +let a = 0.0; +a = fun1(); +a = fun2()!; + +function fun1():number{ + return 1; +} + +function fun2():number|undefined{ + return 1; +} + +import { ArrayList } from "@kit.ArkTS"; + +let arr = new ArrayList() +for (let i:number = 0; i < 100; i++) { + arr.add(i) +} +let cancelIds:ArrayList = arr.subArrayList(6, 86) +let a: Array = Array.from(cancelIds) +let arr1: Array = Array.from(new ArrayList()) \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.args.json b/ets2panda/linter/test/main/numeric_semantics.ets.args.json index 40bac500e37ee9b8de610a9bd90a1128e2bec858..b023016d6bc3b2713d4e02b6f765940828db476b 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets.args.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json b/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json index 78a139f722cc68d8e6c90b632e9900177e5d8708..d8d76c5ce87c4221590181e6ea52baac523f6e38 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.arkts2.json @@ -1,498 +1,1168 @@ -{ - "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": 18, - "column": 5, - "endLine": 18, - "endColumn": 10, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 1, - "endLine": 21, - "endColumn": 8, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 1, - "endLine": 24, - "endColumn": 9, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 13, - "endLine": 28, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 13, - "endLine": 30, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 6, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 1, - "endLine": 35, - "endColumn": 7, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 39, - "column": 5, - "endLine": 39, - "endColumn": 12, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 1, - "endLine": 40, - "endColumn": 6, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 1, - "endLine": 41, - "endColumn": 7, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 10, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 49, - "column": 13, - "endLine": 49, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 5, - "endLine": 51, - "endColumn": 10, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 55, - "column": 5, - "endLine": 55, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 5, - "endLine": 57, - "endColumn": 15, - "problem": "DefiniteAssignmentError", - "suggest": "", - "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 5, - "endLine": 59, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 5, - "endLine": 61, - "endColumn": 19, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 5, - "endLine": 63, - "endColumn": 14, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 5, - "endLine": 65, - "endColumn": 27, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 5, - "endLine": 67, - "endColumn": 27, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 5, - "endLine": 73, - "endColumn": 11, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 75, - "column": 5, - "endLine": 75, - "endColumn": 12, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 4, - "endLine": 78, - "endColumn": 10, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 83, - "column": 5, - "endLine": 83, - "endColumn": 14, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 85, - "column": 5, - "endLine": 85, - "endColumn": 14, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 87, - "column": 5, - "endLine": 87, - "endColumn": 26, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 89, - "column": 5, - "endLine": 89, - "endColumn": 27, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 92, - "column": 1, - "endLine": 94, - "endColumn": 2, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 1, - "endLine": 98, - "endColumn": 2, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 103, - "column": 1, - "endLine": 103, - "endColumn": 13, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 105, - "column": 5, - "endLine": 105, - "endColumn": 23, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 107, - "column": 5, - "endLine": 107, - "endColumn": 19, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 107, - "column": 18, - "endLine": 107, - "endColumn": 18, - "problem": "ArrayIndexExprType", - "suggest": "", - "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", - "severity": "ERROR" - }, - { - "line": 109, - "column": 7, - "endLine": 109, - "endColumn": 12, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 115, - "column": 7, - "endLine": 115, - "endColumn": 20, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 121, - "column": 3, - "endLine": 121, - "endColumn": 19, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 21, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 123, - "column": 3, - "endLine": 123, - "endColumn": 23, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 124, - "column": 3, - "endLine": 124, - "endColumn": 23, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 125, - "column": 3, - "endLine": 125, - "endColumn": 23, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 126, - "column": 3, - "endLine": 126, - "endColumn": 24, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 137, - "column": 7, - "endLine": 137, - "endColumn": 13, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 140, - "column": 3, - "endLine": 140, - "endColumn": 19, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 117, - "column": 2, - "endLine": 117, - "endColumn": 7, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 2, - "endLine": 118, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 120, - "column": 4, - "endLine": 120, - "endColumn": 9, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 129, - "column": 5, - "endLine": 129, - "endColumn": 22, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 130, - "column": 7, - "endLine": 130, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - } - ] +{ + "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": 18, + "column": 5, + "endLine": 18, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 6, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 6, + "endLine": 23, + "endColumn": 7, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 17, + "endLine": 26, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 17, + "endLine": 28, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 17, + "endLine": 33, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 9, + "endLine": 45, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 9, + "endLine": 51, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 17, + "endLine": 53, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 5, + "endLine": 55, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 13, + "endLine": 55, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 16, + "endLine": 55, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 5, + "endLine": 57, + "endColumn": 15, + "problem": "DefiniteAssignmentError", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 5, + "endLine": 59, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 5, + "endLine": 63, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 16, + "endLine": 69, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 19, + "endLine": 71, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 5, + "endLine": 75, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 4, + "endLine": 78, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 8, + "endLine": 78, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 11, + "endLine": 83, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 11, + "endLine": 85, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 23, + "endLine": 92, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 30, + "endLine": 92, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 1, + "endLine": 98, + "endColumn": 2, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 10, + "endLine": 103, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 17, + "endLine": 105, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 19, + "endLine": 105, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 21, + "endLine": 105, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 5, + "endLine": 107, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 18, + "endLine": 107, + "endColumn": 18, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 11, + "endLine": 109, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 7, + "endLine": 115, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 17, + "endLine": 121, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 3, + "endLine": 123, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 3, + "endLine": 124, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 3, + "endLine": 125, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 3, + "endLine": 126, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 18, + "endLine": 126, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 20, + "endLine": 126, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 22, + "endLine": 126, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 7, + "endLine": 137, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 12, + "endLine": 137, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 3, + "endLine": 140, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 17, + "endLine": 140, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 7, + "endLine": 143, + "endColumn": 123, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 30, + "endLine": 143, + "endColumn": 118, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 122, + "endLine": 143, + "endColumn": 123, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 45, + "endLine": 145, + "endColumn": 49, + "problem": "VoidOperator", + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 50, + "endLine": 145, + "endColumn": 51, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 5, + "endLine": 146, + "endColumn": 21, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 147, + "column": 5, + "endLine": 147, + "endColumn": 21, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 5, + "endLine": 149, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 9, + "endLine": 149, + "endColumn": 23, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 5, + "endLine": 150, + "endColumn": 104, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 5, + "endLine": 151, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 9, + "endLine": 151, + "endColumn": 61, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 12, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 17, + "endLine": 149, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 21, + "endLine": 149, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 9, + "endLine": 152, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 22, + "endLine": 152, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 100, + "endLine": 153, + "endColumn": 101, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 84, + "endLine": 160, + "endColumn": 85, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 5, + "endLine": 166, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 18, + "endLine": 167, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 5, + "endLine": 170, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 18, + "endLine": 171, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 9, + "endLine": 180, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 181, + "column": 9, + "endLine": 181, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 5, + "endLine": 182, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 13, + "endLine": 182, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 15, + "endLine": 182, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 17, + "endLine": 182, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 5, + "endLine": 185, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 190, + "column": 10, + "endLine": 190, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 10, + "endLine": 194, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 1, + "endLine": 197, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 5, + "endLine": 199, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 15, + "endLine": 199, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 21, + "endLine": 200, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 28, + "endLine": 200, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 52, + "endLine": 203, + "endColumn": 53, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 55, + "endLine": 203, + "endColumn": 57, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 42, + "endLine": 205, + "endColumn": 51, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 2, + "endLine": 117, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 2, + "endLine": 118, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 4, + "endLine": 120, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 5, + "endLine": 129, + "endColumn": 22, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 7, + "endLine": 130, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 30, + "endLine": 143, + "endColumn": 40, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 46, + "endLine": 153, + "endColumn": 56, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 33, + "endLine": 154, + "endColumn": 43, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json b/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json old mode 100755 new mode 100644 index 2eb4bebd6e6f65b2c98511ed9f7553f9532da2de..148d39bc8276e8eda806b5d3325102c8b6e58239 --- a/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.autofix.json @@ -1,763 +1,2343 @@ -{ - "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": 18, - "column": 5, - "endLine": 18, - "endColumn": 10, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 744, - "end": 749, - "replacementText": "a: number = 1" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 1, - "endLine": 21, - "endColumn": 8, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 1, - "endLine": 24, - "endColumn": 9, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 13, - "endLine": 28, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 13, - "endLine": 30, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 6, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 1, - "endLine": 35, - "endColumn": 7, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 39, - "column": 5, - "endLine": 39, - "endColumn": 12, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1377, - "end": 1384, - "replacementText": "c: number = 1.5" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 1, - "endLine": 40, - "endColumn": 6, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 1, - "endLine": 41, - "endColumn": 7, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 10, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1561, - "end": 1566, - "replacementText": "d: number = 2" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 49, - "column": 13, - "endLine": 49, - "endColumn": 18, - "problem": "NumericSemantics", - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 5, - "endLine": 51, - "endColumn": 10, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1712, - "end": 1717, - "replacementText": "n: number = 2" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 55, - "column": 5, - "endLine": 55, - "endColumn": 18, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1747, - "end": 1760, - "replacementText": "g: number[] = [1, 2, 3]" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 5, - "endLine": 57, - "endColumn": 15, - "problem": "DefiniteAssignmentError", - "suggest": "", - "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", - "severity": "ERROR" - }, - { - "line": 59, - "column": 5, - "endLine": 59, - "endColumn": 18, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1786, - "end": 1799, - "replacementText": "t8: number = Infinity" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 5, - "endLine": 61, - "endColumn": 19, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1807, - "end": 1821, - "replacementText": "t9: number = -Infinity" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 5, - "endLine": 63, - "endColumn": 14, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1830, - "end": 1839, - "replacementText": "t10: number = NaN" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 5, - "endLine": 65, - "endColumn": 27, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1848, - "end": 1870, - "replacementText": "t11: number = Number.MAX_VALUE" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 5, - "endLine": 67, - "endColumn": 27, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1879, - "end": 1901, - "replacementText": "t12: number = Number.MIN_VALUE" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 5, - "endLine": 73, - "endColumn": 11, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1959, - "end": 1965, - "replacementText": "o2: number = o" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 75, - "column": 5, - "endLine": 75, - "endColumn": 12, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 1975, - "end": 1982, - "replacementText": "o3: number = oo" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 4, - "endLine": 78, - "endColumn": 10, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2001, - "end": 2007, - "replacementText": "a: number = 1;" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 83, - "column": 5, - "endLine": 83, - "endColumn": 14, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2043, - "end": 2052, - "replacementText": "t2: number = +123" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 85, - "column": 5, - "endLine": 85, - "endColumn": 14, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2061, - "end": 2070, - "replacementText": "t3: number = -234" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 87, - "column": 5, - "endLine": 87, - "endColumn": 26, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2079, - "end": 2100, - "replacementText": "num: number = Math.floor(4.8)" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 89, - "column": 5, - "endLine": 89, - "endColumn": 27, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2124, - "end": 2146, - "replacementText": "value: number = parseInt(\"42\")" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 92, - "column": 1, - "endLine": 94, - "endColumn": 2, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2188, - "end": 2193, - "replacementText": "x: number = 2" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 92, - "column": 1, - "endLine": 94, - "endColumn": 2, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2195, - "end": 2200, - "replacementText": "y: number = 3" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 92, - "column": 1, - "endLine": 94, - "endColumn": 2, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2201, - "end": 2201, - "replacementText": ": number" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 1, - "endLine": 98, - "endColumn": 2, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2264, - "end": 2264, - "replacementText": ": number" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 103, - "column": 1, - "endLine": 103, - "endColumn": 13, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2347, - "end": 2359, - "replacementText": "identity(42)" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 105, - "column": 5, - "endLine": 105, - "endColumn": 23, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2368, - "end": 2386, - "replacementText": "an_array: number[] = [1, 2, 3]" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 107, - "column": 5, - "endLine": 107, - "endColumn": 19, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2394, - "end": 2408, - "replacementText": "g: number = an_array[]" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 107, - "column": 18, - "endLine": 107, - "endColumn": 18, - "problem": "ArrayIndexExprType", - "suggest": "", - "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", - "severity": "ERROR" - }, - { - "line": 109, - "column": 7, - "endLine": 109, - "endColumn": 12, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2418, - "end": 2423, - "replacementText": "a: number = 1" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 115, - "column": 7, - "endLine": 115, - "endColumn": 20, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2493, - "end": 2506, - "replacementText": "test: number = Test.A" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 121, - "column": 3, - "endLine": 121, - "endColumn": 19, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2593, - "end": 2609, - "replacementText": "readonly c1: number = 1;" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 21, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2620, - "end": 2638, - "replacementText": "readonly c4: number = 1.7;" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 123, - "column": 3, - "endLine": 123, - "endColumn": 23, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2651, - "end": 2671, - "replacementText": "readonly c5: number = 0x123;" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 124, - "column": 3, - "endLine": 124, - "endColumn": 23, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2683, - "end": 2703, - "replacementText": "readonly c6: number = 0o123;" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 125, - "column": 3, - "endLine": 125, - "endColumn": 23, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2713, - "end": 2733, - "replacementText": "readonly c7: number = 0b101;" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 126, - "column": 3, - "endLine": 126, - "endColumn": 24, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2743, - "end": 2764, - "replacementText": "readonly c8: number[] = [1, 2, 3];" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 137, - "column": 7, - "endLine": 137, - "endColumn": 13, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2893, - "end": 2899, - "replacementText": "c1: number = 1" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 140, - "column": 3, - "endLine": 140, - "endColumn": 19, - "problem": "NumericSemantics", - "autofix": [ - { - "start": 2923, - "end": 2939, - "replacementText": "readonly a5: number = 4;" - } - ], - "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", - "severity": "ERROR" - }, - { - "line": 117, - "column": 2, - "endLine": 117, - "endColumn": 7, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 118, - "column": 2, - "endLine": 118, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 120, - "column": 4, - "endLine": 120, - "endColumn": 9, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 129, - "column": 5, - "endLine": 129, - "endColumn": 22, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 130, - "column": 7, - "endLine": 130, - "endColumn": 11, - "problem": "UIInterfaceImport", - "autofix": [ - { - "start": 738, - "end": 738, - "replacementText": "\n\nimport { Entry, Component, State, RelativeContainer, Text } from '@kits.ArkUI';\n" - } - ], - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - } - ] +{ + "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": 18, + "column": 5, + "endLine": 18, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 744, + "end": 749, + "replacementText": "a: number = 1", + "line": 18, + "column": 5, + "endLine": 18, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 748, + "end": 749, + "replacementText": "1.0", + "line": 18, + "column": 9, + "endLine": 18, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 6, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 758, + "end": 759, + "replacementText": "1.0", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 6 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 6, + "endLine": 23, + "endColumn": 7, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 848, + "end": 849, + "replacementText": "1.0", + "line": 23, + "column": 6, + "endLine": 23, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 17, + "endLine": 26, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 921, + "end": 922, + "replacementText": "1.0", + "line": 26, + "column": 17, + "endLine": 26, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 17, + "endLine": 28, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 977, + "end": 978, + "replacementText": "2.0", + "line": 28, + "column": 17, + "endLine": 28, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1083, + "end": 1084, + "replacementText": "2.0", + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 17, + "endLine": 33, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1199, + "end": 1200, + "replacementText": "1.0", + "line": 33, + "column": 17, + "endLine": 33, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1377, + "end": 1384, + "replacementText": "c: number = 1.5", + "line": 39, + "column": 5, + "endLine": 39, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1561, + "end": 1566, + "replacementText": "d: number = 2", + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 9, + "endLine": 45, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1565, + "end": 1566, + "replacementText": "2.0", + "line": 45, + "column": 9, + "endLine": 45, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1712, + "end": 1717, + "replacementText": "n: number = 2", + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 9, + "endLine": 51, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1716, + "end": 1717, + "replacementText": "2.0", + "line": 51, + "column": 9, + "endLine": 51, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 17, + "endLine": 53, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1738, + "end": 1739, + "replacementText": "1.0", + "line": 53, + "column": 17, + "endLine": 53, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 5, + "endLine": 55, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1747, + "end": 1760, + "replacementText": "g: number[] = [1, 2, 3]", + "line": 55, + "column": 5, + "endLine": 55, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1752, + "end": 1753, + "replacementText": "1.0", + "line": 55, + "column": 10, + "endLine": 55, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 13, + "endLine": 55, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1755, + "end": 1756, + "replacementText": "2.0", + "line": 55, + "column": 13, + "endLine": 55, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 16, + "endLine": 55, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1758, + "end": 1759, + "replacementText": "3.0", + "line": 55, + "column": 16, + "endLine": 55, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 5, + "endLine": 57, + "endColumn": 15, + "problem": "DefiniteAssignmentError", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 5, + "endLine": 59, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1786, + "end": 1799, + "replacementText": "t8: number = Infinity", + "line": 59, + "column": 5, + "endLine": 59, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1807, + "end": 1821, + "replacementText": "t9: number = -Infinity", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 5, + "endLine": 63, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1830, + "end": 1839, + "replacementText": "t10: number = NaN", + "line": 63, + "column": 5, + "endLine": 63, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1848, + "end": 1870, + "replacementText": "t11: number = Number.MAX_VALUE", + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1879, + "end": 1901, + "replacementText": "t12: number = Number.MIN_VALUE", + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 16, + "endLine": 69, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1921, + "end": 1924, + "replacementText": "123.0", + "line": 69, + "column": 16, + "endLine": 69, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 19, + "endLine": 71, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1947, + "end": 1950, + "replacementText": "123.0", + "line": 71, + "column": 19, + "endLine": 71, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1959, + "end": 1965, + "replacementText": "o2: number = o", + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 5, + "endLine": 75, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1975, + "end": 1982, + "replacementText": "o3: number = oo", + "line": 75, + "column": 5, + "endLine": 75, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 4, + "endLine": 78, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2001, + "end": 2007, + "replacementText": "a: number = 1;", + "line": 78, + "column": 4, + "endLine": 78, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 8, + "endLine": 78, + "endColumn": 9, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2005, + "end": 2006, + "replacementText": "1.0", + "line": 78, + "column": 8, + "endLine": 78, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2043, + "end": 2052, + "replacementText": "t2: number = +123", + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 11, + "endLine": 83, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2049, + "end": 2052, + "replacementText": "123.0", + "line": 83, + "column": 11, + "endLine": 83, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2061, + "end": 2070, + "replacementText": "t3: number = -234", + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 11, + "endLine": 85, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2067, + "end": 2070, + "replacementText": "234.0", + "line": 85, + "column": 11, + "endLine": 85, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2079, + "end": 2100, + "replacementText": "num: number = Math.floor(4.8)", + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2124, + "end": 2146, + "replacementText": "value: number = parseInt(\"42\")", + "line": 89, + "column": 5, + "endLine": 89, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2188, + "end": 2193, + "replacementText": "x: number = 2", + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2195, + "end": 2200, + "replacementText": "y: number = 3", + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2201, + "end": 2201, + "replacementText": ": number", + "line": 92, + "column": 1, + "endLine": 94, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 23, + "endLine": 92, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2192, + "end": 2193, + "replacementText": "2.0", + "line": 92, + "column": 23, + "endLine": 92, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 30, + "endLine": 92, + "endColumn": 31, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2199, + "end": 2200, + "replacementText": "3.0", + "line": 92, + "column": 30, + "endLine": 92, + "endColumn": 31 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 1, + "endLine": 98, + "endColumn": 2, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2264, + "end": 2264, + "replacementText": ": number", + "line": 96, + "column": 1, + "endLine": 98, + "endColumn": 2 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 10, + "endLine": 103, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2356, + "end": 2358, + "replacementText": "42.0", + "line": 103, + "column": 10, + "endLine": 103, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2368, + "end": 2386, + "replacementText": "an_array: number[] = [1, 2, 3]", + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 17, + "endLine": 105, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2380, + "end": 2381, + "replacementText": "1.0", + "line": 105, + "column": 17, + "endLine": 105, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 19, + "endLine": 105, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2382, + "end": 2383, + "replacementText": "2.0", + "line": 105, + "column": 19, + "endLine": 105, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 21, + "endLine": 105, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2384, + "end": 2385, + "replacementText": "3.0", + "line": 105, + "column": 21, + "endLine": 105, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 5, + "endLine": 107, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2394, + "end": 2408, + "replacementText": "g: number = an_array[]", + "line": 107, + "column": 5, + "endLine": 107, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 18, + "endLine": 107, + "endColumn": 18, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2418, + "end": 2423, + "replacementText": "a: number = 1", + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 11, + "endLine": 109, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2422, + "end": 2423, + "replacementText": "1.0", + "line": 109, + "column": 11, + "endLine": 109, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 7, + "endLine": 115, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2493, + "end": 2506, + "replacementText": "test: number = Test.A", + "line": 115, + "column": 7, + "endLine": 115, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2593, + "end": 2609, + "replacementText": "readonly c1: number = 1;", + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 17, + "endLine": 121, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2607, + "end": 2608, + "replacementText": "1.0", + "line": 121, + "column": 17, + "endLine": 121, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2620, + "end": 2638, + "replacementText": "readonly c4: number = 1.7;", + "line": 122, + "column": 3, + "endLine": 122, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 3, + "endLine": 123, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2651, + "end": 2671, + "replacementText": "readonly c5: number = 0x123;", + "line": 123, + "column": 3, + "endLine": 123, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 3, + "endLine": 124, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2683, + "end": 2703, + "replacementText": "readonly c6: number = 0o123;", + "line": 124, + "column": 3, + "endLine": 124, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 3, + "endLine": 125, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2713, + "end": 2733, + "replacementText": "readonly c7: number = 0b101;", + "line": 125, + "column": 3, + "endLine": 125, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 3, + "endLine": 126, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2743, + "end": 2764, + "replacementText": "readonly c8: number[] = [1, 2, 3];", + "line": 126, + "column": 3, + "endLine": 126, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 18, + "endLine": 126, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2758, + "end": 2759, + "replacementText": "1.0", + "line": 126, + "column": 18, + "endLine": 126, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 20, + "endLine": 126, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2760, + "end": 2761, + "replacementText": "2.0", + "line": 126, + "column": 20, + "endLine": 126, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 22, + "endLine": 126, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2762, + "end": 2763, + "replacementText": "3.0", + "line": 126, + "column": 22, + "endLine": 126, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 7, + "endLine": 137, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2893, + "end": 2899, + "replacementText": "c1: number = 1", + "line": 137, + "column": 7, + "endLine": 137, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 12, + "endLine": 137, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2898, + "end": 2899, + "replacementText": "1.0", + "line": 137, + "column": 12, + "endLine": 137, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 3, + "endLine": 140, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2923, + "end": 2939, + "replacementText": "readonly a5: number = 4;", + "line": 140, + "column": 3, + "endLine": 140, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 17, + "endLine": 140, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2937, + "end": 2938, + "replacementText": "4.0", + "line": 140, + "column": 17, + "endLine": 140, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 7, + "endLine": 143, + "endColumn": 123, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 30, + "endLine": 143, + "endColumn": 118, + "problem": "NumericSemantics", + "autofix": [ + { + "replacementText": "fingerprintPositionY: number = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 0", + "start": 2952, + "end": 3068, + "line": 143, + "column": 30, + "endLine": 143, + "endColumn": 118 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 122, + "endLine": 143, + "endColumn": 123, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3067, + "end": 3068, + "replacementText": "0.0", + "line": 143, + "column": 122, + "endLine": 143, + "endColumn": 123 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 45, + "endLine": 145, + "endColumn": 49, + "problem": "VoidOperator", + "autofix": [ + { + "start": 3117, + "end": 3558, + "replacementText": "(() => {\r\n ({\r\n openFolderLayout, : .getGridSwiperLayout().bgHeight = openFolderLayout.getBackgroundLayout().closedHeight,\r\n openFolderLayout, : .getGridSwiperLayout().bgWidth = openFolderLayout.getBackgroundLayout().closedWidth,\r\n let, pos = [-1, -1],\r\n pos = folderLayoutUtil.getFolderComponentCenterPosition(FolderData.getInstance().getOpenedFolder()),\r\n let, editModeTranslateY = this.getEditModeTranslateY(pos),\r\n if(pos) { }, : .length > 1\r\n });\r\n return undefined;\r\n})()", + "line": 145, + "column": 45, + "endLine": 145, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 50, + "endLine": 145, + "endColumn": 51, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 5, + "endLine": 146, + "endColumn": 21, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3129, + "end": 3145, + "replacementText": "openFolderLayout: openFolderLayout", + "line": 146, + "column": 5, + "endLine": 146, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 147, + "column": 5, + "endLine": 147, + "endColumn": 21, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3237, + "end": 3253, + "replacementText": "openFolderLayout: openFolderLayout", + "line": 147, + "column": 5, + "endLine": 147, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 5, + "endLine": 149, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3345, + "end": 3348, + "replacementText": "let: let", + "line": 149, + "column": 5, + "endLine": 149, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 9, + "endLine": 149, + "endColumn": 23, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3349, + "end": 3363, + "replacementText": "pos: pos", + "line": 149, + "column": 9, + "endLine": 149, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 150, + "column": 5, + "endLine": 150, + "endColumn": 104, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3370, + "end": 3469, + "replacementText": "pos: pos", + "line": 150, + "column": 5, + "endLine": 150, + "endColumn": 104 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 5, + "endLine": 151, + "endColumn": 8, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3476, + "end": 3479, + "replacementText": "let: let", + "line": 151, + "column": 5, + "endLine": 151, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 9, + "endLine": 151, + "endColumn": 61, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 3480, + "end": 3532, + "replacementText": "editModeTranslateY: editModeTranslateY", + "line": 151, + "column": 9, + "endLine": 151, + "endColumn": 61 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 12, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 17, + "endLine": 149, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3357, + "end": 3358, + "replacementText": "1.0", + "line": 149, + "column": 17, + "endLine": 149, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 21, + "endLine": 149, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3361, + "end": 3362, + "replacementText": "1.0", + "line": 149, + "column": 21, + "endLine": 149, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 9, + "endLine": 152, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 22, + "endLine": 152, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3556, + "end": 3557, + "replacementText": "1.0", + "line": 152, + "column": 22, + "endLine": 152, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 100, + "endLine": 153, + "endColumn": 101, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3661, + "end": 3662, + "replacementText": "0.0", + "line": 153, + "column": 100, + "endLine": 153, + "endColumn": 101 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 84, + "endLine": 160, + "endColumn": 85, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4128, + "end": 4129, + "replacementText": "2.0", + "line": 160, + "column": 84, + "endLine": 160, + "endColumn": 85 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 5, + "endLine": 166, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4388, + "end": 4395, + "replacementText": "f: number = 0.0", + "line": 166, + "column": 5, + "endLine": 166, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 18, + "endLine": 167, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4415, + "end": 4416, + "replacementText": "0.0", + "line": 167, + "column": 18, + "endLine": 167, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 170, + "column": 5, + "endLine": 170, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4440, + "end": 4447, + "replacementText": "e: number = 0.0", + "line": 170, + "column": 5, + "endLine": 170, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 171, + "column": 18, + "endLine": 171, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4467, + "end": 4468, + "replacementText": "0.0", + "line": 171, + "column": 18, + "endLine": 171, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 9, + "endLine": 180, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4595, + "end": 4596, + "replacementText": "3.0", + "line": 180, + "column": 9, + "endLine": 180, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 181, + "column": 9, + "endLine": 181, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4613, + "end": 4614, + "replacementText": "3.0", + "line": 181, + "column": 9, + "endLine": 181, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 5, + "endLine": 182, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4627, + "end": 4641, + "replacementText": "arr1: number[] = [1, 2, 3]", + "line": 182, + "column": 5, + "endLine": 182, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 13, + "endLine": 182, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4635, + "end": 4636, + "replacementText": "1.0", + "line": 182, + "column": 13, + "endLine": 182, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 15, + "endLine": 182, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4637, + "end": 4638, + "replacementText": "2.0", + "line": 182, + "column": 15, + "endLine": 182, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 17, + "endLine": 182, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4639, + "end": 4640, + "replacementText": "3.0", + "line": 182, + "column": 17, + "endLine": 182, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 5, + "endLine": 185, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4670, + "end": 4677, + "replacementText": "a: number = 0.0", + "line": 185, + "column": 5, + "endLine": 185, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 190, + "column": 10, + "endLine": 190, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4743, + "end": 4744, + "replacementText": "1.0", + "line": 190, + "column": 10, + "endLine": 190, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 10, + "endLine": 194, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4796, + "end": 4797, + "replacementText": "1.0", + "line": 194, + "column": 10, + "endLine": 194, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 1, + "endLine": 197, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 5, + "endLine": 199, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 15, + "endLine": 199, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 21, + "endLine": 200, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4903, + "end": 4904, + "replacementText": "0.0", + "line": 200, + "column": 21, + "endLine": 200, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 28, + "endLine": 200, + "endColumn": 31, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4910, + "end": 4913, + "replacementText": "100.0", + "line": 200, + "column": 28, + "endLine": 200, + "endColumn": 31 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 52, + "endLine": 203, + "endColumn": 53, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4991, + "end": 4992, + "replacementText": "6.0", + "line": 203, + "column": 52, + "endLine": 203, + "endColumn": 53 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 55, + "endLine": 203, + "endColumn": 57, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4994, + "end": 4996, + "replacementText": "86.0", + "line": 203, + "column": 55, + "endLine": 203, + "endColumn": 57 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 42, + "endLine": 205, + "endColumn": 51, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 2, + "endLine": 117, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 2, + "endLine": 118, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 4, + "endLine": 120, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 129, + "column": 5, + "endLine": 129, + "endColumn": 22, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 7, + "endLine": 130, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 30, + "endLine": 143, + "endColumn": 40, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 46, + "endLine": 153, + "endColumn": 56, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 33, + "endLine": 154, + "endColumn": 43, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 738, + "end": 738, + "replacementText": "\r\n\r\nimport { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI';\r\n", + "line": 155, + "column": 34, + "endLine": 155, + "endColumn": 44 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.json b/ets2panda/linter/test/main/numeric_semantics.ets.json index 35c82b1f9d49623a310f22a2316e92281acb3604..47737941ad04d6a390c617f5cd735c817853aba8 100755 --- a/ets2panda/linter/test/main/numeric_semantics.ets.json +++ b/ets2panda/linter/test/main/numeric_semantics.ets.json @@ -1,28 +1,88 @@ -{ - "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": 57, - "column": 5, - "endLine": 57, - "endColumn": 15, - "problem": "DefiniteAssignment", - "suggest": "", - "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", - "severity": "WARNING" - } - ] +{ + "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": 57, + "column": 5, + "endLine": 57, + "endColumn": 15, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 143, + "column": 7, + "endLine": 143, + "endColumn": 123, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 50, + "endLine": 145, + "endColumn": 51, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 7, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 9, + "endLine": 152, + "endColumn": 12, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 1, + "endLine": 197, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 5, + "endLine": 199, + "endColumn": 34, + "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/main/numeric_semantics.ets.migrate.ets b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..cecf097403e7e26cc5170fc8585ae18efaf67337 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.ets @@ -0,0 +1,211 @@ +/* + * 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. + */ + +// TypeScript: treats 'n' as having type number +// ArkTS: treats 'n' as having type int to reach max code performance + +import { Entry, Component, State, RelativeContainer, Text, AppStorage } from '@kit.ArkUI'; + +let a: number = 1.0; + +a = 1.0; // OK +a = 1.5; // CTE in ArkTS: Type 'double' can't be assigned to type 'int' + +a += 1.0; // OK +a += 1.5; // ArkTS: Result is integer value + +console.log(a + 1.0); // OK +console.log(a - 0.5); // OK +console.log(a / 2.0); // ArkTS: integer division is used, result is integer value +console.log(a / 2.5); // OK +console.log(2.0 / a); // ArkTS: integer division is used, result is integer value +console.log(2.5 / a); // OK + +let b: number = 1.0; +a = b; // CTE in ArkTS: Type 'double' can't be assigned to type 'int' +a += b; // ArkTS: Result is integer value +console.log(a + b); // OK +console.log(a / b); // OK + +let c: number = 1.5; +a = c; // CTE in ArkTS: Type 'double' can't be assigned to type 'int' +a += c; // ArkTS: Result is integer value +console.log(a + c); // OK +console.log(a / c); // OK + +let d: number = 2.0; +a = d; // OK +a += d; // OK +console.log(a + d); // OK +console.log(a / d); // ArkTS: integer division is used, result is integer value + +let n: number = 2.0; + +let f: number = 1.0 + +let g: number[] = [1.0, 2.0, 3.0] + +let x!: number + +let t8: number = Infinity + +let t9: number = -Infinity; + +let t10: number = NaN; + +let t11: number = Number.MAX_VALUE; + +let t12: number = Number.MIN_VALUE; + +let o:number = 123.0; + +const oo:number = 123.0; + +let o2: number = o; + +let o3: number = oo; + +class A{ + a: number = 1.0; + constructor() { + } +} + +let t2: number = +123.0; + +let t3: number = -234.0; + +let num: number = Math.floor(4.8); // num 可能是 int + +let value: number = parseInt("42"); // value 可能是 int + + +function multiply(x: number = 2.0, y: number = 3.0): number { + return x * y; +} + +function divide(x: number, y: number): number { + return x / y; +} + +function identity(value: T): T { + return value; +} +identity(42.0); + +let an_array: number[] = [1.0, 2.0, 3.0] + +let g: number = an_array[] + +const a: number = 1.0 + +enum Test { + A = 1, // 显式赋值为 1 + B = 2 // 显式赋值为 2 +} +const test: number = Test.A; + +@Entry +@Component +struct Index2 { + @State message: string = 'Hello World'; + readonly c1: number = 1.0; // int + readonly c4: number = 1.7; // float + readonly c5: number = 0x123; // 16进制 + readonly c6: number = 0o123; //8进制 + readonly c7: number = 0b101; //2进制 + readonly c8: number[] = [1.0, 2.0, 3.0]; + +build() { + RelativeContainer() { + Text(this.message) + .onClick(() => { + }) + } + } +} + +const c1: number = 1.0; + +export class G{ + readonly a5: number = 4.0; +} + +const fingerprintPositionY: number = AppStorage.get(FingerprintConstants.COORDINATE_Y_OF_FINGERPRINT_UD_SCREEN_IN_PX) ?? 0.0; + +private doCloseFolderBackgroundAnimation(): (() => { + ({ + openFolderLayout: openFolderLayout, : .getGridSwiperLayout().bgHeight = openFolderLayout.getBackgroundLayout().closedHeight, + openFolderLayout: openFolderLayout, : .getGridSwiperLayout().bgWidth = openFolderLayout.getBackgroundLayout().closedWidth, + let: let, pos: pos, + pos: pos, + let: let, editModeTranslateY: editModeTranslateY, + if(pos) { }, : .length > 1.0 + }); + return undefined; +})() { + let translateXForScreenSplit: number = AppStorage.get('translateXForScreenSplit') ?? 0.0 as number; + let screenWidth: number = AppStorage.get('screenWidth') as number; + let screenHeight: number = AppStorage.get('screenHeight') as number; + if (screenWidth > screenHeight) { + log.showInfo('doCloseFolderBackgroundAnimation screenWidth: ' + screenWidth + ', height: ' + screenHeight); + screenWidth = screenHeight; + } + openFolderLayout.getGridSwiperLayout().bgTranslateX = pos[0] - screenWidth / 2.0 + translateXForScreenSplit; + openFolderLayout.getGridSwiperLayout().bgTranslateY = pos[1] + editModeTranslateY - + openFolderLayout.getBackgroundLayout().closedHeight * 0.5 - openFolderLayout.getBackgroundLayout().openedMargin; + } +} + +let f: number = 0.0; +let b5: number = 0.0; +f = b5; // OK + +let e: number = 0.0; +let g1: number = 0.0; + +e += g1; // OK +e -= g1; // OK +e *= g1; // OK +e /= g1; // OK +e <<= g1; // OK +e >>= g1; // OK +e &= g1; // OK +e = e & 3.0; // OK +e = e | 3.0; // OK +let arr1: number[] = [1.0, 2.0, 3.0] +e += arr1[0]; // OK + +let a: number = 0.0; +a = fun1(); +a = fun2()!; + +function fun1():number{ + return 1.0; +} + +function fun2():number|undefined{ + return 1.0; +} + +import { ArrayList } from "@kit.ArkTS"; + +let arr = new ArrayList() +for (let i:number = 0.0; i < 100.0; i++) { + arr.add(i) +} +let cancelIds:ArrayList = arr.subArrayList(6.0, 86.0) +let a: Array = Array.from(cancelIds) +let arr1: Array = Array.from(new ArrayList()) \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c86c2373e15de875d2b44d53c7a5dc66cf1713bf --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics.ets.migrate.json @@ -0,0 +1,118 @@ +{ + "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": 60, + "column": 5, + "endLine": 60, + "endColumn": 15, + "problem": "DefiniteAssignmentError", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 26, + "endLine": 110, + "endColumn": 26, + "problem": "ArrayIndexExprType", + "suggest": "", + "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 6, + "endLine": 149, + "endColumn": 7, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 9, + "endLine": 155, + "endColumn": 20, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 9, + "endLine": 155, + "endColumn": 11, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 12, + "endLine": 155, + "endColumn": 15, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 1, + "endLine": 203, + "endColumn": 40, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 5, + "endLine": 205, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 205, + "column": 15, + "endLine": 205, + "endColumn": 24, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 42, + "endLine": 211, + "endColumn": 51, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics2.ets b/ets2panda/linter/test/main/numeric_semantics2.ets new file mode 100755 index 0000000000000000000000000000000000000000..0d76c6342ba9877b5d708b3b78d4bab902882bed --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.ets @@ -0,0 +1,126 @@ +/* + * 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 NumericSemanticsReport { + const a: number = 11 // NOT OK + const b = 12 // NOT OK + const c = 13.0 // NOT OK + const d: number = 14.0 + const e: number = 15 // NOT OK + console.log('' + 1/2) // NOT OK +} + +namespace NumericSemanticsDone { + const a: number = 11.0 + const b: number = 12.0 + const c: number = 13.0 + const d: number = 14.0 + const e: number = 15.0 + console.log('' + 1.0/2.0) +} + +namespace NoNumericSemantics { + interface X1 { "name": number, 2: number} + interface X2 { "name": number, _2: number} + let x: X1 = {"name": 20.0, 2: 30.0} // OK + console.log(x[2]); // OK + + let x_fix: X2 = {name: 20.0, _2: 20.0}; + + let x_non = {name: 20.0, 2: 20.0}; // OK + + const arr = [] + console.log(arr[2]); + + // Number bases + let c5: number = 0x123; // Hexadecimal + let c6: number = 0o123; // Octal + let c7: number = 0b101; // Binary + + let e1: number = 1e0; + let e2: number = 1E1; + let e3: number = 1e+1; + let e4: number = 1E-1; + let e5: number = +1e2; + let e6: number = -1E2; + + let h: number = arr[12. as int] + + enum E { + A = 1, + B = 2 + } +} + +namespace NumericSemanticsOther { + let e7: number = 1e4 + 11; +} + +namespace BeCareful { + `${1/2}` + +} + +namespace NoDiffInArk1_1To1_2 { + const a1 = `${1/2}` // NOT OK + const a2 = `${1.0/2.0}` + const b1 = `20${20 | 21 | 22 | 23}` // NOT OK + const b2 = `20${20.0 | 21.0 | 22.0 | 23.0}` + const c1 = `20 + ${20}` // NOT OK + const c2 = `20 + ${20.0}` + console.log(a1,a2,b1,b2,c1,c2) + + // Automatically delete decimal parts during bitwise operations + let e = 15 // NOT OK + let e1 = e & 3; // NOT OK + let e2 = e | 3; // NOT OK +} + +namespace GenericTypeCase { + function ReturnGenericNumber(a: T): T { + return a + } + + function ReturnGenericArry(a: T): T[] { + return [a] + } + + ReturnGenericNumber(1) // NOT OK, generic type is + ReturnGenericNumber(true ? 1 : 2) // NOT OK + ReturnGenericArry(1) // NOT OK + + function TestReturnGenericNumber(a: T[]): T[] { + return a.map(item => item) // OK, not report arkts-numeric-semantic + } + + function MapCase(a: number[]): number { + let groupNum: number = new Set(a.map(item => item)).size; // OK, not report arkts-numeric-semantic + return groupNum; + } + + function foo(v:T):T{return v} + foo(12)/24 // NOT OK + foo(12.0)/24 // NOT OK + + function foo1(v:T, u:U, b:boolean):T|U{ + return b ? v: u + } + foo1(12.0, 8, true)/24 // NOT OK + foo1(12.0, 8, false)/24 // NOT OK + + console.log(foo1(12/24, 8, true)) // NOT OK + console.log(foo1(12/24, 8, true)) // NOT OK + console.log(foo1(12.0/24.0, 8, true)) +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics2.ets.args.json b/ets2panda/linter/test/main/numeric_semantics2.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..b023016d6bc3b2713d4e02b6f765940828db476b --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.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/migrate/type_literals.ts.migrate.json b/ets2panda/linter/test/main/numeric_semantics2.ets.arkts2.json old mode 100644 new mode 100755 similarity index 33% rename from ets2panda/linter/test/migrate/type_literals.ts.migrate.json rename to ets2panda/linter/test/main/numeric_semantics2.ets.arkts2.json index bae2bb21043ca18828307c6d95970411b576e409..0b572f009af85043603d7fd6254a8a4ff384c34f --- a/ets2panda/linter/test/migrate/type_literals.ts.migrate.json +++ b/ets2panda/linter/test/main/numeric_semantics2.ets.arkts2.json @@ -1,643 +1,677 @@ { + "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": 14, - "endLine": 16, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 26, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { "line": 17, - "column": 14, + "column": 23, "endLine": 17, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "endColumn": 25, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { "line": 18, - "column": 14, + "column": 11, "endLine": 18, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "endColumn": 17, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 19, - "column": 22, - "endLine": 19, - "endColumn": 23, - "problem": "ObjectTypeLiteral", + "line": 18, + "column": 15, + "endLine": 18, + "endColumn": 17, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { "line": 19, - "column": 47, + "column": 11, "endLine": 19, - "endColumn": 48, - "problem": "ObjectTypeLiteral", + "endColumn": 19, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 20, - "column": 20, - "endLine": 20, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "line": 21, + "column": 23, + "endLine": 21, + "endColumn": 25, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 21, - "column": 14, - "endLine": 21, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "line": 22, + "column": 22, + "endLine": 22, + "endColumn": 23, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 24, - "column": 6, - "endLine": 24, - "endColumn": 7, - "problem": "ObjectTypeLiteral", + "line": 22, + "column": 24, + "endLine": 22, + "endColumn": 25, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 30, - "column": 21, - "endLine": 30, - "endColumn": 22, - "problem": "ObjectTypeLiteral", + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 30, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 32, - "column": 11, - "endLine": 32, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 23, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 32, - "column": 16, - "endLine": 32, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 25, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 33, - "column": 11, - "endLine": 33, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 26, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 33, + "line": 35, "column": 36, - "endLine": 33, + "endLine": 35, "endColumn": 37, - "problem": "ObjectLiteralNoContextType", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 34, - "column": 11, - "endLine": 34, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 36, + "column": 20, + "endLine": 36, + "endColumn": 26, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 35, - "column": 19, - "endLine": 35, - "endColumn": 20, - "problem": "ObjectTypeLiteral", + "line": 37, + "column": 18, + "endLine": 37, + "endColumn": 24, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 35, - "column": 44, - "endLine": 35, - "endColumn": 45, - "problem": "ObjectTypeLiteral", + "line": 37, + "column": 32, + "endLine": 37, + "endColumn": 33, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 36, - "column": 20, - "endLine": 36, + "line": 38, + "column": 17, + "endLine": 38, "endColumn": 21, - "problem": "ObjectTypeLiteral", + "problem": "PropertyAccessByIndex", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, { - "line": 37, - "column": 11, - "endLine": 37, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 42, + "column": 17, + "endLine": 42, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 40, - "column": 6, - "endLine": 40, - "endColumn": 7, - "problem": "ObjectTypeLiteral", + "line": 42, + "column": 30, + "endLine": 42, + "endColumn": 31, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", + "line": 68, + "column": 28, + "endLine": 68, + "endColumn": 30, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 48, - "column": 6, - "endLine": 48, - "endColumn": 7, - "problem": "ObjectLiteralNoContextType", + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 13, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 51, + "line": 72, "column": 8, - "endLine": 51, + "endLine": 72, "endColumn": 9, - "problem": "ObjectLiteralNoContextType", + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 58, - "column": 15, - "endLine": 58, - "endColumn": 16, - "problem": "ObjectTypeLiteral", + "line": 72, + "column": 10, + "endLine": 72, + "endColumn": 11, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 58, - "column": 40, - "endLine": 58, - "endColumn": 41, - "problem": "ObjectTypeLiteral", + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 35, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 59, - "column": 10, - "endLine": 59, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", + "line": 77, + "column": 19, + "endLine": 77, + "endColumn": 20, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 63, - "column": 6, - "endLine": 63, - "endColumn": 7, - "problem": "ObjectTypeLiteral", + "line": 77, + "column": 21, + "endLine": 77, + "endColumn": 22, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 63, - "column": 31, - "endLine": 63, - "endColumn": 32, - "problem": "ObjectLiteralNoContextType", + "line": 79, + "column": 21, + "endLine": 79, + "endColumn": 23, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 65, - "column": 8, - "endLine": 65, - "endColumn": 9, - "problem": "ObjectTypeLiteral", + "line": 79, + "column": 26, + "endLine": 79, + "endColumn": 28, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 65, - "column": 33, - "endLine": 65, - "endColumn": 34, - "problem": "ObjectTypeLiteral", + "line": 79, + "column": 31, + "endLine": 79, + "endColumn": 33, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 66, - "column": 12, - "endLine": 66, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 79, + "column": 36, + "endLine": 79, + "endColumn": 38, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 72, - "column": 22, - "endLine": 72, - "endColumn": 23, - "problem": "ObjectTypeLiteral", + "line": 81, + "column": 24, + "endLine": 81, + "endColumn": 26, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 73, - "column": 14, - "endLine": 73, + "line": 86, + "column": 9, + "endLine": 86, "endColumn": 15, - "problem": "ObjectTypeLiteral", + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 73, - "column": 38, - "endLine": 73, - "endColumn": 39, - "problem": "ObjectTypeLiteral", + "line": 86, + "column": 13, + "endLine": 86, + "endColumn": 15, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 75, - "column": 16, - "endLine": 75, - "endColumn": 17, - "problem": "ObjectTypeLiteral", + "line": 87, + "column": 9, + "endLine": 87, + "endColumn": 19, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 80, - "column": 3, - "endLine": 80, - "endColumn": 4, - "problem": "ObjectTypeLiteral", + "line": 87, + "column": 18, + "endLine": 87, + "endColumn": 19, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 80, - "column": 19, - "endLine": 80, - "endColumn": 20, - "problem": "ObjectLiteralNoContextType", + "line": 88, + "column": 9, + "endLine": 88, + "endColumn": 19, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 82, - "column": 20, - "endLine": 82, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "line": 88, + "column": 18, + "endLine": 88, + "endColumn": 19, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 85, - "column": 3, - "endLine": 85, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 100, + "column": 5, + "endLine": 100, + "endColumn": 27, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 93, - "column": 3, - "endLine": 93, - "endColumn": 23, - "problem": "CallSignature", + "line": 101, + "column": 5, + "endLine": 101, + "endColumn": 38, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 94, - "column": 3, - "endLine": 94, - "endColumn": 22, - "problem": "ConstructorType", + "line": 102, + "column": 5, + "endLine": 102, + "endColumn": 25, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 95, - "column": 3, - "endLine": 95, - "endColumn": 26, - "problem": "IndexMember", + "line": 114, + "column": 5, + "endLine": 114, + "endColumn": 15, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 95, - "column": 18, - "endLine": 95, - "endColumn": 25, - "problem": "UnknownType", + "line": 115, + "column": 5, + "endLine": 115, + "endColumn": 17, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 98, - "column": 18, - "endLine": 98, - "endColumn": 19, - "problem": "ObjectTypeLiteral", + "line": 120, + "column": 5, + "endLine": 120, + "endColumn": 27, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 101, - "column": 3, - "endLine": 101, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 121, + "column": 5, + "endLine": 121, + "endColumn": 28, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 109, - "column": 3, - "endLine": 109, - "endColumn": 23, - "problem": "CallSignature", + "line": 123, + "column": 5, + "endLine": 123, + "endColumn": 38, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 110, - "column": 3, - "endLine": 110, - "endColumn": 22, - "problem": "ConstructorType", + "line": 124, + "column": 5, + "endLine": 124, + "endColumn": 53, + "problem": "NonDeclarationInNamespace", "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", "severity": "ERROR" }, { - "line": 111, - "column": 3, - "endLine": 111, + "line": 125, + "column": 5, + "endLine": 125, + "endColumn": 57, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 25, + "endLine": 100, "endColumn": 26, - "problem": "IndexMember", + "problem": "NumericSemantics", "suggest": "", - "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 111, - "column": 18, - "endLine": 111, - "endColumn": 25, - "problem": "UnknownType", + "line": 101, + "column": 32, + "endLine": 101, + "endColumn": 33, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 115, - "column": 49, - "endLine": 115, - "endColumn": 50, - "problem": "ObjectTypeLiteral", + "line": 101, + "column": 36, + "endLine": 101, + "endColumn": 37, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 116, - "column": 11, - "endLine": 116, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 102, + "column": 23, + "endLine": 102, + "endColumn": 24, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 118, - "column": 20, - "endLine": 118, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "line": 109, + "column": 32, + "endLine": 109, + "endColumn": 60, + "problem": "GenericCallNoTypeArgs", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, { - "line": 119, - "column": 11, - "endLine": 119, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 114, + "column": 9, + "endLine": 114, + "endColumn": 11, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 119, - "column": 30, - "endLine": 119, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", + "line": 114, + "column": 13, + "endLine": 114, + "endColumn": 15, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 119, - "column": 34, - "endLine": 119, - "endColumn": 35, - "problem": "ObjectLiteralNoContextType", + "line": 115, + "column": 15, + "endLine": 115, + "endColumn": 17, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 121, - "column": 25, - "endLine": 121, - "endColumn": 26, - "problem": "ObjectTypeLiteral", + "line": 120, + "column": 16, + "endLine": 120, + "endColumn": 17, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 124, - "column": 11, - "endLine": 124, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 120, + "column": 25, + "endLine": 120, + "endColumn": 27, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 124, - "column": 12, - "endLine": 124, + "line": 121, + "column": 16, + "endLine": 121, "endColumn": 17, - "problem": "ComputedPropertyName", + "problem": "NumericSemantics", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 127, - "column": 11, - "endLine": 127, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 121, + "column": 26, + "endLine": 121, + "endColumn": 28, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 127, - "column": 31, - "endLine": 127, - "endColumn": 32, - "problem": "ObjectLiteralNoContextType", + "line": 123, + "column": 22, + "endLine": 123, + "endColumn": 24, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 129, - "column": 11, - "endLine": 129, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 123, + "column": 25, + "endLine": 123, + "endColumn": 27, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 129, - "column": 17, - "endLine": 129, - "endColumn": 23, - "problem": "TypeQuery", + "line": 123, + "column": 29, + "endLine": 123, + "endColumn": 30, + "problem": "NumericSemantics", "suggest": "", - "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 131, - "column": 11, - "endLine": 131, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 124, + "column": 37, + "endLine": 124, + "endColumn": 39, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 131, - "column": 17, - "endLine": 131, - "endColumn": 23, - "problem": "TypeQuery", + "line": 124, + "column": 40, + "endLine": 124, + "endColumn": 42, + "problem": "NumericSemantics", "suggest": "", - "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 133, - "column": 10, - "endLine": 133, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", + "line": 124, + "column": 44, + "endLine": 124, + "endColumn": 45, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 48, + "endLine": 125, + "endColumn": 49, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/numeric_semantics2.ets.autofix.json b/ets2panda/linter/test/main/numeric_semantics2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..e649323550046bb28030db18baa72b90cdfdd326 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.ets.autofix.json @@ -0,0 +1,1267 @@ +{ + "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": 5, + "endLine": 22, + "endColumn": 26, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 23, + "endLine": 17, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 678, + "end": 680, + "replacementText": "11.0", + "line": 17, + "column": 23, + "endLine": 17, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 702, + "end": 708, + "replacementText": "b: number = 12 // NOT OK\r\n", + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 15, + "endLine": 18, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 706, + "end": 708, + "replacementText": "12.0", + "line": 18, + "column": 15, + "endLine": 18, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 11, + "endLine": 19, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 730, + "end": 738, + "replacementText": "c: number = 13.0 // NOT OK\r\n", + "line": 19, + "column": 11, + "endLine": 19, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 23, + "endLine": 21, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 800, + "end": 802, + "replacementText": "15.0", + "line": 21, + "column": 23, + "endLine": 21, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 22, + "endLine": 22, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 835, + "end": 836, + "replacementText": "1.0", + "line": 22, + "column": 22, + "endLine": 22, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 24, + "endLine": 22, + "endColumn": 25, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 837, + "end": 838, + "replacementText": "2.0", + "line": 22, + "column": 24, + "endLine": 22, + "endColumn": 25 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 30, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 23, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 25, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 20, + "endLine": 35, + "endColumn": 26, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "name", + "start": 1117, + "end": 1123, + "line": 37, + "column": 18, + "endLine": 37, + "endColumn": 24 + }, + { + "replacementText": "name", + "start": 1210, + "end": 1216, + "line": 37, + "column": 18, + "endLine": 37, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 36, + "endLine": 35, + "endColumn": 37, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "__2", + "start": 1133, + "end": 1134, + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21 + }, + { + "replacementText": "__2", + "start": 1224, + "end": 1225, + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21 + }, + { + "replacementText": "x.__2", + "start": 1256, + "end": 1260, + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 20, + "endLine": 36, + "endColumn": 26, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "name", + "start": 1164, + "end": 1170, + "line": 36, + "column": 20, + "endLine": 36, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 18, + "endLine": 37, + "endColumn": 24, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "name", + "start": 1117, + "end": 1123, + "line": 37, + "column": 18, + "endLine": 37, + "endColumn": 24 + }, + { + "replacementText": "name", + "start": 1210, + "end": 1216, + "line": 37, + "column": 18, + "endLine": 37, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 32, + "endLine": 37, + "endColumn": 33, + "problem": "LiteralAsPropertyName", + "autofix": [ + { + "replacementText": "__2", + "start": 1133, + "end": 1134, + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21 + }, + { + "replacementText": "__2", + "start": 1224, + "end": 1225, + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21 + }, + { + "replacementText": "x.__2", + "start": 1256, + "end": 1260, + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21, + "problem": "PropertyAccessByIndex", + "autofix": [ + { + "replacementText": "__2", + "start": 1133, + "end": 1134, + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21 + }, + { + "replacementText": "__2", + "start": 1224, + "end": 1225, + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21 + }, + { + "replacementText": "x.__2", + "start": 1256, + "end": 1260, + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 17, + "endLine": 42, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 30, + "endLine": 42, + "endColumn": 31, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 28, + "endLine": 68, + "endColumn": 30, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1885, + "end": 1887, + "replacementText": "11.0", + "line": 68, + "column": 28, + "endLine": 68, + "endColumn": 30 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 13, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 8, + "endLine": 72, + "endColumn": 9, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1925, + "end": 1926, + "replacementText": "1.0", + "line": 72, + "column": 8, + "endLine": 72, + "endColumn": 9 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 10, + "endLine": 72, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1927, + "end": 1928, + "replacementText": "2.0", + "line": 72, + "column": 10, + "endLine": 72, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 35, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 19, + "endLine": 77, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1994, + "end": 1995, + "replacementText": "1.0", + "line": 77, + "column": 19, + "endLine": 77, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 21, + "endLine": 77, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1996, + "end": 1997, + "replacementText": "2.0", + "line": 77, + "column": 21, + "endLine": 77, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 21, + "endLine": 79, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2060, + "end": 2062, + "replacementText": "20.0", + "line": 79, + "column": 21, + "endLine": 79, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 26, + "endLine": 79, + "endColumn": 28, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2065, + "end": 2067, + "replacementText": "21.0", + "line": 79, + "column": 26, + "endLine": 79, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 31, + "endLine": 79, + "endColumn": 33, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2070, + "end": 2072, + "replacementText": "22.0", + "line": 79, + "column": 31, + "endLine": 79, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 36, + "endLine": 79, + "endColumn": 38, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2075, + "end": 2077, + "replacementText": "23.0", + "line": 79, + "column": 36, + "endLine": 79, + "endColumn": 38 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 24, + "endLine": 81, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2163, + "end": 2165, + "replacementText": "20.0", + "line": 81, + "column": 24, + "endLine": 81, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 9, + "endLine": 86, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2325, + "end": 2331, + "replacementText": "e: number = 15 // NOT OK\r\n", + "line": 86, + "column": 9, + "endLine": 86, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 13, + "endLine": 86, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2329, + "end": 2331, + "replacementText": "15.0", + "line": 86, + "column": 13, + "endLine": 86, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 9, + "endLine": 87, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2351, + "end": 2361, + "replacementText": "e1: number = e & 3", + "line": 87, + "column": 9, + "endLine": 87, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 18, + "endLine": 87, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2360, + "end": 2361, + "replacementText": "3.0", + "line": 87, + "column": 18, + "endLine": 87, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 9, + "endLine": 88, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2382, + "end": 2392, + "replacementText": "e2: number = e | 3", + "line": 88, + "column": 9, + "endLine": 88, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 18, + "endLine": 88, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2391, + "end": 2392, + "replacementText": "3.0", + "line": 88, + "column": 18, + "endLine": 88, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 5, + "endLine": 100, + "endColumn": 27, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 5, + "endLine": 101, + "endColumn": 38, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 5, + "endLine": 102, + "endColumn": 25, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 5, + "endLine": 114, + "endColumn": 15, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 5, + "endLine": 115, + "endColumn": 17, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 5, + "endLine": 120, + "endColumn": 27, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 5, + "endLine": 121, + "endColumn": 28, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 5, + "endLine": 123, + "endColumn": 38, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 5, + "endLine": 124, + "endColumn": 53, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 5, + "endLine": 125, + "endColumn": 57, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 25, + "endLine": 100, + "endColumn": 26, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2615, + "end": 2616, + "replacementText": "1.0", + "line": 100, + "column": 25, + "endLine": 100, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 32, + "endLine": 101, + "endColumn": 33, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2677, + "end": 2678, + "replacementText": "1.0", + "line": 101, + "column": 32, + "endLine": 101, + "endColumn": 33 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 36, + "endLine": 101, + "endColumn": 37, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2681, + "end": 2682, + "replacementText": "2.0", + "line": 101, + "column": 36, + "endLine": 101, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 23, + "endLine": 102, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2717, + "end": 2718, + "replacementText": "1.0", + "line": 102, + "column": 23, + "endLine": 102, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 32, + "endLine": 109, + "endColumn": 60, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 9, + "endLine": 114, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3109, + "end": 3111, + "replacementText": "12.0", + "line": 114, + "column": 9, + "endLine": 114, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 13, + "endLine": 114, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3113, + "end": 3115, + "replacementText": "24.0", + "line": 114, + "column": 13, + "endLine": 114, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 15, + "endLine": 115, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3141, + "end": 3143, + "replacementText": "24.0", + "line": 115, + "column": 15, + "endLine": 115, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 16, + "endLine": 120, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3254, + "end": 3255, + "replacementText": "8.0", + "line": 120, + "column": 16, + "endLine": 120, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 25, + "endLine": 120, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3263, + "end": 3265, + "replacementText": "24.0", + "line": 120, + "column": 25, + "endLine": 120, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 16, + "endLine": 121, + "endColumn": 17, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3292, + "end": 3293, + "replacementText": "8.0", + "line": 121, + "column": 16, + "endLine": 121, + "endColumn": 17 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 26, + "endLine": 121, + "endColumn": 28, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3302, + "end": 3304, + "replacementText": "24.0", + "line": 121, + "column": 26, + "endLine": 121, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 22, + "endLine": 123, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3339, + "end": 3341, + "replacementText": "12.0", + "line": 123, + "column": 22, + "endLine": 123, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 25, + "endLine": 123, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3342, + "end": 3344, + "replacementText": "24.0", + "line": 123, + "column": 25, + "endLine": 123, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 29, + "endLine": 123, + "endColumn": 30, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3346, + "end": 3347, + "replacementText": "8.0", + "line": 123, + "column": 29, + "endLine": 123, + "endColumn": 30 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 37, + "endLine": 124, + "endColumn": 39, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3403, + "end": 3405, + "replacementText": "12.0", + "line": 124, + "column": 37, + "endLine": 124, + "endColumn": 39 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 40, + "endLine": 124, + "endColumn": 42, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3406, + "end": 3408, + "replacementText": "24.0", + "line": 124, + "column": 40, + "endLine": 124, + "endColumn": 42 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 44, + "endLine": 124, + "endColumn": 45, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3410, + "end": 3411, + "replacementText": "8.0", + "line": 124, + "column": 44, + "endLine": 124, + "endColumn": 45 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 48, + "endLine": 125, + "endColumn": 49, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3478, + "end": 3479, + "replacementText": "8.0", + "line": 125, + "column": 48, + "endLine": 125, + "endColumn": 49 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics2.ets.json b/ets2panda/linter/test/main/numeric_semantics2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..af8a3e440fd6719874e75c8e07504feac3577cd7 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.ets.json @@ -0,0 +1,228 @@ +{ + "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": 5, + "endLine": 22, + "endColumn": 26, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 30, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 23, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 25, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 36, + "endLine": 35, + "endColumn": 37, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 32, + "endLine": 37, + "endColumn": 33, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 17, + "endLine": 38, + "endColumn": 21, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 17, + "endLine": 42, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 30, + "endLine": 42, + "endColumn": 31, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 13, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 83, + "column": 5, + "endLine": 83, + "endColumn": 35, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 100, + "column": 5, + "endLine": 100, + "endColumn": 27, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 5, + "endLine": 101, + "endColumn": 38, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 5, + "endLine": 102, + "endColumn": 25, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 5, + "endLine": 114, + "endColumn": 15, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 5, + "endLine": 115, + "endColumn": 17, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 5, + "endLine": 120, + "endColumn": 27, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 5, + "endLine": 121, + "endColumn": 28, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 5, + "endLine": 123, + "endColumn": 38, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 5, + "endLine": 124, + "endColumn": 53, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 5, + "endLine": 125, + "endColumn": 57, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics2.ets.migrate.ets b/ets2panda/linter/test/main/numeric_semantics2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..db5e2adfbe6a5554f1cd828d4ddf012da092cd75 --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.ets.migrate.ets @@ -0,0 +1,129 @@ +/* + * 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 NumericSemanticsReport { + const a: number = 11.0 // NOT OK + const b: number = 12.0 // NOT OK + // NOT OK + const c: number = 13.0 // NOT OK + // NOT OK + const d: number = 14.0 + const e: number = 15.0 // NOT OK + console.log('' + 1.0/2.0) // NOT OK +} + +namespace NumericSemanticsDone { + const a: number = 11.0 + const b: number = 12.0 + const c: number = 13.0 + const d: number = 14.0 + const e: number = 15.0 + console.log('' + 1.0/2.0) +} + +namespace NoNumericSemantics { + interface X1 { name: number, __2: number} + interface X2 { name: number, _2: number} + let x: X1 = {name: 20.0, __2: 30.0} // OK + console.log(x.__2); // OK + + let x_fix: X2 = {name: 20.0, _2: 20.0}; + + let x_non = {name: 20.0, 2: 20.0}; // OK + + const arr = [] + console.log(arr[2]); + + // Number bases + let c5: number = 0x123; // Hexadecimal + let c6: number = 0o123; // Octal + let c7: number = 0b101; // Binary + + let e1: number = 1e0; + let e2: number = 1E1; + let e3: number = 1e+1; + let e4: number = 1E-1; + let e5: number = +1e2; + let e6: number = -1E2; + + let h: number = arr[12. as int] + + enum E { + A = 1, + B = 2 + } +} + +namespace NumericSemanticsOther { + let e7: number = 1e4 + 11.0; +} + +namespace BeCareful { + `${1.0/2.0}` + +} + +namespace NoDiffInArk1_1To1_2 { + const a1 = `${1.0/2.0}` // NOT OK + const a2 = `${1.0/2.0}` + const b1 = `20${20.0 | 21.0 | 22.0 | 23.0}` // NOT OK + const b2 = `20${20.0 | 21.0 | 22.0 | 23.0}` + const c1 = `20 + ${20.0}` // NOT OK + const c2 = `20 + ${20.0}` + console.log(a1,a2,b1,b2,c1,c2) + + // Automatically delete decimal parts during bitwise operations + let e: number = 15.0 // NOT OK + // NOT OK + let e1: number = e & 3.0; // NOT OK + let e2: number = e | 3.0; // NOT OK +} + +namespace GenericTypeCase { + function ReturnGenericNumber(a: T): T { + return a + } + + function ReturnGenericArry(a: T): T[] { + return [a] + } + + ReturnGenericNumber(1.0) // NOT OK, generic type is + ReturnGenericNumber(true ? 1.0 : 2.0) // NOT OK + ReturnGenericArry(1.0) // NOT OK + + function TestReturnGenericNumber(a: T[]): T[] { + return a.map(item => item) // OK, not report arkts-numeric-semantic + } + + function MapCase(a: number[]): number { + let groupNum: number = new Set(a.map(item => item)).size; // OK, not report arkts-numeric-semantic + return groupNum; + } + + function foo(v:T):T{return v} + foo(12.0)/24.0 // NOT OK + foo(12.0)/24.0 // NOT OK + + function foo1(v:T, u:U, b:boolean):T|U{ + return b ? v: u + } + foo1(12.0, 8.0, true)/24.0 // NOT OK + foo1(12.0, 8.0, false)/24.0 // NOT OK + + console.log(foo1(12.0/24.0, 8.0, true)) // NOT OK + console.log(foo1(12.0/24.0, 8.0, true)) // NOT OK + console.log(foo1(12.0/24.0, 8.0, true)) +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/numeric_semantics2.ets.migrate.json b/ets2panda/linter/test/main/numeric_semantics2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..2b4699fa61f8fc34e602920f4759be0300caa0ae --- /dev/null +++ b/ets2panda/linter/test/main/numeric_semantics2.ets.migrate.json @@ -0,0 +1,208 @@ +{ + "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": 24, + "column": 5, + "endLine": 24, + "endColumn": 30, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 30, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 24, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 25, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 17, + "endLine": 44, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 30, + "endLine": 44, + "endColumn": 31, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 5, + "endLine": 74, + "endColumn": 17, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 35, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 5, + "endLine": 103, + "endColumn": 29, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 5, + "endLine": 104, + "endColumn": 42, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 5, + "endLine": 105, + "endColumn": 27, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 5, + "endLine": 117, + "endColumn": 19, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 118, + "column": 5, + "endLine": 118, + "endColumn": 19, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 5, + "endLine": 123, + "endColumn": 31, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 5, + "endLine": 124, + "endColumn": 32, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 5, + "endLine": 126, + "endColumn": 44, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 5, + "endLine": 127, + "endColumn": 59, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 5, + "endLine": 128, + "endColumn": 59, + "problem": "NonDeclarationInNamespace", + "suggest": "", + "rule": "Non-declaration statements in namespaces are not supported (single semicolons are considered as empty non-declaration statements) (arkts-no-ns-statements)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 32, + "endLine": 112, + "endColumn": 60, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals.ets.args.json b/ets2panda/linter/test/main/object_literals.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals.ets.args.json +++ b/ets2panda/linter/test/main/object_literals.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals.ets.migrate.ets b/ets2panda/linter/test/main/object_literals.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..7ae3763807c7b47563a5e35b16254919cc09c93b --- /dev/null +++ b/ets2panda/linter/test/main/object_literals.ets.migrate.ets @@ -0,0 +1,293 @@ +/* + * 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. + */ +import {ohFunction1, ohFunction2, OhosI} from './oh_modules/ohos_lib' +interface I { + a: number; + b: string; +} + +class C { + a: number; + b: string; +} + +interface GeneratedTypeLiteralInterface_1 { + x: number; + y: string; +} +class C2 { + q: GeneratedTypeLiteralInterface_1; + w: any; + e: I; + r: C; +} + +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_2 { + a: number; + b: string; +} +function localVariable(): void { + // Declaration + let a1: GeneratedObjectLiteralInterface_1 = { a: 1, b: 'a' }; // NOT OK + let a2: any = { a: 2, b: 'b' }; // OK - ASSIGNMENT TO ANY + let a3: GeneratedTypeLiteralInterface_2 = { a: 30, b: 'c' }; // NOT OK + let a4: I = { a: 4, b: 'd' }; // OK + let a5: C = { a: 5, b: 'e' }; // OK + let a6: C2 = { + // OK + q: { x: 6, y: 'f' }, // NOT OK + w: { a: 7, b: 'g' }, // OK - ASSIGNMENT TO ANY + e: { a: 8, b: 'h' }, // OK + r: { a: 9, b: 'i' }, // OK + }; + + // Assignment + a1 = { a: 11, b: 'a' }; // NOT OK + a2 = { a: 12, b: 'b' }; // OK - ASSIGNMENT TO ANY + a3 = { a: 13, b: 'c' }; // NOT OK + a4 = { a: 14, b: 'd' }; // OK + a5 = { a: 15, b: 'e' }; // OK + a6 = { + // OK + q: { x: 16, y: 'f' }, // NOT OK + w: { a: 17, b: 'g' }, // OK - ASSIGNMENT TO ANY + e: { a: 18, b: 'h' }, // OK + r: { a: 19, b: 'i' }, // OK + }; +} + +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_3 { + a: number; + b: string; +} +function defaultParamValue(): void { + function foo(x: GeneratedObjectLiteralInterface_2 = { a: 21, b: 'a' }) { + console.log(x.a, x.b); + } // NOT OK + function foo2(x: any = { a: 22, b: 'b' }) { + console.log(x.a, x.b); + } // NOT OK + function foo3(x: GeneratedTypeLiteralInterface_3 = { a: 23, b: 'c' }) { + console.log(x.a, x.b); + } // NOT OK + function foo4(x: I = { a: 24, b: 'd' }) { + console.log(x.a, x.b); + } // OK + function foo5(x: C = { a: 25, b: 'e' }) { + console.log(x.a, x.b); + } // OK + + // Function call + foo({ a: 21, b: 'a' }); // NOT OK + foo2({ a: 22, b: 'b' }); // OK - ASSIGNMENT TO ANY + foo3({ a: 23, b: 'c' }); // NOT OK + foo4({ a: 24, b: 'd' }); // OK + foo5({ a: 25, b: 'e' }); // OK +} + +interface GeneratedObjectLiteralInterface_3 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_4 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_5 { + a: number; + b: string; +} +function returnFromFunction(): void { + function bar() { + return ({ a: 31, b: 'a' } as GeneratedObjectLiteralInterface_3); + } // NOT OK + let bar2: () => any = (): any => { + return { a: 32, b: 'b' }; +}; // OK - ASSIGNMENT TO ANY + let bar3: () => GeneratedTypeLiteralInterface_4 = (): GeneratedTypeLiteralInterface_5 => { + return { a: 33, b: 'c' }; +}; // NOT OK + let bar4: () => I = (): I => { + return { a: 34, b: 'd' }; +}; // OK + let bar5: () => C = (): C => { + return { a: 35, b: 'e' }; +}; // OK +} + +interface GeneratedObjectLiteralInterface_4 { + a: number; + b: string; +} +interface GeneratedObjectLiteralInterface_5 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_6 { + a: number; + b: string; +} +function ternaryOperator(): void { + // In ternary operator + const condition = true; + const a1 = condition ? ({ a: 41, b: 'a' } as GeneratedObjectLiteralInterface_4) : ({ a: 42, b: 'b' } as GeneratedObjectLiteralInterface_5); // NOT OK + const a2: any = condition ? { a: 43, b: 'c' } : { a: 44, b: 'd' }; // OK - ASSIGNMENT TO ANY + const a3: GeneratedTypeLiteralInterface_6 = condition + ? { a: 45, b: 'e' } + : { a: 46, b: 'f' }; // NOT OK + const a4: I = condition ? { a: 47, b: 'g' } : { a: 48, b: 'h' }; // OK + const a5: C = condition ? { a: 49, b: 'i' } : { a: 50, b: 'j' }; // OK +} + +interface GeneratedObjectLiteralInterface_6 { + a: number; + b: string; +} +interface GeneratedObjectLiteralInterface_7 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_7 { + a: number; + b: string; +} +function arrayLiteral(): void { + const arr1 = [ + ({ a: 51, b: 'a' } as GeneratedObjectLiteralInterface_6), + ({ a: 52, b: 'b' } as GeneratedObjectLiteralInterface_7), + ]; // NOT OK + const arr2: any[] = [ + { a: 53, b: 'c' }, + { a: 54, b: 'd' }, + ]; // OK - ASSIGNMENT TO ANY + const arr3: GeneratedTypeLiteralInterface_7[] = [ + { a: 55, b: 'e' }, + { a: 56, b: 'f' }, + ]; // NOT OK + const arr4: I[] = [ + { a: 57, b: 'g' }, + { a: 58, b: 'h' }, + ]; // OK + const arr5: C[] = [ + { a: 59, b: 'i' }, + { a: 60, b: 'j' }, + ]; // OK +} + +enum E { + OK, + NO_OK, +} +interface I1 { + v: E | number +} + +interface I2 { + v: E +} + +let i1: I1 = {v:E.OK} +let i2: I2 = {v:E.NO_OK} + +function g1(a: E) { + let ii1: I1 = {v:a} + let ii2: I2 = {v:a} +} + +function g(): boolean { + return true; +} +interface CondI { + a: number; +} +let a1: CondI = { + a: g() ? 0 : 1, +}; +let b1: CondI = { + a: (g() ? 0 : 1) as number, +}; +let c1 = g() ? 0 : 1; +let d1: CondI = { + a: c1, +}; +let e1: CondI = { +a: 0|1|2|3 +} +let f1: 0|1|2|3 = 3 +let ff : CondI = { + a: f1 +} + +let dict = new Map(); +dict.set('1', 123) + +interface III { + param?: string | number | boolean +} + +let test1: III = { param: dict.get('1') } as III +let test2: III = { param: dict.get('1')! } as III +let test3: III = { param: dict.get('1') as number } as III +let test4: III = { param: dict.get('1') as (number | string) } as III +export interface Style { +} +export class SwitchMenuStyle implements Style { +} +export class ProfileOneLineSwitchMenuStyle extends SwitchMenuStyle { +} +export class ProfileSwitchMenuStyle extends SwitchMenuStyle { +} +export let hfpProfileSwitchMenuStyle = new ProfileSwitchMenuStyle(); +export let hfpProfileOneLineSwitchMenuStyle = new ProfileOneLineSwitchMenuStyle(); + +export interface SettingsBaseMenuData { + style?: Style; +} + +function test(isDisConnected:boolean){ + let a={style: isDisConnected ? hfpProfileOneLineSwitchMenuStyle: hfpProfileSwitchMenuStyle} as SettingsBaseMenuData +} + +interface PPP { + x: number + y: number | undefined + z?: number +} + +let p1: PPP = {x: 10, y: 10} +let p2: PPP = {x: 10, y: undefined} +let p3: PPP = {x: 10, y: undefined, z: undefined} +let p4: PPP = {x: 10, y: undefined, z: 10} +let p5: PPP = {x: 10, y: 10, z: 10} +const cp1: PPP = {x: 10, y: 10} +const cp2: PPP = {x: 10, y: undefined} +const cp3: PPP = {x: 10, y: undefined, z: undefined} +const cp4: PPP = {x: 10, y: undefined, z: 10} +const cp5: PPP = {x: 10, y: 10, z: 10} + +const oi: OhosI = { f: 1 }; + +ohFunction1({d: oi}) +ohFunction1({d: {f: 1}}) +ohFunction2({d: oi}) +ohFunction2({d: {f: 1}}) diff --git a/ets2panda/linter/test/main/object_literals.ets.migrate.json b/ets2panda/linter/test/main/object_literals.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..a227223d64e4327ea0f2bd8d30cd531afce603cc --- /dev/null +++ b/ets2panda/linter/test/main/object_literals.ets.migrate.json @@ -0,0 +1,198 @@ +{ + "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": 32, + "column": 6, + "endLine": 32, + "endColumn": 9, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 11, + "endLine": 48, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 3, + "endLine": 84, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 3, + "endLine": 87, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 20, + "endLine": 87, + "endColumn": 23, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 3, + "endLine": 90, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 3, + "endLine": 93, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 3, + "endLine": 96, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 11, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 19, + "endLine": 124, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 29, + "endLine": 124, + "endColumn": 32, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 13, + "endLine": 154, + "endColumn": 16, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 15, + "endLine": 179, + "endColumn": 18, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'q' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'q' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 33, + "column": 3, + "endLine": 33, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'e' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'e' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'r' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'r' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_2.ets.args.json b/ets2panda/linter/test/main/object_literals_2.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_2.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_2.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_2.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1b08cb786e6c0f1b7e99342d223ee6ea7eb686e4 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_2.ets.migrate.ets @@ -0,0 +1,289 @@ +/* + * 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. + */ + +interface GeneratedObjectLiteralInterface_1 { + n: number; + s: string; +} +let obj: GeneratedObjectLiteralInterface_1 = {n: 42, s: 'foo'} // OK in TypeScript, CTE in ArkTS: unknown type of obj. + +class C { + n: number = 0; + s: string = ""; +} + +let c1: C = {n: 42, s: 'foo'} // Declaration + initialization: type of the literla is inferred from the type of c1. + +let c2: C; +c2 = {n: 42, s: 'foo'}; // Initialization after declaration: type of the literal is inferred from the type of c2. + +let c3: Object = {n: 42, s: 'foo'} as C as Object; // Type of the literal is inferred from the 'as' cast. +console.log(c3 instanceof C); // NB! Output is true in ArkTS, but is false in TS. + +function foo(c: C) { + console.log('foo is called'); +} + +foo({n: 42, s: 'foo'}); // Parsing as an argument: type of the literal is inferred from the type of parameter 'c' + +function bar(): C { + return {n: 42, s: 'foo'}; // Returning from function: type of the literal is inferred from the bar's return type. +} + +let cc: C[] = [{n: 1, s: '1'}, {n: 2, s: '2'}]; // Type of the literal is inferred from the type of the array. + +class D { + b: boolean = false; + c: C = {n: 0, s: ""}; +} + +let d: D = { + b: true, + c: { // Initialization of a field with a literal: type of the literal is inferred from the definition of class D. + n: 42, + s: 'foo' + } +} + +// Restrictions of classes that can be initialized with literal +// Default initializable class. +class C1 { + n: number = 0; + s?: string; +} + +let c4: C1 = {n: 42}; // OK in TS, OK in ArkTS, c.s is null + +class C2 { + s: string; + constructor(s: string) { + this.s = "s = " + s; + } +} + +let c5: C2 = {s: 'foo'} // OK in TS, CTE in ArkTS + +// All class fields are accessible at the point of initialization. +class C3 { + private n: number = 0; + public s: string = ''; +} + +// CTE in TypeScript, CTE in ArkTS // let c6: C3 = {n: 42, s: 'foo'}, + +class C4 { + readonly n: number = 0; + readonly s: string = ''; +} + +let c7: C4 = {n: 42, s: 'foo'}; // OK in TS, CTE in ArkTS + +// Class is non-abstract +abstract class A {} +let a: A = {}; // OK in TS, CTE in ArkTS + +// Class declares no methods, apart from optionally declared constructors and setters. +class C5 { + n: number = 0; + s: string = ''; + f() { + console.log('C5.f is called'); + } +} + +let c8: C5 = {n: 42, s: 'foo', f: () => {}} // OK in TS, CTE in ArkTS + +// NB! If a class has getters/setters the semantics of initialization differs: +class C6 { + n: number = 0; + _s: string = ''; + get s(): string { return this._s; } + set s(s: string) { this._s = s; } +} + +let c9: C6 = {n: 42, _s: 'foo', s: 'bar'} +console.log(c9.s); // TS: 'bar', ArkTS: 'bar' +console.log(c9._s); // TS: 'foo', ArkTS: 'bar' + +// Extra fields are not allowed (eventually it means that it's not possible to assign literals to Object / object): +class C7 { + n: number = 0; + s: string = ''; +} +// TS: CTE, ArtTS: CTE // let c10: C7 = {n: 42, s: '', extra: true}, +let o1: Object = {s: '', n: 42} // OK in TS, CTE in ArkTS: no fields 'n' and 's' in Object +let o2: object = {n: 42, s: ''} // OK in TS, CTE in ArkTS: no fields 'n' and 's' in object + +// If initialized class is inherited from another class, the base class must also be literal-initializable, +// and initialization should happen from the 'glattened' literal: +class Base { + n: number = 0; +} + +class Derived extends Base { + s: string = ''; +} + +let d2: Derived = {n: 42, s: ''}; + +// Interface should not declare methods, only properties are allowed. +interface I { + n: number; + s: string; + f(): void; +} + +let i: I = {n: 42, s: '', f: () => {console.log('I.f is called')}} // OK in TypeScript, CTE in ArkTS + +// Interface properties of reference types must be default-initializable: +interface I2 { + n: number; + s: string; // Assuming that 'string' is an alias for 'String', and there is String() constructor (what is true). +} + +let i2: I2 = {n: 42, s: ''}; + +interface CompilerOptions { + strict?: boolean; + sourcePath?: string; + targetPath?: string; +} + +const options: CompilerOptions = { // OK, as 'targetPath' field is optional + strict: true, + sourcePath: './src', +}; + +// Function parameter with union type. +function funcWithUnionParam(x: C | number): void { } +funcWithUnionParam({ n: 1, s: '2' }) // OK, union type is supported + +// issue 13022: property with union type +class UnionProperty { + a: number | string = 123; + b?: boolean | number; +} +let u: UnionProperty = { a: 1 }; // OK, union type is supported +u = { a: '2' }; // OK, union type is supported +u = { a: 3, b: true }; // OK, union type is supported + +// issue 13022: optional property +class OptionalProp { + a?: number; +} +let o: OptionalProp = {}; +o = {a: 1}; // OK + +class OptionalProp2 { + a?: number; + b: string; +} +function optProp(a: OptionalProp2) {} +optProp({b: ''}); // OK +optProp({a: 0, b: '1'}); // OK + +// Property with inheritance +class E1 { + x: number; + y: Base; +} +let e1 : E1 = { + x: 1, + y: new Derived() +} + +// Property with inheritance through generic type parameter +class E2 { + x: number; + y: T; +} +let e2 : E2 = { + x: 1, + y: new Derived() +} + +// Type alias chain to interface +interface ITypeAlias { a: number; b: T } +type ITA = ITypeAlias; +type ITA2 = ITA; +let ti: ITA2 = { // OK, 'ITA2' is an alias to interface 'ITypeAlias' + a: 12, + b: '34' +} + +// Type alias chain to class +class CTypeAlias { + a: number; + b: T; +} +type CTA = CTypeAlias; +type CTA2 = CTA; +let tc: CTA2 = { // OK, 'CTA' is an alias to class 'CTypeAlias' + a: 4, + b: '4' +} + +// issue 13114: Const enum value converted to string/number type. +const enum ATTRIBUTE { + ROW = 'Row', + COLUMN = 'Column', + COLUMN_REVERSE = 'ColumnReverse', +}; +const enum GROUP { + MAIN_DIRECTION = 'MAIN_DIRECTION', +}; +enum Orientation { + Horizontal, + Vertical +} +class ContainerModuleItem { + groupName: string = ''; + attributeList: string[] = []; + attribute: ATTRIBUTE = ATTRIBUTE.COLUMN; + orientation: number = 0; +} +const FLEX_MODULE: ContainerModuleItem[] = [ + { + groupName: GROUP.MAIN_DIRECTION, + attributeList: [ATTRIBUTE.COLUMN, ATTRIBUTE.ROW, ATTRIBUTE.COLUMN_REVERSE], + attribute: ATTRIBUTE.ROW, + orientation: Orientation.Horizontal + } +]; + +interface I3 {} + +class CCl implements I3 {} + +class CCl2 extends CCl implements I3 {} + +interface I4 { + a: I3; + b: I3; + c: CCl; + d: CCl2; +} + +class DCl { + constructor(a: I4) {} +} + +let c: I4 = {a: new CCl(), b: new CCl2(), c: new CCl2(), d: new CCl2()} + +new DCl({a: new CCl(), b: new CCl2(), c: new CCl2(), d: new CCl2()}) + +let oo1: Object = {} + +let oo2: Object = {a: 12} diff --git a/ets2panda/linter/test/main/object_literals_2.ets.migrate.json b/ets2panda/linter/test/main/object_literals_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..9d29201f6c1b9039667cfe207f1aaf9ac2a1090a --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_2.ets.migrate.json @@ -0,0 +1,178 @@ +{ + "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": 76, + "column": 14, + "endLine": 76, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 14, + "endLine": 91, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 12, + "endLine": 95, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 14, + "endLine": 106, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 18, + "endLine": 126, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 18, + "endLine": 127, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 12, + "endLine": 148, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 19, + "endLine": 287, + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 289, + "column": 19, + "endLine": 289, + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 191, + "column": 5, + "endLine": 191, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 199, + "column": 3, + "endLine": 199, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'x' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'x' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 200, + "column": 3, + "endLine": 200, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'y' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'y' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 209, + "column": 3, + "endLine": 209, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'x' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'x' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 210, + "column": 3, + "endLine": 210, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'y' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'y' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 228, + "column": 5, + "endLine": 228, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 229, + "column": 5, + "endLine": 229, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_3.ets.args.json b/ets2panda/linter/test/main/object_literals_3.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_3.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_3.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_3.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..bce9e88fa1a7909ef4454eb93ee89fe432b527bf --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_3.ets.migrate.ets @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2023-2024 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 GeneratedObjectLiteralInterface_1 { +} +const test1: GeneratedObjectLiteralInterface_1 = {} + +interface GeneratedObjectLiteralInterface_2 { + hello: string; +} +const test2: GeneratedObjectLiteralInterface_2 = { hello: "world" }; + +interface GeneratedTypeLiteralInterface_1 { +} +let test3:GeneratedTypeLiteralInterface_1 = {}; + +interface GeneratedObjectLiteralInterface_3 { + field: string; + field1: string; + field2: string; + field3: string; + field4: string; + field5: string; + field6: string; +} +const test4: GeneratedObjectLiteralInterface_3 = { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7", + }; + +interface GeneratedObjectLiteralInterface_4 { + field: number; + field1: number; + field2: number; + field3: number; + field4: number; + field5: number; + field6: number; +} +const test5: GeneratedObjectLiteralInterface_4 = { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +interface GeneratedObjectLiteralInterface_5 { + field: string; + field1: number; + field2: string; + field3: number; + field4: string; + field5: number; + field6: string; + field7: boolean; + field8: boolean; +} +const test6: GeneratedObjectLiteralInterface_5 = { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +interface test7 { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7" + }; + +interface test8 { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +interface test9 { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +const test10:object = { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7", + }; + +const test11:object = { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +const test12:object = { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +const test13:object = { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7", + }; + +const test14:object = { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +const test15:object = { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +interface GeneratedTypeLiteralInterface_2 { + field: String; + field1: String; + field2: String; + field3: String; + field4: String; + field5: String; + field6: String; +} +let test16:GeneratedTypeLiteralInterface_2 = { + field: "world", + field1: "hello2", + field2: "hello3", + field3: "hello4", + field4: "hello5", + field5: "hello6", + field6: "hello7", + }; + +interface GeneratedTypeLiteralInterface_3 { + field: number; + field1: number; + field2: number; + field3: number; + field4: number; + field5: number; + field6: number; +} +let test17:GeneratedTypeLiteralInterface_3 = { + field: 1, + field1: 2, + field2: 3, + field3: 4, + field4: 5, + field5: 6, + field6: 7, + }; + +interface GeneratedTypeLiteralInterface_4 { + field: String; + field1: number; + field2: String; + field3: number; + field4: String; + field5: number; + field6: String; + field7: boolean; + field8: boolean; +} +let test18:GeneratedTypeLiteralInterface_4 = { + field: "world", + field1: 2, + field2: "hello3", + field3: 4, + field4: "hello5", + field5: 6, + field6: "hello7", + field7: true, + field8: false + }; + +const test19:Record = { + "field": "world", + "field1": "hello2", + "field2": "hello3", + "field3": "hello4", + "field4": "hello5", + "field5": "hello6", + "field6": "hello7", + }; + +const test20:Record = { + "field": 1, + "field1": 2, + "field2": 3, + "field3": 4, + "field4": 5, + "field5": 6, + "field6": 7, + }; + +const test21:Record = { + "field": "world", + "field1": 2, + "field2": "hello3", + "field3": 4, + "field4": "hello5", + "field5": 6, + "field6": "hello7", + "field7": true, + "field8": false + }; \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_3.ets.migrate.json b/ets2panda/linter/test/main/object_literals_3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..69a3046345e42be615adc2be914a29c54ece744f --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_3.ets.migrate.json @@ -0,0 +1,78 @@ +{ + "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": 122, + "column": 23, + "endLine": 122, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 23, + "endLine": 132, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 23, + "endLine": 142, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 23, + "endLine": 154, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 23, + "endLine": 164, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 174, + "column": 23, + "endLine": 174, + "endColumn": 24, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_4.ets.args.json b/ets2panda/linter/test/main/object_literals_4.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_4.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_4.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_4.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_4.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..19e21b00c1b27f394376f2093fa5778f975e8b37 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_4.ets.migrate.ets @@ -0,0 +1,73 @@ +/* + * 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. + */ + +type T = () => void + +class A { + foo?: T + bar?: Function +} + +let a: A = { + foo: () => { + console.log("Hello") + }, + bar: () => { + console.log("Hello") + } +} + +//====================== +class Resource{} + +class ContainerModuleItem { + groupName: string = ""; + moduleName: Resource | null = null; + atributeList: string[] = []; +} + +const FLEX_MODULE: ContainerModuleItem[] = [{ + groupName: GROUP.MAIN_DIRECTION, + moduleName: "ASF", + atributeList: [ATTRIBUTE.COLUMN, ATTRIBUTE.ROW, ATTRIBUTE.COLUMN_REVERSE], +}] + +const enum ATTRIBUTE { + ROW = 'Row', + COLUMN = 'Column', + COLUMN_REVERSE = 'ColumnReverse' +} + +const enum GROUP { + MAIN_DIRECTION = 'MAIN_DIRECTION' +} + +//==================================== + +class C { + s: string = "" + n: number = 0 + l: () => void = () => {} +} + +let c : C = { + s: "foo", + n: 42, + l: () => { + console.log("Hi") + } +} + +c.l() \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_4.ets.migrate.json b/ets2panda/linter/test/main/object_literals_4.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_4.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 diff --git a/ets2panda/linter/test/main/object_literals_autofixes.ets b/ets2panda/linter/test/main/object_literals_autofixes.ets index 87814c7da5d5feafdf064a64253db60213519298..9bc2be4e2f61d64ec487b21f7b3ab8e7b6a5ec50 100644 --- a/ets2panda/linter/test/main/object_literals_autofixes.ets +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets @@ -102,7 +102,7 @@ function bar(): void { let d = {g: 7, d: foo({q:1,w:2}.q + {q:3,w:4}.w)}; } -const o9 = { 1: '1', '2': 2 }; +const o9 = { 1: '1', '2': 2 }; // Not fixable, property name is string/numeric literal const o10 = { [3]: 3 }; // Not fixable, computed property value const o11 = { [o2.hello]: 'world' }; // Not fixable, computed property value @@ -110,9 +110,9 @@ const anyVal: any = 1; const o12 = { a: anyVal }; // Not fixable, type of property 'a' is not supported let val = 1; -const o13 = { val }; // Not fixable, property is not 'key:value' pair +const o13 = { val }; // Fixable const o14 = { ...o1 }; // Not fixable, property is not 'key:value' pair -const o15 = { m() {} }; // Not fixable, property is not 'key:value' pair +const o15 = { m() {} }; // Fixable const o16 = { // Not fixable, property 'c' is initialized with non-fixable nested object literal, and thus will always have unsupported type (object type literal) a: 1, diff --git a/ets2panda/linter/test/main/object_literals_autofixes.ets.args.json b/ets2panda/linter/test/main/object_literals_autofixes.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_autofixes.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json b/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json index e139fc2d4af9bcea40ce57baac617c7ade95eb33..5f107cd9acf91e6c0e34bb23e215062f712baa54 100644 --- a/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.autofix.json @@ -738,18 +738,6 @@ "endLine": 105, "endColumn": 13, "problem": "ObjectLiteralNoContextType", - "autofix": [ - { - "start": 2600, - "end": 2600, - "replacementText": "interface GeneratedObjectLiteralInterface_37 {\n 1: string;\n '2': number;\n}\n" - }, - { - "start": 2608, - "end": 2608, - "replacementText": ": GeneratedObjectLiteralInterface_37" - } - ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" @@ -860,6 +848,18 @@ "endLine": 115, "endColumn": 14, "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 3051, + "end": 3051, + "replacementText": "class GeneratedObjectLiteralClass_1 {\n m() { }\n}\n\n" + }, + { + "start": 3063, + "end": 3073, + "replacementText": "new GeneratedObjectLiteralClass_1()" + } + ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" @@ -922,8 +922,8 @@ "problem": "ObjectTypeLiteral", "autofix": [ { - "start": 3779, - "end": 3819, + "start": 3759, + "end": 3799, "replacementText": "interface LocalType {\n a: number;\n b: string;\n}" } ], @@ -999,18 +999,18 @@ "problem": "ObjectLiteralNoContextType", "autofix": [ { - "start": 4301, - "end": 4302, + "start": 4281, + "end": 4282, "replacementText": "\"a\"" }, { - "start": 4311, - "end": 4312, + "start": 4291, + "end": 4292, "replacementText": "\"b\"" }, { - "start": 4321, - "end": 4322, + "start": 4301, + "end": 4302, "replacementText": "\"c\"" } ], @@ -1036,18 +1036,18 @@ "problem": "ObjectLiteralNoContextType", "autofix": [ { - "start": 4376, - "end": 4379, + "start": 4356, + "end": 4359, "replacementText": "\"foo\"" }, { - "start": 4388, - "end": 4391, + "start": 4368, + "end": 4371, "replacementText": "\"bar\"" }, { - "start": 4430, - "end": 4433, + "start": 4410, + "end": 4413, "replacementText": "\"baz\"" } ], @@ -1103,13 +1103,13 @@ "problem": "ObjectLiteralNoContextType", "autofix": [ { - "start": 4721, - "end": 4724, + "start": 4701, + "end": 4704, "replacementText": "\"key\"" }, { - "start": 4739, - "end": 4746, + "start": 4719, + "end": 4726, "replacementText": "\"message\"" } ], diff --git a/ets2panda/linter/test/migrate/object_literals_autofixes.sts b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.ets similarity index 40% rename from ets2panda/linter/test/migrate/object_literals_autofixes.sts rename to ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.ets index 48d3fe6aa346024a7f903a3fd274f45d201bbd9e..7022a9431a8d73e070ab3a752587dcf911fe6975 100644 --- a/ets2panda/linter/test/migrate/object_literals_autofixes.sts +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.ets @@ -20,7 +20,7 @@ import { GeneratedObjectLiteralInterface_8, foo as GeneratedObjectLiteralInterface_9 } from 'x'; -interface GeneratedObjectLiteralInterface_11 {} +interface GeneratedObjectLiteralInterface_11 {} class GeneratedObjectLiteralInterface_12 {} function GeneratedObjectLiteralInterface_15() {} @@ -30,10 +30,27 @@ function foo(x): number { return 1; } -const o1 = {}; -const o2 = { hello: "world" }; -const o3! = {a: 1, b: 2}; -const o4 = { +interface GeneratedObjectLiteralInterface_1 { +} +const o1: GeneratedObjectLiteralInterface_1 = {}; +interface GeneratedObjectLiteralInterface_2 { + hello: string; +} +const o2: GeneratedObjectLiteralInterface_2 = { hello: "world" }; +interface GeneratedObjectLiteralInterface_3 { + a: number; + b: number; +} +const o3!: GeneratedObjectLiteralInterface_3 = {a: 1, b: 2}; +interface GeneratedObjectLiteralInterface_5 { + field: string; + field1: number; + field2: string; + field3: number; + field4: boolean; + field5: boolean; +} +const o4: GeneratedObjectLiteralInterface_5 = { field: "hello", field1: 2, field2: "world", @@ -43,66 +60,184 @@ const o4 = { }; // Properties with various types. Nested object literals -const o5 = { +interface GeneratedObjectLiteralInterface_6 { +} +interface GeneratedObjectLiteralInterface_10 { + a: number; + b: string; +} +interface GeneratedObjectLiteralInterface_13 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_25 { + a: number; + b: string; + c: boolean; + d: C; + e: GeneratedObjectLiteralInterface_6; + f: GeneratedObjectLiteralInterface_10; + g: GeneratedObjectLiteralInterface_13; +} +const o5: GeneratedObjectLiteralInterface_25 = { a: 1, b: '2', c: true, d: new C(), - e: {}, - f: { a: 1, b: '2' }, - g: { - q: 10, - w: 20 - }, + e: ({} as GeneratedObjectLiteralInterface_6), + f: ({ a: 1, b: '2' } as GeneratedObjectLiteralInterface_10), + g: ({ q: 10, + w: 20 } as GeneratedObjectLiteralInterface_13), }; -const o6 = { +interface GeneratedObjectLiteralInterface_14 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_16 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_21 { + a: number; + b: string; + c: GeneratedObjectLiteralInterface_14; + d: boolean; + e: GeneratedObjectLiteralInterface_16; +} +const o6: GeneratedObjectLiteralInterface_21 = { a: 1, b: '2', - c: { q: 10, w: 20 }, + c: ({ q: 10, w: 20 } as GeneratedObjectLiteralInterface_14), d: true, - e: { q: 30, w: 40 } + e: ({ q: 30, w: 40 } as GeneratedObjectLiteralInterface_16) }; // Object literals inside another expression -const o7 = { a:1, b:2 }.a + { a:3, b:4 }.b; -const o8 = { - a: 1, +interface GeneratedObjectLiteralInterface_17 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_18 { + a: number; + b: number; +} +const o7 = ({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_17).a + ({ a: 3, b: 4 } as GeneratedObjectLiteralInterface_18).b; +interface GeneratedObjectLiteralInterface_19 { + x: number; + y: number; +} +interface GeneratedObjectLiteralInterface_20 { + a: number; + b: number; + c: GeneratedObjectLiteralInterface_19; + d: number; +} +interface GeneratedObjectLiteralInterface_23 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_27 { + q: number; + w: number; +} +const o8: GeneratedObjectLiteralInterface_20 = { + a: 1, b: 2, - c: ({x:1, y:2}), - d: foo({q:1, w:2}.q + {q:3, w:4}.w) + c: ({ x: 1, y: 2 } as GeneratedObjectLiteralInterface_19), + d: foo(({ q: 1, w: 2 } as GeneratedObjectLiteralInterface_23).q + ({ q: 3, w: 4 } as GeneratedObjectLiteralInterface_27).w) }; // Object literals inside class declaration +interface GeneratedObjectLiteralInterface_22 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_24 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_26 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_28 { + c: number; + d: number; +} +interface GeneratedObjectLiteralInterface_29 { + e: number; +} +interface GeneratedObjectLiteralInterface_32 { + f: number; + g: number; +} +interface GeneratedObjectLiteralInterface_34 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_36 { + c: number; + d: number; + e: number; +} class D { - f1 = {a: 1, b: 2}; - f2? = {a: 1, b: 2}; - f3! = {a: 1, b: 2}; - f4 = ({c: 3, d: 4}); - f5 = {e: 5}.e + {f: 6, g: 7}.f; + f1: GeneratedObjectLiteralInterface_22 = {a: 1, b: 2}; + f2?: GeneratedObjectLiteralInterface_24 = {a: 1, b: 2}; + f3!: GeneratedObjectLiteralInterface_26 = {a: 1, b: 2}; + f4 = ({ c: 3, d: 4 } as GeneratedObjectLiteralInterface_28); + f5 = ({ e: 5 } as GeneratedObjectLiteralInterface_29).e + ({ f: 6, g: 7 } as GeneratedObjectLiteralInterface_32).f; m() { - let x = {a:1, b:2}; - let y = {c:1, d:2, e:3}; + let x: GeneratedObjectLiteralInterface_34 = {a:1, b:2}; + let y: GeneratedObjectLiteralInterface_36 = {c:1, d:2, e:3}; } } // Object literals as function parameter initializer -function funInit(p = { a: 1, b: 2 }) {} +interface GeneratedObjectLiteralInterface_30 { + a: number; + b: number; +} +function funInit(p: GeneratedObjectLiteralInterface_30 = { a: 1, b: 2 }) {} function funInit2({a, b} = { a: 3, b: 4 }) {} // Not fixable, as in case of destructuring parameters, the contextual type of expression is implied by the binding pattern // Object literals inside function declaration +interface GeneratedObjectLiteralInterface_31 { + a: number; + b: number; +} +interface GeneratedObjectLiteralInterface_33 { + c: number; + d: number; +} +interface GeneratedObjectLiteralInterface_35 { + e: number; + f: number; +} +interface GeneratedObjectLiteralInterface_37 { + g: number; + d: number; +} +interface GeneratedObjectLiteralInterface_38 { + q: number; + w: number; +} +interface GeneratedObjectLiteralInterface_39 { + q: number; + w: number; +} function bar(): void { - let a = {a: 1, b: 2}; - let b = {c: 3, d: 4}; + let a: GeneratedObjectLiteralInterface_31 = {a: 1, b: 2}; + let b: GeneratedObjectLiteralInterface_33 = {c: 3, d: 4}; if (a.b > b.c) { - let c = {e: 5, f: 6}; + let c: GeneratedObjectLiteralInterface_35 = {e: 5, f: 6}; } - let d = {g: 7, d: foo({q:1,w:2}.q + {q:3,w:4}.w)}; + let d: GeneratedObjectLiteralInterface_37 = {g: 7, d: foo(({ q: 1, w: 2 } as GeneratedObjectLiteralInterface_38).q + ({ q: 3, w: 4 } as GeneratedObjectLiteralInterface_39).w)}; } -const o9 = { 1: '1', '2': 2 }; +const o9 = { 1: '1', '2': 2 }; // Not fixable, property name is string/numeric literal const o10 = { [3]: 3 }; // Not fixable, computed property value const o11 = { [o2.hello]: 'world' }; // Not fixable, computed property value @@ -110,9 +245,13 @@ const anyVal: any = 1; const o12 = { a: anyVal }; // Not fixable, type of property 'a' is not supported let val = 1; -const o13 = { val }; // Not fixable, property is not 'key:value' pair +const o13 = { val }; // Fixable const o14 = { ...o1 }; // Not fixable, property is not 'key:value' pair -const o15 = { m() {} }; // Not fixable, property is not 'key:value' pair +class GeneratedObjectLiteralClass_1 { + m() { } +} + +const o15 = new GeneratedObjectLiteralClass_1(); // Fixable const o16 = { // Not fixable, property 'c' is initialized with non-fixable nested object literal, and thus will always have unsupported type (object type literal) a: 1, @@ -130,30 +269,33 @@ function captureFromLocalScope(t: T): void { let v1 = {a: 1, b: '2', c: t}; // Not fixable, `c` references local type parameter `T` let v2 = {a: 1, b: '2', c: new X()}; // Not fixable, `c` references local type parameter `T` let v3 = {a: 1, b: '2', c: new Y>()}; // Not fixable, `c` references local type parameter `T` - - type LocalType = {a: number, b: string}; + + interface LocalType { + a: number; + b: string; +} let localTypeVar: LocalType = {a:1, b:'2'}; let v4 = { x: localTypeVar }; // Non-fixable, `x` references type `LocalType` declared in local scope - + class LocalClass {x: number = 1}; let v5 = { y: new LocalClass() }; // Non-fixable, `y` references type `LocalClass` declared in local scope - + let v6 = { z: LocalClass }; // Non-fixable, `z` references type `LocalClass` declared in local scope } // Record object literals let rec1: Record = { - a: 1, - b: 2, - c: 3 + "a": 1, + "b": 2, + "c": 3 } let rec2: Record = { - foo: 1, - bar: 2, + "foo": 1, + "bar": 2, 10: 'foo', 20: 'bar', - baz: 3, + "baz": 3, 'daz': 4 } @@ -169,7 +311,7 @@ interface NullableRecord { } let rec4: NullableRecord = { params: { - key: '1', - message: '2' + "key": '1', + "message": '2' } }; \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.json b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json similarity index 37% rename from ets2panda/linter/test/migrate/object_literals_autofixes.ts.json rename to ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json index ff838327c3663578824e6dc51fac496988831862..e69f8c28502e98e3389a8c244620b123c4cd1ca1 100644 --- a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.json +++ b/ets2panda/linter/test/main/object_literals_autofixes.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 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", @@ -25,289 +25,29 @@ "severity": "ERROR" }, { - "line": 33, - "column": 12, - "endLine": 33, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 12, - "endLine": 34, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 35, + "line": 44, "column": 7, - "endLine": 35, - "endColumn": 25, + "endLine": 44, + "endColumn": 60, "problem": "DefiniteAssignment", "suggest": "", "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "WARNING" }, { - "line": 35, - "column": 13, - "endLine": 35, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 12, - "endLine": 36, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 12, - "endLine": 46, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 8, - "endLine": 51, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 8, - "endLine": 52, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 8, - "endLine": 53, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 12, - "endLine": 58, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 8, - "endLine": 61, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 8, - "endLine": 63, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 12, - "endLine": 67, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 29, - "endLine": 67, - "endColumn": 30, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 12, - "endLine": 68, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 9, - "endLine": 71, - "endColumn": 10, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 12, - "endLine": 72, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 27, - "endLine": 72, - "endColumn": 28, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 77, - "column": 10, - "endLine": 77, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 11, - "endLine": 78, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 79, + "line": 186, "column": 5, - "endLine": 79, - "endColumn": 24, + "endLine": 186, + "endColumn": 60, "problem": "DefiniteAssignment", "suggest": "", "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", "severity": "WARNING" }, { - "line": 79, - "column": 11, - "endLine": 79, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 11, - "endLine": 80, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 10, - "endLine": 81, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 21, - "endLine": 81, - "endColumn": 22, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 84, - "column": 17, - "endLine": 84, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 85, - "column": 17, - "endLine": 85, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 90, - "column": 22, - "endLine": 90, - "endColumn": 23, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 91, + "line": 202, "column": 19, - "endLine": 91, + "endLine": 202, "endColumn": 42, "problem": "DestructuringParameter", "suggest": "", @@ -315,9 +55,9 @@ "severity": "ERROR" }, { - "line": 91, + "line": 202, "column": 28, - "endLine": 91, + "endLine": 202, "endColumn": 29, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -325,69 +65,9 @@ "severity": "ERROR" }, { - "line": 95, - "column": 13, - "endLine": 95, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 13, - "endLine": 96, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 99, - "column": 17, - "endLine": 99, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 13, - "endLine": 102, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 27, - "endLine": 102, - "endColumn": 28, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 41, - "endLine": 102, - "endColumn": 42, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 105, + "line": 240, "column": 12, - "endLine": 105, + "endLine": 240, "endColumn": 13, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -395,9 +75,9 @@ "severity": "ERROR" }, { - "line": 105, + "line": 240, "column": 14, - "endLine": 105, + "endLine": 240, "endColumn": 15, "problem": "LiteralAsPropertyName", "suggest": "", @@ -405,9 +85,9 @@ "severity": "ERROR" }, { - "line": 106, + "line": 241, "column": 13, - "endLine": 106, + "endLine": 241, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -415,9 +95,9 @@ "severity": "ERROR" }, { - "line": 106, + "line": 241, "column": 15, - "endLine": 106, + "endLine": 241, "endColumn": 18, "problem": "ComputedPropertyName", "suggest": "", @@ -425,9 +105,9 @@ "severity": "ERROR" }, { - "line": 107, + "line": 242, "column": 13, - "endLine": 107, + "endLine": 242, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -435,9 +115,9 @@ "severity": "ERROR" }, { - "line": 107, + "line": 242, "column": 15, - "endLine": 107, + "endLine": 242, "endColumn": 25, "problem": "ComputedPropertyName", "suggest": "", @@ -445,9 +125,9 @@ "severity": "ERROR" }, { - "line": 109, + "line": 244, "column": 15, - "endLine": 109, + "endLine": 244, "endColumn": 18, "problem": "AnyType", "suggest": "", @@ -455,9 +135,9 @@ "severity": "ERROR" }, { - "line": 110, + "line": 245, "column": 13, - "endLine": 110, + "endLine": 245, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -465,9 +145,9 @@ "severity": "ERROR" }, { - "line": 113, + "line": 248, "column": 13, - "endLine": 113, + "endLine": 248, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -475,9 +155,9 @@ "severity": "ERROR" }, { - "line": 114, + "line": 249, "column": 13, - "endLine": 114, + "endLine": 249, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -485,9 +165,9 @@ "severity": "ERROR" }, { - "line": 114, + "line": 249, "column": 15, - "endLine": 114, + "endLine": 249, "endColumn": 20, "problem": "SpreadOperator", "suggest": "", @@ -495,9 +175,9 @@ "severity": "ERROR" }, { - "line": 115, + "line": 256, "column": 13, - "endLine": 115, + "endLine": 256, "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -505,19 +185,9 @@ "severity": "ERROR" }, { - "line": 117, - "column": 13, - "endLine": 117, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 120, + "line": 259, "column": 8, - "endLine": 120, + "endLine": 259, "endColumn": 9, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -525,9 +195,9 @@ "severity": "ERROR" }, { - "line": 130, + "line": 269, "column": 14, - "endLine": 130, + "endLine": 269, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -535,9 +205,9 @@ "severity": "ERROR" }, { - "line": 131, + "line": 270, "column": 14, - "endLine": 131, + "endLine": 270, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -545,9 +215,9 @@ "severity": "ERROR" }, { - "line": 132, + "line": 271, "column": 14, - "endLine": 132, + "endLine": 271, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -555,29 +225,9 @@ "severity": "ERROR" }, { - "line": 134, - "column": 22, - "endLine": 134, - "endColumn": 23, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 135, - "column": 35, - "endLine": 135, - "endColumn": 36, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 136, + "line": 278, "column": 14, - "endLine": 136, + "endLine": 278, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -585,9 +235,9 @@ "severity": "ERROR" }, { - "line": 139, + "line": 281, "column": 14, - "endLine": 139, + "endLine": 281, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -595,9 +245,9 @@ "severity": "ERROR" }, { - "line": 141, + "line": 283, "column": 14, - "endLine": 141, + "endLine": 283, "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -605,9 +255,9 @@ "severity": "ERROR" }, { - "line": 141, + "line": 283, "column": 19, - "endLine": 141, + "endLine": 283, "endColumn": 29, "problem": "ClassAsObject", "suggest": "", @@ -615,9 +265,9 @@ "severity": "WARNING" }, { - "line": 145, + "line": 287, "column": 26, - "endLine": 145, + "endLine": 287, "endColumn": 29, "problem": "AnyType", "suggest": "", @@ -625,19 +275,9 @@ "severity": "ERROR" }, { - "line": 145, - "column": 33, - "endLine": 145, - "endColumn": 34, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 151, + "line": 293, "column": 35, - "endLine": 151, + "endLine": 293, "endColumn": 38, "problem": "AnyType", "suggest": "", @@ -645,19 +285,9 @@ "severity": "ERROR" }, { - "line": 151, - "column": 42, - "endLine": 151, - "endColumn": 43, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 160, + "line": 302, "column": 35, - "endLine": 160, + "endLine": 302, "endColumn": 38, "problem": "AnyType", "suggest": "", @@ -665,9 +295,9 @@ "severity": "ERROR" }, { - "line": 160, + "line": 302, "column": 42, - "endLine": 160, + "endLine": 302, "endColumn": 43, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -675,34 +305,14 @@ "severity": "ERROR" }, { - "line": 164, + "line": 306, "column": 5, - "endLine": 164, + "endLine": 306, "endColumn": 10, "problem": "ComputedPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" - }, - { - "line": 170, - "column": 28, - "endLine": 170, - "endColumn": 29, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 171, - "column": 13, - "endLine": 171, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.args.json b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.autofix.json b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.autofix.json index ed06927858202011e91cc471fbc0afb3bb0512a8..6d432798b177133770fabaf6205cb4a157dd7dc9 100644 --- a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.autofix.json +++ b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.autofix.json @@ -24,6 +24,16 @@ "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", "severity": "ERROR" }, + { + "line": 53, + "column": 6, + "endLine": 53, + "endColumn": 14, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, { "line": 23, "column": 3, diff --git a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.json b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.json index a5443694a5d0a81f01d4f86180027a6263f668fc..04c9b8ff9983ba61c505ce63e2994dcf484cb7bf 100644 --- a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.json +++ b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.json @@ -24,6 +24,16 @@ "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", "severity": "ERROR" }, + { + "line": 53, + "column": 6, + "endLine": 53, + "endColumn": 14, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, { "line": 23, "column": 3, diff --git a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d1901e50e01e4fb1463cdbfacc8798aa0f672bb4 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.ets @@ -0,0 +1,54 @@ +/* + * 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. + */ + +type F = () => void; +interface FuncInterface { + (x: number): string + f?: number; +} + +class A { + a: F; + b: Function; + c: () => void; + d: FuncInterface; +} + +let a: A = { + a: () => { console.log('Hello'); }, + b: () => { console.log('Bye'); }, + c: () => { console.log('Apple'); }, + d: (x: number) => x.toString(), +} + +let q: F = () => {}; +let w: Function = (x: number) => x * x; +let e = () => { console.log('Orange'); }; +let r: FuncInterface = (x: number) => x.toString(); + +a = { + a: q, + b: w, + c: e, + d: r, +} + +// #14569 - initialize field with 'Function' object +class B { + f: Function = () => {}; +} +let b: B = { + f: Function +}; \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.json b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..8c06a808b0b1241a3206f1b11d66841c5335c971 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_prop_func_type.ets.migrate.json @@ -0,0 +1,78 @@ +{ + "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": 18, + "column": 3, + "endLine": 18, + "endColumn": 22, + "problem": "CallSignature", + "suggest": "", + "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 6, + "endLine": 53, + "endColumn": 14, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 25, + "column": 3, + "endLine": 25, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'c' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'c' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 26, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'd' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'd' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_properties.ets b/ets2panda/linter/test/main/object_literals_properties.ets index e6956798332d731b6f0b637b84e97f85b8eb769a..d5265f74931ccea9f47fc03753efec7076b19d3b 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets +++ b/ets2panda/linter/test/main/object_literals_properties.ets @@ -13,32 +13,246 @@ * limitations under the License. */ -class MyClass { - a: string = "" - b: number = 0 -} +// Untyped object literals +let method = { + m() { console.log(1); } // Error, fixable +}; + +let getMethod = { + get property() { return 2; } // Error, fixable +}; + +let setMethod = { + set property(value: number) { // Error, fixable + console.log(value); + } +}; + +let x = 1, y = '2', z = true; + +let shorthand = { + x, // Error, fixable + y, // Error, fixable + z // Error, fixable +}; -let c: MyClass = {a: "a", b: 3} +let spread = { + ...shorthand // Error, not fixable +}; -let b: MyClass = { - a: "Alice", - "c", // Error - c, // Error - b: "num", - method() { // Error +let mixed = { // Fixable + a: "foo", + b: 42, + c: [1, 2, 3], + x, // Error + y, // Error + + method() { // Error console.log(42) }, + + get property() { // Error + return 0; + }, + + set property(value: number) { // Error + if (value < 0) { + throw new Error('Bad value'); + } + } +}; + +let x2 = 1, y2 = 2, z2 = 3; +let mixedBad = { // Not fixable + a: 1, + b: 2, + x2, // Error, fixable + y2, // Error, fixable + z2, // Error, fixable + m() {}, + ...shorthand // Error, not fixable } -let o: MyClass = { - a: "foo", - b: 42, - c: {}, - 1: "number literal property", // Error - "foo:bar": "string literal property", // Error +// Typed object literals +interface I { + m(): void; +} +let i: I = { + m() { // Fixable + console.log(100); + } +}; - get property() {}, // Error - set property(value) {}, // Error +class C { + m(): void { + console.log(200); + } +} +let c: C = { + m(): void { // Fixable + console.log(300); + } +}; + +function foo(c: C) {} +foo({ + m() { console.log(300); } // Fixable +}); - [expression]: "computed property", // Error +class C2 { + x2 = 10; + y2 = 20; + z2 = 30; + + m() {} +} +let c2: C2 = { + x2, // Fixable + y2, // Fixable + z2, // Fixable + m() { console.log(1); } // Fixable }; + +let c22: C2 = { + x2, // Fixable + y2, // Fixable + z2, // Fixable + m() { console.log(1); }, // Not fixable, object has spread property + ...shorthand // Not fixable +}; + +class C3 { + x2 = 10; + y2 = 20; + z2 = 30; + + m() {} + + constructor(a: number) {} +} +let c3: C3 = { + x2, // Fixable + y2, // Fixable + z2, // Fixable + m() { console.log(1); } // Not fixable, class type has constructor with parameters +}; + +function capturesFromLocalScope() { + let a = 1, b = 2; + let captureLocalVal = { + m() { // Not fixable, captures local values 'a' and 'b' + console.log(a, b); + } + }; + + let captureLocalVal2: C = { + m(): void { // Not fixable, captures local values 'a' and 'b' + console.log(a, b); + } + }; + + type LocalType = {a: number, b: string}; + let localTypeVar: LocalType = { a: 1, b: '2' }; + let captureLocalType = { + m() { // Not fixable, captures value of type `LocalType` declared in local scope + console.log(localTypeVar); + } + }; + let captureLocalType2 = { + m(x: LocalType) { // Not fixable, `x` references type `LocalType` declared in local scope + console.log(x); + } + }; + + class LocalClass { x: number = 1 }; + let captureLocalType3 = { + m() { // Not fixable, references type `LocalClass` declared in local scope + console.log(new LocalClass()); + } + }; +} + +// Method overriding field +class C4 { + a: number = 0; + b() {}; +} +let c4: C4 = { // Not fixable, overrides class method with property of functional type + a: 1, + b: () => {} +}; + +class C5 { + a: number = 0; + b: () => void; +} +let c5: C5 = { // Not fixable, overrides class property with method + a: 1, + b() {} +}; + +interface I2 { + a: number; + b(): void; +} +let i2: I2 = { // Not fixable, implements method as functional-type property + a: 1, + b: () => {} +}; + +interface I3 { + a: number; + b: () => void; +} +let ii: I3 = { // Not fixable, implements functional-type property as a method + a: 1, + b() {} +}; + +// Inheritance +class Base { + constructor() {} +} +class Derived extends Base { + m() {} +} +let b: Derived = { // Fixable + m() { console.log(2); } +}; + +class Base2 { + constructor(a: number) {} +} +class Derived2 extends Base2 { + m() {} +} +let b2: Derived2 = { // Not fixable, derived class inherits a constructor with parameters from base class + m() { console.log(2); } +}; + +class Base3 { + constructor(a: number) {} +} +class Derived3 extends Base3 { + m() {} + + constructor() { + super(1); + } +} +let b3: Derived3 = { // Fixable + m() { console.log(2); } +}; + +interface A { + map: Map; +} +let map:Map = new Map(); +let a:A = {map}; + +class C { + map1: Map = new Map(); +} + +let map1:Map = new Map(); +let c:C = {map1}; \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.args.json b/ets2panda/linter/test/main/object_literals_properties.ets.args.json index 720715a55cfe7d0e9847cee28d64d03e7888416e..f9fc1047e86a36642e6e262c41779a581f640a7f 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.args.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "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", @@ -14,6 +14,8 @@ "limitations under the License." ], "mode": { - "arkts2": "" + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json b/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json index d22a34564890885fbeb7121dfe5683cd0dd568fc..cc12e25c14161a7519fb9115fec3540ee4a842d2 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.arkts2.json @@ -15,59 +15,159 @@ ], "result": [ { - "line": 23, - "column": 18, - "endLine": 23, - "endColumn": 19, + "line": 17, + "column": 14, + "endLine": 17, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 25, + "line": 18, "column": 3, - "endLine": 25, - "endColumn": 6, + "endLine": 18, + "endColumn": 26, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 26, + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 22, "column": 3, - "endLine": 26, - "endColumn": 4, + "endLine": 22, + "endColumn": 31, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 28, + "line": 22, + "column": 27, + "endLine": 22, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 26, "column": 3, - "endLine": 30, + "endLine": 28, "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 9, + "endLine": 31, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 33, - "column": 18, + "column": 17, "endLine": 33, - "endColumn": 19, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 14, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 37, + "line": 50, "column": 3, - "endLine": 37, + "endLine": 52, "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", @@ -75,39 +175,179 @@ "severity": "ERROR" }, { - "line": 38, + "line": 54, "column": 3, - "endLine": 38, - "endColumn": 12, + "endLine": 56, + "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 40, + "line": 58, "column": 3, - "endLine": 40, - "endColumn": 20, + "endLine": 62, + "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 41, + "line": 45, + "column": 6, + "endLine": 45, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 7, + "endLine": 46, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 13, + "endLine": 46, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 17, + "endLine": 51, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 12, + "endLine": 55, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 17, + "endLine": 59, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 10, + "endLine": 65, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 13, + "endLine": 65, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 18, + "endLine": 65, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 21, + "endLine": 65, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 26, + "endLine": 65, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 72, "column": 3, - "endLine": 41, - "endColumn": 25, + "endLine": 72, + "endColumn": 9, "problem": "ObjectLiteralProperty", "suggest": "", "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 43, + "line": 73, "column": 3, - "endLine": 43, + "endLine": 73, "endColumn": 15, "problem": "ObjectLiteralProperty", "suggest": "", @@ -115,33 +355,763 @@ "severity": "ERROR" }, { - "line": 36, + "line": 67, + "column": 6, + "endLine": 67, + "endColumn": 7, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 68, "column": 6, - "endLine": 36, + "endLine": 68, "endColumn": 7, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 3, + "endLine": 73, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 12, + "endLine": 80, + "endColumn": 13, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 37, + "line": 81, "column": 3, - "endLine": 37, + "endLine": 83, "endColumn": 4, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 43, + "line": 82, + "column": 17, + "endLine": 82, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 17, + "endLine": 88, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 12, + "endLine": 91, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 92, "column": 3, - "endLine": 43, + "endLine": 94, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 17, + "endLine": 93, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 5, + "endLine": 98, + "endColumn": 6, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 3, + "endLine": 99, + "endColumn": 28, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 21, + "endLine": 99, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 8, + "endLine": 103, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 8, + "endLine": 104, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 3, + "endLine": 105, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 8, + "endLine": 105, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 14, + "endLine": 109, "endColumn": 15, - "problem": "ComputedPropertyName", + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 3, + "endLine": 113, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 21, + "endLine": 113, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 15, + "endLine": 116, + "endColumn": 16, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 3, + "endLine": 120, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 21, + "endLine": 120, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 3, + "endLine": 125, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 8, + "endLine": 125, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 3, + "endLine": 126, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 8, + "endLine": 126, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 3, + "endLine": 127, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 8, + "endLine": 127, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 14, + "endLine": 133, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 3, + "endLine": 137, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 21, + "endLine": 137, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 7, + "endLine": 141, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 11, + "endLine": 141, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 14, + "endLine": 141, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 18, + "endLine": 141, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 25, + "endLine": 142, + "endColumn": 26, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 5, + "endLine": 145, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 29, + "endLine": 148, + "endColumn": 30, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 5, + "endLine": 151, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 20, + "endLine": 154, + "endColumn": 21, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 33, + "endLine": 155, + "endColumn": 34, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 38, + "endLine": 155, + "endColumn": 39, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 156, + "column": 26, + "endLine": 156, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 5, + "endLine": 159, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 27, + "endLine": 161, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 5, + "endLine": 164, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 34, + "endLine": 167, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 27, + "endLine": 168, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 5, + "endLine": 171, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 15, + "endLine": 177, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 14, + "endLine": 180, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 181, + "column": 6, + "endLine": 181, + "endColumn": 7, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 186, + "column": 15, + "endLine": 186, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 191, + "column": 3, + "endLine": 191, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 190, + "column": 6, + "endLine": 190, + "endColumn": 7, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 14, + "endLine": 198, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 6, + "endLine": 199, + "endColumn": 7, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 3, + "endLine": 209, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 208, + "column": 6, + "endLine": 208, + "endColumn": 7, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 219, + "column": 18, + "endLine": 219, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 3, + "endLine": 220, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 21, + "endLine": 220, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 229, + "column": 20, + "endLine": 229, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 3, + "endLine": 230, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 21, + "endLine": 230, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 240, + "column": 11, + "endLine": 240, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 20, + "endLine": 243, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 3, + "endLine": 244, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 21, + "endLine": 244, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 11, + "endLine": 258, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 3, + "endLine": 187, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json b/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..8e5ca8740328ce6d6ff6e2c7106760e138b5718d --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_properties.ets.autofix.json @@ -0,0 +1,1923 @@ +{ + "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": 17, + "column": 14, + "endLine": 17, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 637, + "end": 637, + "replacementText": "class GeneratedObjectLiteralClass_1 {\n m() { console.log(1); } // Error, fixable\n}\n\n", + "line": 17, + "column": 14, + "endLine": 17, + "endColumn": 15 + }, + { + "start": 650, + "end": 697, + "replacementText": "new GeneratedObjectLiteralClass_1()", + "line": 17, + "column": 14, + "endLine": 17, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 672, + "end": 673, + "replacementText": "1.0", + "line": 18, + "column": 21, + "endLine": 18, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 700, + "end": 700, + "replacementText": "class GeneratedObjectLiteralClass_2 {\n get property() { return 2; } // Error, fixable\n}\n\n", + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 18 + }, + { + "start": 716, + "end": 768, + "replacementText": "new GeneratedObjectLiteralClass_2()", + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 3, + "endLine": 22, + "endColumn": 31, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 27, + "endLine": 22, + "endColumn": 28, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 744, + "end": 745, + "replacementText": "2.0", + "line": 22, + "column": 27, + "endLine": 22, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 771, + "end": 771, + "replacementText": "class GeneratedObjectLiteralClass_3 {\n set property(value: number) {\n console.log(value);\n }\n}\n\n", + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 18 + }, + { + "start": 787, + "end": 868, + "replacementText": "new GeneratedObjectLiteralClass_3()", + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 3, + "endLine": 28, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 875, + "end": 880, + "replacementText": "x: number = 1", + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 9, + "endLine": 31, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 879, + "end": 880, + "replacementText": "1.0", + "line": 31, + "column": 9, + "endLine": 31, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 17, + "endLine": 33, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 3, + "endLine": 40, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 1048, + "end": 1048, + "replacementText": "class GeneratedObjectLiteralClass_4 {\n a: string;\n b: number;\n c: number[];\n x: number;\n y: string;\n constructor(init: GeneratedObjectLiteralInitInterface_4) {\n this.a = init.a;\n this.b = init.b;\n this.c = init.c;\n this.x = init.x;\n this.y = init.y;\n }\n method() {\n console.log(42);\n }\n get property() {\n return 0;\n }\n set property(value: number) {\n if (value < 0) {\n throw new Error('Bad value');\n }\n }\n}\n\ninterface GeneratedObjectLiteralInitInterface_4 {\n a: string;\n b: number;\n c: number[];\n x: number;\n y: string;\n}\n\n", + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 14 + }, + { + "start": 1060, + "end": 1344, + "replacementText": "new GeneratedObjectLiteralClass_4({\n a: \"foo\",\n b: 42,\n c: [1, 2, 3],\n x: x,\n y: y\n})", + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 3, + "endLine": 52, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 56, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 3, + "endLine": 62, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 6, + "endLine": 45, + "endColumn": 8, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1090, + "end": 1092, + "replacementText": "42.0", + "line": 45, + "column": 6, + "endLine": 45, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 7, + "endLine": 46, + "endColumn": 8, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1100, + "end": 1101, + "replacementText": "1.0", + "line": 46, + "column": 7, + "endLine": 46, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1103, + "end": 1104, + "replacementText": "2.0", + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 13, + "endLine": 46, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1106, + "end": 1107, + "replacementText": "3.0", + "line": 46, + "column": 13, + "endLine": 46, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 17, + "endLine": 51, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1177, + "end": 1179, + "replacementText": "42.0", + "line": 51, + "column": 17, + "endLine": 51, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 12, + "endLine": 55, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1226, + "end": 1227, + "replacementText": "0.0", + "line": 55, + "column": 12, + "endLine": 55, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 17, + "endLine": 59, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1292, + "end": 1293, + "replacementText": "0.0", + "line": 59, + "column": 17, + "endLine": 59, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1351, + "end": 1357, + "replacementText": "x2: number = 1", + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 10, + "endLine": 65, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1356, + "end": 1357, + "replacementText": "1.0", + "line": 65, + "column": 10, + "endLine": 65, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 13, + "endLine": 65, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1359, + "end": 1365, + "replacementText": "y2: number = 2", + "line": 65, + "column": 13, + "endLine": 65, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 18, + "endLine": 65, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1364, + "end": 1365, + "replacementText": "2.0", + "line": 65, + "column": 18, + "endLine": 65, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 21, + "endLine": 65, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1367, + "end": 1373, + "replacementText": "z2: number = 3", + "line": 65, + "column": 21, + "endLine": 65, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 26, + "endLine": 65, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1372, + "end": 1373, + "replacementText": "3.0", + "line": 65, + "column": 26, + "endLine": 65, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 3, + "endLine": 72, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 3, + "endLine": 73, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 6, + "endLine": 67, + "endColumn": 7, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1412, + "end": 1413, + "replacementText": "1.0", + "line": 67, + "column": 6, + "endLine": 67, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 6, + "endLine": 68, + "endColumn": 7, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1420, + "end": 1421, + "replacementText": "2.0", + "line": 68, + "column": 6, + "endLine": 68, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 3, + "endLine": 73, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 12, + "endLine": 80, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 3, + "endLine": 83, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1599, + "end": 1599, + "replacementText": "class GeneratedObjectLiteralClass_5 implements I {\n m() {\n console.log(100);\n }\n}\n\n", + "line": 81, + "column": 3, + "endLine": 83, + "endColumn": 4 + }, + { + "start": 1610, + "end": 1658, + "replacementText": "new GeneratedObjectLiteralClass_5()", + "line": 81, + "column": 3, + "endLine": 83, + "endColumn": 4 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 17, + "endLine": 82, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1647, + "end": 1650, + "replacementText": "100.0", + "line": 82, + "column": 17, + "endLine": 82, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 88, + "column": 17, + "endLine": 88, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1701, + "end": 1704, + "replacementText": "200.0", + "line": 88, + "column": 17, + "endLine": 88, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 12, + "endLine": 91, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 3, + "endLine": 94, + "endColumn": 4, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1713, + "end": 1713, + "replacementText": "class GeneratedObjectLiteralClass_6 extends C {\n m(): void {\n console.log(300);\n }\n}\n\n", + "line": 92, + "column": 3, + "endLine": 94, + "endColumn": 4 + }, + { + "start": 1724, + "end": 1778, + "replacementText": "new GeneratedObjectLiteralClass_6()", + "line": 92, + "column": 3, + "endLine": 94, + "endColumn": 4 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 17, + "endLine": 93, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1767, + "end": 1770, + "replacementText": "300.0", + "line": 93, + "column": 17, + "endLine": 93, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 5, + "endLine": 98, + "endColumn": 6, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 3, + "endLine": 99, + "endColumn": 28, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1803, + "end": 1803, + "replacementText": "class GeneratedObjectLiteralClass_7 extends C {\n m() { console.log(300); } // Fixable\n}\n\n", + "line": 99, + "column": 3, + "endLine": 99, + "endColumn": 28 + }, + { + "start": 1807, + "end": 1849, + "replacementText": "new GeneratedObjectLiteralClass_7()", + "line": 99, + "column": 3, + "endLine": 99, + "endColumn": 28 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 21, + "endLine": 99, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1829, + "end": 1832, + "replacementText": "300.0", + "line": 99, + "column": 21, + "endLine": 99, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1866, + "end": 1874, + "replacementText": "x2: number = 10;", + "line": 103, + "column": 3, + "endLine": 103, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 8, + "endLine": 103, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1871, + "end": 1873, + "replacementText": "10.0", + "line": 103, + "column": 8, + "endLine": 103, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1877, + "end": 1885, + "replacementText": "y2: number = 20;", + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 8, + "endLine": 104, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1882, + "end": 1884, + "replacementText": "20.0", + "line": 104, + "column": 8, + "endLine": 104, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 3, + "endLine": 105, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1888, + "end": 1896, + "replacementText": "z2: number = 30;", + "line": 105, + "column": 3, + "endLine": 105, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 8, + "endLine": 105, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1893, + "end": 1895, + "replacementText": "30.0", + "line": 105, + "column": 8, + "endLine": 105, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 14, + "endLine": 109, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 3, + "endLine": 113, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 1909, + "end": 1909, + "replacementText": "class GeneratedObjectLiteralClass_8 extends C2 {\n x2: number;\n y2: number;\n z2: number;\n constructor(init: GeneratedObjectLiteralInitInterface_8) {\n super();\n this.x2 = init.x2;\n this.y2 = init.y2;\n this.z2 = init.z2;\n }\n m() { console.log(1); } // Fixable\n}\n\ninterface GeneratedObjectLiteralInitInterface_8 {\n x2: number;\n y2: number;\n z2: number;\n}\n\n", + "line": 113, + "column": 3, + "endLine": 113, + "endColumn": 26 + }, + { + "start": 1922, + "end": 2013, + "replacementText": "new GeneratedObjectLiteralClass_8({\n x2: x2,\n y2: y2,\n z2: z2\n})", + "line": 113, + "column": 3, + "endLine": 113, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 21, + "endLine": 113, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1995, + "end": 1996, + "replacementText": "1.0", + "line": 113, + "column": 21, + "endLine": 113, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 15, + "endLine": 116, + "endColumn": 16, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 3, + "endLine": 120, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 21, + "endLine": 120, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2103, + "end": 2104, + "replacementText": "1.0", + "line": 120, + "column": 21, + "endLine": 120, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 3, + "endLine": 125, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2200, + "end": 2208, + "replacementText": "x2: number = 10;", + "line": 125, + "column": 3, + "endLine": 125, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 8, + "endLine": 125, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2205, + "end": 2207, + "replacementText": "10.0", + "line": 125, + "column": 8, + "endLine": 125, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 3, + "endLine": 126, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2211, + "end": 2219, + "replacementText": "y2: number = 20;", + "line": 126, + "column": 3, + "endLine": 126, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 8, + "endLine": 126, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2216, + "end": 2218, + "replacementText": "20.0", + "line": 126, + "column": 8, + "endLine": 126, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 3, + "endLine": 127, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2222, + "end": 2230, + "replacementText": "z2: number = 30;", + "line": 127, + "column": 3, + "endLine": 127, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 8, + "endLine": 127, + "endColumn": 10, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2227, + "end": 2229, + "replacementText": "30.0", + "line": 127, + "column": 8, + "endLine": 127, + "endColumn": 10 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 14, + "endLine": 133, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 3, + "endLine": 137, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 21, + "endLine": 137, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2358, + "end": 2359, + "replacementText": "1.0", + "line": 137, + "column": 21, + "endLine": 137, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 7, + "endLine": 141, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2469, + "end": 2474, + "replacementText": "a: number = 1", + "line": 141, + "column": 7, + "endLine": 141, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 11, + "endLine": 141, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2473, + "end": 2474, + "replacementText": "1.0", + "line": 141, + "column": 11, + "endLine": 141, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 14, + "endLine": 141, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2476, + "end": 2481, + "replacementText": "b: number = 2", + "line": 141, + "column": 14, + "endLine": 141, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 18, + "endLine": 141, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2480, + "end": 2481, + "replacementText": "2.0", + "line": 141, + "column": 18, + "endLine": 141, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 25, + "endLine": 142, + "endColumn": 26, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 5, + "endLine": 145, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 29, + "endLine": 148, + "endColumn": 30, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 149, + "column": 5, + "endLine": 151, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 20, + "endLine": 154, + "endColumn": 21, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 2741, + "end": 2781, + "replacementText": "interface LocalType {\n a: number;\n b: string;\n}", + "line": 154, + "column": 20, + "endLine": 154, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 33, + "endLine": 155, + "endColumn": 34, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 38, + "endLine": 155, + "endColumn": 39, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 2819, + "end": 2820, + "replacementText": "1.0", + "line": 155, + "column": 38, + "endLine": 155, + "endColumn": 39 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 156, + "column": 26, + "endLine": 156, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 5, + "endLine": 159, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 27, + "endLine": 161, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 162, + "column": 5, + "endLine": 164, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 34, + "endLine": 167, + "endColumn": 35, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3177, + "end": 3178, + "replacementText": "1.0", + "line": 167, + "column": 34, + "endLine": 167, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 27, + "endLine": 168, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 5, + "endLine": 171, + "endColumn": 6, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 15, + "endLine": 177, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3392, + "end": 3393, + "replacementText": "0.0", + "line": 177, + "column": 15, + "endLine": 177, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 14, + "endLine": 180, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 181, + "column": 6, + "endLine": 181, + "endColumn": 7, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3499, + "end": 3500, + "replacementText": "1.0", + "line": 181, + "column": 6, + "endLine": 181, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 186, + "column": 15, + "endLine": 186, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3545, + "end": 3546, + "replacementText": "0.0", + "line": 186, + "column": 15, + "endLine": 186, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 191, + "column": 3, + "endLine": 191, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 190, + "column": 6, + "endLine": 190, + "endColumn": 7, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3640, + "end": 3641, + "replacementText": "1.0", + "line": 190, + "column": 6, + "endLine": 190, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 14, + "endLine": 198, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 6, + "endLine": 199, + "endColumn": 7, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3781, + "end": 3782, + "replacementText": "1.0", + "line": 199, + "column": 6, + "endLine": 199, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 3, + "endLine": 209, + "endColumn": 9, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 208, + "column": 6, + "endLine": 208, + "endColumn": 7, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 3933, + "end": 3934, + "replacementText": "1.0", + "line": 208, + "column": 6, + "endLine": 208, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 219, + "column": 18, + "endLine": 219, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 3, + "endLine": 220, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 4038, + "end": 4038, + "replacementText": "class GeneratedObjectLiteralClass_9 extends Derived {\n m() { console.log(2); }\n}\n\n", + "line": 220, + "column": 3, + "endLine": 220, + "endColumn": 26 + }, + { + "start": 4055, + "end": 4095, + "replacementText": "new GeneratedObjectLiteralClass_9()", + "line": 220, + "column": 3, + "endLine": 220, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 220, + "column": 21, + "endLine": 220, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4088, + "end": 4089, + "replacementText": "2.0", + "line": 220, + "column": 21, + "endLine": 220, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 229, + "column": 20, + "endLine": 229, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 3, + "endLine": 230, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 21, + "endLine": 230, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4310, + "end": 4311, + "replacementText": "2.0", + "line": 230, + "column": 21, + "endLine": 230, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 240, + "column": 11, + "endLine": 240, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4433, + "end": 4434, + "replacementText": "1.0", + "line": 240, + "column": 11, + "endLine": 240, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 20, + "endLine": 243, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 3, + "endLine": 244, + "endColumn": 26, + "problem": "ObjectLiteralProperty", + "autofix": [ + { + "start": 4443, + "end": 4443, + "replacementText": "class GeneratedObjectLiteralClass_10 extends Derived3 {\n m() { console.log(2); }\n}\n\n", + "line": 244, + "column": 3, + "endLine": 244, + "endColumn": 26 + }, + { + "start": 4462, + "end": 4502, + "replacementText": "new GeneratedObjectLiteralClass_10()", + "line": 244, + "column": 3, + "endLine": 244, + "endColumn": 26 + } + ], + "suggest": "", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 21, + "endLine": 244, + "endColumn": 22, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 4495, + "end": 4496, + "replacementText": "2.0", + "line": 244, + "column": 21, + "endLine": 244, + "endColumn": 22 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 11, + "endLine": 258, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 3, + "endLine": 187, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.json b/ets2panda/linter/test/main/object_literals_properties.ets.json index f49a2e6be91dd6343b7307145784ad7f89c9aaf7..8548318c10fef89543ca13c38b6e81e90ce6a607 100644 --- a/ets2panda/linter/test/main/object_literals_properties.ets.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.json @@ -15,10 +15,30 @@ ], "result": [ { - "line": 23, - "column": 18, - "endLine": 23, - "endColumn": 19, + "line": 17, + "column": 14, + "endLine": 17, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 17, + "endLine": 21, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 17, + "endLine": 25, + "endColumn": 18, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", @@ -26,42 +46,272 @@ }, { "line": 33, - "column": 18, + "column": 17, "endLine": 33, - "endColumn": 19, + "endColumn": 18, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 36, - "column": 6, - "endLine": 36, - "endColumn": 7, + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 37, + "line": 40, "column": 3, - "endLine": 37, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "endLine": 40, + "endColumn": 15, + "problem": "SpreadOperator", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", "severity": "ERROR" }, { "line": 43, - "column": 3, + "column": 13, "endLine": 43, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 16, + "endLine": 66, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 3, + "endLine": 73, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 12, + "endLine": 80, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 91, + "column": 12, + "endLine": 91, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 5, + "endLine": 98, + "endColumn": 6, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 14, + "endLine": 109, "endColumn": 15, - "problem": "ComputedPropertyName", + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 15, + "endLine": 116, + "endColumn": 16, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 3, + "endLine": 121, + "endColumn": 15, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + }, + { + "line": 133, + "column": 14, + "endLine": 133, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 142, + "column": 25, + "endLine": 142, + "endColumn": 26, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 148, + "column": 29, + "endLine": 148, + "endColumn": 30, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 20, + "endLine": 154, + "endColumn": 21, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 155, + "column": 33, + "endLine": 155, + "endColumn": 34, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 156, + "column": 26, + "endLine": 156, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 161, + "column": 27, + "endLine": 161, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 27, + "endLine": 168, + "endColumn": 28, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 180, + "column": 14, + "endLine": 180, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 14, + "endLine": 198, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 219, + "column": 18, + "endLine": 219, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 229, + "column": 20, + "endLine": 229, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 20, + "endLine": 243, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 11, + "endLine": 258, + "endColumn": 12, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 3, + "endLine": 187, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..eb3a50b921ec2d55d356fce7716ddd3fe683f8a8 --- /dev/null +++ b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.ets @@ -0,0 +1,315 @@ +/* + * 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. + */ + +// Untyped object literals +class GeneratedObjectLiteralClass_1 { + m() { console.log(1.0); } // Error, fixable +} + +let method = new GeneratedObjectLiteralClass_1(); + +class GeneratedObjectLiteralClass_2 { + get property() { return 2.0; } // Error, fixable +} + +let getMethod = new GeneratedObjectLiteralClass_2(); + +class GeneratedObjectLiteralClass_3 { + set property(value: number) { + console.log(value); + } +} + +let setMethod = new GeneratedObjectLiteralClass_3(); + +let x: number = 1.0, y = '2', z = true; + +let shorthand = { + x, // Error, fixable + y, // Error, fixable + z // Error, fixable +}; + +let spread = { + ...shorthand // Error, not fixable +}; + +class GeneratedObjectLiteralClass_4 { + a: string; + b: number; + c: number[]; + x: number; + y: string; + constructor(init: GeneratedObjectLiteralInitInterface_4) { + this.a = init.a; + this.b = init.b; + this.c = init.c; + this.x = init.x; + this.y = init.y; + } + method() { + console.log(42.0); + } + get property() { + return 0.0; + } + set property(value: number) { + if (value < 0.0) { + throw new Error('Bad value'); + } + } +} + +interface GeneratedObjectLiteralInitInterface_4 { + a: string; + b: number; + c: number[]; + x: number; + y: string; +} + +let mixed = new GeneratedObjectLiteralClass_4({ + a: "foo", + b: 42.0, + c: [1.0, 2.0, 3.0], + x: x, + y: y +}); + +let x2: number = 1.0, y2: number = 2.0, z2: number = 3.0; +let mixedBad = { // Not fixable + a: 1.0, + b: 2.0, + x2, // Error, fixable + y2, // Error, fixable + z2, // Error, fixable + m() {}, + ...shorthand // Error, not fixable +} + +// Typed object literals +interface I { + m(): void; +} +class GeneratedObjectLiteralClass_5 implements I { + m() { + console.log(100.0); + } +} + +let i: I = new GeneratedObjectLiteralClass_5(); + +class C { + m(): void { + console.log(200.0); + } +} +class GeneratedObjectLiteralClass_6 extends C { + m(): void { + console.log(300.0); + } +} + +let c: C = new GeneratedObjectLiteralClass_6(); + +function foo(c: C) {} +class GeneratedObjectLiteralClass_7 extends C { + m() { console.log(300.0); } // Fixable +} + +foo(new GeneratedObjectLiteralClass_7()); + +class C2 { + x2: number = 10.0; + y2: number = 20.0; + z2: number = 30.0; + + m() {} +} +class GeneratedObjectLiteralClass_8 extends C2 { + x2: number; + y2: number; + z2: number; + constructor(init: GeneratedObjectLiteralInitInterface_8) { + super(); + this.x2 = init.x2; + this.y2 = init.y2; + this.z2 = init.z2; + } + m() { console.log(1.0); } // Fixable +} + +interface GeneratedObjectLiteralInitInterface_8 { + x2: number; + y2: number; + z2: number; +} + +let c2: C2 = new GeneratedObjectLiteralClass_8({ + x2: x2, + y2: y2, + z2: z2 +}); + +let c22: C2 = { + x2, // Fixable + y2, // Fixable + z2, // Fixable + m() { console.log(1.0); }, // Not fixable, object has spread property + ...shorthand // Not fixable +}; + +class C3 { + x2: number = 10.0; + y2: number = 20.0; + z2: number = 30.0; + + m() {} + + constructor(a: number) {} +} +let c3: C3 = { + x2, // Fixable + y2, // Fixable + z2, // Fixable + m() { console.log(1.0); } // Not fixable, class type has constructor with parameters +}; + +function capturesFromLocalScope() { + let a: number = 1.0, b: number = 2.0; + let captureLocalVal = { + m() { // Not fixable, captures local values 'a' and 'b' + console.log(a, b); + } + }; + + let captureLocalVal2: C = { + m(): void { // Not fixable, captures local values 'a' and 'b' + console.log(a, b); + } + }; + + interface LocalType { + a: number; + b: string; +} + let localTypeVar: LocalType = { a: 1.0, b: '2' }; + let captureLocalType = { + m() { // Not fixable, captures value of type `LocalType` declared in local scope + console.log(localTypeVar); + } + }; + let captureLocalType2 = { + m(x: LocalType) { // Not fixable, `x` references type `LocalType` declared in local scope + console.log(x); + } + }; + + class LocalClass { x: number = 1.0 }; + let captureLocalType3 = { + m() { // Not fixable, references type `LocalClass` declared in local scope + console.log(new LocalClass()); + } + }; +} + +// Method overriding field +class C4 { + a: number = 0.0; + b() {}; +} +let c4: C4 = { // Not fixable, overrides class method with property of functional type + a: 1.0, + b: () => {} +}; + +class C5 { + a: number = 0.0; + b: () => void; +} +let c5: C5 = { // Not fixable, overrides class property with method + a: 1.0, + b() {} +}; + +interface I2 { + a: number; + b(): void; +} +let i2: I2 = { // Not fixable, implements method as functional-type property + a: 1.0, + b: () => {} +}; + +interface I3 { + a: number; + b: () => void; +} +let ii: I3 = { // Not fixable, implements functional-type property as a method + a: 1.0, + b() {} +}; + +// Inheritance +class Base { + constructor() {} +} +class Derived extends Base { + m() {} +} +class GeneratedObjectLiteralClass_9 extends Derived { + m() { console.log(2.0); } +} + +let b: Derived = new GeneratedObjectLiteralClass_9(); + +class Base2 { + constructor(a: number) {} +} +class Derived2 extends Base2 { + m() {} +} +let b2: Derived2 = { // Not fixable, derived class inherits a constructor with parameters from base class + m() { console.log(2.0); } +}; + +class Base3 { + constructor(a: number) {} +} +class Derived3 extends Base3 { + m() {} + + constructor() { + super(1.0); + } +} +class GeneratedObjectLiteralClass_10 extends Derived3 { + m() { console.log(2.0); } +} + +let b3: Derived3 = new GeneratedObjectLiteralClass_10(); + +interface A { + map: Map; +} +let map:Map = new Map(); +let a:A = {map}; + +class C { + map1: Map = new Map(); +} + +let map1:Map = new Map(); +let c:C = {map1}; \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/destructuring_declarations.ts.migrate.json b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json similarity index 31% rename from ets2panda/linter/test/migrate/destructuring_declarations.ts.migrate.json rename to ets2panda/linter/test/main/object_literals_properties.ets.migrate.json index 0729d4936cb374f8b43bd73043faa9da2d2cc6c0..9143d0676d166e6b9291a69bf5f6a0bbf880a2b3 100644 --- a/ets2panda/linter/test/migrate/destructuring_declarations.ts.migrate.json +++ b/ets2panda/linter/test/main/object_literals_properties.ets.migrate.json @@ -1,493 +1,337 @@ { + "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": 17, - "column": 5, - "endLine": 17, - "endColumn": 47, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 19, - "endLine": 17, - "endColumn": 20, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 40, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 24, - "endLine": 18, - "endColumn": 25, + "line": 39, + "column": 17, + "endLine": 39, + "endColumn": 18, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 68, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 34, - "endLine": 19, - "endColumn": 35, + "line": 45, + "column": 14, + "endLine": 45, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 19, - "column": 47, - "endLine": 19, - "endColumn": 48, - "problem": "ObjectLiteralNoContextType", + "line": 46, + "column": 3, + "endLine": 46, + "endColumn": 15, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 20, - "column": 5, - "endLine": 20, - "endColumn": 66, - "problem": "DestructuringDeclaration", + "line": 46, + "column": 3, + "endLine": 46, + "endColumn": 15, + "problem": "SpreadOperator", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", "severity": "ERROR" }, { - "line": 20, - "column": 32, - "endLine": 20, - "endColumn": 33, + "line": 92, + "column": 16, + "endLine": 92, + "endColumn": 17, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 20, - "column": 45, - "endLine": 20, - "endColumn": 46, - "problem": "ObjectLiteralNoContextType", + "line": 98, + "column": 3, + "endLine": 98, + "endColumn": 9, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 22, - "column": 5, - "endLine": 22, - "endColumn": 21, - "problem": "DestructuringDeclaration", + "line": 99, + "column": 3, + "endLine": 99, + "endColumn": 15, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 22, - "column": 19, - "endLine": 22, - "endColumn": 20, - "problem": "ObjectLiteralNoContextType", + "line": 99, + "column": 3, + "endLine": 99, + "endColumn": 15, + "problem": "SpreadOperator", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", "severity": "ERROR" }, { - "line": 25, - "column": 10, - "endLine": 25, - "endColumn": 11, + "line": 166, + "column": 15, + "endLine": 166, + "endColumn": 16, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 27, - "column": 5, - "endLine": 27, - "endColumn": 29, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 7, - "endLine": 30, - "endColumn": 34, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 7, - "endLine": 31, - "endColumn": 48, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 7, - "endLine": 32, - "endColumn": 52, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 7, - "endLine": 33, - "endColumn": 56, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 7, - "endLine": 35, - "endColumn": 64, - "problem": "DestructuringDeclaration", + "line": 170, + "column": 3, + "endLine": 170, + "endColumn": 28, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 36, - "column": 7, - "endLine": 36, - "endColumn": 85, - "problem": "DestructuringDeclaration", + "line": 171, + "column": 3, + "endLine": 171, + "endColumn": 15, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 39, - "column": 5, - "endLine": 39, - "endColumn": 25, - "problem": "DestructuringDeclaration", + "line": 171, + "column": 3, + "endLine": 171, + "endColumn": 15, + "problem": "SpreadOperator", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", "severity": "ERROR" }, { - "line": 40, - "column": 5, - "endLine": 40, - "endColumn": 29, - "problem": "DestructuringDeclaration", + "line": 183, + "column": 14, + "endLine": 183, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 43, - "column": 5, - "endLine": 43, + "line": 187, + "column": 3, + "endLine": 187, "endColumn": 28, - "problem": "DestructuringDeclaration", + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 46, - "column": 5, - "endLine": 46, + "line": 192, + "column": 25, + "endLine": 192, "endColumn": 26, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 49, - "column": 5, - "endLine": 49, - "endColumn": 35, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 5, - "endLine": 52, - "endColumn": 67, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 41, - "endLine": 52, - "endColumn": 66, - "problem": "ArrayLiteralNoContextType", - "suggest": "", - "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 55, - "endLine": 52, - "endColumn": 56, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 53, + "line": 193, "column": 5, - "endLine": 53, - "endColumn": 60, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 43, - "endLine": 53, - "endColumn": 60, - "problem": "ArrayLiteralNoContextType", + "endLine": 195, + "endColumn": 6, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 53, - "column": 50, - "endLine": 53, - "endColumn": 51, + "line": 198, + "column": 29, + "endLine": 198, + "endColumn": 30, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 54, - "column": 7, - "endLine": 54, - "endColumn": 45, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 56, + "line": 199, "column": 5, - "endLine": 56, - "endColumn": 55, - "problem": "DestructuringDeclaration", + "endLine": 201, + "endColumn": 6, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 56, - "column": 32, - "endLine": 56, - "endColumn": 33, + "line": 209, + "column": 26, + "endLine": 209, + "endColumn": 27, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 57, + "line": 210, "column": 5, - "endLine": 63, - "endColumn": 52, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 5, - "endLine": 63, + "endLine": 212, "endColumn": 6, - "problem": "ObjectLiteralNoContextType", + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 63, - "column": 21, - "endLine": 63, - "endColumn": 22, + "line": 214, + "column": 27, + "endLine": 214, + "endColumn": 28, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 66, + "line": 215, "column": 5, - "endLine": 66, - "endColumn": 51, - "problem": "DestructuringDeclaration", + "endLine": 217, + "endColumn": 6, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 66, - "column": 23, - "endLine": 66, - "endColumn": 24, + "line": 221, + "column": 27, + "endLine": 221, + "endColumn": 28, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 67, + "line": 222, "column": 5, - "endLine": 67, - "endColumn": 73, - "problem": "DestructuringDeclaration", + "endLine": 224, + "endColumn": 6, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 67, - "column": 39, - "endLine": 67, - "endColumn": 40, + "line": 233, + "column": 14, + "endLine": 233, + "endColumn": 15, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 67, - "column": 52, - "endLine": 67, - "endColumn": 53, - "problem": "ObjectLiteralNoContextType", + "line": 244, + "column": 3, + "endLine": 244, + "endColumn": 9, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 68, - "column": 5, - "endLine": 68, - "endColumn": 33, - "problem": "DestructuringDeclaration", + "line": 251, + "column": 14, + "endLine": 251, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 69, - "column": 5, - "endLine": 69, - "endColumn": 60, - "problem": "DestructuringDeclaration", + "line": 262, + "column": 3, + "endLine": 262, + "endColumn": 9, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 69, - "column": 37, - "endLine": 69, - "endColumn": 38, + "line": 284, + "column": 20, + "endLine": 284, + "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 70, - "column": 5, - "endLine": 76, - "endColumn": 52, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", - "severity": "ERROR" - }, - { - "line": 76, - "column": 5, - "endLine": 76, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", + "line": 285, + "column": 3, + "endLine": 285, + "endColumn": 28, + "problem": "ObjectLiteralProperty", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object literal properties can only contain name-value pairs (arkts-obj-literal-props)", "severity": "ERROR" }, { - "line": 76, - "column": 21, - "endLine": 76, - "endColumn": 22, + "line": 315, + "column": 11, + "endLine": 315, + "endColumn": 12, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 85, - "column": 5, - "endLine": 85, - "endColumn": 26, - "problem": "DestructuringDeclaration", - "suggest": "", - "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "line": 240, + "column": 3, + "endLine": 240, + "endColumn": 4, + "problem": "StrictDiagnostic", + "suggest": "Property 'b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'b' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/object_spread.ets.args.json b/ets2panda/linter/test/main/object_spread.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/object_spread.ets.args.json +++ b/ets2panda/linter/test/main/object_spread.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/object_spread.ets.migrate.ets b/ets2panda/linter/test/main/object_spread.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..0925345ec75f9e3f93949e9a4753fcfcdd9d9c0c --- /dev/null +++ b/ets2panda/linter/test/main/object_spread.ets.migrate.ets @@ -0,0 +1,26 @@ +/* + * 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. + */ + +interface GeneratedObjectLiteralInterface_1 { + x: number; + y: number; +} +const pt2D: GeneratedObjectLiteralInterface_1 = { x: 1, y: 2 }; + +console.log(pt2D); + +const pt3D = { ...pt2D, z: 3 }; + +console.log(pt3D); diff --git a/ets2panda/linter/test/main/object_spread.ets.migrate.json b/ets2panda/linter/test/main/object_spread.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..b1bad3882fd487054e27edcac38ef174bb8b4684 --- /dev/null +++ b/ets2panda/linter/test/main/object_spread.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 24, + "column": 14, + "endLine": 24, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 16, + "endLine": 24, + "endColumn": 23, + "problem": "SpreadOperator", + "suggest": "", + "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@arkts.collections.d.ets b/ets2panda/linter/test/main/oh_modules/@arkts.collections.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..f54a1fd4d6e9776e65d68aeb141b9e54d5163559 --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@arkts.collections.d.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. + */ + +export namespace collections { + export class Array implements ConcatArray { + constructor(); + } + + export class Map { + constructor(entries?: readonly (readonly [K, V])[] | null); + } + + export interface ConcatArray { + + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.ets b/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..df9184137493b52f8f3387f4c5518985c9d24e5a --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@arkts.utils.d.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. + */ + +export namespace utils { + namespace ASON { + function stringify(value: Object | null | undefined): string; + } +} + +export default utils; \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ets b/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd994ead622471b25a9e0e8a233865d567fac6b4 --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@kit.ArkTS.d.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. + */ + +export { worker } from '../oh_modules/@ohos.worker'; +export { collections } from '../oh_modules/@arkts.collections'; +export { utils } from '../oh_modules/@arkts.utils'; +export { taskpool } from '../oh_modules/@ohos.taskpool'; \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@ohos.taskpool.d.ets b/ets2panda/linter/test/main/oh_modules/@ohos.taskpool.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..f727b78f7a23e2d0c034d02fe71aef9d9c045d36 --- /dev/null +++ b/ets2panda/linter/test/main/oh_modules/@ohos.taskpool.d.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 namespace taskpool { + export const isConcurrent: () => boolean; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/oh_modules/@ohos.worker.d.ts b/ets2panda/linter/test/main/oh_modules/@ohos.worker.d.ets similarity index 100% rename from ets2panda/linter/test/main/oh_modules/@ohos.worker.d.ts rename to ets2panda/linter/test/main/oh_modules/@ohos.worker.d.ets diff --git a/ets2panda/linter/test/main/parameter_properties.ets b/ets2panda/linter/test/main/parameter_properties.ets index 3be0d8ac58ab4aa37054209aae12415ad9bd0678..77065182777c657ac558b395830d55c605b8e9a4 100644 --- a/ets2panda/linter/test/main/parameter_properties.ets +++ b/ets2panda/linter/test/main/parameter_properties.ets @@ -88,4 +88,16 @@ class F4 extends E { console.log('after super() call'); let f5: number = 1; } +} + +class G { + constructor(a?: number) {} +} + +class G1 { + constructor(public a?: number, public b: number) {} +} + +class G2 { + constructor(public a?: number, public b?: number) {} } \ No newline at end of file diff --git a/ets2panda/linter/test/main/parameter_properties.ets.args.json b/ets2panda/linter/test/main/parameter_properties.ets.args.json index 4e9dc628f7cbbb3ac73a21b2ce9f794758fcaae0..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100644 --- a/ets2panda/linter/test/main/parameter_properties.ets.args.json +++ b/ets2panda/linter/test/main/parameter_properties.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/parameter_properties.ets.arkts2.json b/ets2panda/linter/test/main/parameter_properties.ets.arkts2.json index 4cf7c679962af5d9c788f96898eb39d0a9fe5d90..70d8cbcfa4df48aa1d164eeb6c88d7ce540829db 100644 --- a/ets2panda/linter/test/main/parameter_properties.ets.arkts2.json +++ b/ets2panda/linter/test/main/parameter_properties.ets.arkts2.json @@ -44,6 +44,46 @@ "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" }, + { + "line": 28, + "column": 17, + "endLine": 28, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 34, "column": 26, @@ -64,6 +104,46 @@ "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" }, + { + "line": 34, + "column": 92, + "endLine": 34, + "endColumn": 93, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 95, + "endLine": 34, + "endColumn": 96, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 98, + "endLine": 34, + "endColumn": 99, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 17, + "endLine": 39, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 43, "column": 15, @@ -114,6 +194,26 @@ "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, + { + "line": 51, + "column": 15, + "endLine": 51, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 15, + "endLine": 52, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 54, "column": 15, @@ -164,6 +264,16 @@ "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" }, + { + "line": 69, + "column": 22, + "endLine": 69, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 76, "column": 15, @@ -174,6 +284,16 @@ "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" }, + { + "line": 78, + "column": 22, + "endLine": 78, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 84, "column": 15, @@ -183,6 +303,66 @@ "suggest": "", "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" + }, + { + "line": 85, + "column": 22, + "endLine": 85, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 22, + "endLine": 89, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 15, + "endLine": 98, + "endColumn": 21, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 15, + "endLine": 102, + "endColumn": 21, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/parameter_properties.ets.autofix.json b/ets2panda/linter/test/main/parameter_properties.ets.autofix.json index 03a87b740ce5ce4ec6667f3924db6d77604be8d1..cd0ccd75eea12792b175ccd228d33d91e6cb5b8f 100644 --- a/ets2panda/linter/test/main/parameter_properties.ets.autofix.json +++ b/ets2panda/linter/test/main/parameter_properties.ets.autofix.json @@ -24,27 +24,47 @@ { "start": 622, "end": 622, - "replacementText": "public readonly x: number;\nprotected y: number;\nprivate z: number;\n" + "replacementText": "public readonly x: number;\nprotected y: number;\nprivate z: number;\n", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 639, "end": 664, - "replacementText": "x: number" + "replacementText": "x: number", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 670, "end": 689, - "replacementText": "y: number" + "replacementText": "y: number", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 695, "end": 712, - "replacementText": "z: number" + "replacementText": "z: number", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 717, "end": 719, - "replacementText": "{\n this.x = x;\n this.y = y;\n this.z = z;\n}" + "replacementText": "{\n this.x = x;\n this.y = y;\n this.z = z;\n}", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 } ], "suggest": "", @@ -61,27 +81,47 @@ { "start": 622, "end": 622, - "replacementText": "public readonly x: number;\nprotected y: number;\nprivate z: number;\n" + "replacementText": "public readonly x: number;\nprotected y: number;\nprivate z: number;\n", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 639, "end": 664, - "replacementText": "x: number" + "replacementText": "x: number", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 670, "end": 689, - "replacementText": "y: number" + "replacementText": "y: number", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 695, "end": 712, - "replacementText": "z: number" + "replacementText": "z: number", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 717, "end": 719, - "replacementText": "{\n this.x = x;\n this.y = y;\n this.z = z;\n}" + "replacementText": "{\n this.x = x;\n this.y = y;\n this.z = z;\n}", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 } ], "suggest": "", @@ -98,33 +138,137 @@ { "start": 622, "end": 622, - "replacementText": "public readonly x: number;\nprotected y: number;\nprivate z: number;\n" + "replacementText": "public readonly x: number;\nprotected y: number;\nprivate z: number;\n", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 639, "end": 664, - "replacementText": "x: number" + "replacementText": "x: number", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 670, "end": 689, - "replacementText": "y: number" + "replacementText": "y: number", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 695, "end": 712, - "replacementText": "z: number" + "replacementText": "z: number", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 }, { "start": 717, "end": 719, - "replacementText": "{\n this.x = x;\n this.y = y;\n this.z = z;\n}" + "replacementText": "{\n this.x = x;\n this.y = y;\n this.z = z;\n}", + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 12 } ], "suggest": "", "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" }, + { + "line": 28, + "column": 17, + "endLine": 28, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 803, + "end": 804, + "replacementText": "1.0", + "line": 28, + "column": 17, + "endLine": 28, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 21, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 806, + "end": 807, + "replacementText": "2.0", + "line": 28, + "column": 20, + "endLine": 28, + "endColumn": 21 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 809, + "end": 810, + "replacementText": "3.0", + "line": 28, + "column": 23, + "endLine": 28, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 24, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 863, + "end": 865, + "replacementText": "10.0", + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 24 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 34, "column": 26, @@ -135,22 +279,38 @@ { "start": 870, "end": 870, - "replacementText": "public w: string;\nprivate readonly r: number[];\n" + "replacementText": "public w: string;\nprivate readonly r: number[];\n", + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 67 }, { "start": 893, "end": 913, - "replacementText": "w = 'default'" + "replacementText": "w = 'default'", + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 67 }, { "start": 927, "end": 967, - "replacementText": "r: number[] = [1, 2, 3]" + "replacementText": "r: number[] = [1, 2, 3]", + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 67 }, { "start": 969, "end": 1021, - "replacementText": "{\n this.w = w;\n this.r = r;\n console.log(q, this.w, e, this.r, this.f);\n}" + "replacementText": "{\n this.w = w;\n this.r = r;\n console.log(q, this.w, e, this.r, this.f);\n}", + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 67 } ], "suggest": "", @@ -167,28 +327,128 @@ { "start": 870, "end": 870, - "replacementText": "public w: string;\nprivate readonly r: number[];\n" + "replacementText": "public w: string;\nprivate readonly r: number[];\n", + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 67 }, { "start": 893, "end": 913, - "replacementText": "w = 'default'" + "replacementText": "w = 'default'", + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 67 }, { "start": 927, "end": 967, - "replacementText": "r: number[] = [1, 2, 3]" + "replacementText": "r: number[] = [1, 2, 3]", + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 67 }, { "start": 969, "end": 1021, - "replacementText": "{\n this.w = w;\n this.r = r;\n console.log(q, this.w, e, this.r, this.f);\n}" + "replacementText": "{\n this.w = w;\n this.r = r;\n console.log(q, this.w, e, this.r, this.f);\n}", + "line": 34, + "column": 60, + "endLine": 34, + "endColumn": 67 } ], "suggest": "", "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" }, + { + "line": 34, + "column": 92, + "endLine": 34, + "endColumn": 93, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 959, + "end": 960, + "replacementText": "1.0", + "line": 34, + "column": 92, + "endLine": 34, + "endColumn": 93 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 95, + "endLine": 34, + "endColumn": 96, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 962, + "end": 963, + "replacementText": "2.0", + "line": 34, + "column": 95, + "endLine": 34, + "endColumn": 96 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 98, + "endLine": 34, + "endColumn": 99, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 965, + "end": 966, + "replacementText": "3.0", + "line": 34, + "column": 98, + "endLine": 34, + "endColumn": 99 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 17, + "endLine": 39, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1041, + "end": 1042, + "replacementText": "1.0", + "line": 39, + "column": 17, + "endLine": 39, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 43, "column": 15, @@ -239,18 +499,68 @@ { "start": 1139, "end": 1139, - "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n x: string;\n}\n" + "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n x: string;\n}\n", + "line": 47, + "column": 44, + "endLine": 47, + "endColumn": 45 }, { "start": 1192, "end": 1203, - "replacementText": "GeneratedTypeLiteralInterface_1" + "replacementText": "GeneratedTypeLiteralInterface_1", + "line": 47, + "column": 44, + "endLine": 47, + "endColumn": 45 } ], "suggest": "", "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", "severity": "ERROR" }, + { + "line": 51, + "column": 15, + "endLine": 51, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1250, + "end": 1251, + "replacementText": "0.0", + "line": 51, + "column": 15, + "endLine": 51, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 15, + "endLine": 52, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1267, + "end": 1268, + "replacementText": "0.0", + "line": 52, + "column": 15, + "endLine": 52, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 54, "column": 15, @@ -261,17 +571,29 @@ { "start": 1275, "end": 1275, - "replacementText": "readonly a: number;\n" + "replacementText": "readonly a: number;\n", + "line": 54, + "column": 15, + "endLine": 54, + "endColumn": 33 }, { "start": 1287, "end": 1305, - "replacementText": "a: number" + "replacementText": "a: number", + "line": 54, + "column": 15, + "endLine": 54, + "endColumn": 33 }, { "start": 1307, "end": 1309, - "replacementText": "{\n this.a = a;\n}" + "replacementText": "{\n this.a = a;\n}", + "line": 54, + "column": 15, + "endLine": 54, + "endColumn": 33 } ], "suggest": "", @@ -288,27 +610,47 @@ { "start": 1335, "end": 1335, - "replacementText": "readonly aa: number;\nb: number;\npublic c: number;\n" + "replacementText": "readonly aa: number;\nb: number;\npublic c: number;\n", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1352, "end": 1371, - "replacementText": "aa: number" + "replacementText": "aa: number", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1377, "end": 1395, - "replacementText": "b: number" + "replacementText": "b: number", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1401, "end": 1426, - "replacementText": "c: number" + "replacementText": "c: number", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1430, "end": 1450, - "replacementText": "{\n super(aa);\n this.aa = aa;\n this.b = b;\n this.c = c;\n}" + "replacementText": "{\n super(aa);\n this.aa = aa;\n this.b = b;\n this.c = c;\n}", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 } ], "suggest": "", @@ -325,27 +667,47 @@ { "start": 1335, "end": 1335, - "replacementText": "readonly aa: number;\nb: number;\npublic c: number;\n" + "replacementText": "readonly aa: number;\nb: number;\npublic c: number;\n", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1352, "end": 1371, - "replacementText": "aa: number" + "replacementText": "aa: number", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1377, "end": 1395, - "replacementText": "b: number" + "replacementText": "b: number", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1401, "end": 1426, - "replacementText": "c: number" + "replacementText": "c: number", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1430, "end": 1450, - "replacementText": "{\n super(aa);\n this.aa = aa;\n this.b = b;\n this.c = c;\n}" + "replacementText": "{\n super(aa);\n this.aa = aa;\n this.b = b;\n this.c = c;\n}", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 } ], "suggest": "", @@ -362,27 +724,47 @@ { "start": 1335, "end": 1335, - "replacementText": "readonly aa: number;\nb: number;\npublic c: number;\n" + "replacementText": "readonly aa: number;\nb: number;\npublic c: number;\n", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1352, "end": 1371, - "replacementText": "aa: number" + "replacementText": "aa: number", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1377, "end": 1395, - "replacementText": "b: number" + "replacementText": "b: number", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1401, "end": 1426, - "replacementText": "c: number" + "replacementText": "c: number", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 }, { "start": 1430, "end": 1450, - "replacementText": "{\n super(aa);\n this.aa = aa;\n this.b = b;\n this.c = c;\n}" + "replacementText": "{\n super(aa);\n this.aa = aa;\n this.b = b;\n this.c = c;\n}", + "line": 61, + "column": 5, + "endLine": 61, + "endColumn": 11 } ], "suggest": "", @@ -399,23 +781,56 @@ { "start": 1477, "end": 1477, - "replacementText": "readonly aa: number;\n" + "replacementText": "readonly aa: number;\n", + "line": 68, + "column": 15, + "endLine": 68, + "endColumn": 34 }, { "start": 1489, "end": 1508, - "replacementText": "aa: number" + "replacementText": "aa: number", + "line": 68, + "column": 15, + "endLine": 68, + "endColumn": 34 }, { "start": 1510, "end": 1594, - "replacementText": "{\n let f2: number = 1;\n console.log('before super() call');\n super(aa);\n this.aa = aa;\n}" + "replacementText": "{\n let f2: number = 1;\n console.log('before super() call');\n super(aa);\n this.aa = aa;\n}", + "line": 68, + "column": 15, + "endLine": 68, + "endColumn": 34 } ], "suggest": "", "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" }, + { + "line": 69, + "column": 22, + "endLine": 69, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1533, + "end": 1534, + "replacementText": "1.0", + "line": 69, + "column": 22, + "endLine": 69, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 76, "column": 15, @@ -426,23 +841,56 @@ { "start": 1621, "end": 1621, - "replacementText": "readonly aa: number;\n" + "replacementText": "readonly aa: number;\n", + "line": 76, + "column": 15, + "endLine": 76, + "endColumn": 34 }, { "start": 1633, "end": 1652, - "replacementText": "aa: number" + "replacementText": "aa: number", + "line": 76, + "column": 15, + "endLine": 76, + "endColumn": 34 }, { "start": 1654, "end": 1737, - "replacementText": "{\n super(aa);\n this.aa = aa;\n let f3: number = 1;\n console.log('after super() call');\n}" + "replacementText": "{\n super(aa);\n this.aa = aa;\n let f3: number = 1;\n console.log('after super() call');\n}", + "line": 76, + "column": 15, + "endLine": 76, + "endColumn": 34 } ], "suggest": "", "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR" }, + { + "line": 78, + "column": 22, + "endLine": 78, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1692, + "end": 1693, + "replacementText": "1.0", + "line": 78, + "column": 22, + "endLine": 78, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 84, "column": 15, @@ -453,17 +901,263 @@ { "start": 1764, "end": 1764, - "replacementText": "readonly aa: number;\n" + "replacementText": "readonly aa: number;\n", + "line": 84, + "column": 15, + "endLine": 84, + "endColumn": 34 }, { "start": 1776, "end": 1795, - "replacementText": "aa: number" + "replacementText": "aa: number", + "line": 84, + "column": 15, + "endLine": 84, + "endColumn": 34 }, { "start": 1797, "end": 1944, - "replacementText": "{\n let f4: number = 1;\n console.log('before super() call');\n super(aa);\n this.aa = aa;\n console.log('after super() call');\n let f5: number = 1;\n}" + "replacementText": "{\n let f4: number = 1;\n console.log('before super() call');\n super(aa);\n this.aa = aa;\n console.log('after super() call');\n let f5: number = 1;\n}", + "line": 84, + "column": 15, + "endLine": 84, + "endColumn": 34 + } + ], + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 22, + "endLine": 85, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1820, + "end": 1821, + "replacementText": "1.0", + "line": 85, + "column": 22, + "endLine": 85, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 89, + "column": 22, + "endLine": 89, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1938, + "end": 1939, + "replacementText": "1.0", + "line": 89, + "column": 22, + "endLine": 89, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 15, + "endLine": 98, + "endColumn": 21, + "problem": "ParameterProperties", + "autofix": [ + { + "start": 2003, + "end": 2003, + "replacementText": "public a?: number;\npublic b: number;\n", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 + }, + { + "start": 2015, + "end": 2032, + "replacementText": "a?: number", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 + }, + { + "start": 2034, + "end": 2050, + "replacementText": "b: number", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 + }, + { + "start": 2052, + "end": 2054, + "replacementText": "{\n this.a = a;\n this.b = b;\n}", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 + } + ], + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40, + "problem": "ParameterProperties", + "autofix": [ + { + "start": 2003, + "end": 2003, + "replacementText": "public a?: number;\npublic b: number;\n", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 + }, + { + "start": 2015, + "end": 2032, + "replacementText": "a?: number", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 + }, + { + "start": 2034, + "end": 2050, + "replacementText": "b: number", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 + }, + { + "start": 2052, + "end": 2054, + "replacementText": "{\n this.a = a;\n this.b = b;\n}", + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40 + } + ], + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 15, + "endLine": 102, + "endColumn": 21, + "problem": "ParameterProperties", + "autofix": [ + { + "start": 2071, + "end": 2071, + "replacementText": "public a?: number;\npublic b?: number;\n", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 + }, + { + "start": 2083, + "end": 2100, + "replacementText": "a?: number", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 + }, + { + "start": 2102, + "end": 2119, + "replacementText": "b?: number", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 + }, + { + "start": 2121, + "end": 2123, + "replacementText": "{\n this.a = a;\n this.b = b;\n}", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 + } + ], + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40, + "problem": "ParameterProperties", + "autofix": [ + { + "start": 2071, + "end": 2071, + "replacementText": "public a?: number;\npublic b?: number;\n", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 + }, + { + "start": 2083, + "end": 2100, + "replacementText": "a?: number", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 + }, + { + "start": 2102, + "end": 2119, + "replacementText": "b?: number", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 + }, + { + "start": 2121, + "end": 2123, + "replacementText": "{\n this.a = a;\n this.b = b;\n}", + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/parameter_properties.ets.json b/ets2panda/linter/test/main/parameter_properties.ets.json index 740ab08888c77cd9ea9000e8d6820c91728ead43..f532162ae3b48fcc24939e15eeeb52d68499024c 100644 --- a/ets2panda/linter/test/main/parameter_properties.ets.json +++ b/ets2panda/linter/test/main/parameter_properties.ets.json @@ -178,6 +178,46 @@ "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", "severity": "ERROR", "exclusive": "SDK" + }, + { + "line": 98, + "column": 15, + "endLine": 98, + "endColumn": 21, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 34, + "endLine": 98, + "endColumn": 40, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 15, + "endLine": 102, + "endColumn": 21, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 34, + "endLine": 102, + "endColumn": 40, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/parameter_properties.ets.migrate.ets b/ets2panda/linter/test/main/parameter_properties.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..0633fc1c9940ea94220e26ef0f0117939450dbef --- /dev/null +++ b/ets2panda/linter/test/main/parameter_properties.ets.migrate.ets @@ -0,0 +1,147 @@ +/* + * 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. + */ + +class A { + public readonly x: number; +protected y: number; +private z: number; +constructor( + x: number, + y: number, + z: number + ) { + this.x = x; + this.y = y; + this.z = z; +} + + foo(): void { + console.log(this.x + this.y + this.z); + } +} + +const a = new A(1.0, 2.0, 3.0); +console.log(a.x); + +class B { + public f: number = 10.0; + + public w: string; +private readonly r: number[]; +constructor(q: number, w = 'default', e: boolean, r: number[] = [1.0, 2.0, 3.0]) { + this.w = w; + this.r = r; + console.log(q, this.w, e, this.r, this.f); +} +} + +const b = new B(1.0, '2', true, []); +console.log(b.w); + +class C { + constructor(public a: any) {} // not fixable +} + +interface GeneratedTypeLiteralInterface_1 { + x: string; +} +class D { + public a: number; +private b: GeneratedTypeLiteralInterface_1; +constructor(a: number, b: GeneratedTypeLiteralInterface_1) { + this.a = a; + this.b = b; +} // not fixable +} + +class E { + b: number = 0.0; + c: number = 0.0; + + readonly a: number; +constructor(a: number) { + this.a = a; +} +} + +class F extends E { + readonly aa: number; +b: number; +public c: number; +constructor( + aa: number, + b: number, + c: number + ){ + super(aa); + this.aa = aa; + this.b = b; + this.c = c; +} +} + +class F2 extends E { + readonly aa: number; +constructor(aa: number) { + let f2: number = 1.0; + console.log('before super() call'); + super(aa); + this.aa = aa; +} +} + +class F3 extends E { + readonly aa: number; +constructor(aa: number) { + super(aa); + this.aa = aa; + let f3: number = 1.0; + console.log('after super() call'); +} +} + +class F4 extends E { + readonly aa: number; +constructor(aa: number) { + let f4: number = 1.0; + console.log('before super() call'); + super(aa); + this.aa = aa; + console.log('after super() call'); + let f5: number = 1.0; +} +} + +class G { + constructor(a?: number) {} +} + +class G1 { + public a?: number; +public b: number; +constructor(a?: number, b: number) { + this.a = a; + this.b = b; +} +} + +class G2 { + public a?: number; +public b?: number; +constructor(a?: number, b?: number) { + this.a = a; + this.b = b; +} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/parameter_properties.ets.migrate.json b/ets2panda/linter/test/main/parameter_properties.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..03cac9f4e47f0a3b2f7cc5966991917f603ee4d0 --- /dev/null +++ b/ets2panda/linter/test/main/parameter_properties.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 54, + "column": 15, + "endLine": 54, + "endColumn": 21, + "problem": "ParameterProperties", + "suggest": "", + "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 25, + "endLine": 54, + "endColumn": 28, + "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/main/private_identifiers.ets.args.json b/ets2panda/linter/test/main/private_identifiers.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/private_identifiers.ets.args.json +++ b/ets2panda/linter/test/main/private_identifiers.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/private_identifiers.ets.migrate.ets b/ets2panda/linter/test/main/private_identifiers.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..001beccf210eebba407f1d00bc14b8846391f25f --- /dev/null +++ b/ets2panda/linter/test/main/private_identifiers.ets.migrate.ets @@ -0,0 +1,78 @@ +/* + * 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 C { + private p: number; + + p2: number; + #p2: string; // not fixable + + private q?: string; + private e!: string; + private static s = 0; + private readonly r = 20; + private static readonly sr = 0; + private static readonly srq?: string; + + private m(x: number): void { } + + m2(x: number): void {} + #m2(x: number): void {} // not fixable + + m3: boolean; + #m3(x: number): void {} // not fixable + + private get g1(): number { return 10; } + private set s1(x: number) { } + + private static get g2(): number { return 10; } + private static set s2(x: number) { } + + test() { + console.log(this.p + this.#p2 + this.q + this.e + C.s + this.r + C.sr + C.srq); // '#p2' is not fixable + this.m(10); + this.#m2(20); // not fixable + this.#m3(30); // not fixable + let x = this.g1; + this.s1 = x; + let y = C.g2; + C.s2 = y; + } +} + +class D extends C { + private a: string; + #p: number; // not fixable + + #m(): string { return 'foo'; } // not fixable + + private bar(): string { return 'baz'; } + + test() { + console.log(this.#p + this.a); // '#p' is not fixable + let x = this.#m(); // not fixable + let y = this.bar(); + } +} + +class E { + private a: number; + #b: string; // not fixable + + public b: number; +constructor(b: number) { + this.b = b; +} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/private_identifiers.ets.migrate.json b/ets2panda/linter/test/main/private_identifiers.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..4b6bcee72005fd48c5985cc177fe2dad249d7a20 --- /dev/null +++ b/ets2panda/linter/test/main/private_identifiers.ets.migrate.json @@ -0,0 +1,318 @@ +{ + "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": 19, + "column": 3, + "endLine": 19, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 6, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 32, + "endColumn": 6, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 6, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 6, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 3, + "endLine": 23, + "endColumn": 22, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 32, + "column": 3, + "endLine": 32, + "endColumn": 6, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 6, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 31, + "endLine": 44, + "endColumn": 34, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 10, + "endLine": 46, + "endColumn": 13, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 10, + "endLine": 47, + "endColumn": 13, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 5, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 22, + "endLine": 64, + "endColumn": 24, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 18, + "endLine": 65, + "endColumn": 20, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 3, + "endLine": 72, + "endColumn": 5, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 10, + "endLine": 74, + "endColumn": 11, + "problem": "DeclWithDuplicateName", + "suggest": "", + "rule": "Use unique names for types and namespaces. (arkts-unique-names)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 3, + "endLine": 72, + "endColumn": 5, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 11, + "endLine": 17, + "endColumn": 12, + "problem": "StrictDiagnostic", + "suggest": "Property 'p' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'p' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property 'p2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'p2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 20, + "column": 3, + "endLine": 20, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property '#p2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '#p2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property 'm3' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'm3' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 56, + "column": 11, + "endLine": 56, + "endColumn": 12, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property '#p' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '#p' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 71, + "column": 11, + "endLine": 71, + "endColumn": 12, + "problem": "StrictDiagnostic", + "suggest": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'a' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 72, + "column": 3, + "endLine": 72, + "endColumn": 5, + "problem": "StrictDiagnostic", + "suggest": "Property '#b' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '#b' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..7f83645b5e8aa5d4df1227701293a81aa80a7897 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets @@ -0,0 +1,39 @@ +/* + * 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 User { + name: string = "" + age: number = 0 +} + +@Entry +@Component +struct FatherComponent { + @Prop user1: User = new User() + @StorageLink("user2") user2: User = new User() + @LocalStorageLink("user3") user3: User = new User() + + build() { + } +} + +@Component +struct ChildComponent { + @StorageProp("user2") user2: User = new User() + @LocalStorageProp("user3") user3: User = new User() + + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.args.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.arkts2.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..2bf08fd4ccfd72ff49c58ef08d1ae0df86136eb1 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.arkts2.json @@ -0,0 +1,138 @@ +{ + "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": 18, + "column": 17, + "endLine": 18, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 33, + "problem": "PropDecoratorNotSupported", + "suggest": "", + "rule": "\"@Prop\" decorator is not supported (arkui-no-prop-decorator)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 3, + "endLine": 34, + "endColumn": 49, + "problem": "StoragePropDecoratorNotSupported", + "suggest": "", + "rule": "\"@StorageProp\" decorator is not supported (arkui-no-storageprop-decorator)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 3, + "endLine": 35, + "endColumn": 54, + "problem": "LocalStoragePropDecoratorNotSupported", + "suggest": "", + "rule": "\"@LocalStorageProp\" decorator is not supported (arkui-no-localstorageprop-decorator)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 4, + "endLine": 24, + "endColumn": 8, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 4, + "endLine": 25, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 4, + "endLine": 26, + "endColumn": 20, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 2, + "endLine": 32, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 4, + "endLine": 34, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 4, + "endLine": 35, + "endColumn": 20, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_1.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/prop_decorator_and_interfaces_2.ets b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..f218bde1db65360c1d8e33e6bebc75814dded0a9 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets @@ -0,0 +1,49 @@ +/* + * 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 MyClassA { + +} + +let para: Record = { 'PropA': 47 } +let storage: LocalStorage = new LocalStorage(para) +let prop1 = storage.prop('PropA') +let prop2 = storage.prop('PropA') +let prop3 = storage.prop('PropA') +let prop4: SubscribedAbstractProperty = storage.prop('PropA') +let prop5: SubscribedAbstractProperty = storage.prop('PropA') +let prop6: SubscribedAbstractProperty = storage.prop('PropA') + +AppStorage.SetOrCreate('PropB', 46) +let prop7 = AppStorage.prop('PropB') +let prop8 = AppStorage.prop('PropB') +let prop9 = AppStorage.prop('PropB') +let prop10: SubscribedAbstractProperty = AppStorage.prop('PropB') +let prop11: SubscribedAbstractProperty = AppStorage.prop('PropB') +let prop12: SubscribedAbstractProperty = AppStorage.prop('PropB') + +@Entry +@Component +struct MyComponent { + + aboutToAppear(): void { + let storage = LocalStorage.getShared() + let prop1 = storage.prop('PropA') + let prop2: SubscribedAbstractProperty = storage.prop('PropA') + } + + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.args.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/types.ts.migrate.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.arkts2.json similarity index 34% rename from ets2panda/linter/test/migrate/types.ts.migrate.json rename to ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.arkts2.json index 58dcba3064bfe3da860676abdf6ee444eb2b924c..791b77c85e61b4463b108d16f15083fa86c74a2a 100644 --- a/ets2panda/linter/test/migrate/types.ts.migrate.json +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.arkts2.json @@ -1,453 +1,467 @@ { + "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": 17, - "column": 15, - "endLine": 17, - "endColumn": 18, - "problem": "AnyType", + "line": 20, + "column": 47, + "endLine": 20, + "endColumn": 49, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 18, - "column": 15, - "endLine": 18, - "endColumn": 21, - "problem": "SymbolType", + "line": 21, + "column": 33, + "endLine": 21, + "endColumn": 45, + "problem": "DynamicCtorCall", "suggest": "", - "rule": "\"Symbol()\" API is not supported (arkts-no-symbol)", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, { - "line": 19, - "column": 20, - "endLine": 19, - "endColumn": 27, - "problem": "UnknownType", + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 42, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 26, - "column": 18, - "endLine": 26, - "endColumn": 19, - "problem": "ObjectLiteralNoContextType", + "line": 22, + "column": 5, + "endLine": 22, + "endColumn": 42, + "problem": "AnyType", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 32, - "column": 16, - "endLine": 32, - "endColumn": 17, - "problem": "ObjectTypeLiteral", + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 44, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 34, - "column": 15, - "endLine": 34, - "endColumn": 25, - "problem": "IndexedAccessType", + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 44, + "problem": "AnyType", "suggest": "", - "rule": "Indexed access types are not supported (arkts-no-aliases-by-index)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 36, - "column": 24, - "endLine": 36, - "endColumn": 31, - "problem": "UnknownType", + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 53, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 37, - "column": 20, - "endLine": 37, - "endColumn": 23, + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 53, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 43, - "column": 3, - "endLine": 43, - "endColumn": 11, - "problem": "LocalFunction", + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 70, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 43, - "column": 24, - "endLine": 43, - "endColumn": 27, - "problem": "AnyType", + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 72, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 43, - "column": 30, - "endLine": 43, - "endColumn": 41, - "problem": "IsOperator", + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 81, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 54, - "column": 26, - "endLine": 54, - "endColumn": 27, - "problem": "ObjectTypeLiteral", + "line": 29, + "column": 33, + "endLine": 29, + "endColumn": 35, + "problem": "NumericSemantics", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 56, - "column": 3, - "endLine": 56, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 45, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 57, - "column": 3, - "endLine": 57, - "endColumn": 6, - "problem": "ComputedPropertyName", + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 45, + "problem": "AnyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 58, - "column": 3, - "endLine": 58, - "endColumn": 6, - "problem": "ComputedPropertyName", + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 45, + "problem": "NumericSemantics", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 62, - "column": 3, - "endLine": 62, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 47, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 67, - "column": 3, - "endLine": 67, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 47, + "problem": "AnyType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 71, - "column": 19, - "endLine": 71, - "endColumn": 20, - "problem": "ObjectTypeLiteral", + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 56, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 72, - "column": 3, - "endLine": 72, - "endColumn": 26, - "problem": "IndexMember", + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 56, + "problem": "AnyType", "suggest": "", - "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 72, - "column": 18, - "endLine": 72, - "endColumn": 25, - "problem": "UnknownType", + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 74, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 76, - "column": 32, - "endLine": 76, - "endColumn": 35, - "problem": "AnyType", + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 76, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 77, - "column": 11, - "endLine": 77, - "endColumn": 13, - "problem": "InOperator", + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 85, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "\"in\" operator is not supported (arkts-no-in)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 78, - "column": 5, - "endLine": 78, - "endColumn": 14, - "problem": "PropertyAccessByIndex", + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 47, + "problem": "AnyType", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 92, - "column": 22, - "endLine": 92, - "endColumn": 29, - "problem": "IntersectionType", + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 52, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Use inheritance instead of intersection types (arkts-no-intersection-types)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 94, - "column": 28, - "endLine": 94, - "endColumn": 29, - "problem": "ObjectTypeLiteral", + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 52, + "problem": "AnyType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 96, - "column": 3, - "endLine": 96, - "endColumn": 30, - "problem": "CallSignature", + "line": 44, + "column": 13, + "endLine": 44, + "endColumn": 80, + "problem": "PropFunctionNotSupported", "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "rule": "\"prop\" function is not supported (arkui-no-prop-function)", "severity": "ERROR" }, { - "line": 111, - "column": 19, - "endLine": 111, - "endColumn": 20, - "problem": "ObjectTypeLiteral", + "line": 21, + "column": 14, + "endLine": 21, + "endColumn": 26, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 112, - "column": 12, - "endLine": 112, - "endColumn": 13, - "problem": "ObjectTypeLiteral", + "line": 21, + "column": 33, + "endLine": 21, + "endColumn": 45, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 112, - "column": 35, - "endLine": 112, - "endColumn": 36, - "problem": "ObjectTypeLiteral", + "line": 25, + "column": 12, + "endLine": 25, + "endColumn": 38, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 116, - "column": 9, - "endLine": 116, - "endColumn": 10, - "problem": "ObjectTypeLiteral", + "line": 26, + "column": 12, + "endLine": 26, + "endColumn": 38, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 116, - "column": 25, - "endLine": 116, - "endColumn": 26, - "problem": "ObjectLiteralNoContextType", + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 38, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 119, - "column": 9, - "endLine": 119, - "endColumn": 21, - "problem": "AnyType", + "line": 29, + "column": 1, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 119, - "column": 15, - "endLine": 119, - "endColumn": 21, - "problem": "TypeAssertion", + "line": 30, + "column": 13, + "endLine": 30, + "endColumn": 23, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 119, - "column": 16, - "endLine": 119, - "endColumn": 19, - "problem": "AnyType", + "line": 31, + "column": 13, + "endLine": 31, + "endColumn": 23, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 120, - "column": 20, - "endLine": 120, - "endColumn": 77, - "problem": "TypeAssertion", + "line": 32, + "column": 13, + "endLine": 32, + "endColumn": 23, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 124, + "line": 33, "column": 13, - "endLine": 124, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "endLine": 33, + "endColumn": 39, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 125, - "column": 3, - "endLine": 125, - "endColumn": 9, - "problem": "PropertyAccessByIndex", + "line": 33, + "column": 50, + "endLine": 33, + "endColumn": 60, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 126, - "column": 15, - "endLine": 126, - "endColumn": 21, - "problem": "PropertyAccessByIndex", + "line": 34, + "column": 13, + "endLine": 34, + "endColumn": 39, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 128, - "column": 12, - "endLine": 128, - "endColumn": 15, - "problem": "AnyType", + "line": 34, + "column": 52, + "endLine": 34, + "endColumn": 62, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 138, - "column": 3, - "endLine": 138, - "endColumn": 11, - "problem": "LocalFunction", + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 39, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 157, - "column": 5, - "endLine": 157, - "endColumn": 23, - "problem": "AnyType", + "line": 35, + "column": 61, + "endLine": 35, + "endColumn": 71, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 106, - "column": 3, - "endLine": 106, - "endColumn": 6, - "problem": "StrictDiagnostic", - "suggest": "Property 'val' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property 'val' has no initializer and is not definitely assigned in the constructor.", + "line": 37, + "column": 2, + "endLine": 37, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 148, - "column": 3, - "endLine": 148, - "endColumn": 4, - "problem": "StrictDiagnostic", - "suggest": "Type 'undefined' is not assignable to type 'string'.", - "rule": "Type 'undefined' is not assignable to type 'string'.", + "line": 38, + "column": 2, + "endLine": 38, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 149, - "column": 18, - "endLine": 149, - "endColumn": 27, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'undefined' is not assignable to parameter of type 'string'.", - "rule": "Argument of type 'undefined' is not assignable to parameter of type 'string'.", + "line": 42, + "column": 23, + "endLine": 42, + "endColumn": 35, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 150, - "column": 17, - "endLine": 150, - "endColumn": 26, - "problem": "StrictDiagnostic", - "suggest": "Argument of type 'undefined' is not assignable to parameter of type 'number'.", - "rule": "Argument of type 'undefined' is not assignable to parameter of type 'number'.", + "line": 44, + "column": 20, + "endLine": 44, + "endColumn": 46, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..897276b6ebb2bfcd6175508d9288d7154b6a58a1 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_2.ets.json @@ -0,0 +1,98 @@ +{ + "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": 5, + "endLine": 22, + "endColumn": 42, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 5, + "endLine": 23, + "endColumn": 44, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 5, + "endLine": 30, + "endColumn": 45, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 5, + "endLine": 32, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 47, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 13, + "endLine": 43, + "endColumn": 52, + "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/main/data_observation_1.ets b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets similarity index 40% rename from ets2panda/linter/test/main/data_observation_1.ets rename to ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets index 855d8cb121a9d1dbaffc52e9182c13d0f300c693..5a75d8e00d8979f2a84a8fd4ec69e4e3899dfff0 100644 --- a/ets2panda/linter/test/main/data_observation_1.ets +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets @@ -11,54 +11,49 @@ * 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 { MyClassB, MyClassD } from './' + */1q class MyClassA { -} -class MyClassC { } -@Observed -class MyClassE { -} +class MyClassB { -AppStorage.setOrCreate('PropA', 47); -AppStorage.setOrCreate('PropB', new MyClassC()); -let storage = new LocalStorage(); -storage.setOrCreate('LinkA', 48); -storage.setOrCreate('LinkB', new MyClassA()); +} -@Entry -@Component -struct Test { - @State data1: number = 0 - @State data2: MyClassA = 0 - @State data3: MyClassB | string = 0 - @State data4: undefined | string | MyClassC | MyClassD = 0 - @State data5: MyClassE = 0 - @Prop data6: MyClassA = 0 - @Provide selectedDate: Date = new Date('2021-08-08') - @StorageLink('PropA') storageLink1: number = 1 - @StorageLink('PropB') storageLink2: MyClassC = new MyClassC() - @LocalStorageLink('LinkA') localStorageLink1: number = 1 - @LocalStorageLink('LinkB') localStorageLink2: MyClassA = new MyClassA() - @StorageProp('test') test1: MyClassB = 0; - @LocalStorageProp('test') test2: MyClassB = 0; +function getClass1 { + let a = new MyClassA() - build() { + if (1 > 0) { + return new MyClassB() + } else { + return a + } +} - } +function getClass2 { + if (1 > 0) { + return 1 + } else { + return new MyClassA() + } } +let para: Record = { 'PropA': 47 } +let storage: LocalStorage = new LocalStorage(para) +let prop1 = storage.setAndProp('PropA', getClass1()) +let prop2 = storage.setAndProp('PropA', getClass2()) +let prop3 = storage.setAndProp('PropA', {name: "jack", age: 2}) +let prop4 = storage.setAndProp('PropA', 1 > 0 ? 1 : getClass1()) +let prop5 = storage.setAndProp('PropA', 1 > 0 ? {name: "jack"} : "test") +let prop6 = storage.setAndProp('PropA', new MyClassA()) +let prop7 = storage.setAndProp('PropA', 1) +let prop8 = storage.setAndProp('PropA', "test") +let prop9 = storage.setAndProp('PropA', true) + +@Entry @Component struct MyComponent { - @Link data2: MyClassA - @Consume selectedDate: Date - - build() { - - } + build() { + } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.args.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..4acc088d1da62353e56ced57f16b342de413cb78 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.arkts2.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..07fee6d056caec554e2c8a300304c1c9489eac6e --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.arkts2.json @@ -0,0 +1,388 @@ +{ + "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": 14, + "column": 4, + "endLine": 14, + "endColumn": 5, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 9, + "endLine": 27, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 13, + "endLine": 27, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 9, + "endLine": 35, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 16, + "endLine": 36, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 47, + "endLine": 42, + "endColumn": 49, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 33, + "endLine": 43, + "endColumn": 45, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 53, + "problem": "SetAndPropFunctionNotSupported", + "suggest": "", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 53, + "problem": "SetAndPropFunctionNotSupported", + "suggest": "", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 64, + "problem": "SetAndPropFunctionNotSupported", + "suggest": "", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 64, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 61, + "endLine": 46, + "endColumn": 62, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 65, + "problem": "SetAndPropFunctionNotSupported", + "suggest": "", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 65, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 41, + "endLine": 47, + "endColumn": 42, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 45, + "endLine": 47, + "endColumn": 46, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 49, + "endLine": 47, + "endColumn": 50, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 73, + "problem": "SetAndPropFunctionNotSupported", + "suggest": "", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 73, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 41, + "endLine": 48, + "endColumn": 42, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 45, + "endLine": 48, + "endColumn": 46, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 56, + "problem": "SetAndPropFunctionNotSupported", + "suggest": "", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 43, + "problem": "SetAndPropFunctionNotSupported", + "suggest": "", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 41, + "endLine": 50, + "endColumn": 42, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 48, + "problem": "SetAndPropFunctionNotSupported", + "suggest": "", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 48, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 46, + "problem": "SetAndPropFunctionNotSupported", + "suggest": "", + "rule": "\"setAndProp\" function is not supported (arkui-no-setandprop-function)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 46, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 14, + "endLine": 43, + "endColumn": 26, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 33, + "endLine": 43, + "endColumn": 45, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 2, + "endLine": 54, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 2, + "endLine": 55, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.json b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..de7a4258a1f6b8da812a9b2a4c008c68ffd109f1 --- /dev/null +++ b/ets2panda/linter/test/main/prop_decorator_and_interfaces_3.ets.json @@ -0,0 +1,108 @@ +{ + "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": 44, + "column": 5, + "endLine": 44, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 53, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 64, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 5, + "endLine": 47, + "endColumn": 65, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 5, + "endLine": 48, + "endColumn": 73, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 5, + "endLine": 49, + "endColumn": 56, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 5, + "endLine": 51, + "endColumn": 48, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 5, + "endLine": 52, + "endColumn": 46, + "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/main/prop_name_from_value.ets b/ets2panda/linter/test/main/prop_name_from_value.ets new file mode 100644 index 0000000000000000000000000000000000000000..bdfdc1a80d5529ad17bdec94f11f1a0e7e493de8 --- /dev/null +++ b/ets2panda/linter/test/main/prop_name_from_value.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. + */ + +enum TEST { + A, + B, + C +} +const arr = ['a', 'b', 'c']; + +const val = TEST[1]; +const value: number = TEST.A; //legal +const arrVal = arr[1]; //legal \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_name_from_value.ets.args.json b/ets2panda/linter/test/main/prop_name_from_value.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..66fb88f85945924e8be0e83d90123507033f4c5d --- /dev/null +++ b/ets2panda/linter/test/main/prop_name_from_value.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/prop_name_from_value.ets.arkts2.json b/ets2panda/linter/test/main/prop_name_from_value.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..4218268d314b5d23e17b0cb47ab709da3f410059 --- /dev/null +++ b/ets2panda/linter/test/main/prop_name_from_value.ets.arkts2.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": 23, + "column": 13, + "endLine": 23, + "endColumn": 20, + "problem": "UnsupportPropNameFromValue", + "suggest": "", + "rule": "Enum cannot get member name by member value (arkts-unsupport-prop-name-from-value)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/prop_name_from_value.ets.json b/ets2panda/linter/test/main/prop_name_from_value.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/prop_name_from_value.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/property_access_by_index.ets.args.json b/ets2panda/linter/test/main/property_access_by_index.ets.args.json index a830284339c398efecc87cc656cada022d6db5c4..7341e330faa243cfdd4795226601488b62c2f729 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ets.args.json +++ b/ets2panda/linter/test/main/property_access_by_index.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -15,6 +15,7 @@ ], "mode": { "autofix": "", - "arkts2": "" + "arkts2": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/property_access_by_index.ets.arkts2.json b/ets2panda/linter/test/main/property_access_by_index.ets.arkts2.json index 7fd2c9eac2ad5e1904127c7f0332f01322fcde8a..8bdc1c6d5d3ea74b51d8fa0e7c98ba16717df53e 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ets.arkts2.json +++ b/ets2panda/linter/test/main/property_access_by_index.ets.arkts2.json @@ -14,6 +14,16 @@ "limitations under the License." ], "result": [ + { + "line": 16, + "column": 10, + "endLine": 16, + "endColumn": 21, + "problem": "NoNeedStdLibSendableContainer", + "suggest": "", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, { "line": 22, "column": 3, @@ -44,6 +54,76 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 33, + "column": 12, + "endLine": 33, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 18, + "endLine": 33, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 21, + "endLine": 33, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 12, + "endLine": 34, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 20, + "endLine": 34, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 23, + "endLine": 34, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 41, "column": 7, @@ -94,6 +174,26 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 53, + "column": 15, + "endLine": 53, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 17, + "endLine": 53, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 54, "column": 5, @@ -104,6 +204,156 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 54, + "column": 15, + "endLine": 54, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 17, + "endLine": 54, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 19, + "endLine": 54, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 21, + "endLine": 54, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 23, + "endLine": 54, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 25, + "endLine": 55, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 27, + "endLine": 55, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 29, + "endLine": 55, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 31, + "endLine": 55, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 33, + "endLine": 55, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 30, + "endLine": 56, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 32, + "endLine": 56, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 34, + "endLine": 56, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 36, + "endLine": 56, + "endColumn": 37, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 38, + "endLine": 56, + "endColumn": 39, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 57, "column": 5, @@ -124,6 +374,156 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, + { + "line": 57, + "column": 24, + "endLine": 57, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 28, + "endLine": 58, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 29, + "endLine": 59, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 36, + "endLine": 60, + "endColumn": 38, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 29, + "endLine": 61, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 31, + "endLine": 62, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 30, + "endLine": 63, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 31, + "endLine": 64, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 32, + "endLine": 65, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 32, + "endLine": 66, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 33, + "endLine": 67, + "endColumn": 35, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 34, + "endLine": 68, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 31, + "endLine": 105, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 33, + "endLine": 105, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 35, + "endLine": 105, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 107, "column": 24, @@ -134,6 +534,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 107, + "column": 24, + "endLine": 107, + "endColumn": 39, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, { "line": 108, "column": 5, @@ -174,6 +584,16 @@ "rule": "The index expression must be of a numeric type (arkts-array-index-expr-type)", "severity": "ERROR" }, + { + "line": 117, + "column": 20, + "endLine": 117, + "endColumn": 35, + "problem": "BuiltinSymbolIterator", + "suggest": "", + "rule": "Using \"Symbol.iterator\" is not allowed in this API (arkts-builtin-symbol-iterator)", + "severity": "ERROR" + }, { "line": 118, "column": 5, @@ -204,6 +624,16 @@ "rule": "Avoid using union types (arkts-common-union-member-access)", "severity": "ERROR" }, + { + "line": 139, + "column": 12, + "endLine": 139, + "endColumn": 31, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, { "line": 159, "column": 3, @@ -245,13 +675,23 @@ "severity": "ERROR" }, { - "line": 176, - "column": 1, - "endLine": 176, - "endColumn": 10, - "problem": "LimitedStdLibApi", + "line": 177, + "column": 23, + "endLine": 177, + "endColumn": 34, + "problem": "NoNeedStdLibSendableContainer", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Sendable containers are not supported (arkts-no-need-stdlib-sendable-containers)", + "severity": "ERROR" + }, + { + "line": 179, + "column": 11, + "endLine": 179, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -263,6 +703,26 @@ "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" + }, + { + "line": 180, + "column": 18, + "endLine": 180, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 181, + "column": 17, + "endLine": 181, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/property_access_by_index.ets.migrate.ets b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a19d0154802a6a02c685d077909c66a95a19c687 --- /dev/null +++ b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.ets @@ -0,0 +1,184 @@ +/* + * 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. + */ +import {OhosInterface} from './oh_modules/ohos_lib'; +import { collections } from './@arkts.collections'; +// #14071 +class A { + v: string = ''; +} +function SetProperty(oldObj: T, str: string, obj: Object): void { + oldObj[str] = obj; // Should report error +} +function GetProperty(oldObj: T, str: string): U { + return oldObj[str]; // Should report error +} +function test() { + let a: A = { v: 'abc' }; + SetProperty(a, 'u', 'def'); + return GetProperty(a, 'v') + GetProperty(a, 'u'); +} + +let ar1 = [1, 2, 3, 4]; +let ar2 = [1, '2', 3, 4]; +let ar3: number[] = []; + +ar1[2]; +ar2[2]; +ar3[2]; + +const r0 = [1, 2, 3][1]; +let r1 = [1, 2, 3, 4][0] +let r2 = [1, '2', 3, 4][0] + +function fobject1(o: object) { + o['j'] +} + +function fobject2(o: Object) { + o['k'] +} + +let array1 = [0,1] +let array2 = [1,2,3,4,5] +let array3: number[] = [1,2,3,4,5] +let array4: Array = [1,2,3,4,5] +let array5 = new Array(10) +let array6 = new Int8Array(10) +let array7 = new Uint8Array(10) +let array8 = new Uint8ClampedArray(10) +let array9 = new Int16Array(10) +let array10 = new Uint16Array(10) +let array11 = new Int32Array(10) +let array12 = new Uint32Array(10) +let array13 = new Float32Array(10) +let array14 = new Float64Array(10) +let array15 = new BigInt64Array(10) +let array16 = new BigUint64Array(10) + +array1[0]; +array2[0]; +array3[0]; +array4[0]; +array5[0]; +array6[0]; +array7[0]; +array8[0]; +array9[0]; +array10[0]; +array11[0]; +array12[0]; +array13[0]; +array14[0]; +array15[0]; +array16[0]; + +function fff1(r: Record) { + r['bob'] +} + +enum CCCCCCCCC { + KATE, + BOB, + ROB, +} + +CCCCCCCCC['KATE'] +CCCCCCCCC['BOB'] +CCCCCCCCC['ROB'] + +CCCCCCCCC[CCCCCCCCC.KATE] +CCCCCCCCC[CCCCCCCCC.BOB] +CCCCCCCCC[CCCCCCCCC.ROB] + +let arr32 = new Float32Array([1,2,3]) + +let iter_arr32 = arr32[Symbol.iterator]() +let tmp_arr32 = iter_arr32.next().value; +while (!!tmp_arr32) { + console.log(tmp_arr32[0]) + + tmp_arr32 = iter_arr32.next().value +} + +let arr = new Array() +arr = ['a','f','g'] +let iter_arr = arr[Symbol.iterator]() +let tmp_arr = iter_arr.next().value; +while (!!tmp_arr) { + console.log(tmp_arr[0]) + tmp_arr = iter_arr.next().value +} + +// #14415 +class ArrayContainer { + numbers: number[] = []; +} +class NullableArray { + container: ArrayContainer | null = null; + + print() { + console.log(this.container?.numbers[0]); + } +} + +let str1 = 'sssss' +let str2 = "aaaaa" +let str3 = `sssss` +let str4 = new String('sssss') +let str5 = str1 +let str6 = str2 + +str1[1] +str2[1] +str3[1] +str4[1] +str5[1] +str6[1] + +class AString extends String {} +let str7 = new AString('dwdd') +str7[1] + +type IndexableUnion = string[] | (number | string)[] | Uint8Array; +type NonIndexableUnion = string[] | number[] | Uint8Array | number; + +function indexUnion(iu: IndexableUnion, niu: NonIndexableUnion) { + iu[0]; + niu[0]; +} + +function testLibraryUnnamedType(a: OhosInterface) { + a['kek']; +} + +class MMap extends Map {} + +let mmap1 = new Map(); +let mmap2 = new Map(); +let mmap3 = new MMap(); + +mmap1[1]; +mmap2['222']; +mmap3["kkr"]; + +@Sendable +class MyClass extends collections.BitVector { + constructor() { + super(0); + for (let i = 0; i < this.length; i++) { + this[i] = 1; + } + } +} diff --git a/ets2panda/linter/test/main/property_access_by_index.ts.arkts2.json b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.json similarity index 68% rename from ets2panda/linter/test/main/property_access_by_index.ts.arkts2.json rename to ets2panda/linter/test/main/property_access_by_index.ets.migrate.json index 610499fd9a153ebf2958618031d833763770078d..e700885404cdb3909d85aea7ff974569658ce43f 100644 --- a/ets2panda/linter/test/main/property_access_by_index.ts.arkts2.json +++ b/ets2panda/linter/test/main/property_access_by_index.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 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", @@ -34,16 +34,6 @@ "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" }, - { - "line": 46, - "column": 3, - "endLine": 46, - "endColumn": 9, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, { "line": 50, "column": 3, @@ -93,36 +83,6 @@ "suggest": "", "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", "severity": "ERROR" - }, - { - "line": 172, - "column": 1, - "endLine": 172, - "endColumn": 9, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 173, - "column": 1, - "endLine": 173, - "endColumn": 13, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 174, - "column": 1, - "endLine": 174, - "endColumn": 13, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/property_decl_on_function.ets.arkts2.json b/ets2panda/linter/test/main/property_decl_on_function.ets.arkts2.json index 75c1cb86793d40361ea4fb1b20fd7fe97ab87599..a530f796c469479484c8dacbd48144df1ca587b6 100644 --- a/ets2panda/linter/test/main/property_decl_on_function.ets.arkts2.json +++ b/ets2panda/linter/test/main/property_decl_on_function.ets.arkts2.json @@ -14,16 +14,6 @@ "limitations under the License." ], "result": [ - { - "line": 16, - "column": 1, - "endLine": 18, - "endColumn": 2, - "problem": "TsOverload", - "suggest": "", - "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", - "severity": "ERROR" - }, { "line": 20, "column": 1, @@ -54,6 +44,16 @@ "rule": "Declaring properties on functions is not supported (arkts-no-func-props)", "severity": "ERROR" }, + { + "line": 24, + "column": 11, + "endLine": 24, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 26, "column": 1, @@ -74,6 +74,26 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 26, + "column": 16, + "endLine": 26, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 22, + "endLine": 26, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 28, "column": 13, @@ -144,6 +164,16 @@ "rule": "Declaring properties on functions is not supported (arkts-no-func-props)", "severity": "ERROR" }, + { + "line": 40, + "column": 12, + "endLine": 40, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 41, "column": 13, @@ -194,16 +224,6 @@ "rule": "Declaring properties on functions is not supported (arkts-no-func-props)", "severity": "ERROR" }, - { - "line": 48, - "column": 16, - "endLine": 48, - "endColumn": 24, - "problem": "ExplicitFunctionType", - "suggest": "", - "rule": "The function type should be explicit (arkts-no-ts-like-function)", - "severity": "ERROR" - }, { "line": 52, "column": 13, diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets b/ets2panda/linter/test/main/provide_annotation_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..6ef3ea67563dac6af76c8baffbfb64cc69395a02 --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_1.ets @@ -0,0 +1,44 @@ +/* + * 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. + */ + +@Component +struct Index { + @Provide + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide("value") + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({allowOverride: "value"}) + value: number; + build() { + Column() { + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.args.json b/ets2panda/linter/test/main/provide_annotation_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b023016d6bc3b2713d4e02b6f765940828db476b --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_1.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/provide_annotation_1.ets.arkts2.json b/ets2panda/linter/test/main/provide_annotation_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..a11e915085f45661608340affe7a0f9687cdf9f6 --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.arkts2.json @@ -0,0 +1,158 @@ +{ + "copyright": [ + "Copyright (c) 2023-2024 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": 28, + "column": 3, + "endLine": 29, + "endColumn": 17, + "problem": "ProvideAnnotation", + "suggest": "", + "rule": "The \"@Provide\" annotation does not support dynamic parameters (arkui-provide-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 3, + "endLine": 39, + "endColumn": 17, + "problem": "ProvideAnnotation", + "suggest": "", + "rule": "The \"@Provide\" annotation does not support dynamic parameters (arkui-provide-annotation-parameters)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 4, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 2, + "endLine": 26, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 4, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 2, + "endLine": 36, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 4, + "endLine": 38, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/data_observation_1.ets.autofix.json b/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json similarity index 46% rename from ets2panda/linter/test/main/data_observation_1.ets.autofix.json rename to ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json index 04f4870665697eb029c54b66f4d229814a50153f..499fa5b2964077f05d7b44e759e4cc617cc850c0 100644 --- a/ets2panda/linter/test/main/data_observation_1.ets.autofix.json +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.autofix.json @@ -15,234 +15,220 @@ ], "result": [ { - "line": 30, - "column": 5, - "endLine": 30, - "endColumn": 33, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 19, - "endLine": 30, - "endColumn": 31, - "problem": "DynamicCtorCall", - "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 17, - "endLine": 38, - "endColumn": 25, - "problem": "DataObservation", + "line": 28, + "column": 3, + "endLine": 29, + "endColumn": 17, + "problem": "ProvideAnnotation", "autofix": [ { - "start": 646, - "end": 646, - "replacementText": "@Observed\n" + "start": 727, + "end": 744, + "replacementText": "@Provide({ alias: \"value\" })" } ], "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "The \"@Provide\" annotation does not support dynamic parameters (arkui-provide-annotation-parameters)", "severity": "ERROR" }, { - "line": 39, - "column": 17, + "line": 38, + "column": 3, "endLine": 39, - "endColumn": 25, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 38, - "endLine": 40, - "endColumn": 46, - "problem": "DataObservation", + "endColumn": 17, + "problem": "ProvideAnnotation", "autofix": [ { - "start": 666, - "end": 666, - "replacementText": "@Observed\n" + "start": 830, + "end": 864, + "replacementText": "@Provide({ alias: \"value\", allowOverride: true })" } ], "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "The \"@Provide\" annotation does not support dynamic parameters (arkui-provide-annotation-parameters)", "severity": "ERROR" }, { - "line": 40, - "column": 49, - "endLine": 40, - "endColumn": 57, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 43, - "column": 26, - "endLine": 43, - "endColumn": 30, - "problem": "DataObservation", - "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", - "severity": "ERROR" - }, - { - "line": 24, + "line": 16, "column": 2, - "endLine": 24, - "endColumn": 10, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 1, - "endLine": 28, + "endLine": 16, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 30, - "column": 19, - "endLine": 30, - "endColumn": 31, + "line": 18, + "column": 4, + "endLine": 18, + "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 34, - "column": 2, - "endLine": 34, - "endColumn": 7, + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 35, + "line": 26, "column": 2, - "endLine": 35, + "endLine": 26, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 37, - "column": 4, - "endLine": 37, - "endColumn": 9, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 42, + "line": 28, "column": 4, - "endLine": 42, - "endColumn": 8, + "endLine": 28, + "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 43, - "column": 4, - "endLine": 43, + "line": 31, + "column": 5, + "endLine": 31, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 44, - "column": 4, - "endLine": 44, - "endColumn": 15, + "line": 36, + "column": 2, + "endLine": 36, + "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 46, + "line": 38, "column": 4, - "endLine": 46, - "endColumn": 20, + "endLine": 38, + "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 48, - "column": 4, - "endLine": 48, - "endColumn": 15, + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 49, - "column": 4, - "endLine": 49, - "endColumn": 20, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" }, { - "line": 58, - "column": 4, - "endLine": 58, + "line": 29, + "column": 3, + "endLine": 29, "endColumn": 8, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" }, { - "line": 59, - "column": 4, - "endLine": 59, - "endColumn": 11, - "problem": "UIInterfaceImport", - "autofix": [ - { - "start": 603, - "end": 603, - "replacementText": "\n\nimport { Observed, AppStorage, LocalStorage, Entry, Component, State, Prop, Provide, StorageLink, LocalStorageLink, StorageProp, LocalStorageProp, Link, Consume } from '@kits.ArkUI';" - } - ], - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.json b/ets2panda/linter/test/main/provide_annotation_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..23189d668f56defd820047411939682281bca1ac --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.json @@ -0,0 +1,48 @@ +{ + "copyright": [ + "Copyright (c) 2023-2024 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": 19, + "column": 3, + "endLine": 19, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba3e7877529a70f08c4e368f72f937afb629de7e --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.ets @@ -0,0 +1,46 @@ +/* + * 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 { Component, Provide, Column } from '@kit.ArkUI'; + +@Component +struct Index { + @Provide + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value" }) + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value", allowOverride: true }) + value: number; + build() { + Column() { + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.json b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..2817e72894d499711b29674c52d22fb304b2bd01 --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_1.ets.migrate.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": 21, + "column": 3, + "endLine": 21, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 41, + "column": 3, + "endLine": 41, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets b/ets2panda/linter/test/main/provide_annotation_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..bddf1e72c0a37b914608dab6842cfdb253adba23 --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_2.ets @@ -0,0 +1,44 @@ +/* + * 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. + */ + +@Component +struct Index { + @Provide + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value" }) + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value", allowOverride: true }) + value: number; + build() { + Column() { + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.args.json b/ets2panda/linter/test/main/provide_annotation_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..b023016d6bc3b2713d4e02b6f765940828db476b --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_2.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/provide_annotation_2.ets.arkts2.json b/ets2panda/linter/test/main/provide_annotation_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5683673096519aab356d8c5e39f24523630fc5f8 --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.arkts2.json @@ -0,0 +1,138 @@ +{ + "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": 2, + "endLine": 16, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 4, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 2, + "endLine": 26, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 4, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 2, + "endLine": 36, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 4, + "endLine": 38, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json b/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..f828839e124ace4ad3d38b7f2893c16b7f4d09d7 --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.autofix.json @@ -0,0 +1,201 @@ +{ + "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": 2, + "endLine": 16, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 4, + "endLine": 18, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 5, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 2, + "endLine": 26, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 4, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 5, + "endLine": 31, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 2, + "endLine": 36, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 4, + "endLine": 38, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, Provide, Column } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.json b/ets2panda/linter/test/main/provide_annotation_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..23189d668f56defd820047411939682281bca1ac --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.json @@ -0,0 +1,48 @@ +{ + "copyright": [ + "Copyright (c) 2023-2024 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": 19, + "column": 3, + "endLine": 19, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 29, + "column": 3, + "endLine": 29, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 39, + "column": 3, + "endLine": 39, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba3e7877529a70f08c4e368f72f937afb629de7e --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.ets @@ -0,0 +1,46 @@ +/* + * 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 { Component, Provide, Column } from '@kit.ArkUI'; + +@Component +struct Index { + @Provide + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value" }) + value: number; + build() { + Column() { + } + } +} + +@Component +struct Index { + @Provide({ alias: "value", allowOverride: true }) + value: number; + build() { + Column() { + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.json b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..2817e72894d499711b29674c52d22fb304b2bd01 --- /dev/null +++ b/ets2panda/linter/test/main/provide_annotation_2.ets.migrate.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": 21, + "column": 3, + "endLine": 21, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 31, + "column": 3, + "endLine": 31, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 41, + "column": 3, + "endLine": 41, + "endColumn": 8, + "problem": "StrictDiagnostic", + "suggest": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'value' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/record_object_literals_properties.ets.arkts2.json b/ets2panda/linter/test/main/record_object_literals_properties.ets.arkts2.json index 167c48a33a21c1fc3895d8e8830b9cf767800a97..2e90fcfeea9c6b6c6c7850473c39df977d817e6c 100644 --- a/ets2panda/linter/test/main/record_object_literals_properties.ets.arkts2.json +++ b/ets2panda/linter/test/main/record_object_literals_properties.ets.arkts2.json @@ -13,5 +13,66 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 17, + "column": 11, + "endLine": 17, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 11, + "endLine": 18, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 18, + "endLine": 26, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 30, + "endLine": 26, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 18, + "endLine": 27, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 30, + "endLine": 27, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets b/ets2panda/linter/test/main/runtime_array_bound.ets new file mode 100644 index 0000000000000000000000000000000000000000..435c6ac0e6817708630365cdac50f50fdb0b8e78 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.ets @@ -0,0 +1,90 @@ +/* + * 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. + */ +'use static' + +const arr: int[] = [1, 2, 3, 4]; + +for (let i = 0; i < arr.length; i++) { + arr[i]; //legal +} + +for (let i = 0; i < 100; i++) { + console.log(i); //legal +} + +const arr2: int[] = [1, 2, 3, 4]; +for (let i = 0; i < 100; i++) { + arr2[10] //should report +} + +const arr3: int[] = [1, 2, 3, 4]; +for (let i = 0; i < arr3.length; i++) { + arr3[10] //should report +} + +const arr4: int[] = [1, 2, 3, 4]; +let x: int = 3; +for (let i = 0; i < arr4.length; i++) { + arr4[x]; //should report +} + +const arr5: int[] = [1, 2, 3, 4]; +for (let i = 0; i < 10; i++) { + arr5[i]; //should report +} + + +const arr6: int[] = [1, 2, 3, 4]; +if (arr6.length > 10) { + arr6[10] +} + +const arr7: int[] = [1, 2, 3, 4]; +if (arr7.length > 10) { + return; +} + +arr7[10] + +const arr8: int[] = [1, 2, 3, 4]; +const index: int = 9; +if (arr8.length > 10 && index > 0) { + return; +} + +arr8[index]; + +const arr9: int[] = [1, 2, 3, 4]; +if (arr9.length > 10 && index > 0) { + arr9[index]; +} + +const arr10: int[] = [1, 2, 3, 4]; +if (index > 0) { + arr10[index]; +} + +const arr10: int[] = [1, 2, 3, 4]; +let newIndex = 10; +if (arr10.length > newIndex) { + return; +} + +newIndex = 22; + +arr10[newIndex]; + + + diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.args.json b/ets2panda/linter/test/main/runtime_array_bound.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..8a4be28991e8164c0366b8b3ad0dffbc04910a27 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.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": "", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json b/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ee17b482f008213a6ee5cdd32b3dd9d4964579b9 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.arkts2.json @@ -0,0 +1,808 @@ +{ + "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": 17, + "column": 21, + "endLine": 17, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 24, + "endLine": 17, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 27, + "endLine": 17, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 30, + "endLine": 17, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 10, + "endLine": 19, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 14, + "endLine": 19, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 10, + "endLine": 23, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 14, + "endLine": 23, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 21, + "endLine": 23, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 22, + "endLine": 27, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 25, + "endLine": 27, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 28, + "endLine": 27, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 31, + "endLine": 27, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 10, + "endLine": 28, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 14, + "endLine": 28, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 21, + "endLine": 28, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 25, + "endLine": 32, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 28, + "endLine": 32, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 31, + "endLine": 32, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 10, + "endLine": 33, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 14, + "endLine": 33, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 22, + "endLine": 37, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 25, + "endLine": 37, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 28, + "endLine": 37, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 31, + "endLine": 37, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 10, + "endLine": 39, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 14, + "endLine": 39, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 22, + "endLine": 43, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 25, + "endLine": 43, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 28, + "endLine": 43, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 31, + "endLine": 43, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 10, + "endLine": 44, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 14, + "endLine": 44, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 21, + "endLine": 44, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 22, + "endLine": 49, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 25, + "endLine": 49, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 28, + "endLine": 49, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 31, + "endLine": 49, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 19, + "endLine": 50, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 22, + "endLine": 54, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 25, + "endLine": 54, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 28, + "endLine": 54, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 31, + "endLine": 54, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 19, + "endLine": 55, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 22, + "endLine": 61, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 25, + "endLine": 61, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 28, + "endLine": 61, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 31, + "endLine": 61, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 20, + "endLine": 62, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 19, + "endLine": 63, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 33, + "endLine": 63, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 22, + "endLine": 69, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 25, + "endLine": 69, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 28, + "endLine": 69, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 31, + "endLine": 69, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 19, + "endLine": 70, + "endColumn": 21, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 33, + "endLine": 70, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 23, + "endLine": 74, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 26, + "endLine": 74, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 29, + "endLine": 74, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 32, + "endLine": 74, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 5, + "endLine": 76, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 13, + "endLine": 75, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 23, + "endLine": 79, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 26, + "endLine": 79, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 29, + "endLine": 79, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 32, + "endLine": 79, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 16, + "endLine": 80, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 12, + "endLine": 85, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 1, + "endLine": 87, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.json b/ets2panda/linter/test/main/runtime_array_bound.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bd1b7140ca95b67336908f5fca6dec77fb46b2c0 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.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": [] +} diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3ac6cbf3433c32bd8b7df05ca36ab3d12d5ccd01 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.ets @@ -0,0 +1,90 @@ +/* + * 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. + */ +'use static' + +const arr: int[] = [1.0, 2.0, 3.0, 4.0]; + +for (let i: number = 0.0; i < arr.length; i++) { + arr[i as int]; //legal +} + +for (let i: number = 0.0; i < 100.0; i++) { + console.log(i); //legal +} + +const arr2: int[] = [1.0, 2.0, 3.0, 4.0]; +for (let i: number = 0.0; i < 100.0; i++) { + arr2[10] //should report +} + +const arr3: int[] = [1.0, 2.0, 3.0, 4.0]; +for (let i: number = 0.0; i < arr3.length; i++) { + arr3[10] //should report +} + +const arr4: int[] = [1.0, 2.0, 3.0, 4.0]; +let x: int = 3.0; +for (let i: number = 0.0; i < arr4.length; i++) { + arr4[x]; //should report +} + +const arr5: int[] = [1.0, 2.0, 3.0, 4.0]; +for (let i: number = 0.0; i < 10.0; i++) { + arr5[i as int]; //should report +} + + +const arr6: int[] = [1.0, 2.0, 3.0, 4.0]; +if (arr6.length > 10.0) { + arr6[10] +} + +const arr7: int[] = [1.0, 2.0, 3.0, 4.0]; +if (arr7.length > 10.0) { + return; +} + +arr7[10] + +const arr8: int[] = [1.0, 2.0, 3.0, 4.0]; +const index: int = 9.0; +if (arr8.length > 10.0 && index > 0.0) { + return; +} + +arr8[index]; + +const arr9: int[] = [1.0, 2.0, 3.0, 4.0]; +if (arr9.length > 10.0 && index > 0.0) { + arr9[index]; +} + +const arr10: int[] = [1.0, 2.0, 3.0, 4.0]; +if (index > 0.0) { + arr10[index]; +} + +const arr10: int[] = [1.0, 2.0, 3.0, 4.0]; +let newIndex: number = 10.0; +if (arr10.length > newIndex) { + return; +} + +newIndex = 22.0; + +arr10[newIndex as int]; + + + diff --git a/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..2801165e5d8611744782d6aaaccc8604be228967 --- /dev/null +++ b/ets2panda/linter/test/main/runtime_array_bound.ets.migrate.json @@ -0,0 +1,78 @@ +{ + "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": 29, + "column": 5, + "endLine": 29, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 13, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 12, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 16, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 5, + "endLine": 76, + "endColumn": 10, + "problem": "RuntimeArrayCheck", + "suggest": "", + "rule": "Array bound not checked. (arkts-runtime-array-check)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/sendable_class_inheritance.ets.args.json b/ets2panda/linter/test/main/sendable_class_inheritance.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_class_inheritance.ets.args.json +++ b/ets2panda/linter/test/main/sendable_class_inheritance.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.ets b/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..34b7339258a705bb7d30797ea73f4547782e7591 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.ets @@ -0,0 +1,190 @@ +/* + * 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 { + sendableClassA, + sendableVar, + nonSendableClassB, + nonSendableVar, + sendableInterface, + nonSendableInterface, + lang, +} from './@arkts.lang'; + +// sendable class +@Sendable +class localSendableClassA {} + +// sendable class var +let localSendableVar = localSendableClassA + + +// non-sendable class +class localNonSendableClassB {} + +// non-sendable class var +let localNonSendableVar = localNonSendableClassB + +// sendable interface +interface localSendableInterface extends lang.ISendable {} + +// non-sendable interface +interface localNonSendableInterface {} + +// sendable interface type alias +type localSendableInterfaceAlias = localSendableInterface + +// non-sendable interface type alias +type localNonSendableInterfaceAlias = localNonSendableInterface + +// left: sendable class + +// class + class + +// case1: extends import var +// == case1.1: extends sendable +@Sendable +class sendableClass1 extends sendableVar {} // ERROR + +// == case1.2: extends non-sendable +@Sendable +class sendableClass2 extends nonSendableVar {} // ERROR + +// case2: extends local var +// == case2.1: extends sendable +@Sendable +class sendableClass3 extends localSendableVar {} // ERROR + +// == case2.2: extends non-sendable +@Sendable +class sendableClass4 extends localNonSendableVar {} // ERROR + +// case3: extends import class +// == case3.1: extends sendable +@Sendable +class sendableClass5 extends sendableClassA {} // OK + +// == case3.2: extends non-sendable +@Sendable +class sendableClass6 extends nonSendableClassB {} // ERROR + +// case4: extends local class +// == case4.1: extends sendable +@Sendable +class sendableClass7 extends localSendableClassA {} // OK + +// == case4.2: extends non-sendable +@Sendable +class sendableClass8 extends localNonSendableClassB {} // ERROR + +// class + interface + +// case1: implements local interface +// == case1.1: implements sendable +@Sendable +class sendableClass9 implements localSendableInterface {} // OK + +// == case1.2: implements non-sendable +@Sendable +class sendableClass10 implements localNonSendableInterface {} // OK + +// case2: implements import interface +// == case2.1: implements sendable +@Sendable +class sendableClass11 implements sendableInterface {} // OK + +// == case2.2: implements non-sendable +@Sendable +class sendableClass12 implements nonSendableInterface {} // OK + +// case3: implements type alias +// == case3.1: implements sendable +@Sendable +class sendableClass13 implements localSendableInterfaceAlias {} // OK + +// == case3.2: implements non-sendable +@Sendable +class sendableClass14 implements localNonSendableInterfaceAlias {} // OK + +// left: non sendable class + +// case1: extends import var +// == case1.1: extends sendable +class sendableClass15 extends sendableVar {} // ERROR + +// == case1.2: extends non-sendable +class sendableClass16 extends nonSendableVar {} // OK + +// case2: extends local var +// == case2.1: extends sendable +class sendableClass17 extends localSendableVar {} // ERROR + +// == case2.2: extends non-sendable +class sendableClass18 extends localNonSendableVar {} // OK + +// case3: extends import class +// == case3.1: extends sendable +@Sendable +class sendableClass19 extends sendableClassA {} // ERROR + +// == case3.2: extends non-sendable +class sendableClass20 extends nonSendableClassB {} // OK + +// case4: extends local class +// == case4.1: extends sendable +@Sendable +class sendableClass21 extends localSendableClassA {} // ERROR + +// == case4.2: extends non-sendable +class sendableClass22 extends localNonSendableClassB {} // OK + +// class + interface + +// case1: implements local interface +// == case1.1: implements sendable +@Sendable +class sendableClass23 implements localSendableInterface {} // ERROR + +// == case1.2: implements non-sendable +class sendableClass24 implements localNonSendableInterface {} // OK + +// case2: implements import interface +// == case2.1: implements sendable +@Sendable +class sendableClass25 implements sendableInterface {} // ERROR + +// == case2.2: implements non-sendable +class sendableClass26 implements nonSendableInterface {} // OK + +// case3: implements type alias +// == case4.1: implements sendable +@Sendable +class sendableClass27 implements localSendableInterfaceAlias {} // ERROR + +// == case4.2: implements non-sendable +class sendableClass28 implements localNonSendableInterfaceAlias {} // OK + +// ISendable created by developer is not a sendable interface + +interface ISendable {} + +interface fakeSendableInterface extends ISendable {} + +// fake sendable interface type alias +type fakeSendableInterfaceAlias = fakeSendableInterface + +class sendableClass29 implements fakeSendableInterface {} // OK + +class sendableClass30 implements fakeSendableInterfaceAlias {} // OK \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.json b/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..1b1edbb0f96d0f628ef1f7765111f8ee495443b8 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_class_inheritance.ets.migrate.json @@ -0,0 +1,118 @@ +{ + "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": 31, + "column": 24, + "endLine": 31, + "endColumn": 43, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 38, + "column": 27, + "endLine": 38, + "endColumn": 49, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + }, + { + "line": 59, + "column": 30, + "endLine": 59, + "endColumn": 41, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 30, + "endLine": 63, + "endColumn": 44, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 30, + "endLine": 68, + "endColumn": 46, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 30, + "endLine": 72, + "endColumn": 49, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 30, + "endLine": 81, + "endColumn": 47, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 30, + "endLine": 90, + "endColumn": 52, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 31, + "endLine": 125, + "endColumn": 42, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + }, + { + "line": 132, + "column": 31, + "endLine": 132, + "endColumn": 47, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.args.json b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.args.json +++ b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.ets b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..42ff9e372ca8b0b2d3fcbabacdde227b81437ca7 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.ets @@ -0,0 +1,49 @@ +/* + * 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 { lang } from './@arkts.lang'; + +@Sendable +class GoodA implements lang.ISendable {} + +@Sendable +class BadA implements lang.ISendable {} // Fixable + +interface B extends lang.ISendable {} + +@Sendable +class GoodB implements B {} + +@Sendable +class BadB implements B {} // Fixable + +@Sendable +class C {} + +@Sendable +class GoodC extends C {} + +@Sendable +class BadC extends C {} // Fixable + +@Sendable +class BadC2 extends C implements lang.ISendable {} // Fixable + +class D {} + +@Sendable +class BadD extends D {} // Not fixable + +class GoodD extends D {} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.json b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..6cc01d31bc0a8e4bcff67bd288847a52525a0967 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_class_inheritance_2.ets.migrate.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": 47, + "column": 20, + "endLine": 47, + "endColumn": 21, + "problem": "SendableClassInheritance", + "suggest": "", + "rule": "The inheritance for \"Sendable\" classes is limited (arkts-sendable-class-inheritance)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets index 604e2aadb360b91099eb1219065061150bd097e5..ad7642039b2fb9f41631f91b9e8a6876e2258a70 100644 --- a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' @Sendable // ERROR class SendableClass { diff --git a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.args.json b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.args.json index 4e9dc628f7cbbb3ac73a21b2ce9f794758fcaae0..571ee6bb76b0cad72a9443db47c2f9d7db474bd0 100644 --- a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.args.json +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.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/sendable_decorator_arkts2.ets.arkts2.json b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.arkts2.json index 9a72d0f98a6f7f384e37fb2e02f4362ba216c519..84cf5f2ee31640facc568576a4300a791e76078a 100644 --- a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.arkts2.json +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.arkts2.json @@ -1,28 +1,14 @@ { - "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, + "line": 17, "column": 1, - "endLine": 16, + "endLine": 17, "endColumn": 10, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoSendableDecorator", "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.autofix.json b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.autofix.json index 4c8d17a17a59846281654444569726255232e24d..713f44e680df8e8ee976ff1d7ffb58711f2fc498 100644 --- a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.autofix.json @@ -15,20 +15,20 @@ ], "result": [ { - "line": 16, + "line": 17, "column": 1, - "endLine": 16, + "endLine": 17, "endColumn": 10, - "problem": "LimitedStdLibApi", + "problem": "LimitedStdLibNoSendableDecorator", "autofix": [ { - "start": 610, - "end": 619, + "start": 623, + "end": 632, "replacementText": "" } ], "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", + "rule": "Usage of standard library is restricted(arkts-limited-stdlib-no-sendable-decorator)", "severity": "ERROR" } ] diff --git a/ets2panda/test/parser/ets/user_defined_6.ets b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.ets similarity index 93% rename from ets2panda/test/parser/ets/user_defined_6.ets rename to ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.ets index 8e3f4782f0551cfbb0f546e1717361181b3f9007..32a1cd22fac0d4d421315e744b06b8b6cbe6c8d1 100644 --- a/ets2panda/test/parser/ets/user_defined_6.ets +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.ets @@ -12,6 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +'use static' -function float() { + // ERROR +class SendableClass { } diff --git a/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.json b/ets2panda/linter/test/main/sendable_decorator_arkts2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_decorator_arkts2.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 diff --git a/ets2panda/linter/test/main/sendable_decorator_limited.ets.args.json b/ets2panda/linter/test/main/sendable_decorator_limited.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/sendable_decorator_limited.ets.args.json +++ b/ets2panda/linter/test/main/sendable_decorator_limited.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.ets b/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..7b27a36af23bb3774a09df40af4eefeda6f101bb --- /dev/null +++ b/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.ets @@ -0,0 +1,53 @@ +/* + * 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. + */ + +@Sendable // OK +class SendableClass { +} + +@Sendable // OK +function sendableFunction(): void { +}; + +@Sendable // OK +type SendableType = () => void; + + // ERROR +struct SendableStruct { +}; + + +class NormalClass { + // ERROR + name: string = 'name'; + + // ERROR + handle() { + + }; + + handle2( param: string) { // ERROR + + } + + // ERROR + get age(): number { + return 1; + } + + // ERROR + set age(value: number) { + } +} diff --git a/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.json b/ets2panda/linter/test/main/sendable_decorator_limited.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_decorator_limited.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 diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.args.json b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.args.json +++ b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.autofix.json b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.autofix.json index ca304dd6c5151064dd79af5775651fa379dc337a..4431346a560958da8ac5ba18547d9074c9d8de0f 100644 --- a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.autofix.json +++ b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.autofix.json @@ -542,9 +542,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3320, - "end": 3447, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp4: boolean = true;" + "start": 3439, + "end": 3439, + "replacementText": ": boolean" } ], "suggest": "", @@ -559,9 +559,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3447, - "end": 3469, - "replacementText": "numberProp4: number = 42;" + "start": 3463, + "end": 3463, + "replacementText": ": number" } ], "suggest": "", @@ -576,9 +576,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3469, - "end": 3496, - "replacementText": "stringProp4: string = \"Hello\";" + "start": 3485, + "end": 3485, + "replacementText": ": string" } ], "suggest": "", @@ -593,9 +593,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3496, - "end": 3524, - "replacementText": "arrayProp4: number[] = [1, 2, 3];" + "start": 3511, + "end": 3511, + "replacementText": ": number[]" } ], "suggest": "", @@ -610,9 +610,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3524, - "end": 3560, - "replacementText": "tupleProp4: (string | number)[] = [\"typescript\", 4];" + "start": 3539, + "end": 3539, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -627,9 +627,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3560, - "end": 3589, - "replacementText": "enumProp4: Color = Color.Green;" + "start": 3574, + "end": 3574, + "replacementText": ": Color" } ], "suggest": "", @@ -676,9 +676,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3622, - "end": 3649, - "replacementText": "voidProp4: undefined = undefined;" + "start": 3636, + "end": 3636, + "replacementText": ": undefined" } ], "suggest": "", @@ -693,9 +693,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3649, - "end": 3671, - "replacementText": "nullProp4: null = null;" + "start": 3663, + "end": 3663, + "replacementText": ": null" } ], "suggest": "", @@ -710,9 +710,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3671, - "end": 3703, - "replacementText": "undefinedProp4: undefined = undefined;" + "start": 3690, + "end": 3690, + "replacementText": ": undefined" } ], "suggest": "", @@ -759,9 +759,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3748, - "end": 3790, - "replacementText": "sendableClass4: SendableClass = new SendableClass();" + "start": 3767, + "end": 3767, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -776,9 +776,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3790, - "end": 3836, - "replacementText": "noSendableClass4: NoSendableClass = new NoSendableClass();" + "start": 3811, + "end": 3811, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -793,9 +793,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3836, - "end": 3964, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp5?: boolean | undefined = true;" + "start": 3956, + "end": 3956, + "replacementText": ": boolean | undefined" } ], "suggest": "", @@ -810,9 +810,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3964, - "end": 3987, - "replacementText": "numberProp5?: number | undefined = 42;" + "start": 3981, + "end": 3981, + "replacementText": ": number | undefined" } ], "suggest": "", @@ -827,9 +827,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 3987, - "end": 4015, - "replacementText": "stringProp5?: string | undefined = \"Hello\";" + "start": 4004, + "end": 4004, + "replacementText": ": string | undefined" } ], "suggest": "", @@ -844,9 +844,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4015, - "end": 4044, - "replacementText": "arrayProp5?: number[] | undefined = [1, 2, 3];" + "start": 4031, + "end": 4031, + "replacementText": ": number[] | undefined" } ], "suggest": "", @@ -861,9 +861,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4044, - "end": 4081, - "replacementText": "tupleProp5?: (string | number)[] | undefined = [\"typescript\", 4];" + "start": 4060, + "end": 4060, + "replacementText": ": (string | number)[] | undefined" } ], "suggest": "", @@ -878,9 +878,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4081, - "end": 4111, - "replacementText": "enumProp5?: Color | undefined = Color.Green;" + "start": 4096, + "end": 4096, + "replacementText": ": Color | undefined" } ], "suggest": "", @@ -927,9 +927,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4145, - "end": 4173, - "replacementText": "voidProp5?: undefined = undefined;" + "start": 4160, + "end": 4160, + "replacementText": ": undefined" } ], "suggest": "", @@ -944,9 +944,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4173, - "end": 4196, - "replacementText": "nullProp5?: null | undefined = null;" + "start": 4188, + "end": 4188, + "replacementText": ": null | undefined" } ], "suggest": "", @@ -961,9 +961,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4196, - "end": 4229, - "replacementText": "undefinedProp5?: undefined = undefined;" + "start": 4216, + "end": 4216, + "replacementText": ": undefined" } ], "suggest": "", @@ -1010,9 +1010,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4275, - "end": 4318, - "replacementText": "sendableClass5?: SendableClass | undefined = new SendableClass();" + "start": 4295, + "end": 4295, + "replacementText": ": SendableClass | undefined" } ], "suggest": "", @@ -1027,9 +1027,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4318, - "end": 4365, - "replacementText": "noSendableClass5?: NoSendableClass | undefined = new NoSendableClass();" + "start": 4340, + "end": 4340, + "replacementText": ": NoSendableClass | undefined" } ], "suggest": "", @@ -1044,9 +1044,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4365, - "end": 4502, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\npublic optBooleanProp6: boolean = true;" + "start": 4494, + "end": 4494, + "replacementText": ": boolean" } ], "suggest": "", @@ -1061,9 +1061,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4502, - "end": 4534, - "replacementText": "public optNumberProp6: number = 42;" + "start": 4528, + "end": 4528, + "replacementText": ": number" } ], "suggest": "", @@ -1078,9 +1078,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4534, - "end": 4571, - "replacementText": "public optStringProp6: string = \"Hello\";" + "start": 4560, + "end": 4560, + "replacementText": ": string" } ], "suggest": "", @@ -1095,9 +1095,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4571, - "end": 4609, - "replacementText": "public optArrayProp6: number[] = [1, 2, 3];" + "start": 4596, + "end": 4596, + "replacementText": ": number[]" } ], "suggest": "", @@ -1112,9 +1112,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4609, - "end": 4655, - "replacementText": "public optTupleProp6: (string | number)[] = [\"typescript\", 4];" + "start": 4634, + "end": 4634, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -1129,9 +1129,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4655, - "end": 4694, - "replacementText": "public optEnumProp6: Color = Color.Green;" + "start": 4679, + "end": 4679, + "replacementText": ": Color" } ], "suggest": "", @@ -1178,9 +1178,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4737, - "end": 4774, - "replacementText": "public optVoidProp6: undefined = undefined;" + "start": 4761, + "end": 4761, + "replacementText": ": undefined" } ], "suggest": "", @@ -1195,9 +1195,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4774, - "end": 4806, - "replacementText": "public optNullProp6: null = null;" + "start": 4798, + "end": 4798, + "replacementText": ": null" } ], "suggest": "", @@ -1212,9 +1212,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4806, - "end": 4848, - "replacementText": "public optUndefinedProp6: undefined = undefined;" + "start": 4835, + "end": 4835, + "replacementText": ": undefined" } ], "suggest": "", @@ -1261,9 +1261,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4903, - "end": 4955, - "replacementText": "public optSendableClass6: SendableClass = new SendableClass();" + "start": 4932, + "end": 4932, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -1278,9 +1278,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 4955, - "end": 5011, - "replacementText": "public optNoSendableClass6: NoSendableClass = new NoSendableClass();" + "start": 4986, + "end": 4986, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -1295,9 +1295,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5011, - "end": 5150, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nreadonly optBooleanProp7: true = true;" + "start": 5142, + "end": 5142, + "replacementText": ": true" } ], "suggest": "", @@ -1312,9 +1312,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5150, - "end": 5184, - "replacementText": "readonly optNumberProp7: 42 = 42;" + "start": 5178, + "end": 5178, + "replacementText": ": 42" } ], "suggest": "", @@ -1329,9 +1329,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5184, - "end": 5223, - "replacementText": "readonly optStringProp7: \"Hello\" = \"Hello\";" + "start": 5212, + "end": 5212, + "replacementText": ": \"Hello\"" } ], "suggest": "", @@ -1346,9 +1346,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5223, - "end": 5263, - "replacementText": "readonly optArrayProp7: number[] = [1, 2, 3];" + "start": 5250, + "end": 5250, + "replacementText": ": number[]" } ], "suggest": "", @@ -1363,9 +1363,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5263, - "end": 5311, - "replacementText": "readonly optTupleProp7: (string | number)[] = [\"typescript\", 4];" + "start": 5290, + "end": 5290, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -1380,9 +1380,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5311, - "end": 5352, - "replacementText": "readonly optEnumProp7: Color.Green = Color.Green;" + "start": 5337, + "end": 5337, + "replacementText": ": Color.Green" } ], "suggest": "", @@ -1429,9 +1429,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5397, - "end": 5436, - "replacementText": "readonly optVoidProp7: undefined = undefined;" + "start": 5423, + "end": 5423, + "replacementText": ": undefined" } ], "suggest": "", @@ -1446,9 +1446,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5436, - "end": 5470, - "replacementText": "readonly optNullProp7: null = null;" + "start": 5462, + "end": 5462, + "replacementText": ": null" } ], "suggest": "", @@ -1463,9 +1463,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5470, - "end": 5514, - "replacementText": "readonly optUndefinedProp7: undefined = undefined;" + "start": 5501, + "end": 5501, + "replacementText": ": undefined" } ], "suggest": "", @@ -1512,9 +1512,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5571, - "end": 5625, - "replacementText": "readonly optSendableClass7: SendableClass = new SendableClass();" + "start": 5602, + "end": 5602, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -1529,9 +1529,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 5625, - "end": 5683, - "replacementText": "readonly optNoSendableClass7: NoSendableClass = new NoSendableClass();" + "start": 5658, + "end": 5658, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -2066,9 +2066,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8256, - "end": 8383, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp4: boolean = true;" + "start": 8375, + "end": 8375, + "replacementText": ": boolean" } ], "suggest": "", @@ -2083,9 +2083,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8383, - "end": 8405, - "replacementText": "numberProp4: number = 42;" + "start": 8399, + "end": 8399, + "replacementText": ": number" } ], "suggest": "", @@ -2100,9 +2100,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8405, - "end": 8432, - "replacementText": "stringProp4: string = \"Hello\";" + "start": 8421, + "end": 8421, + "replacementText": ": string" } ], "suggest": "", @@ -2117,9 +2117,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8432, - "end": 8460, - "replacementText": "arrayProp4: number[] = [1, 2, 3];" + "start": 8447, + "end": 8447, + "replacementText": ": number[]" } ], "suggest": "", @@ -2134,9 +2134,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8460, - "end": 8496, - "replacementText": "tupleProp4: (string | number)[] = [\"typescript\", 4];" + "start": 8475, + "end": 8475, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -2151,9 +2151,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8496, - "end": 8525, - "replacementText": "enumProp4: Color = Color.Green;" + "start": 8510, + "end": 8510, + "replacementText": ": Color" } ], "suggest": "", @@ -2200,9 +2200,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8558, - "end": 8585, - "replacementText": "voidProp4: undefined = undefined;" + "start": 8572, + "end": 8572, + "replacementText": ": undefined" } ], "suggest": "", @@ -2217,9 +2217,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8585, - "end": 8607, - "replacementText": "nullProp4: null = null;" + "start": 8599, + "end": 8599, + "replacementText": ": null" } ], "suggest": "", @@ -2234,9 +2234,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8607, - "end": 8639, - "replacementText": "undefinedProp4: undefined = undefined;" + "start": 8626, + "end": 8626, + "replacementText": ": undefined" } ], "suggest": "", @@ -2283,9 +2283,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8684, - "end": 8726, - "replacementText": "sendableClass4: SendableClass = new SendableClass();" + "start": 8703, + "end": 8703, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -2300,9 +2300,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8726, - "end": 8772, - "replacementText": "noSendableClass4: NoSendableClass = new NoSendableClass();" + "start": 8747, + "end": 8747, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -2317,9 +2317,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8772, - "end": 8900, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp5?: boolean | undefined = true;" + "start": 8892, + "end": 8892, + "replacementText": ": boolean | undefined" } ], "suggest": "", @@ -2334,9 +2334,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8900, - "end": 8923, - "replacementText": "numberProp5?: number | undefined = 42;" + "start": 8917, + "end": 8917, + "replacementText": ": number | undefined" } ], "suggest": "", @@ -2351,9 +2351,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8923, - "end": 8951, - "replacementText": "stringProp5?: string | undefined = \"Hello\";" + "start": 8940, + "end": 8940, + "replacementText": ": string | undefined" } ], "suggest": "", @@ -2368,9 +2368,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8951, - "end": 8980, - "replacementText": "arrayProp5?: number[] | undefined = [1, 2, 3];" + "start": 8967, + "end": 8967, + "replacementText": ": number[] | undefined" } ], "suggest": "", @@ -2385,9 +2385,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 8980, - "end": 9017, - "replacementText": "tupleProp5?: (string | number)[] | undefined = [\"typescript\", 4];" + "start": 8996, + "end": 8996, + "replacementText": ": (string | number)[] | undefined" } ], "suggest": "", @@ -2402,9 +2402,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9017, - "end": 9047, - "replacementText": "enumProp5?: Color | undefined = Color.Green;" + "start": 9032, + "end": 9032, + "replacementText": ": Color | undefined" } ], "suggest": "", @@ -2451,9 +2451,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9081, - "end": 9109, - "replacementText": "voidProp5?: undefined = undefined;" + "start": 9096, + "end": 9096, + "replacementText": ": undefined" } ], "suggest": "", @@ -2468,9 +2468,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9109, - "end": 9132, - "replacementText": "nullProp5?: null | undefined = null;" + "start": 9124, + "end": 9124, + "replacementText": ": null | undefined" } ], "suggest": "", @@ -2485,9 +2485,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9132, - "end": 9165, - "replacementText": "undefinedProp5?: undefined = undefined;" + "start": 9152, + "end": 9152, + "replacementText": ": undefined" } ], "suggest": "", @@ -2534,9 +2534,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9211, - "end": 9254, - "replacementText": "sendableClass5?: SendableClass | undefined = new SendableClass();" + "start": 9231, + "end": 9231, + "replacementText": ": SendableClass | undefined" } ], "suggest": "", @@ -2551,9 +2551,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9254, - "end": 9301, - "replacementText": "noSendableClass5?: NoSendableClass | undefined = new NoSendableClass();" + "start": 9276, + "end": 9276, + "replacementText": ": NoSendableClass | undefined" } ], "suggest": "", @@ -2568,9 +2568,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9301, - "end": 9438, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\npublic optBooleanProp6: boolean = true;" + "start": 9430, + "end": 9430, + "replacementText": ": boolean" } ], "suggest": "", @@ -2585,9 +2585,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9438, - "end": 9470, - "replacementText": "public optNumberProp6: number = 42;" + "start": 9464, + "end": 9464, + "replacementText": ": number" } ], "suggest": "", @@ -2602,9 +2602,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9470, - "end": 9507, - "replacementText": "public optStringProp6: string = \"Hello\";" + "start": 9496, + "end": 9496, + "replacementText": ": string" } ], "suggest": "", @@ -2619,9 +2619,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9507, - "end": 9545, - "replacementText": "public optArrayProp6: number[] = [1, 2, 3];" + "start": 9532, + "end": 9532, + "replacementText": ": number[]" } ], "suggest": "", @@ -2636,9 +2636,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9545, - "end": 9591, - "replacementText": "public optTupleProp6: (string | number)[] = [\"typescript\", 4];" + "start": 9570, + "end": 9570, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -2653,9 +2653,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9591, - "end": 9630, - "replacementText": "public optEnumProp6: Color = Color.Green;" + "start": 9615, + "end": 9615, + "replacementText": ": Color" } ], "suggest": "", @@ -2702,9 +2702,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9673, - "end": 9710, - "replacementText": "public optVoidProp6: undefined = undefined;" + "start": 9697, + "end": 9697, + "replacementText": ": undefined" } ], "suggest": "", @@ -2719,9 +2719,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9710, - "end": 9742, - "replacementText": "public optNullProp6: null = null;" + "start": 9734, + "end": 9734, + "replacementText": ": null" } ], "suggest": "", @@ -2736,9 +2736,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9742, - "end": 9784, - "replacementText": "public optUndefinedProp6: undefined = undefined;" + "start": 9771, + "end": 9771, + "replacementText": ": undefined" } ], "suggest": "", @@ -2785,9 +2785,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9839, - "end": 9891, - "replacementText": "public optSendableClass6: SendableClass = new SendableClass();" + "start": 9868, + "end": 9868, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -2802,9 +2802,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9891, - "end": 9947, - "replacementText": "public optNoSendableClass6: NoSendableClass = new NoSendableClass();" + "start": 9922, + "end": 9922, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -2819,9 +2819,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 9947, - "end": 10086, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nreadonly optBooleanProp7: true = true;" + "start": 10078, + "end": 10078, + "replacementText": ": true" } ], "suggest": "", @@ -2836,9 +2836,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10086, - "end": 10120, - "replacementText": "readonly optNumberProp7: 42 = 42;" + "start": 10114, + "end": 10114, + "replacementText": ": 42" } ], "suggest": "", @@ -2853,9 +2853,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10120, - "end": 10159, - "replacementText": "readonly optStringProp7: \"Hello\" = \"Hello\";" + "start": 10148, + "end": 10148, + "replacementText": ": \"Hello\"" } ], "suggest": "", @@ -2870,9 +2870,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10159, - "end": 10199, - "replacementText": "readonly optArrayProp7: number[] = [1, 2, 3];" + "start": 10186, + "end": 10186, + "replacementText": ": number[]" } ], "suggest": "", @@ -2887,9 +2887,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10199, - "end": 10247, - "replacementText": "readonly optTupleProp7: (string | number)[] = [\"typescript\", 4];" + "start": 10226, + "end": 10226, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -2904,9 +2904,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10247, - "end": 10288, - "replacementText": "readonly optEnumProp7: Color.Green = Color.Green;" + "start": 10273, + "end": 10273, + "replacementText": ": Color.Green" } ], "suggest": "", @@ -2953,9 +2953,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10333, - "end": 10372, - "replacementText": "readonly optVoidProp7: undefined = undefined;" + "start": 10359, + "end": 10359, + "replacementText": ": undefined" } ], "suggest": "", @@ -2970,9 +2970,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10372, - "end": 10406, - "replacementText": "readonly optNullProp7: null = null;" + "start": 10398, + "end": 10398, + "replacementText": ": null" } ], "suggest": "", @@ -2987,9 +2987,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10406, - "end": 10450, - "replacementText": "readonly optUndefinedProp7: undefined = undefined;" + "start": 10437, + "end": 10437, + "replacementText": ": undefined" } ], "suggest": "", @@ -3036,9 +3036,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10507, - "end": 10561, - "replacementText": "readonly optSendableClass7: SendableClass = new SendableClass();" + "start": 10538, + "end": 10538, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -3053,9 +3053,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 10561, - "end": 10619, - "replacementText": "readonly optNoSendableClass7: NoSendableClass = new NoSendableClass();" + "start": 10594, + "end": 10594, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -3590,9 +3590,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13165, - "end": 13292, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp4: boolean = true;" + "start": 13284, + "end": 13284, + "replacementText": ": boolean" } ], "suggest": "", @@ -3607,9 +3607,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13292, - "end": 13314, - "replacementText": "numberProp4: number = 42;" + "start": 13308, + "end": 13308, + "replacementText": ": number" } ], "suggest": "", @@ -3624,9 +3624,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13314, - "end": 13341, - "replacementText": "stringProp4: string = \"Hello\";" + "start": 13330, + "end": 13330, + "replacementText": ": string" } ], "suggest": "", @@ -3641,9 +3641,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13341, - "end": 13369, - "replacementText": "arrayProp4: number[] = [1, 2, 3];" + "start": 13356, + "end": 13356, + "replacementText": ": number[]" } ], "suggest": "", @@ -3658,9 +3658,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13369, - "end": 13405, - "replacementText": "tupleProp4: (string | number)[] = [\"typescript\", 4];" + "start": 13384, + "end": 13384, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -3675,9 +3675,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13405, - "end": 13434, - "replacementText": "enumProp4: Color = Color.Green;" + "start": 13419, + "end": 13419, + "replacementText": ": Color" } ], "suggest": "", @@ -3724,9 +3724,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13467, - "end": 13494, - "replacementText": "voidProp4: undefined = undefined;" + "start": 13481, + "end": 13481, + "replacementText": ": undefined" } ], "suggest": "", @@ -3741,9 +3741,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13494, - "end": 13516, - "replacementText": "nullProp4: null = null;" + "start": 13508, + "end": 13508, + "replacementText": ": null" } ], "suggest": "", @@ -3758,9 +3758,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13516, - "end": 13548, - "replacementText": "undefinedProp4: undefined = undefined;" + "start": 13535, + "end": 13535, + "replacementText": ": undefined" } ], "suggest": "", @@ -3807,9 +3807,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13593, - "end": 13635, - "replacementText": "sendableClass4: SendableClass = new SendableClass();" + "start": 13612, + "end": 13612, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -3824,9 +3824,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13635, - "end": 13681, - "replacementText": "noSendableClass4: NoSendableClass = new NoSendableClass();" + "start": 13656, + "end": 13656, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -3841,9 +3841,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13681, - "end": 13809, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nbooleanProp5?: boolean | undefined = true;" + "start": 13801, + "end": 13801, + "replacementText": ": boolean | undefined" } ], "suggest": "", @@ -3858,9 +3858,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13809, - "end": 13832, - "replacementText": "numberProp5?: number | undefined = 42;" + "start": 13826, + "end": 13826, + "replacementText": ": number | undefined" } ], "suggest": "", @@ -3875,9 +3875,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13832, - "end": 13860, - "replacementText": "stringProp5?: string | undefined = \"Hello\";" + "start": 13849, + "end": 13849, + "replacementText": ": string | undefined" } ], "suggest": "", @@ -3892,9 +3892,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13860, - "end": 13889, - "replacementText": "arrayProp5?: number[] | undefined = [1, 2, 3];" + "start": 13876, + "end": 13876, + "replacementText": ": number[] | undefined" } ], "suggest": "", @@ -3909,9 +3909,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13889, - "end": 13926, - "replacementText": "tupleProp5?: (string | number)[] | undefined = [\"typescript\", 4];" + "start": 13905, + "end": 13905, + "replacementText": ": (string | number)[] | undefined" } ], "suggest": "", @@ -3926,9 +3926,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13926, - "end": 13956, - "replacementText": "enumProp5?: Color | undefined = Color.Green;" + "start": 13941, + "end": 13941, + "replacementText": ": Color | undefined" } ], "suggest": "", @@ -3975,9 +3975,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 13990, - "end": 14018, - "replacementText": "voidProp5?: undefined = undefined;" + "start": 14005, + "end": 14005, + "replacementText": ": undefined" } ], "suggest": "", @@ -3992,9 +3992,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14018, - "end": 14041, - "replacementText": "nullProp5?: null | undefined = null;" + "start": 14033, + "end": 14033, + "replacementText": ": null | undefined" } ], "suggest": "", @@ -4009,9 +4009,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14041, - "end": 14074, - "replacementText": "undefinedProp5?: undefined = undefined;" + "start": 14061, + "end": 14061, + "replacementText": ": undefined" } ], "suggest": "", @@ -4058,9 +4058,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14120, - "end": 14163, - "replacementText": "sendableClass5?: SendableClass | undefined = new SendableClass();" + "start": 14140, + "end": 14140, + "replacementText": ": SendableClass | undefined" } ], "suggest": "", @@ -4075,9 +4075,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14163, - "end": 14210, - "replacementText": "noSendableClass5?: NoSendableClass | undefined = new NoSendableClass();" + "start": 14185, + "end": 14185, + "replacementText": ": NoSendableClass | undefined" } ], "suggest": "", @@ -4092,9 +4092,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14210, - "end": 14347, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\npublic optBooleanProp6: boolean = true;" + "start": 14339, + "end": 14339, + "replacementText": ": boolean" } ], "suggest": "", @@ -4109,9 +4109,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14347, - "end": 14379, - "replacementText": "public optNumberProp6: number = 42;" + "start": 14373, + "end": 14373, + "replacementText": ": number" } ], "suggest": "", @@ -4126,9 +4126,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14379, - "end": 14416, - "replacementText": "public optStringProp6: string = \"Hello\";" + "start": 14405, + "end": 14405, + "replacementText": ": string" } ], "suggest": "", @@ -4143,9 +4143,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14416, - "end": 14454, - "replacementText": "public optArrayProp6: number[] = [1, 2, 3];" + "start": 14441, + "end": 14441, + "replacementText": ": number[]" } ], "suggest": "", @@ -4160,9 +4160,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14454, - "end": 14500, - "replacementText": "public optTupleProp6: (string | number)[] = [\"typescript\", 4];" + "start": 14479, + "end": 14479, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -4177,9 +4177,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14500, - "end": 14539, - "replacementText": "public optEnumProp6: Color = Color.Green;" + "start": 14524, + "end": 14524, + "replacementText": ": Color" } ], "suggest": "", @@ -4226,9 +4226,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14582, - "end": 14619, - "replacementText": "public optVoidProp6: undefined = undefined;" + "start": 14606, + "end": 14606, + "replacementText": ": undefined" } ], "suggest": "", @@ -4243,9 +4243,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14619, - "end": 14651, - "replacementText": "public optNullProp6: null = null;" + "start": 14643, + "end": 14643, + "replacementText": ": null" } ], "suggest": "", @@ -4260,9 +4260,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14651, - "end": 14693, - "replacementText": "public optUndefinedProp6: undefined = undefined;" + "start": 14680, + "end": 14680, + "replacementText": ": undefined" } ], "suggest": "", @@ -4309,9 +4309,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14748, - "end": 14800, - "replacementText": "public optSendableClass6: SendableClass = new SendableClass();" + "start": 14777, + "end": 14777, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -4326,9 +4326,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14800, - "end": 14856, - "replacementText": "public optNoSendableClass6: NoSendableClass = new NoSendableClass();" + "start": 14831, + "end": 14831, + "replacementText": ": NoSendableClass" } ], "suggest": "", @@ -4343,9 +4343,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14856, - "end": 14995, - "replacementText": "// Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)\nreadonly optBooleanProp7: true = true;" + "start": 14987, + "end": 14987, + "replacementText": ": true" } ], "suggest": "", @@ -4360,9 +4360,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 14995, - "end": 15029, - "replacementText": "readonly optNumberProp7: 42 = 42;" + "start": 15023, + "end": 15023, + "replacementText": ": 42" } ], "suggest": "", @@ -4377,9 +4377,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15029, - "end": 15068, - "replacementText": "readonly optStringProp7: \"Hello\" = \"Hello\";" + "start": 15057, + "end": 15057, + "replacementText": ": \"Hello\"" } ], "suggest": "", @@ -4394,9 +4394,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15068, - "end": 15108, - "replacementText": "readonly optArrayProp7: number[] = [1, 2, 3];" + "start": 15095, + "end": 15095, + "replacementText": ": number[]" } ], "suggest": "", @@ -4411,9 +4411,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15108, - "end": 15156, - "replacementText": "readonly optTupleProp7: (string | number)[] = [\"typescript\", 4];" + "start": 15135, + "end": 15135, + "replacementText": ": (string | number)[]" } ], "suggest": "", @@ -4428,9 +4428,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15156, - "end": 15197, - "replacementText": "readonly optEnumProp7: Color.Green = Color.Green;" + "start": 15182, + "end": 15182, + "replacementText": ": Color.Green" } ], "suggest": "", @@ -4477,9 +4477,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15242, - "end": 15281, - "replacementText": "readonly optVoidProp7: undefined = undefined;" + "start": 15268, + "end": 15268, + "replacementText": ": undefined" } ], "suggest": "", @@ -4494,9 +4494,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15281, - "end": 15315, - "replacementText": "readonly optNullProp7: null = null;" + "start": 15307, + "end": 15307, + "replacementText": ": null" } ], "suggest": "", @@ -4511,9 +4511,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15315, - "end": 15359, - "replacementText": "readonly optUndefinedProp7: undefined = undefined;" + "start": 15346, + "end": 15346, + "replacementText": ": undefined" } ], "suggest": "", @@ -4560,9 +4560,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15416, - "end": 15470, - "replacementText": "readonly optSendableClass7: SendableClass = new SendableClass();" + "start": 15447, + "end": 15447, + "replacementText": ": SendableClass" } ], "suggest": "", @@ -4577,9 +4577,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 15470, - "end": 15528, - "replacementText": "readonly optNoSendableClass7: NoSendableClass = new NoSendableClass();" + "start": 15503, + "end": 15503, + "replacementText": ": NoSendableClass" } ], "suggest": "", diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.ets b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..8bcbd308819d074fadbfa76b621642921619ca53 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.ets @@ -0,0 +1,659 @@ +/* + * 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 namespace lang { + interface ISendable {} +} + +enum Color {Red, Green, Blue} + +@Sendable +class SendableClass { + public a: number = 1; +} + +class NoSendableClass { + public b: number = 1; +} + +interface GeneratedObjectLiteralInterface_1 { + key: string; +} +interface GeneratedObjectLiteralInterface_2 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_3 { + key: string; +} +interface GeneratedObjectLiteralInterface_4 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_5 { + key: string; +} +interface GeneratedObjectLiteralInterface_6 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_7 { + key: string; +} +interface GeneratedObjectLiteralInterface_8 { + name: string; + age: number; +} +@Sendable +class A { + booleanProp: boolean = true; + numberProp: number = 42; + stringProp: string = "Hello"; + arrayProp: number[] = [1, 2, 3]; + tupleProp: [string, number] = ["typescript", 4]; + enumProp: Color = Color.Green; + anyProp: any = { key: "value" }; + voidProp: void = undefined; + nullProp: null = null; + undefinedProp: undefined = undefined; + objectProp: object = { name: "John", age: 30 }; + sendableClass: SendableClass = new SendableClass(); + noSendableClass: NoSendableClass = new NoSendableClass(); + + optBooleanProp1?: boolean = true; + optNumberProp1?: number = 42; + optStringProp1?: string = "Hello"; + optArrayProp1?: number[] = [1, 2, 3]; + optTupleProp1?: [string, number] = ["typescript", 4]; + optEnumProp1?: Color = Color.Green; + optAnyProp1?: any = { key: "value" }; + optVoidProp1?: void = undefined; + optNullProp1?: null = null; + optUndefinedProp1?: undefined = undefined; + optObjectProp1?: object = { name: "John", age: 30 }; + optSendableClass1?: SendableClass = new SendableClass(); + optNoSendableClass1?: NoSendableClass = new NoSendableClass(); + + public optBooleanProp2: boolean = true; + public optNumberProp2: number = 42; + public optStringProp2: string = "Hello"; + public optArrayProp2: number[] = [1, 2, 3]; + public optTupleProp2: [string, number] = ["typescript", 4]; + public optEnumProp2: Color = Color.Green; + public optAnyProp2: any = { key: "value" }; + public optVoidProp2: void = undefined; + public optNullProp2: null = null; + public optUndefinedProp2: undefined = undefined; + public optObjectProp2: object = { name: "John", age: 30 }; + public optSendableClass2: SendableClass = new SendableClass(); + public optNoSendableClass2: NoSendableClass = new NoSendableClass(); + + readonly optBooleanProp3: boolean = true; + readonly optNumberProp3: number = 42; + readonly optStringProp3: string = "Hello"; + readonly optArrayProp3: number[] = [1, 2, 3]; + readonly optTupleProp3: [string, number] = ["typescript", 4]; + readonly optEnumProp3: Color = Color.Green; + readonly optAnyProp3: any = { key: "value" }; + readonly optVoidProp3: void = undefined; + readonly optNullProp3: null = null; + readonly optUndefinedProp3: undefined = undefined; + readonly optObjectProp3: object = { name: "John", age: 30 }; + readonly optSendableClass3: SendableClass = new SendableClass(); + readonly optNoSendableClass3: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp4: boolean = true; + numberProp4: number = 42; + stringProp4: string = "Hello"; + arrayProp4: number[] = [1, 2, 3]; + tupleProp4: (string | number)[] = ["typescript", 4]; + enumProp4: Color = Color.Green; + anyProp4: GeneratedObjectLiteralInterface_1 = { key: "value" }; + voidProp4: undefined = undefined; + nullProp4: null = null; + undefinedProp4: undefined = undefined; + objectProp4: GeneratedObjectLiteralInterface_2 = { name: "John", age: 30 }; + sendableClass4: SendableClass = new SendableClass(); + noSendableClass4: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp5?: boolean | undefined = true; + numberProp5?: number | undefined = 42; + stringProp5?: string | undefined = "Hello"; + arrayProp5?: number[] | undefined = [1, 2, 3]; + tupleProp5?: (string | number)[] | undefined = ["typescript", 4]; + enumProp5?: Color | undefined = Color.Green; + anyProp5?: GeneratedObjectLiteralInterface_3 = { key: "value" }; + voidProp5?: undefined = undefined; + nullProp5?: null | undefined = null; + undefinedProp5?: undefined = undefined; + objectProp5?: GeneratedObjectLiteralInterface_4 = { name: "John", age: 30 }; + sendableClass5?: SendableClass | undefined = new SendableClass(); + noSendableClass5?: NoSendableClass | undefined = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + public optBooleanProp6: boolean = true; + public optNumberProp6: number = 42; + public optStringProp6: string = "Hello"; + public optArrayProp6: number[] = [1, 2, 3]; + public optTupleProp6: (string | number)[] = ["typescript", 4]; + public optEnumProp6: Color = Color.Green; + public optAnyProp6: GeneratedObjectLiteralInterface_5 = { key: "value" }; + public optVoidProp6: undefined = undefined; + public optNullProp6: null = null; + public optUndefinedProp6: undefined = undefined; + public optObjectProp6: GeneratedObjectLiteralInterface_6 = { name: "John", age: 30 }; + public optSendableClass6: SendableClass = new SendableClass(); + public optNoSendableClass6: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + readonly optBooleanProp7: true = true; + readonly optNumberProp7: 42 = 42; + readonly optStringProp7: "Hello" = "Hello"; + readonly optArrayProp7: number[] = [1, 2, 3]; + readonly optTupleProp7: (string | number)[] = ["typescript", 4]; + readonly optEnumProp7: Color.Green = Color.Green; + readonly optAnyProp7: GeneratedObjectLiteralInterface_7 = { key: "value" }; + readonly optVoidProp7: undefined = undefined; + readonly optNullProp7: null = null; + readonly optUndefinedProp7: undefined = undefined; + readonly optObjectProp7: GeneratedObjectLiteralInterface_8 = { name: "John", age: 30 }; + readonly optSendableClass7: SendableClass = new SendableClass(); + readonly optNoSendableClass7: NoSendableClass = new NoSendableClass(); +} + +interface GeneratedObjectLiteralInterface_9 { + key: string; +} +interface GeneratedObjectLiteralInterface_10 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_11 { + key: string; +} +interface GeneratedObjectLiteralInterface_12 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_13 { + key: string; +} +interface GeneratedObjectLiteralInterface_14 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_15 { + key: string; +} +interface GeneratedObjectLiteralInterface_16 { + name: string; + age: number; +} +@Sendable +class A1 extends A { + constructor() { + super(); + } + booleanProp: boolean = true; + numberProp: number = 42; + stringProp: string = "Hello"; + arrayProp: number[] = [1, 2, 3]; + tupleProp: [string, number] = ["typescript", 4]; + enumProp: Color = Color.Green; + anyProp: any = { key: "value" }; + voidProp: void = undefined; + nullProp: null = null; + undefinedProp: undefined = undefined; + objectProp: object = { name: "John", age: 30 }; + sendableClass: SendableClass = new SendableClass(); + noSendableClass: NoSendableClass = new NoSendableClass(); + + optBooleanProp1?: boolean = true; + optNumberProp1?: number = 42; + optStringProp1?: string = "Hello"; + optArrayProp1?: number[] = [1, 2, 3]; + optTupleProp1?: [string, number] = ["typescript", 4]; + optEnumProp1?: Color = Color.Green; + optAnyProp1?: any = { key: "value" }; + optVoidProp1?: void = undefined; + optNullProp1?: null = null; + optUndefinedProp1?: undefined = undefined; + optObjectProp1?: object = { name: "John", age: 30 }; + optSendableClass1?: SendableClass = new SendableClass(); + optNoSendableClass1?: NoSendableClass = new NoSendableClass(); + + public optBooleanProp2: boolean = true; + public optNumberProp2: number = 42; + public optStringProp2: string = "Hello"; + public optArrayProp2: number[] = [1, 2, 3]; + public optTupleProp2: [string, number] = ["typescript", 4]; + public optEnumProp2: Color = Color.Green; + public optAnyProp2: any = { key: "value" }; + public optVoidProp2: void = undefined; + public optNullProp2: null = null; + public optUndefinedProp2: undefined = undefined; + public optObjectProp2: object = { name: "John", age: 30 }; + public optSendableClass2: SendableClass = new SendableClass(); + public optNoSendableClass2: NoSendableClass = new NoSendableClass(); + + readonly optBooleanProp3: boolean = true; + readonly optNumberProp3: number = 42; + readonly optStringProp3: string = "Hello"; + readonly optArrayProp3: number[] = [1, 2, 3]; + readonly optTupleProp3: [string, number] = ["typescript", 4]; + readonly optEnumProp3: Color = Color.Green; + readonly optAnyProp3: any = { key: "value" }; + readonly optVoidProp3: void = undefined; + readonly optNullProp3: null = null; + readonly optUndefinedProp3: undefined = undefined; + readonly optObjectProp3: object = { name: "John", age: 30 }; + readonly optSendableClass3: SendableClass = new SendableClass(); + readonly optNoSendableClass3: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp4: boolean = true; + numberProp4: number = 42; + stringProp4: string = "Hello"; + arrayProp4: number[] = [1, 2, 3]; + tupleProp4: (string | number)[] = ["typescript", 4]; + enumProp4: Color = Color.Green; + anyProp4: GeneratedObjectLiteralInterface_9 = { key: "value" }; + voidProp4: undefined = undefined; + nullProp4: null = null; + undefinedProp4: undefined = undefined; + objectProp4: GeneratedObjectLiteralInterface_10 = { name: "John", age: 30 }; + sendableClass4: SendableClass = new SendableClass(); + noSendableClass4: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp5?: boolean | undefined = true; + numberProp5?: number | undefined = 42; + stringProp5?: string | undefined = "Hello"; + arrayProp5?: number[] | undefined = [1, 2, 3]; + tupleProp5?: (string | number)[] | undefined = ["typescript", 4]; + enumProp5?: Color | undefined = Color.Green; + anyProp5?: GeneratedObjectLiteralInterface_11 = { key: "value" }; + voidProp5?: undefined = undefined; + nullProp5?: null | undefined = null; + undefinedProp5?: undefined = undefined; + objectProp5?: GeneratedObjectLiteralInterface_12 = { name: "John", age: 30 }; + sendableClass5?: SendableClass | undefined = new SendableClass(); + noSendableClass5?: NoSendableClass | undefined = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + public optBooleanProp6: boolean = true; + public optNumberProp6: number = 42; + public optStringProp6: string = "Hello"; + public optArrayProp6: number[] = [1, 2, 3]; + public optTupleProp6: (string | number)[] = ["typescript", 4]; + public optEnumProp6: Color = Color.Green; + public optAnyProp6: GeneratedObjectLiteralInterface_13 = { key: "value" }; + public optVoidProp6: undefined = undefined; + public optNullProp6: null = null; + public optUndefinedProp6: undefined = undefined; + public optObjectProp6: GeneratedObjectLiteralInterface_14 = { name: "John", age: 30 }; + public optSendableClass6: SendableClass = new SendableClass(); + public optNoSendableClass6: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + readonly optBooleanProp7: true = true; + readonly optNumberProp7: 42 = 42; + readonly optStringProp7: "Hello" = "Hello"; + readonly optArrayProp7: number[] = [1, 2, 3]; + readonly optTupleProp7: (string | number)[] = ["typescript", 4]; + readonly optEnumProp7: Color.Green = Color.Green; + readonly optAnyProp7: GeneratedObjectLiteralInterface_15 = { key: "value" }; + readonly optVoidProp7: undefined = undefined; + readonly optNullProp7: null = null; + readonly optUndefinedProp7: undefined = undefined; + readonly optObjectProp7: GeneratedObjectLiteralInterface_16 = { name: "John", age: 30 }; + readonly optSendableClass7: SendableClass = new SendableClass(); + readonly optNoSendableClass7: NoSendableClass = new NoSendableClass(); +} + +interface GeneratedObjectLiteralInterface_17 { + key: string; +} +interface GeneratedObjectLiteralInterface_18 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_19 { + key: string; +} +interface GeneratedObjectLiteralInterface_20 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_21 { + key: string; +} +interface GeneratedObjectLiteralInterface_22 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_23 { + key: string; +} +interface GeneratedObjectLiteralInterface_24 { + name: string; + age: number; +} +@Sendable +class A2 implements lang.ISendable { + booleanProp: boolean = true; + numberProp: number = 42; + stringProp: string = "Hello"; + arrayProp: number[] = [1, 2, 3]; + tupleProp: [string, number] = ["typescript", 4]; + enumProp: Color = Color.Green; + anyProp: any = { key: "value" }; + voidProp: void = undefined; + nullProp: null = null; + undefinedProp: undefined = undefined; + objectProp: object = { name: "John", age: 30 }; + sendableClass: SendableClass = new SendableClass(); + noSendableClass: NoSendableClass = new NoSendableClass(); + + optBooleanProp1?: boolean = true; + optNumberProp1?: number = 42; + optStringProp1?: string = "Hello"; + optArrayProp1?: number[] = [1, 2, 3]; + optTupleProp1?: [string, number] = ["typescript", 4]; + optEnumProp1?: Color = Color.Green; + optAnyProp1?: any = { key: "value" }; + optVoidProp1?: void = undefined; + optNullProp1?: null = null; + optUndefinedProp1?: undefined = undefined; + optObjectProp1?: object = { name: "John", age: 30 }; + optSendableClass1?: SendableClass = new SendableClass(); + optNoSendableClass1?: NoSendableClass = new NoSendableClass(); + + public optBooleanProp2: boolean = true; + public optNumberProp2: number = 42; + public optStringProp2: string = "Hello"; + public optArrayProp2: number[] = [1, 2, 3]; + public optTupleProp2: [string, number] = ["typescript", 4]; + public optEnumProp2: Color = Color.Green; + public optAnyProp2: any = { key: "value" }; + public optVoidProp2: void = undefined; + public optNullProp2: null = null; + public optUndefinedProp2: undefined = undefined; + public optObjectProp2: object = { name: "John", age: 30 }; + public optSendableClass2: SendableClass = new SendableClass(); + public optNoSendableClass2: NoSendableClass = new NoSendableClass(); + + readonly optBooleanProp3: boolean = true; + readonly optNumberProp3: number = 42; + readonly optStringProp3: string = "Hello"; + readonly optArrayProp3: number[] = [1, 2, 3]; + readonly optTupleProp3: [string, number] = ["typescript", 4]; + readonly optEnumProp3: Color = Color.Green; + readonly optAnyProp3: any = { key: "value" }; + readonly optVoidProp3: void = undefined; + readonly optNullProp3: null = null; + readonly optUndefinedProp3: undefined = undefined; + readonly optObjectProp3: object = { name: "John", age: 30 }; + readonly optSendableClass3: SendableClass = new SendableClass(); + readonly optNoSendableClass3: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp4: boolean = true; + numberProp4: number = 42; + stringProp4: string = "Hello"; + arrayProp4: number[] = [1, 2, 3]; + tupleProp4: (string | number)[] = ["typescript", 4]; + enumProp4: Color = Color.Green; + anyProp4: GeneratedObjectLiteralInterface_17 = { key: "value" }; + voidProp4: undefined = undefined; + nullProp4: null = null; + undefinedProp4: undefined = undefined; + objectProp4: GeneratedObjectLiteralInterface_18 = { name: "John", age: 30 }; + sendableClass4: SendableClass = new SendableClass(); + noSendableClass4: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + booleanProp5?: boolean | undefined = true; + numberProp5?: number | undefined = 42; + stringProp5?: string | undefined = "Hello"; + arrayProp5?: number[] | undefined = [1, 2, 3]; + tupleProp5?: (string | number)[] | undefined = ["typescript", 4]; + enumProp5?: Color | undefined = Color.Green; + anyProp5?: GeneratedObjectLiteralInterface_19 = { key: "value" }; + voidProp5?: undefined = undefined; + nullProp5?: null | undefined = null; + undefinedProp5?: undefined = undefined; + objectProp5?: GeneratedObjectLiteralInterface_20 = { name: "John", age: 30 }; + sendableClass5?: SendableClass | undefined = new SendableClass(); + noSendableClass5?: NoSendableClass | undefined = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + public optBooleanProp6: boolean = true; + public optNumberProp6: number = 42; + public optStringProp6: string = "Hello"; + public optArrayProp6: number[] = [1, 2, 3]; + public optTupleProp6: (string | number)[] = ["typescript", 4]; + public optEnumProp6: Color = Color.Green; + public optAnyProp6: GeneratedObjectLiteralInterface_21 = { key: "value" }; + public optVoidProp6: undefined = undefined; + public optNullProp6: null = null; + public optUndefinedProp6: undefined = undefined; + public optObjectProp6: GeneratedObjectLiteralInterface_22 = { name: "John", age: 30 }; + public optSendableClass6: SendableClass = new SendableClass(); + public optNoSendableClass6: NoSendableClass = new NoSendableClass(); + + // Error, Field in sendable class must have type annotation (arkts-sendable-explicit-field-type) + readonly optBooleanProp7: true = true; + readonly optNumberProp7: 42 = 42; + readonly optStringProp7: "Hello" = "Hello"; + readonly optArrayProp7: number[] = [1, 2, 3]; + readonly optTupleProp7: (string | number)[] = ["typescript", 4]; + readonly optEnumProp7: Color.Green = Color.Green; + readonly optAnyProp7: GeneratedObjectLiteralInterface_23 = { key: "value" }; + readonly optVoidProp7: undefined = undefined; + readonly optNullProp7: null = null; + readonly optUndefinedProp7: undefined = undefined; + readonly optObjectProp7: GeneratedObjectLiteralInterface_24 = { name: "John", age: 30 }; + readonly optSendableClass7: SendableClass = new SendableClass(); + readonly optNoSendableClass7: NoSendableClass = new NoSendableClass(); +} + +interface GeneratedObjectLiteralInterface_25 { + key: string; +} +interface GeneratedObjectLiteralInterface_26 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_27 { + key: string; +} +interface GeneratedObjectLiteralInterface_28 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_29 { + key: string; +} +interface GeneratedObjectLiteralInterface_30 { + name: string; + age: number; +} +interface GeneratedObjectLiteralInterface_31 { + key: string; +} +interface GeneratedObjectLiteralInterface_32 { + name: string; + age: number; +} +class A3 { + booleanProp: boolean = true; + numberProp: number = 42; + stringProp: string = "Hello"; + arrayProp: number[] = [1, 2, 3]; + tupleProp: [string, number] = ["typescript", 4]; + enumProp: Color = Color.Green; + anyProp: any = { key: "value" }; + voidProp: void = undefined; + nullProp: null = null; + undefinedProp: undefined = undefined; + objectProp: object = { name: "John", age: 30 }; + sendableClass: SendableClass = new SendableClass(); + noSendableClass: NoSendableClass = new NoSendableClass(); + + optBooleanProp1?: boolean = true; + optNumberProp1?: number = 42; + optStringProp1?: string = "Hello"; + optArrayProp1?: number[] = [1, 2, 3]; + optTupleProp1?: [string, number] = ["typescript", 4]; + optEnumProp1?: Color = Color.Green; + optAnyProp1?: any = { key: "value" }; + optVoidProp1?: void = undefined; + optNullProp1?: null = null; + optUndefinedProp1?: undefined = undefined; + optObjectProp1?: object = { name: "John", age: 30 }; + optSendableClass1?: SendableClass = new SendableClass(); + optNoSendableClass1?: NoSendableClass = new NoSendableClass(); + + public optBooleanProp2: boolean = true; + public optNumberProp2: number = 42; + public optStringProp2: string = "Hello"; + public optArrayProp2: number[] = [1, 2, 3]; + public optTupleProp2: [string, number] = ["typescript", 4]; + public optEnumProp2: Color = Color.Green; + public optAnyProp2: any = { key: "value" }; + public optVoidProp2: void = undefined; + public optNullProp2: null = null; + public optUndefinedProp2: undefined = undefined; + public optObjectProp2: object = { name: "John", age: 30 }; + public optSendableClass2: SendableClass = new SendableClass(); + public optNoSendableClass2: NoSendableClass = new NoSendableClass(); + + readonly optBooleanProp3: boolean = true; + readonly optNumberProp3: number = 42; + readonly optStringProp3: string = "Hello"; + readonly optArrayProp3: number[] = [1, 2, 3]; + readonly optTupleProp3: [string, number] = ["typescript", 4]; + readonly optEnumProp3: Color = Color.Green; + readonly optAnyProp3: any = { key: "value" }; + readonly optVoidProp3: void = undefined; + readonly optNullProp3: null = null; + readonly optUndefinedProp3: undefined = undefined; + readonly optObjectProp3: object = { name: "John", age: 30 }; + readonly optSendableClass3: SendableClass = new SendableClass(); + readonly optNoSendableClass3: NoSendableClass = new NoSendableClass(); + + booleanProp4 = true; + numberProp4 = 42; + stringProp4 = "Hello"; + arrayProp4 = [1, 2, 3]; + tupleProp4 = ["typescript", 4]; + enumProp4 = Color.Green; + anyProp4: GeneratedObjectLiteralInterface_25 = { key: "value" }; + voidProp4 = undefined; + nullProp4 = null; + undefinedProp4 = undefined; + objectProp4: GeneratedObjectLiteralInterface_26 = { name: "John", age: 30 }; + sendableClass4 = new SendableClass(); + noSendableClass4 = new NoSendableClass(); + + booleanProp5? = true; + numberProp5? = 42; + stringProp5? = "Hello"; + arrayProp5? = [1, 2, 3]; + tupleProp5? = ["typescript", 4]; + enumProp5? = Color.Green; + anyProp5?: GeneratedObjectLiteralInterface_27 = { key: "value" }; + voidProp5? = undefined; + nullProp5? = null; + undefinedProp5? = undefined; + objectProp5?: GeneratedObjectLiteralInterface_28 = { name: "John", age: 30 }; + sendableClass5? = new SendableClass(); + noSendableClass5? = new NoSendableClass(); + + public optBooleanProp6 = true; + public optNumberProp6 = 42; + public optStringProp6 = "Hello"; + public optArrayProp6 = [1, 2, 3]; + public optTupleProp6 = ["typescript", 4]; + public optEnumProp6 = Color.Green; + public optAnyProp6: GeneratedObjectLiteralInterface_29 = { key: "value" }; + public optVoidProp6 = undefined; + public optNullProp6 = null; + public optUndefinedProp6 = undefined; + public optObjectProp6: GeneratedObjectLiteralInterface_30 = { name: "John", age: 30 }; + public optSendableClass6 = new SendableClass(); + public optNoSendableClass6 = new NoSendableClass(); + + readonly optBooleanProp7 = true; + readonly optNumberProp7 = 42; + readonly optStringProp7 = "Hello"; + readonly optArrayProp7 = [1, 2, 3]; + readonly optTupleProp7 = ["typescript", 4]; + readonly optEnumProp7 = Color.Green; + readonly optAnyProp7: GeneratedObjectLiteralInterface_31 = { key: "value" }; + readonly optVoidProp7 = undefined; + readonly optNullProp7 = null; + readonly optUndefinedProp7 = undefined; + readonly optObjectProp7: GeneratedObjectLiteralInterface_32 = { name: "John", age: 30 }; + readonly optSendableClass7 = new SendableClass(); + readonly optNoSendableClass7 = new NoSendableClass(); +} + +interface I extends lang.ISendable { + booleanProp: boolean; + numberProp: number; + stringProp: string; + arrayProp: number[]; + tupleProp: [string, number]; + enumProp: Color; + anyProp: any; + voidProp: void; + nullProp: null; + undefinedProp: undefined; + objectProp: object; + sendableClass: SendableClass; + noSendableClass: NoSendableClass; + + optBooleanProp1?: boolean; + optNumberProp1?: number; + optStringProp1?: string; + optArrayProp1?: number[]; + optTupleProp1?: [string, number]; + optEnumProp1?: Color; + optAnyProp1?: any; + optVoidProp1?: void; + optNullProp1?: null; + optUndefinedProp1?: undefined; + optObjectProp1?: object; + optSendableClass1?: SendableClass; + optNoSendableClass1?: NoSendableClass; + + readonly optBooleanProp3: boolean; + readonly optNumberProp3: number; + readonly optStringProp3: string; + readonly optArrayProp3: number[]; + readonly optTupleProp3: [string, number]; + readonly optEnumProp3: Color; + readonly optAnyProp3: any; + readonly optVoidProp3: void; + readonly optNullProp3: null; + readonly optUndefinedProp3: undefined; + readonly optObjectProp3: object; + readonly optSendableClass3: SendableClass; + readonly optNoSendableClass3: NoSendableClass; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.json b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..b8c6d94da97f3dde594b2f0e940b89889bbcdc23 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_explicit_field_type.ets.migrate.json @@ -0,0 +1,2498 @@ +{ + "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": 66, + "column": 23, + "endLine": 66, + "endColumn": 28, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 44, + "endLine": 73, + "endColumn": 59, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 28, + "endLine": 80, + "endColumn": 33, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 49, + "endLine": 87, + "endColumn": 64, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 34, + "endLine": 94, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 55, + "endLine": 101, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 36, + "endLine": 108, + "endColumn": 41, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 57, + "endLine": 115, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 24, + "endLine": 123, + "endColumn": 29, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 45, + "endLine": 130, + "endColumn": 60, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 37, + "endLine": 138, + "endColumn": 42, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 58, + "endLine": 145, + "endColumn": 73, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 34, + "endLine": 153, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 55, + "endLine": 160, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 42, + "endLine": 168, + "endColumn": 47, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 57, + "endLine": 175, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 5, + "endLine": 64, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 53, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 35, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 5, + "endLine": 67, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 14, + "endLine": 67, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 5, + "endLine": 68, + "endColumn": 32, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 5, + "endLine": 71, + "endColumn": 52, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 26, + "endLine": 71, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 62, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 5, + "endLine": 78, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 5, + "endLine": 79, + "endColumn": 58, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 40, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 19, + "endLine": 81, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 5, + "endLine": 82, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 5, + "endLine": 85, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 31, + "endLine": 85, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 5, + "endLine": 92, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 5, + "endLine": 93, + "endColumn": 64, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 5, + "endLine": 94, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 5, + "endLine": 95, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 25, + "endLine": 95, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 5, + "endLine": 96, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 5, + "endLine": 99, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 37, + "endLine": 99, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 5, + "endLine": 101, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 5, + "endLine": 106, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 5, + "endLine": 107, + "endColumn": 66, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 5, + "endLine": 108, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 5, + "endLine": 109, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 27, + "endLine": 109, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 5, + "endLine": 110, + "endColumn": 45, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 5, + "endLine": 113, + "endColumn": 65, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 39, + "endLine": 113, + "endColumn": 40, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 5, + "endLine": 115, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 121, + "column": 5, + "endLine": 121, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 5, + "endLine": 122, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 123, + "column": 5, + "endLine": 123, + "endColumn": 36, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 5, + "endLine": 124, + "endColumn": 68, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 5, + "endLine": 128, + "endColumn": 80, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 130, + "column": 5, + "endLine": 130, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 136, + "column": 5, + "endLine": 136, + "endColumn": 51, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 5, + "endLine": 137, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 5, + "endLine": 138, + "endColumn": 49, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 5, + "endLine": 139, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 143, + "column": 5, + "endLine": 143, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 5, + "endLine": 145, + "endColumn": 76, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 5, + "endLine": 151, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 5, + "endLine": 152, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 5, + "endLine": 153, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 154, + "column": 5, + "endLine": 154, + "endColumn": 78, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 5, + "endLine": 158, + "endColumn": 90, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 160, + "column": 5, + "endLine": 160, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 5, + "endLine": 163, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 164, + "column": 5, + "endLine": 164, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 165, + "column": 5, + "endLine": 165, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 166, + "column": 5, + "endLine": 166, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 5, + "endLine": 167, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 168, + "column": 5, + "endLine": 168, + "endColumn": 54, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 5, + "endLine": 169, + "endColumn": 80, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 5, + "endLine": 173, + "endColumn": 92, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 5, + "endLine": 175, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 216, + "column": 23, + "endLine": 216, + "endColumn": 28, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 223, + "column": 44, + "endLine": 223, + "endColumn": 59, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 28, + "endLine": 230, + "endColumn": 33, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 237, + "column": 49, + "endLine": 237, + "endColumn": 64, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 34, + "endLine": 244, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 251, + "column": 55, + "endLine": 251, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 36, + "endLine": 258, + "endColumn": 41, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 265, + "column": 57, + "endLine": 265, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 24, + "endLine": 273, + "endColumn": 29, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 45, + "endLine": 280, + "endColumn": 60, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 288, + "column": 37, + "endLine": 288, + "endColumn": 42, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 295, + "column": 58, + "endLine": 295, + "endColumn": 73, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 303, + "column": 34, + "endLine": 303, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 310, + "column": 55, + "endLine": 310, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 318, + "column": 42, + "endLine": 318, + "endColumn": 47, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 325, + "column": 57, + "endLine": 325, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 214, + "column": 5, + "endLine": 214, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 215, + "column": 5, + "endLine": 215, + "endColumn": 53, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 216, + "column": 5, + "endLine": 216, + "endColumn": 35, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 5, + "endLine": 217, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 14, + "endLine": 217, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 218, + "column": 5, + "endLine": 218, + "endColumn": 32, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 221, + "column": 5, + "endLine": 221, + "endColumn": 52, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 221, + "column": 26, + "endLine": 221, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 223, + "column": 5, + "endLine": 223, + "endColumn": 62, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 5, + "endLine": 228, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 229, + "column": 5, + "endLine": 229, + "endColumn": 58, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 5, + "endLine": 230, + "endColumn": 40, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 231, + "column": 5, + "endLine": 231, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 231, + "column": 19, + "endLine": 231, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 232, + "column": 5, + "endLine": 232, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 235, + "column": 5, + "endLine": 235, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 235, + "column": 31, + "endLine": 235, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 237, + "column": 5, + "endLine": 237, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 242, + "column": 5, + "endLine": 242, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 243, + "column": 5, + "endLine": 243, + "endColumn": 64, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 244, + "column": 5, + "endLine": 244, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 245, + "column": 5, + "endLine": 245, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 245, + "column": 25, + "endLine": 245, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 246, + "column": 5, + "endLine": 246, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 249, + "column": 5, + "endLine": 249, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 249, + "column": 37, + "endLine": 249, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 251, + "column": 5, + "endLine": 251, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 256, + "column": 5, + "endLine": 256, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 257, + "column": 5, + "endLine": 257, + "endColumn": 66, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 258, + "column": 5, + "endLine": 258, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 259, + "column": 5, + "endLine": 259, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 259, + "column": 27, + "endLine": 259, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 260, + "column": 5, + "endLine": 260, + "endColumn": 45, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 263, + "column": 5, + "endLine": 263, + "endColumn": 65, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 263, + "column": 39, + "endLine": 263, + "endColumn": 40, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 265, + "column": 5, + "endLine": 265, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 271, + "column": 5, + "endLine": 271, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 272, + "column": 5, + "endLine": 272, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 273, + "column": 5, + "endLine": 273, + "endColumn": 36, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 274, + "column": 5, + "endLine": 274, + "endColumn": 68, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 278, + "column": 5, + "endLine": 278, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 5, + "endLine": 280, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 286, + "column": 5, + "endLine": 286, + "endColumn": 51, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 5, + "endLine": 287, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 288, + "column": 5, + "endLine": 288, + "endColumn": 49, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 289, + "column": 5, + "endLine": 289, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 293, + "column": 5, + "endLine": 293, + "endColumn": 82, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 295, + "column": 5, + "endLine": 295, + "endColumn": 76, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 301, + "column": 5, + "endLine": 301, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 302, + "column": 5, + "endLine": 302, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 303, + "column": 5, + "endLine": 303, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 304, + "column": 5, + "endLine": 304, + "endColumn": 79, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 308, + "column": 5, + "endLine": 308, + "endColumn": 91, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 310, + "column": 5, + "endLine": 310, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 5, + "endLine": 313, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 314, + "column": 5, + "endLine": 314, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 315, + "column": 5, + "endLine": 315, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 316, + "column": 5, + "endLine": 316, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 317, + "column": 5, + "endLine": 317, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 318, + "column": 5, + "endLine": 318, + "endColumn": 54, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 319, + "column": 5, + "endLine": 319, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 323, + "column": 5, + "endLine": 323, + "endColumn": 93, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 325, + "column": 5, + "endLine": 325, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 363, + "column": 23, + "endLine": 363, + "endColumn": 28, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 370, + "column": 44, + "endLine": 370, + "endColumn": 59, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 377, + "column": 28, + "endLine": 377, + "endColumn": 33, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 384, + "column": 49, + "endLine": 384, + "endColumn": 64, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 391, + "column": 34, + "endLine": 391, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 398, + "column": 55, + "endLine": 398, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 405, + "column": 36, + "endLine": 405, + "endColumn": 41, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 412, + "column": 57, + "endLine": 412, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 420, + "column": 24, + "endLine": 420, + "endColumn": 29, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 427, + "column": 45, + "endLine": 427, + "endColumn": 60, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 435, + "column": 37, + "endLine": 435, + "endColumn": 42, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 442, + "column": 58, + "endLine": 442, + "endColumn": 73, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 450, + "column": 34, + "endLine": 450, + "endColumn": 39, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 457, + "column": 55, + "endLine": 457, + "endColumn": 70, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 465, + "column": 42, + "endLine": 465, + "endColumn": 47, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 472, + "column": 57, + "endLine": 472, + "endColumn": 72, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 361, + "column": 5, + "endLine": 361, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 362, + "column": 5, + "endLine": 362, + "endColumn": 53, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 363, + "column": 5, + "endLine": 363, + "endColumn": 35, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 364, + "column": 5, + "endLine": 364, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 364, + "column": 14, + "endLine": 364, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 365, + "column": 5, + "endLine": 365, + "endColumn": 32, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 368, + "column": 5, + "endLine": 368, + "endColumn": 52, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 368, + "column": 26, + "endLine": 368, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 370, + "column": 5, + "endLine": 370, + "endColumn": 62, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 375, + "column": 5, + "endLine": 375, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 376, + "column": 5, + "endLine": 376, + "endColumn": 58, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 377, + "column": 5, + "endLine": 377, + "endColumn": 40, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 378, + "column": 5, + "endLine": 378, + "endColumn": 42, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 378, + "column": 19, + "endLine": 378, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 379, + "column": 5, + "endLine": 379, + "endColumn": 37, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 382, + "column": 5, + "endLine": 382, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 382, + "column": 31, + "endLine": 382, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 384, + "column": 5, + "endLine": 384, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 389, + "column": 5, + "endLine": 389, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 390, + "column": 5, + "endLine": 390, + "endColumn": 64, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 391, + "column": 5, + "endLine": 391, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 392, + "column": 5, + "endLine": 392, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 392, + "column": 25, + "endLine": 392, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 393, + "column": 5, + "endLine": 393, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 396, + "column": 5, + "endLine": 396, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 396, + "column": 37, + "endLine": 396, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 398, + "column": 5, + "endLine": 398, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 403, + "column": 5, + "endLine": 403, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 404, + "column": 5, + "endLine": 404, + "endColumn": 66, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 405, + "column": 5, + "endLine": 405, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 406, + "column": 5, + "endLine": 406, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 406, + "column": 27, + "endLine": 406, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 407, + "column": 5, + "endLine": 407, + "endColumn": 45, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 410, + "column": 5, + "endLine": 410, + "endColumn": 65, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 410, + "column": 39, + "endLine": 410, + "endColumn": 40, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 412, + "column": 5, + "endLine": 412, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 418, + "column": 5, + "endLine": 418, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 419, + "column": 5, + "endLine": 419, + "endColumn": 57, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 420, + "column": 5, + "endLine": 420, + "endColumn": 36, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 421, + "column": 5, + "endLine": 421, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 425, + "column": 5, + "endLine": 425, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 427, + "column": 5, + "endLine": 427, + "endColumn": 63, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 433, + "column": 5, + "endLine": 433, + "endColumn": 51, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 434, + "column": 5, + "endLine": 434, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 435, + "column": 5, + "endLine": 435, + "endColumn": 49, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 436, + "column": 5, + "endLine": 436, + "endColumn": 70, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 440, + "column": 5, + "endLine": 440, + "endColumn": 82, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 442, + "column": 5, + "endLine": 442, + "endColumn": 76, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 448, + "column": 5, + "endLine": 448, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 449, + "column": 5, + "endLine": 449, + "endColumn": 67, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 450, + "column": 5, + "endLine": 450, + "endColumn": 46, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 451, + "column": 5, + "endLine": 451, + "endColumn": 79, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 455, + "column": 5, + "endLine": 455, + "endColumn": 91, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 457, + "column": 5, + "endLine": 457, + "endColumn": 73, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 460, + "column": 5, + "endLine": 460, + "endColumn": 43, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 461, + "column": 5, + "endLine": 461, + "endColumn": 38, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 462, + "column": 5, + "endLine": 462, + "endColumn": 48, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 463, + "column": 5, + "endLine": 463, + "endColumn": 50, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 464, + "column": 5, + "endLine": 464, + "endColumn": 69, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 465, + "column": 5, + "endLine": 465, + "endColumn": 54, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 466, + "column": 5, + "endLine": 466, + "endColumn": 81, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 470, + "column": 5, + "endLine": 470, + "endColumn": 93, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 472, + "column": 5, + "endLine": 472, + "endColumn": 75, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 510, + "column": 14, + "endLine": 510, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 514, + "column": 26, + "endLine": 514, + "endColumn": 27, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 524, + "column": 19, + "endLine": 524, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 528, + "column": 31, + "endLine": 528, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 538, + "column": 25, + "endLine": 538, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 542, + "column": 37, + "endLine": 542, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 552, + "column": 27, + "endLine": 552, + "endColumn": 30, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 556, + "column": 39, + "endLine": 556, + "endColumn": 40, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 624, + "column": 14, + "endLine": 624, + "endColumn": 17, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 638, + "column": 19, + "endLine": 638, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 652, + "column": 27, + "endLine": 652, + "endColumn": 30, + "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/main/sendable_explicit_field_type_2.ets.args.json b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.args.json +++ b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.autofix.json b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.autofix.json index 4debe785776201f8b8a308d021e0af56b941e5e0..210cf70cd25cd718ae339791a7815e4ecc5966dd 100644 --- a/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.autofix.json +++ b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.autofix.json @@ -22,9 +22,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 647, - "end": 673, - "replacementText": "// fixable\na: number = 0;" + "start": 668, + "end": 668, + "replacementText": ": number" } ], "suggest": "", @@ -39,9 +39,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 673, - "end": 693, - "replacementText": "static b: string = ' ';" + "start": 686, + "end": 686, + "replacementText": ": string" } ], "suggest": "", @@ -56,9 +56,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 693, - "end": 720, - "replacementText": "private c: undefined = undefined;" + "start": 707, + "end": 707, + "replacementText": ": undefined" } ], "suggest": "", @@ -73,9 +73,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 720, - "end": 751, - "replacementText": "public static d: A = new A();" + "start": 740, + "end": 740, + "replacementText": ": A" } ], "suggest": "", @@ -90,9 +90,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 751, - "end": 764, - "replacementText": "e?: number | undefined = 10;" + "start": 758, + "end": 758, + "replacementText": ": number | undefined" } ], "suggest": "", @@ -107,9 +107,9 @@ "problem": "SendableExplicitFieldType", "autofix": [ { - "start": 764, - "end": 783, - "replacementText": "f: number[] = [1, 2, 3];" + "start": 770, + "end": 770, + "replacementText": ": number[]" } ], "suggest": "", diff --git a/ets2panda/linter/test/migrate/parameter_properties.sts b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.ets similarity index 52% rename from ets2panda/linter/test/migrate/parameter_properties.sts rename to ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.ets index d6878228fd421a282f65636dece4d068fc28604b..75be1fcd7712126eb96e0d736a8c144f55114080 100644 --- a/ets2panda/linter/test/migrate/parameter_properties.sts +++ b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.ets @@ -13,36 +13,35 @@ * limitations under the License. */ +@Sendable class A { - constructor( - public readonly x: number, - protected y: number, - private z: number - ) {} - - foo(): void { - console.log(this.x + this.y + this.z); - } } -const a = new A(1, 2, 3); -console.log(a.x); - -class B { - public f: number = 10; - - constructor(q: number, public w = 'default', e: boolean, private readonly r: number[] = [1, 2, 3]) { - console.log(q, this.w, e, this.r, this.f); - } +interface GeneratedObjectLiteralInterface_1 { + e1: number; + e2: string; } - -const b = new B(1, '2', true, []); -console.log(b.w); - -class C { - constructor(public a: any) {} // not fixable +@Sendable +class B { + // fixable + a: number = 0; + static b: string = ' '; + private c: undefined = undefined; + public static d: A = new A(); + e?: number | undefined = 10; + f: number[] = [1, 2, 3]; + + // not fixable + bad; + + ehelper1: number = 4; + ehelper2: string = 'abc'; + public bad3: GeneratedObjectLiteralInterface_1 = { + e1: this.ehelper1, + e2: this.ehelper2 + }; + + constructor(x: boolean) { + this.bad = x; + } } - -class D { - constructor(public a: number, private b: {x: string}) {} // not fixable -} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.json b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ab1db740e7d949840de01758ecef958cd5a438bb --- /dev/null +++ b/ets2panda/linter/test/main/sendable_explicit_field_type_2.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 32, + "column": 5, + "endLine": 32, + "endColumn": 29, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 9, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 5, + "endLine": 35, + "endColumn": 9, + "problem": "SendableExplicitFieldType", + "suggest": "", + "rule": "Field in sendable class must have type annotation (arkts-sendable-explicit-field-type)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 5, + "endLine": 42, + "endColumn": 7, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_function.ets.args.json b/ets2panda/linter/test/main/sendable_function.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_function.ets.args.json +++ b/ets2panda/linter/test/main/sendable_function.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_function.ets.migrate.ets b/ets2panda/linter/test/main/sendable_function.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..2c4a30f42de8bd637c7ddf7af21fa85c383a376a --- /dev/null +++ b/ets2panda/linter/test/main/sendable_function.ets.migrate.ets @@ -0,0 +1,230 @@ +/* + * 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 { D_Sft, D_Nft } from './sendable_function_dependencie'; +import { + D_sf, Dv_sf, D_nf, Dv_nf, Dv_Sft, Dv_Nft, D_Sc, D_Nc, + D_sf as AS_D_sf, Dv_sf as AS_Dv_sf, D_nf as AS_D_nf, Dv_nf as AS_Dv_nf, + D_Sft as AS_D_Sft, Dv_Sft as AS_Dv_Sft, D_Nft as AS_D_Nft, Dv_Nft as AS_Dv_Nft, + D_Sc as AS_D_Sc, D_Nc as AS_D_Nc +} from './sendable_function_dependencie'; + +// -------------------- check sendable-function declaration -------------------- // +@Sendable +function sf():void {} // OK +@Sendable +function stf(p:T):T { + return p; +} // OK +@Sendable +@Other // ERROR +function sf2():void {} + + +// check overloading +@Sendable +function sf3():void; // OK +@Sendable +function sf3():void; + +@Sendable +function sf3():void {} + +@Sendable +function sf4():void; +@Sendable +function sf4():void; // ERROR +@Sendable +function sf4():void {} + +@Sendable +function sf5():void; + +@Sendable +@Other // ERROR +function sf5():void; + +@Sendable +function sf5():void {} + +function nf():void {} + +// -------------------- check sendable-typealias declaration -------------------- // +@Sendable +type Sft = () => void; // OK +@Sendable +type Sft2 = () => void; // OK +@Sendable +type Sft3 = (p:T) => T; // OK +@Sendable +@Other // ERROR +type Sft4 = () => void; +@Sendable +type Sft5 = number; // ERROR +@Sendable +type Sft6 = Sft; // ERROR +type Sft7 = () => void; + +@Sendable +type Sft8 = Sft4; // ERROR + +type Nft = ()=>void; + +// -------------------- check sendable-function closure -------------------- // +@Sendable +class Sc {} +class Nc {} + +@Sendable +class SendableClassClosure { + constructor() { + const a1:Sft = sf; // OK + const a2:Nft = nf; // ERROR + const a3:Sc = new Sc(); // OK + const a4:Nc = new Nc(); // ERROR + + const b1:D_Sft = D_sf; // OK + const b2:D_Nft = D_nf; // OK + const b3:D_Sc = new D_Sc(); // OK + const b4:D_Nc = new D_Nc(); // OK + } + + @nf + handle() {} +} + +@Sendable +@nf +function SendableFunctionClosure() { + const a1:Sft = sf; // OK + const a2:Nft = nf; // ERROR + const a3:Sc = new Sc(); // OK + const a4:Nc = new Nc(); // ERROR + const b1:D_Sft = D_sf; // OK + const b2:D_Nft = D_nf; // OK + const b3:D_Sc = new D_Sc(); // OK + const b4:D_Nc = new D_Nc(); // OK +} + +namespace ns { + @Sendable + function sf():void; + @Sendable + function sf():void {} +} + + + +// -------------------- check sendable-typealias is sendaboe-data-type -------------------- // + + +// check property +@Sendable +class Sc2 { + p1: Sft = sf; // OK + p2: D_Nft = sf; // ERROR +} +// check genericity +new Sc2(); +new Sc2(); // ERROR + +// -------------------- check sendable-function cannot operation property --------------------// +sf.prop = 1; // ERROR +D_nf.prop = 1; // OK +D_sf.prop = 1; // ERROR +AS_D_sf.prop = 1;// ERROR + +// -------------------- check sendable-function assignment --------------------// + +@Sendable +function stf1(p:T):T {return p;}; +function ntf1(p:T):T {return p}; +// +const of1 = ()=>{}; +// +@Sendable +type Stft1 = (p:T)=>T; +@Sendable +type Stft2 = ()=>void; +// +type Nft1 = ()=>void; +type Nft2 = ()=>number; +type Ntft1 = (p:T)=>T; +type Ntft2 = ()=>void; +// +type U_Sft1 = Sft | D_Sft; +type U_Sft2 = Sft | Stft1; +type U_Nft1 = Nft1 | Nft2; +type U_Nft2 = Nft1 | Ntft1; +type U_ft1 = Sft | Nft1; +type U_ft2 = Sft | Stft1| Nft1 | Ntft1; +// +type TU_Sft1 = Sft | D_Sft; +type TU_Sft2 = Sft | Stft1 | Stft1 ; +type TU_Nft1 = Nft1 | Nft2; +type TU_Nft2 = Nft1 | Ntft1| Ntft2; +type TU_ft1 = Sft | Stft1 | Nft1 | Ntft1; +// +type DU_Sft1 = U_Sft1 | U_Sft2; +type DU_Sft2 = DU_Sft1 | TU_Sft1; +type DU_Sft3 = DU_Sft2 | TU_Sft2; +type DU_Nft = DU_Sft3 | TU_Nft2; +// normal +const a1: Sft = sf; // OK +const a2: Sft = nf; // ERROR +const a3: Sft = of1; // ERROR +const a4: Nft1 = nf; // OK +const a5: Sft = a1; // OK +const a6: Sft = a4; // ERROR +// generic +const b1: Stft1 = stf1; // OK +const b2: Stft1 = ntf1; // ERROR +const b3: Ntft1 = ntf1; // OK +const b4: Stft1 = b1; // OK +const b5: Stft1 = b3; // ERROR +// unite +const f1: U_ft1 = sf; // OK +const f2: U_ft2 = stf1; // OK +const f3: U_ft1 = nf; // ERROR +const f4: U_ft2 = ntf1; // ERROR +const d1: U_Sft1 = sf; // OK +const d2: U_Sft1 = nf; // ERROR +const d3: U_Sft1 = of1; // ERROR +const d4: U_Nft1 = sf; // OK +const d5: U_Nft1 = nf; // OK +const d6: U_Nft1 = of1; // OK +const d7: U_Sft1 = d1; // OK +const d18: U_Sft1 = d4; // ERROR +const d9: U_Sft1 = f1; // ERROR +// const d10: U_Sft1 = f2; // ERROR +const e1: U_Sft2 = stf1; // OK +const e2: U_Sft2 = ntf1; // ERROR +const e3: U_Nft2 = ntf1; // OK +const e4: U_Sft2 = e1; // OK +const e5: U_Sft2 = e3; // ERROR +const e6: U_Sft2 = f1; // ERROR +const e7: U_Sft2 = f2; // ERROR +// unite & generic +const g1: TU_ft1 = sf; // OK +const g2: TU_ft1 = stf1; // OK +const g3: TU_ft1 = nf; // ERROR +const h1: TU_Sft1 = sf; // OK +const h2: TU_Sft1 = nf; // ERROR +const h3: TU_Sft1 = of1; // ERROR +const h4: TU_Nft1 = nf; // OK +const h5: TU_Sft1 = h1; // OK +const h6: TU_Sft1 = h4; // ERROR +const h7: TU_Sft2 = stf1; // OK +const h8: TU_Sft2 = ntf1; // ERROR diff --git a/ets2panda/linter/test/main/sendable_function.ets.migrate.json b/ets2panda/linter/test/main/sendable_function.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..405511857491108238c01607fa2232a95dbd0fa5 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_function.ets.migrate.json @@ -0,0 +1,388 @@ +{ + "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": 32, + "column": 1, + "endLine": 32, + "endColumn": 7, + "problem": "SendableFunctionDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" function (arkts-sendable-function-decorator)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 1, + "endLine": 56, + "endColumn": 7, + "problem": "SendableFunctionDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" function (arkts-sendable-function-decorator)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 1, + "endLine": 72, + "endColumn": 7, + "problem": "SendableTypeAliasDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" typeAlias (arkts-sendable-typealias-decorator)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 13, + "endLine": 75, + "endColumn": 19, + "problem": "SendableTypeAliasDeclaration", + "suggest": "", + "rule": "Only \"FunctionType\" can declare \"Sendable\" typeAlias (arkts-sendable-typeAlias-declaration)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 13, + "endLine": 77, + "endColumn": 16, + "problem": "SendableTypeAliasDeclaration", + "suggest": "", + "rule": "Only \"FunctionType\" can declare \"Sendable\" typeAlias (arkts-sendable-typeAlias-declaration)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 13, + "endLine": 81, + "endColumn": 17, + "problem": "SendableTypeAliasDeclaration", + "suggest": "", + "rule": "Only \"FunctionType\" can declare \"Sendable\" typeAlias (arkts-sendable-typeAlias-declaration)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 20, + "endLine": 94, + "endColumn": 22, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 23, + "endLine": 96, + "endColumn": 25, + "problem": "SendableCapturedVars", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" class (arkts-sendable-imported-variables)", + "severity": "ERROR" + }, + { + "line": 104, + "column": 3, + "endLine": 104, + "endColumn": 6, + "problem": "SendableClassDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" class (arkts-sendable-class-decorator)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 1, + "endLine": 109, + "endColumn": 4, + "problem": "SendableFunctionDecorator", + "suggest": "", + "rule": "Only \"@Sendable\" decorator can be used on \"Sendable\" function (arkts-sendable-function-decorator)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 18, + "endLine": 112, + "endColumn": 20, + "problem": "SendableFunctionImportedVariables", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" function (arkts-sendable-function-imported-variables)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 21, + "endLine": 114, + "endColumn": 23, + "problem": "SendableFunctionImportedVariables", + "suggest": "", + "rule": "Only imported variables can be captured by \"Sendable\" function (arkts-sendable-function-imported-variables)", + "severity": "ERROR" + }, + { + "line": 137, + "column": 3, + "endLine": 137, + "endColumn": 18, + "problem": "SendablePropType", + "suggest": "", + "rule": "Properties in \"Sendable\" classes and interfaces must have a Sendable data type (arkts-sendable-prop-types)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 9, + "endLine": 141, + "endColumn": 14, + "problem": "SendableGenericTypes", + "suggest": "", + "rule": "Type arguments of generic \"Sendable\" type must be a \"Sendable\" data type (arkts-sendable-generic-types)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 1, + "endLine": 144, + "endColumn": 8, + "problem": "SendableFunctionProperty", + "suggest": "", + "rule": "The property of \"Sendable\" function is limited (arkts-sendable-function-property)", + "severity": "ERROR" + }, + { + "line": 146, + "column": 1, + "endLine": 146, + "endColumn": 10, + "problem": "SendableFunctionProperty", + "suggest": "", + "rule": "The property of \"Sendable\" function is limited (arkts-sendable-function-property)", + "severity": "ERROR" + }, + { + "line": 147, + "column": 1, + "endLine": 147, + "endColumn": 13, + "problem": "SendableFunctionProperty", + "suggest": "", + "rule": "The property of \"Sendable\" function is limited (arkts-sendable-function-property)", + "severity": "ERROR" + }, + { + "line": 186, + "column": 7, + "endLine": 186, + "endColumn": 19, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 7, + "endLine": 187, + "endColumn": 20, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 190, + "column": 7, + "endLine": 190, + "endColumn": 19, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 7, + "endLine": 193, + "endColumn": 23, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 196, + "column": 7, + "endLine": 196, + "endColumn": 21, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 200, + "column": 7, + "endLine": 200, + "endColumn": 21, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 7, + "endLine": 201, + "endColumn": 23, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 203, + "column": 7, + "endLine": 203, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 204, + "column": 7, + "endLine": 204, + "endColumn": 23, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 7, + "endLine": 209, + "endColumn": 23, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 210, + "column": 7, + "endLine": 210, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 213, + "column": 7, + "endLine": 213, + "endColumn": 24, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 216, + "column": 7, + "endLine": 216, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 217, + "column": 7, + "endLine": 217, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 218, + "column": 7, + "endLine": 218, + "endColumn": 22, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 222, + "column": 7, + "endLine": 222, + "endColumn": 30, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 224, + "column": 7, + "endLine": 224, + "endColumn": 31, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 7, + "endLine": 225, + "endColumn": 32, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 228, + "column": 7, + "endLine": 228, + "endColumn": 31, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + }, + { + "line": 230, + "column": 7, + "endLine": 230, + "endColumn": 33, + "problem": "SendableFunctionAssignment", + "suggest": "", + "rule": "Only \"Sendable\" function or \"Sendable\" typeAlias object can be assigned to \"Sendable\" typeAlias (arkts-sendable-function-assignment)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/sendable_function_2.ets.args.json b/ets2panda/linter/test/main/sendable_function_2.ets.args.json index 4ce1a4c45ca7a4b605acb645dd9b0be9fe153b5b..12b3ca8decaeda0b8758fdb4a74d2ae3fba065f7 100644 --- a/ets2panda/linter/test/main/sendable_function_2.ets.args.json +++ b/ets2panda/linter/test/main/sendable_function_2.ets.args.json @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/sendable_function_2.ets.migrate.ets b/ets2panda/linter/test/main/sendable_function_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..db2a902510a9c6414d2012845baabb3e4eafba5f --- /dev/null +++ b/ets2panda/linter/test/main/sendable_function_2.ets.migrate.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. + */ + +@Sendable +function foo(name: string): void; +@Sendable +function foo(age: number): void; // Fixable +@Sendable +function foo(...args: Object[]): void {} // Fixable + +@Sendable +function bar(name: string): void; // Fixable +@Sendable +function bar(age: number): void; // Fixable +@Sendable +function bar(...args: Object[]): void {} diff --git a/ets2panda/linter/test/main/sendable_function_2.ets.migrate.json b/ets2panda/linter/test/main/sendable_function_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/sendable_function_2.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 diff --git a/ets2panda/linter/test/main/static_class.ets b/ets2panda/linter/test/main/static_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..3316c3afad05c8a0fda1c2720b05810e896a190e --- /dev/null +++ b/ets2panda/linter/test/main/static_class.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. + */ +'use static' + +class A { + static { + console.log("Shouldn't be here"); + } +} diff --git a/ets2panda/linter/test/main/static_class.ets.args.json b/ets2panda/linter/test/main/static_class.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..8a4be28991e8164c0366b8b3ad0dffbc04910a27 --- /dev/null +++ b/ets2panda/linter/test/main/static_class.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": "", + "migrate": "--arkts-2" + } +} diff --git a/ets2panda/linter/test/main/static_class.ets.arkts2.json b/ets2panda/linter/test/main/static_class.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..614cb2e9da0d7473cfd9fc84d6da43667358ccc4 --- /dev/null +++ b/ets2panda/linter/test/main/static_class.ets.arkts2.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": 18, + "column": 5, + "endLine": 20, + "endColumn": 6, + "problem": "NoStaticOnClass", + "suggest": "", + "rule": "Class cannot have static codeblocks. (arkts-class-lazy-import)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/static_class.ets.json b/ets2panda/linter/test/main/static_class.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bd1b7140ca95b67336908f5fca6dec77fb46b2c0 --- /dev/null +++ b/ets2panda/linter/test/main/static_class.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": [] +} diff --git a/ets2panda/linter/test/main/static_class.ets.migrate.ets b/ets2panda/linter/test/main/static_class.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3316c3afad05c8a0fda1c2720b05810e896a190e --- /dev/null +++ b/ets2panda/linter/test/main/static_class.ets.migrate.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. + */ +'use static' + +class A { + static { + console.log("Shouldn't be here"); + } +} diff --git a/ets2panda/linter/test/main/static_class.ets.migrate.json b/ets2panda/linter/test/main/static_class.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..614cb2e9da0d7473cfd9fc84d6da43667358ccc4 --- /dev/null +++ b/ets2panda/linter/test/main/static_class.ets.migrate.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": 18, + "column": 5, + "endLine": 20, + "endColumn": 6, + "problem": "NoStaticOnClass", + "suggest": "", + "rule": "Class cannot have static codeblocks. (arkts-class-lazy-import)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/stdlib_array.ets.arkts2.json b/ets2panda/linter/test/main/stdlib_array.ets.arkts2.json index bcc25e7c3a7315356c27b440db185baaf050ffd0..071dffbe54d7b371f9c3d04390e1ea8bff75b602 100644 --- a/ets2panda/linter/test/main/stdlib_array.ets.arkts2.json +++ b/ets2panda/linter/test/main/stdlib_array.ets.arkts2.json @@ -104,6 +104,126 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 44, + "column": 29, + "endLine": 44, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 31, + "endLine": 44, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 33, + "endLine": 44, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 37, + "endLine": 45, + "endColumn": 38, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 39, + "endLine": 45, + "endColumn": 40, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 41, + "endLine": 45, + "endColumn": 42, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 35, + "endLine": 46, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 37, + "endLine": 46, + "endColumn": 38, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 39, + "endLine": 46, + "endColumn": 40, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 33, + "endLine": 47, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 35, + "endLine": 47, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 37, + "endLine": 47, + "endColumn": 38, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 53, "column": 10, diff --git a/ets2panda/linter/test/main/structural_identity.ets b/ets2panda/linter/test/main/structural_identity.ets index 8ecde15cd2828a369f124b2c54bffbfce81788e7..eae4133097d265060b89928949fb24982901a27b 100644 --- a/ets2panda/linter/test/main/structural_identity.ets +++ b/ets2panda/linter/test/main/structural_identity.ets @@ -671,16 +671,25 @@ function test_10(): B_10 { return obj1; // NOT OK } -let task1: taskpool.Task = new taskpool.Task(funObject1); - taskpool.execute(task1).then((value:Object) => { - console.info("result test taskpool: " + JSON.stringify(value)); - let aa = value as Array; - expect(aa[0]).assertEqual('toString result: bb : cc') - expect(aa[1]).assertEqual(200) - expect(aa[2]).assertEqual('testtoString') - }) -function funObject1():Array{ - let aa:ObjectInfo1=new ObjectInfo1('bb','cc') - let ee:Array=[aa.toString(),aa.toString(2),aa.toString('test')] - return ee; -} \ No newline at end of file +class MyObj2 { + +} +class MyObj1 { + +} +class MyObj3 { + +} +interface goodPerson extends IPerson { + like: MyObj2, + like1: MyObj3 + } + + let lily:goodPerson = { + like: new MyObj1(), + name: 'Alice', + age: 30, + sayHello:()=> { + return new MyObj2() + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json index 7ddd4b230e3cfc3597791bd734078006b252aa10..1a9ca3c7cfd29082482d0da6d3c02b04726fdfde 100644 --- a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json +++ b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json @@ -664,6 +664,16 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, + { + "line": 319, + "column": 15, + "endLine": 319, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 329, "column": 10, @@ -974,26 +984,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 480, - "column": 1, - "endLine": 480, - "endColumn": 10, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", - "severity": "ERROR" - }, - { - "line": 485, - "column": 1, - "endLine": 485, - "endColumn": 10, - "problem": "LimitedStdLibApi", - "suggest": "", - "rule": "Usage of standard library is restricted (arkts-limited-stdlib)", - "severity": "ERROR" - }, { "line": 502, "column": 7, @@ -1304,6 +1294,26 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, + { + "line": 609, + "column": 15, + "endLine": 609, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 612, + "column": 15, + "endLine": 612, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 614, "column": 16, @@ -1344,16 +1354,6 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, - { - "line": 622, - "column": 50, - "endLine": 622, - "endColumn": 58, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 626, "column": 5, @@ -1555,23 +1555,33 @@ "severity": "ERROR" }, { - "line": 674, - "column": 32, - "endLine": 674, - "endColumn": 45, - "problem": "DynamicCtorCall", + "line": 688, + "column": 6, + "endLine": 695, + "endColumn": 3, + "problem": "StructuralIdentity", "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, { - "line": 683, - "column": 26, - "endLine": 683, - "endColumn": 37, - "problem": "DynamicCtorCall", + "line": 688, + "column": 24, + "endLine": 688, + "endColumn": 25, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 691, + "column": 10, + "endLine": 691, + "endColumn": 12, + "problem": "NumericSemantics", "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/structural_identity.ets.json b/ets2panda/linter/test/main/structural_identity.ets.json index e2e91f0c1d8eed55108a05966af3b00eb8aec8e9..ba557cfd4379bc3548161375e6ea09a280971c97 100644 --- a/ets2panda/linter/test/main/structural_identity.ets.json +++ b/ets2panda/linter/test/main/structural_identity.ets.json @@ -643,6 +643,16 @@ "suggest": "", "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" + }, + { + "line": 688, + "column": 24, + "endLine": 688, + "endColumn": 25, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json index 521013f4fb2cdc4b4ebe21988ac696440c671c69..d99589819b7c1c733556a8b374aacea208846905 100644 --- a/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json +++ b/ets2panda/linter/test/main/structural_identity_extended_inheritance.ets.arkts2.json @@ -14,6 +14,146 @@ "limitations under the License." ], "result": [ + { + "line": 16, + "column": 30, + "endLine": 16, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 64, + "endLine": 17, + "endColumn": 65, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 79, + "endLine": 17, + "endColumn": 80, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 35, + "endLine": 23, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 35, + "endLine": 24, + "endColumn": 36, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 29, + "endLine": 25, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 31, + "endLine": 26, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 31, + "endLine": 27, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 37, + "endLine": 28, + "endColumn": 38, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 45, + "endLine": 29, + "endColumn": 46, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 31, + "endLine": 30, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 33, + "endLine": 31, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 33, + "endLine": 32, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 39, + "endLine": 33, + "endColumn": 40, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 49, "column": 5, diff --git a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.args.json b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..df6e67a5c9292c4c7e7aa5e976a3b8d1104fa082 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.args.json @@ -1,20 +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" - } + "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/styles_decorator_anon_1.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.arkts2.json index ff8b6e8a6e4c49d1c23a7a078547243f61adf83c..3b45c45182eb75c9df74d168b0d611c54f7c2a1c 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.arkts2.json @@ -16,14 +16,44 @@ "result": [ { "line": 27, - "column": 6, + "column": 18, "endLine": 40, - "endColumn": 7, + "endColumn": 6, "problem": "StylesDecoratorNotSupported", "suggest": "", "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, + { + "line": 30, + "column": 22, + "endLine": 30, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 14, + "endLine": 35, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 14, + "endLine": 36, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 16, "column": 2, diff --git a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.autofix.json index 8a7e665d36f306b3b4989aca848738a657a1133c..a6ab4947d57c2baf40d87da6c55d4f162abc4383 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.autofix.json @@ -16,27 +16,105 @@ "result": [ { "line": 27, - "column": 6, + "column": 18, "endLine": 40, - "endColumn": 7, + "endColumn": 6, "problem": "StylesDecoratorNotSupported", "autofix": [ { "start": 767, "end": 1035, - "replacementText": "{\n normal: @Memo (instance: CommonMethod): void => {\n instance.backgroundColor(\"#00ffff\");\n instance.borderWidth(8);\n },\n pressed: @Memo (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n instance.backgroundImagePosition({\n x: 0,\n y: 0\n });\n instance.backgroundColor(\"#ffff00\");\n }\n}" + "replacementText": "{\n normal: (instance: CommonMethod): void => {\n instance.backgroundColor(\"#00ffff\");\n instance.borderWidth(8);\n },\n pressed: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n instance.backgroundImagePosition({\n x: 0,\n y: 0\n });\n instance.backgroundColor(\"#ffff00\");\n }\n }", + "line": 27, + "column": 18, + "endLine": 40, + "endColumn": 6 } ], "suggest": "", "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, + { + "line": 30, + "column": 22, + "endLine": 30, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 842, + "end": 843, + "replacementText": "8.0", + "line": 30, + "column": 22, + "endLine": 30, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 14, + "endLine": 35, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 956, + "end": 957, + "replacementText": "0.0", + "line": 35, + "column": 14, + "endLine": 35, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 14, + "endLine": 36, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 972, + "end": 973, + "replacementText": "0.0", + "line": 36, + "column": 14, + "endLine": 36, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 16, "column": 2, "endLine": 16, "endColumn": 7, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -47,6 +125,17 @@ "endLine": 17, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -57,6 +146,17 @@ "endLine": 19, "endColumn": 16, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -67,6 +167,17 @@ "endLine": 20, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -77,6 +188,17 @@ "endLine": 24, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -91,7 +213,11 @@ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Memo, Color } from '@kits.ArkUI';" + "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI';", + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 31 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a8c3964416681b0cd7403294884867093c1e1f67 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.ets @@ -0,0 +1,44 @@ +/* + * 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, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI'; + +@Entry +@Component +struct TestStateStyle { + @BuilderParam + @Require + content: () => void; + + build() { + Button() { + this.content + } + .stateStyles({ + normal: (instance: CommonMethod): void => { + instance.backgroundColor("#00ffff"); + instance.borderWidth(8.0); + }, + pressed: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + instance.backgroundImagePosition({ + x: 0.0, + y: 0.0 + }); + instance.backgroundColor("#ffff00"); + } + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_anon_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_anon_1.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 diff --git a/ets2panda/linter/test/main/styles_decorator_anon_2.ets b/ets2panda/linter/test/main/styles_decorator_anon_2.ets index 31a12d2f4e66a9b00346a23bb9f5c6691e320444..a0888e5b74cd5c44c475b4f91aefe12e0cbd5d8b 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_2.ets +++ b/ets2panda/linter/test/main/styles_decorator_anon_2.ets @@ -13,6 +13,8 @@ * limitations under the License. */ +import { Entry, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI'; + @Entry @Component struct TestStateStyle { @@ -25,11 +27,11 @@ struct TestStateStyle { this.content } .stateStyles({ - normal: @Memo (instance: CommonMethod): void => { + normal: (instance: CommonMethod): void => { instance.backgroundColor("#00ffff"); instance.borderWidth(8); }, - pressed: @Memo (instance: CommonMethod): void => { + pressed: (instance: CommonMethod): void => { instance.backgroundColor(Color.Red); instance.backgroundImagePosition({ x: 0, diff --git a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.args.json b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.arkts2.json index e8f578a4218ce48a85c579e310cafa13d8ac3f1b..0488a4d89dbaec02d2924554868837a9a968cc9c 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.arkts2.json @@ -14,124 +14,34 @@ "limitations under the License." ], "result": [ - { - "line": 28, - "column": 15, - "endLine": 28, - "endColumn": 45, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 47, - "endLine": 28, - "endColumn": 51, - "problem": "VoidOperator", - "suggest": "", - "rule": "\"void\" operator is not supported (arkts-no-void-operator)", - "severity": "ERROR" - }, { "line": 32, - "column": 16, + "column": 30, "endLine": 32, - "endColumn": 46, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 48, - "endLine": 32, - "endColumn": 52, - "problem": "VoidOperator", - "suggest": "", - "rule": "\"void\" operator is not supported (arkts-no-void-operator)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 2, - "endLine": 16, - "endColumn": 7, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 2, - "endLine": 17, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 4, - "endLine": 19, - "endColumn": 16, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 4, - "endLine": 20, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 5, - "endLine": 24, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 16, - "endLine": 28, - "endColumn": 20, - "problem": "UIInterfaceImport", + "endColumn": 31, + "problem": "NumericSemantics", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 28, - "column": 32, - "endLine": 28, - "endColumn": 44, - "problem": "UIInterfaceImport", + "line": 37, + "column": 14, + "endLine": 37, + "endColumn": 15, + "problem": "NumericSemantics", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 33, - "column": 34, - "endLine": 33, - "endColumn": 39, - "problem": "UIInterfaceImport", + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15, + "problem": "NumericSemantics", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.autofix.json index 122547e43ee65155e0e30a59f40c9e69e4882af5..498a13cc8e4c2fb806dc7a79cb649c1fea421a2d 100644 --- a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.autofix.json @@ -15,144 +15,66 @@ ], "result": [ { - "line": 28, - "column": 15, - "endLine": 28, - "endColumn": 45, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 47, - "endLine": 28, - "endColumn": 51, - "problem": "VoidOperator", + "line": 32, + "column": 30, + "endLine": 32, + "endColumn": 31, + "problem": "NumericSemantics", "autofix": [ { - "start": 815, - "end": 819, - "replacementText": "(() => {\n ;\n return undefined;\n})()" + "start": 993, + "end": 994, + "replacementText": "8.0", + "line": 32, + "column": 30, + "endLine": 32, + "endColumn": 31 } ], "suggest": "", - "rule": "\"void\" operator is not supported (arkts-no-void-operator)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 32, - "column": 16, - "endLine": 32, - "endColumn": 46, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 48, - "endLine": 32, - "endColumn": 52, - "problem": "VoidOperator", + "line": 37, + "column": 14, + "endLine": 37, + "endColumn": 15, + "problem": "NumericSemantics", "autofix": [ { - "start": 959, - "end": 963, - "replacementText": "(() => {\n ;\n return undefined;\n})()" + "start": 1158, + "end": 1159, + "replacementText": "0.0", + "line": 37, + "column": 14, + "endLine": 37, + "endColumn": 15 } ], "suggest": "", - "rule": "\"void\" operator is not supported (arkts-no-void-operator)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 2, - "endLine": 16, - "endColumn": 7, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 2, - "endLine": 17, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 4, - "endLine": 19, - "endColumn": 16, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 4, - "endLine": 20, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 5, - "endLine": 24, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 16, - "endLine": 28, - "endColumn": 20, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 32, - "endLine": 28, - "endColumn": 44, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 33, - "column": 34, - "endLine": 33, - "endColumn": 39, - "problem": "UIInterfaceImport", + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15, + "problem": "NumericSemantics", "autofix": [ { - "start": 603, - "end": 603, - "replacementText": "\n\nimport { Entry, Component, BuilderParam, Require, Button, Memo, CommonMethod, Color } from '@kits.ArkUI';" + "start": 1174, + "end": 1175, + "replacementText": "0.0", + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e1abcac9d184f377f76cab573c68abe54f870935 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.ets @@ -0,0 +1,44 @@ +/* + * 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, Component, BuilderParam, Require, Button, CommonMethod, Color } from '@kit.ArkUI'; + +@Entry +@Component +struct TestStateStyle { + @BuilderParam + @Require + content: () => void; + + build() { + Button() { + this.content + } + .stateStyles({ + normal: (instance: CommonMethod): void => { + instance.backgroundColor("#00ffff"); + instance.borderWidth(8.0); + }, + pressed: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + instance.backgroundImagePosition({ + x: 0.0, + y: 0.0 + }); + instance.backgroundColor("#ffff00"); + } + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_anon_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_anon_2.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 diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets b/ets2panda/linter/test/main/styles_decorator_global_1.ets index e7ebe0041b60903801359902091a1c030ba1b925..0c7853382e20805550eb2507a6138c19791e1d46 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_1.ets +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets @@ -32,9 +32,10 @@ function cardStyle1() struct MyCard1 { build() { Column() { - + Text("TestStyles").cardStyle1() } .cardStyle1() + .backgroundColor(Color.Red) } } diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.args.json b/ets2panda/linter/test/main/styles_decorator_global_1.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_1.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_global_1.ets.arkts2.json index e0c5852c0444e5c244383c4b276bae9e4b715c9d..8ecdfbedea15ebdf30d7ea7db404c7334023ab05 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.arkts2.json @@ -25,9 +25,49 @@ "severity": "ERROR" }, { - "line": 41, + "line": 23, + "column": 19, + "endLine": 23, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 14, + "endLine": 24, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 12, + "endLine": 26, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 42, "column": 1, - "endLine": 44, + "endLine": 45, "endColumn": 2, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -35,9 +75,9 @@ "severity": "ERROR" }, { - "line": 46, + "line": 47, "column": 1, - "endLine": 49, + "endLine": 50, "endColumn": 2, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -75,10 +115,30 @@ "severity": "ERROR" }, { - "line": 53, - "column": 6, - "endLine": 53, - "endColumn": 18, + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 26, + "endLine": 38, + "endColumn": 31, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 2, + "endLine": 52, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", @@ -88,6 +148,16 @@ "line": 54, "column": 6, "endLine": 54, + "endColumn": 18, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 6, + "endLine": 55, "endColumn": 13, "problem": "UIInterfaceImport", "suggest": "", @@ -95,9 +165,9 @@ "severity": "ERROR" }, { - "line": 58, + "line": 59, "column": 9, - "endLine": 58, + "endLine": 59, "endColumn": 15, "problem": "UIInterfaceImport", "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_global_1.ets.autofix.json index f5537b16eae36d3e82e06441f2bd0a05099b06fc..6327fe8134fd4cac64975f7fb438c94abc393cf6 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_1.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.autofix.json @@ -24,12 +24,29 @@ { "start": 640, "end": 835, - "replacementText": "@Memo\nfunction cardStyle1(instance: CommonMethod): void {\n instance.backgroundColor(mycolor);\n instance.borderColor(Color.Red);\n instance.borderRadius(8);\n instance.padding(8);\n instance.backgroundImagePosition({\n x: 0,\n y: 0\n });\n}" + "replacementText": "function cardStyle1(instance: CommonMethod): void {\n instance.backgroundColor(mycolor);\n instance.borderColor(Color.Red);\n instance.borderRadius(8);\n instance.padding(8);\n instance.backgroundImagePosition({\n x: 0,\n y: 0\n });\n}", + "line": 18, + "column": 1, + "endLine": 29, + "endColumn": 2 }, { - "start": 918, - "end": 930, - "replacementText": "applyStyles(cardStyle1)" + "start": 929, + "end": 941, + "replacementText": "applyStyles(cardStyle1)", + "line": 18, + "column": 1, + "endLine": 29, + "endColumn": 2 + }, + { + "start": 961, + "end": 973, + "replacementText": "applyStyles(cardStyle1)", + "line": 18, + "column": 1, + "endLine": 29, + "endColumn": 2 } ], "suggest": "", @@ -37,16 +54,104 @@ "severity": "ERROR" }, { - "line": 41, + "line": 23, + "column": 19, + "endLine": 23, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 749, + "end": 750, + "replacementText": "8.0", + "line": 23, + "column": 19, + "endLine": 23, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 14, + "endLine": 24, + "endColumn": 15, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 765, + "end": 766, + "replacementText": "8.0", + "line": 24, + "column": 14, + "endLine": 24, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 12, + "endLine": 26, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 810, + "end": 811, + "replacementText": "0.0", + "line": 26, + "column": 12, + "endLine": 26, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 824, + "end": 825, + "replacementText": "0.0", + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 42, "column": 1, - "endLine": 44, + "endLine": 45, "endColumn": 2, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 940, - "end": 1007, - "replacementText": "@Memo\nfunction NormalStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}" + "start": 1019, + "end": 1086, + "replacementText": "function NormalStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}", + "line": 42, + "column": 1, + "endLine": 45, + "endColumn": 2 } ], "suggest": "", @@ -54,16 +159,20 @@ "severity": "ERROR" }, { - "line": 46, + "line": 47, "column": 1, - "endLine": 49, + "endLine": 50, "endColumn": 2, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 1009, - "end": 1077, - "replacementText": "@Memo\nfunction PressedStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}" + "start": 1088, + "end": 1156, + "replacementText": "function PressedStyles(instance: CommonMethod): void {\n instance.backgroundColor(\"#ffffff\");\n}", + "line": 47, + "column": 1, + "endLine": 50, + "endColumn": 2 } ], "suggest": "", @@ -76,6 +185,17 @@ "endLine": 22, "endColumn": 23, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -86,6 +206,17 @@ "endLine": 31, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -96,16 +227,80 @@ "endLine": 34, "endColumn": 15, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 53, - "column": 6, - "endLine": 53, - "endColumn": 18, + "line": 35, + "column": 13, + "endLine": 35, + "endColumn": 17, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 26, + "endLine": 38, + "endColumn": 31, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 2, + "endLine": 52, + "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -114,23 +309,59 @@ "line": 54, "column": 6, "endLine": 54, + "endColumn": 18, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 6, + "endLine": 55, "endColumn": 13, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 58, + "line": 59, "column": 9, - "endLine": 58, + "endLine": 59, "endColumn": 15, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { CommonMethod, Memo, Color, Component, Column, BuilderParam, Require, Button } from '@kits.ArkUI';" + "replacementText": "\n\nimport { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI';", + "line": 59, + "column": 9, + "endLine": 59, + "endColumn": 15 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..b98a8816ae8afaaee7940b969ac164531deb561f --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.ets @@ -0,0 +1,65 @@ +/* + * 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 { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI'; + +const mycolor: string = "#ffff00" + +function cardStyle1(instance: CommonMethod): void { + instance.backgroundColor(mycolor); + instance.borderColor(Color.Red); + instance.borderRadius(8.0); + instance.padding(8.0); + instance.backgroundImagePosition({ + x: 0.0, + y: 0.0 + }); +} + +@Component +struct MyCard1 { + build() { + Column() { + Text("TestStyles").applyStyles(cardStyle1) + } + .applyStyles(cardStyle1) + .backgroundColor(Color.Red) + } +} + +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor("#ffffff"); +} + +function PressedStyles(instance: CommonMethod): void { + instance.backgroundColor("#ffffff"); +} + +@Component +struct MyButton { + @BuilderParam + @Require + content: () => void; + + build() { + Button() { + this.content() + } + .stateStyles({ + normal: NormalStyles, + pressed: PressedStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_global_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_global_1.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 diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets b/ets2panda/linter/test/main/styles_decorator_global_2.ets index df5108380a54adae4db5e2fab2237eeba7dbcaa5..fd272fd000da58d98840d17fbb58c3de7fc89e21 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_2.ets +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets @@ -13,9 +13,10 @@ * limitations under the License. */ +import { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI'; + const mycolor: string = "#ffff00" -@Memo function cardStyle1(instance: CommonMethod): void { instance.backgroundColor(mycolor); instance.borderColor(Color.Red); @@ -31,18 +32,17 @@ function cardStyle1(instance: CommonMethod): void { struct MyCard1 { build() { Column() { - + Text("TestStyles").applyStyles(cardStyle1) } - applyStyles.cardStyle1() + .applyStyles(cardStyle1) + .backgroundColor(Color.Red) } } -@Memo function NormalStyles(instance: CommonMethod): void { instance.backgroundColor("#ffffff"); } -@Memo function PressedStyles(instance: CommonMethod): void { instance.backgroundColor("#ffffff"); } diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets.args.json b/ets2panda/linter/test/main/styles_decorator_global_2.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_2.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_global_2.ets.arkts2.json index 711fbbe4076ccb4669fdf0194db959c60de8ddec..ad6581e89d7e6398c5cc7c062fcf17ba0674acae 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets.arkts2.json @@ -15,113 +15,43 @@ ], "result": [ { - "line": 18, - "column": 1, - "endLine": 18, - "endColumn": 6, - "problem": "DecoratorsNotSupported", + "line": 23, + "column": 27, + "endLine": 23, + "endColumn": 28, + "problem": "NumericSemantics", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 40, - "column": 1, - "endLine": 40, - "endColumn": 6, - "problem": "DecoratorsNotSupported", + "line": 24, + "column": 22, + "endLine": 24, + "endColumn": 23, + "problem": "NumericSemantics", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 45, - "column": 1, - "endLine": 45, - "endColumn": 6, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 2, - "endLine": 18, - "endColumn": 6, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 31, - "endLine": 19, - "endColumn": 43, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 26, - "endLine": 21, - "endColumn": 31, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 2, - "endLine": 30, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 9, - "endLine": 33, - "endColumn": 15, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 6, - "endLine": 52, - "endColumn": 18, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 6, - "endLine": 53, + "line": 26, + "column": 12, + "endLine": 26, "endColumn": 13, - "problem": "UIInterfaceImport", + "problem": "NumericSemantics", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 57, - "column": 9, - "endLine": 57, - "endColumn": 15, - "problem": "UIInterfaceImport", + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 13, + "problem": "NumericSemantics", "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_global_2.ets.autofix.json index 1beb2245526e4e96f29c7f3a63d19f685cc61522..f06d87b1b5c4bfc9ebf0da251e2a7b5ea61719cd 100644 --- a/ets2panda/linter/test/main/styles_decorator_global_2.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets.autofix.json @@ -15,120 +15,87 @@ ], "result": [ { - "line": 18, - "column": 1, - "endLine": 18, - "endColumn": 6, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 1, - "endLine": 40, - "endColumn": 6, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 45, - "column": 1, - "endLine": 45, - "endColumn": 6, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 2, - "endLine": 18, - "endColumn": 6, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 31, - "endLine": 19, - "endColumn": 43, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 26, - "endLine": 21, - "endColumn": 31, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 2, - "endLine": 30, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 9, - "endLine": 33, - "endColumn": 15, - "problem": "UIInterfaceImport", + "line": 23, + "column": 27, + "endLine": 23, + "endColumn": 28, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 901, + "end": 902, + "replacementText": "8.0", + "line": 23, + "column": 27, + "endLine": 23, + "endColumn": 28 + } + ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 52, - "column": 6, - "endLine": 52, - "endColumn": 18, - "problem": "UIInterfaceImport", + "line": 24, + "column": 22, + "endLine": 24, + "endColumn": 23, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 926, + "end": 927, + "replacementText": "8.0", + "line": 24, + "column": 22, + "endLine": 24, + "endColumn": 23 + } + ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 53, - "column": 6, - "endLine": 53, + "line": 26, + "column": 12, + "endLine": 26, "endColumn": 13, - "problem": "UIInterfaceImport", + "problem": "NumericSemantics", + "autofix": [ + { + "start": 980, + "end": 981, + "replacementText": "0.0", + "line": 26, + "column": 12, + "endLine": 26, + "endColumn": 13 + } + ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 57, - "column": 9, - "endLine": 57, - "endColumn": 15, - "problem": "UIInterfaceImport", + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 13, + "problem": "NumericSemantics", "autofix": [ { - "start": 603, - "end": 603, - "replacementText": "\n\nimport { Memo, CommonMethod, Color, Component, Column, BuilderParam, Require, Button } from '@kits.ArkUI';" + "start": 994, + "end": 995, + "replacementText": "0.0", + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 13 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..b98a8816ae8afaaee7940b969ac164531deb561f --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.ets @@ -0,0 +1,65 @@ +/* + * 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 { CommonMethod, Color, Component, Column, Text, BuilderParam, Require, Button } from '@kit.ArkUI'; + +const mycolor: string = "#ffff00" + +function cardStyle1(instance: CommonMethod): void { + instance.backgroundColor(mycolor); + instance.borderColor(Color.Red); + instance.borderRadius(8.0); + instance.padding(8.0); + instance.backgroundImagePosition({ + x: 0.0, + y: 0.0 + }); +} + +@Component +struct MyCard1 { + build() { + Column() { + Text("TestStyles").applyStyles(cardStyle1) + } + .applyStyles(cardStyle1) + .backgroundColor(Color.Red) + } +} + +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor("#ffffff"); +} + +function PressedStyles(instance: CommonMethod): void { + instance.backgroundColor("#ffffff"); +} + +@Component +struct MyButton { + @BuilderParam + @Require + content: () => void; + + build() { + Button() { + this.content() + } + .stateStyles({ + normal: NormalStyles, + pressed: PressedStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_global_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_global_2.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 diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets b/ets2panda/linter/test/main/styles_decorator_mix_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..040d2154f7bdae6d19d54cf1e0c4256c2824a71a --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets @@ -0,0 +1,92 @@ +/* + * 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. + */ + +@Styles +function NormalStyles() { + .backgroundColor(Color.Blue) +} + +@Entry +@Component +struct MyButton1 { + @BuilderParam + @Require + content: () => void; + + @Styles + PressedStyles() { + .backgroundColor(Color.Green) + } + + build() { + Button("MyButton1") { + this.content + } + .stateStyles({ + pressed: this.PressedStyles, + selected: { + .backgroundColor(Color.Red) + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton2 { + @BuilderParam + @Require + content: () => void; + + build() { + Button("MyButton2") { + this.content + } + .stateStyles({ + selected: { + .backgroundColor(Color.Red) + }, + normal: NormalStyles, + }) + } +} + +@Component +struct MyButton3 { + + build() { + Button("MyButton3") + .stateStyles({ + normal: NormalStyles, + selected: { + .backgroundColor(Color.Red) + } + }) + } +} + +@Component +struct MyButton4 { + + build() { + Button("MyButton4") + .stateStyles({ + selected: { + .backgroundColor(Color.Red) + }, + normal: NormalStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.args.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.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/data_observation_1.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json similarity index 59% rename from ets2panda/linter/test/main/data_observation_1.ets.arkts2.json rename to ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json index fc333a843fd6d3fe402dcb7e2a1b22550ff65263..b0c53b4c8e59d1cb200b077428a1b0c7d7cf5173 100644 --- a/ets2panda/linter/test/main/data_observation_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.arkts2.json @@ -15,89 +15,109 @@ ], "result": [ { - "line": 30, - "column": 5, - "endLine": 30, - "endColumn": 33, - "problem": "AnyType", + "line": 16, + "column": 1, + "endLine": 19, + "endColumn": 2, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 30, - "column": 19, - "endLine": 30, - "endColumn": 31, - "problem": "DynamicCtorCall", + "line": 28, + "column": 3, + "endLine": 31, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 38, - "column": 17, - "endLine": 38, - "endColumn": 25, - "problem": "DataObservation", + "line": 37, + "column": 18, + "endLine": 43, + "endColumn": 6, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 39, - "column": 17, - "endLine": 39, - "endColumn": 25, - "problem": "DataObservation", + "line": 57, + "column": 18, + "endLine": 62, + "endColumn": 6, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 40, - "column": 38, - "endLine": 40, - "endColumn": 46, - "problem": "DataObservation", + "line": 71, + "column": 20, + "endLine": 76, + "endColumn": 8, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 40, - "column": 49, - "endLine": 40, - "endColumn": 57, - "problem": "DataObservation", + "line": 85, + "column": 20, + "endLine": 90, + "endColumn": 8, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 43, - "column": 26, - "endLine": 43, - "endColumn": 30, - "problem": "DataObservation", + "line": 18, + "column": 22, + "endLine": 18, + "endColumn": 27, + "problem": "UIInterfaceImport", "suggest": "", - "rule": "Data observation needs to add \"@Observed\" (arkui-data-observation)", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 24, + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, "column": 2, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 4, "endLine": 24, - "endColumn": 10, + "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 28, - "column": 1, - "endLine": 28, + "line": 25, + "column": 4, + "endLine": 25, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -106,9 +126,9 @@ }, { "line": 30, - "column": 19, + "column": 22, "endLine": 30, - "endColumn": 31, + "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", @@ -116,18 +136,28 @@ }, { "line": 34, - "column": 2, + "column": 5, "endLine": 34, - "endColumn": 7, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 35, + "line": 40, + "column": 26, + "endLine": 40, + "endColumn": 31, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 47, "column": 2, - "endLine": 35, + "endLine": 47, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -135,29 +165,29 @@ "severity": "ERROR" }, { - "line": 37, + "line": 49, "column": 4, - "endLine": 37, - "endColumn": 9, + "endLine": 49, + "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 42, + "line": 50, "column": 4, - "endLine": 42, - "endColumn": 8, + "endLine": 50, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 43, - "column": 4, - "endLine": 43, + "line": 54, + "column": 5, + "endLine": 54, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -165,64 +195,74 @@ "severity": "ERROR" }, { - "line": 44, - "column": 4, - "endLine": 44, - "endColumn": 15, + "line": 59, + "column": 26, + "endLine": 59, + "endColumn": 31, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 46, - "column": 4, - "endLine": 46, - "endColumn": 20, + "line": 66, + "column": 2, + "endLine": 66, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 48, - "column": 4, - "endLine": 48, - "endColumn": 15, + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 49, - "column": 4, - "endLine": 49, - "endColumn": 20, + "line": 74, + "column": 28, + "endLine": 74, + "endColumn": 33, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 58, - "column": 4, - "endLine": 58, - "endColumn": 8, + "line": 80, + "column": 2, + "endLine": 80, + "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 59, - "column": 4, - "endLine": 59, + "line": 84, + "column": 5, + "endLine": 84, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" + }, + { + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..a84810a9e76f91e0a4988d7bb703da2ca2631e99 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.autofix.json @@ -0,0 +1,443 @@ +{ + "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": 1, + "endLine": 19, + "endColumn": 2, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 605, + "end": 673, + "replacementText": "function NormalStyles(instance: CommonMethod): void {\n instance.backgroundColor(Color.Blue);\n}" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 3, + "endLine": 31, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 765, + "end": 830, + "replacementText": "PressedStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Green);\n };" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 18, + "endLine": 43, + "endColumn": 6, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 912, + "end": 1044, + "replacementText": "{\n pressed: this.PressedStyles,\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 18, + "endLine": 62, + "endColumn": 6, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 1214, + "end": 1312, + "replacementText": "{\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 20, + "endLine": 76, + "endColumn": 8, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 1407, + "end": 1514, + "replacementText": "{\n normal: NormalStyles,\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n }\n }" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 20, + "endLine": 90, + "endColumn": 8, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 1609, + "end": 1716, + "replacementText": "{\n selected: (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n },\n normal: NormalStyles\n }" + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 22, + "endLine": 18, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 4, + "endLine": 24, + "endColumn": 16, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 4, + "endLine": 25, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 22, + "endLine": 30, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 5, + "endLine": 34, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 26, + "endLine": 40, + "endColumn": 31, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 2, + "endLine": 47, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 4, + "endLine": 49, + "endColumn": 16, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 4, + "endLine": 50, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 5, + "endLine": 54, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 26, + "endLine": 59, + "endColumn": 31, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 2, + "endLine": 66, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 5, + "endLine": 70, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 28, + "endLine": 74, + "endColumn": 33, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 2, + "endLine": 80, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 84, + "column": 5, + "endLine": 84, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 28, + "endLine": 87, + "endColumn": 33, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI';" + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.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/styles_decorator_mix_1.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e9c2b35e023074c8d1813a6a7c22a487bd97e25 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.ets @@ -0,0 +1,92 @@ +/* + * 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 { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI'; + +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor(Color.Blue); +} + +@Entry +@Component +struct MyButton1 { + @BuilderParam + @Require + content: () => void; + + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; + + build() { + Button("MyButton1") { + this.content + } + .stateStyles({ + pressed: this.PressedStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton2 { + @BuilderParam + @Require + content: () => void; + + build() { + Button("MyButton2") { + this.content + } + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton3 { + + build() { + Button("MyButton3") + .stateStyles({ + normal: NormalStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + } + }) + } +} + +@Component +struct MyButton4 { + + build() { + Button("MyButton4") + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_mix_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_1.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 diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets b/ets2panda/linter/test/main/styles_decorator_mix_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e9c2b35e023074c8d1813a6a7c22a487bd97e25 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets @@ -0,0 +1,92 @@ +/* + * 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 { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI'; + +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor(Color.Blue); +} + +@Entry +@Component +struct MyButton1 { + @BuilderParam + @Require + content: () => void; + + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; + + build() { + Button("MyButton1") { + this.content + } + .stateStyles({ + pressed: this.PressedStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton2 { + @BuilderParam + @Require + content: () => void; + + build() { + Button("MyButton2") { + this.content + } + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton3 { + + build() { + Button("MyButton3") + .stateStyles({ + normal: NormalStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + } + }) + } +} + +@Component +struct MyButton4 { + + build() { + Button("MyButton4") + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets.args.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.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/styles_decorator_mix_2.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.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/styles_decorator_mix_2.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.autofix.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/styles_decorator_mix_2.ets.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_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/styles_decorator_mix_2.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e9c2b35e023074c8d1813a6a7c22a487bd97e25 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.ets @@ -0,0 +1,92 @@ +/* + * 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 { CommonMethod, Color, Entry, Component, BuilderParam, Require, Button } from '@kit.ArkUI'; + +function NormalStyles(instance: CommonMethod): void { + instance.backgroundColor(Color.Blue); +} + +@Entry +@Component +struct MyButton1 { + @BuilderParam + @Require + content: () => void; + + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; + + build() { + Button("MyButton1") { + this.content + } + .stateStyles({ + pressed: this.PressedStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton2 { + @BuilderParam + @Require + content: () => void; + + build() { + Button("MyButton2") { + this.content + } + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} + +@Component +struct MyButton3 { + + build() { + Button("MyButton3") + .stateStyles({ + normal: NormalStyles, + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + } + }) + } +} + +@Component +struct MyButton4 { + + build() { + Button("MyButton4") + .stateStyles({ + selected: (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }, + normal: NormalStyles + }) + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_mix_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_mix_2.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 diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets b/ets2panda/linter/test/main/styles_decorator_struct_1.ets index 0a861800f49e65b86753ca8f4a3b79931c6a88fc..d6be55373484396d021fdc85e09448c25cdab905 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets @@ -23,9 +23,38 @@ struct MyCard1 { build() { Column() { - Text('Card') + Text('Card').cardStyle1() } .cardStyle1() + .backgroundColor(Color.Red) + } +} + +@Component +struct MyCard2 { + @Styles + cardStyle2() { + .border({ + color: this.getColor(), + width: this.getWidth() + }) + .backgroundColor('#ffffff') + } + + private getColor(): Color { + return Color.Red + } + + private getWidth(): number { + return 10 + } + + build() { + Column() { + Text('Card').cardStyle2() + } + .cardStyle2() + .backgroundColor(Color.Red) } } @@ -50,8 +79,71 @@ struct MyButton { this.content } .stateStyles({ - normal: this.NormalStyles(), - pressed: this.PressedStyles() + normal: this.NormalStyles, + pressed: this.PressedStyles + }) + } +} + +const TAG: string = 'common_ImageTest'; + +class MediaItem { + public path: string = ''; + public uri: string = ''; + + public getDateModified(): string { + return '' + } +} + +@Component +struct imageTest { + private mediaItem: MediaItem | undefined; + private previewUri: string | undefined; + private DragBuilder: CustomBuilder | undefined; + + @Styles + imageStyle() { + .draggable(this.isShowLongPressMenu() && this.isPC()) + .onDragStart(() => { + console.info(TAG, 'onDragStart'); + this.touchVibrate(VibrateType.DRAG); + if (this.mediaItem?.path) { + this.previewUri = + this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true); + } + return this.DragBuilder; }) + .accessibilityText(this.isOpenTouchGuide ? this.getImageItemGridAccessibilityText() : '') + } + + private isShowLongPressMenu(): boolean { + return true; + } + + private isPC(): boolean { + return true; + } + + private touchVibrate(type: VibrateType): void { + } + + private isOpenTouchGuide: boolean = true; + + private getImageItemGridAccessibilityText(): string { + return '' + } + + private getPreviewUri(path: string, date: string, isOk: boolean, ready: boolean): string { + return '' + } + + build() { + + } +} + +enum VibrateType { + DRAG } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.args.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json index 4a545a2c081c63a4eee9bebc84f468164f2cb523..c4491ce76c85e78ae3744d72560d97a5696cf707 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.arkts2.json @@ -25,9 +25,19 @@ "severity": "ERROR" }, { - "line": 38, + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, "column": 3, - "endLine": 41, + "endLine": 42, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -35,9 +45,19 @@ "severity": "ERROR" }, { - "line": 43, + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, "column": 3, - "endLine": 46, + "endLine": 70, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "suggest": "", @@ -45,23 +65,33 @@ "severity": "ERROR" }, { - "line": 53, - "column": 15, - "endLine": 53, - "endColumn": 34, - "problem": "LimitedVoidType", + "line": 72, + "column": 3, + "endLine": 75, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 54, - "column": 16, - "endLine": 54, - "endColumn": 36, - "problem": "LimitedVoidType", + "line": 105, + "column": 3, + "endLine": 118, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 18, + "endLine": 116, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { @@ -95,9 +125,89 @@ "severity": "ERROR" }, { - "line": 34, + "line": 29, + "column": 22, + "endLine": 29, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 2, + "endLine": 33, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 23, + "endLine": 44, + "endColumn": 28, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 12, + "endLine": 45, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 5, + "endLine": 53, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 22, + "endLine": 57, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 2, + "endLine": 61, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 63, "column": 4, - "endLine": 34, + "endLine": 63, "endColumn": 16, "problem": "UIInterfaceImport", "suggest": "", @@ -105,9 +215,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 64, "column": 4, - "endLine": 35, + "endLine": 64, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", @@ -115,9 +225,9 @@ "severity": "ERROR" }, { - "line": 40, + "line": 69, "column": 22, - "endLine": 40, + "endLine": 69, "endColumn": 27, "problem": "UIInterfaceImport", "suggest": "", @@ -125,14 +235,44 @@ "severity": "ERROR" }, { - "line": 49, + "line": 74, + "column": 22, + "endLine": 74, + "endColumn": 27, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 78, "column": 5, - "endLine": 49, + "endLine": 78, "endColumn": 11, "problem": "UIInterfaceImport", "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" + }, + { + "line": 99, + "column": 2, + "endLine": 99, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json index 72114405f708fbad0a3047aba87d8108b964890c..3575cf7b84094c6a660c67fa31e736c2d582318a 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.autofix.json @@ -24,12 +24,29 @@ { "start": 635, "end": 716, - "replacementText": "cardStyle1 = @Memo (instance: CommonMethod): void => {\n instance.backgroundColor('#ffffff');\n instance.borderRadius(8);\n}" + "replacementText": "cardStyle1 = (instance: CommonMethod): void => {\n instance.backgroundColor('#ffffff');\n instance.borderRadius(8);\n };", + "line": 18, + "column": 3, + "endLine": 22, + "endColumn": 4 }, { - "start": 775, - "end": 787, - "replacementText": "applyStyles(this.cardStyle1)" + "start": 764, + "end": 776, + "replacementText": "applyStyles(this.cardStyle1)", + "line": 18, + "column": 3, + "endLine": 22, + "endColumn": 4 + }, + { + "start": 788, + "end": 800, + "replacementText": "applyStyles(this.cardStyle1)", + "line": 18, + "column": 3, + "endLine": 22, + "endColumn": 4 } ], "suggest": "", @@ -37,16 +54,59 @@ "severity": "ERROR" }, { - "line": 38, + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 20, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 710, + "end": 711, + "replacementText": "8.0", + "line": 21, + "column": 19, + "endLine": 21, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 35, "column": 3, - "endLine": 41, + "endLine": 42, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 877, - "end": 939, - "replacementText": "NormalStyles = @Memo (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n}" + "start": 870, + "end": 1010, + "replacementText": "cardStyle2 = (instance: CommonMethod): void => {\n instance.border({\n color: this.getColor(),\n width: this.getWidth()\n });\n instance.backgroundColor('#ffffff');\n };", + "line": 35, + "column": 3, + "endLine": 42, + "endColumn": 4 + }, + { + "start": 1168, + "end": 1180, + "replacementText": "applyStyles(this.cardStyle2)", + "line": 35, + "column": 3, + "endLine": 42, + "endColumn": 4 + }, + { + "start": 1192, + "end": 1204, + "replacementText": "applyStyles(this.cardStyle2)", + "line": 35, + "column": 3, + "endLine": 42, + "endColumn": 4 } ], "suggest": "", @@ -54,16 +114,41 @@ "severity": "ERROR" }, { - "line": 43, + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1114, + "end": 1116, + "replacementText": "10.0", + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 67, "column": 3, - "endLine": 46, + "endLine": 70, "endColumn": 4, "problem": "StylesDecoratorNotSupported", "autofix": [ { - "start": 943, - "end": 1008, - "replacementText": "PressedStyles = @Memo (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Green);\n}" + "start": 1326, + "end": 1388, + "replacementText": "NormalStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Red);\n };", + "line": 67, + "column": 3, + "endLine": 70, + "endColumn": 4 } ], "suggest": "", @@ -71,23 +156,55 @@ "severity": "ERROR" }, { - "line": 53, - "column": 15, - "endLine": 53, - "endColumn": 34, - "problem": "LimitedVoidType", + "line": 72, + "column": 3, + "endLine": 75, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 1392, + "end": 1457, + "replacementText": "PressedStyles = (instance: CommonMethod): void => {\n instance.backgroundColor(Color.Green);\n };", + "line": 72, + "column": 3, + "endLine": 75, + "endColumn": 4 + } + ], "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", "severity": "ERROR" }, { - "line": 54, - "column": 16, - "endLine": 54, - "endColumn": 36, - "problem": "LimitedVoidType", + "line": 105, + "column": 3, + "endLine": 118, + "endColumn": 4, + "problem": "StylesDecoratorNotSupported", + "autofix": [ + { + "start": 1953, + "end": 2449, + "replacementText": "imageStyle = (instance: CommonMethod): void => {\n instance.draggable(this.isShowLongPressMenu() && this.isPC());\n instance.onDragStart(() => {\n console.info(TAG, 'onDragStart');\n this.touchVibrate(VibrateType.DRAG);\n if (this.mediaItem?.path) {\n this.previewUri =\n this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true);\n }\n return this.DragBuilder;\n });\n instance.accessibilityText(this.isOpenTouchGuide ? this.getImageItemGridAccessibilityText() : '');\n };", + "line": 105, + "column": 3, + "endLine": 118, + "endColumn": 4 + } + ], + "suggest": "", + "rule": "\"@Styles\" decorator is not supported (arkui-no-styles-decorator)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 18, + "endLine": 116, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { @@ -96,6 +213,17 @@ "endLine": 16, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -106,6 +234,17 @@ "endLine": 25, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" @@ -116,51 +255,330 @@ "endLine": 26, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 22, + "endLine": 29, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 2, + "endLine": 33, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 23, + "endLine": 44, + "endColumn": 28, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 12, + "endLine": 45, + "endColumn": 17, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 5, + "endLine": 53, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 22, + "endLine": 57, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 2, + "endLine": 61, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 34, + "line": 63, "column": 4, - "endLine": 34, + "endLine": 63, "endColumn": 16, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 35, + "line": 64, "column": 4, - "endLine": 35, + "endLine": 64, "endColumn": 11, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 40, + "line": 69, "column": 22, - "endLine": 40, + "endLine": 69, "endColumn": 27, "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], "suggest": "", "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", "severity": "ERROR" }, { - "line": 49, + "line": 74, + "column": 22, + "endLine": 74, + "endColumn": 27, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 78, "column": 5, - "endLine": 49, + "endLine": 78, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 2, + "endLine": 99, "endColumn": 11, "problem": "UIInterfaceImport", "autofix": [ { "start": 603, "end": 603, - "replacementText": "\n\nimport { Component, CommonMethod, Memo, Column, Text, BuilderParam, Require, Color, Button } from '@kits.ArkUI';" + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI';", + "line": 103, + "column": 24, + "endLine": 103, + "endColumn": 37 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.json index ca88f857e960b437dcf767c0ac40be998c8f1236..967418d91151ac7a883ceec1516bb396845937e8 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.json @@ -13,5 +13,16 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 108, + "column": 18, + "endLine": 116, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..006f34c3422980e169fdbbbb5ca1a633ba585bfb --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.ets @@ -0,0 +1,146 @@ +/* + * 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 { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI'; + +@Component +struct MyCard1 { + cardStyle1 = (instance: CommonMethod): void => { + instance.backgroundColor('#ffffff'); + instance.borderRadius(8.0); + }; + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle1) + } + .applyStyles(this.cardStyle1) + .backgroundColor(Color.Red) + } +} + +@Component +struct MyCard2 { + cardStyle2 = (instance: CommonMethod): void => { + instance.border({ + color: this.getColor(), + width: this.getWidth() + }); + instance.backgroundColor('#ffffff'); + }; + + private getColor(): Color { + return Color.Red + } + + private getWidth(): number { + return 10.0 + } + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle2) + } + .applyStyles(this.cardStyle2) + .backgroundColor(Color.Red) + } +} + +@Component +struct MyButton { + @BuilderParam + @Require + content: () => void; + + NormalStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }; + + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; + + build() { + Button() { + this.content + } + .stateStyles({ + normal: this.NormalStyles, + pressed: this.PressedStyles + }) + } +} + +const TAG: string = 'common_ImageTest'; + +class MediaItem { + public path: string = ''; + public uri: string = ''; + + public getDateModified(): string { + return '' + } +} + +@Component +struct imageTest { + private mediaItem: MediaItem | undefined; + private previewUri: string | undefined; + private DragBuilder: CustomBuilder | undefined; + + imageStyle = (instance: CommonMethod): void => { + instance.draggable(this.isShowLongPressMenu() && this.isPC()); + instance.onDragStart(() => { + console.info(TAG, 'onDragStart'); + this.touchVibrate(VibrateType.DRAG); + if (this.mediaItem?.path) { + this.previewUri = + this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true); + } + return this.DragBuilder; + }); + instance.accessibilityText(this.isOpenTouchGuide ? this.getImageItemGridAccessibilityText() : ''); + }; + + private isShowLongPressMenu(): boolean { + return true; + } + + private isPC(): boolean { + return true; + } + + private touchVibrate(type: VibrateType): void { + + } + + private isOpenTouchGuide: boolean = true; + + private getImageItemGridAccessibilityText(): string { + return '' + } + + private getPreviewUri(path: string, date: string, isOk: boolean, ready: boolean): string { + return '' + } + + build() { + + } +} + +enum VibrateType { + DRAG +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..0e17a7dad5ec718d7915c535975cf8c692eecda6 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_1.ets.migrate.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": 105, + "column": 26, + "endLine": 113, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets b/ets2panda/linter/test/main/styles_decorator_struct_2.ets index ae9c6072f23be7d2575853bc59f0ff058ad70b71..31fb825cee110c0a92e0531cd375c90a965e6ec2 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets @@ -13,18 +13,48 @@ * limitations under the License. */ +import { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI'; + @Component struct MyCard1 { - cardStyle1 = @Memo (instance: CommonMethod): void => { + cardStyle1 = (instance: CommonMethod): void => { instance.backgroundColor('#ffffff'); instance.borderRadius(8); + }; + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle1) + } + .applyStyles(this.cardStyle1) + .backgroundColor(Color.Red) + } +} + +@Component +struct MyCard2 { + cardStyle2 = (instance: CommonMethod): void => { + instance.border({ + color: this.getColor(), + width: this.getWidth() + }); + instance.backgroundColor('#ffffff'); + }; + + private getColor(): Color { + return Color.Red + } + + private getWidth(): number { + return 10 } build() { Column() { - Text('Card') + Text('Card').applyStyles(this.cardStyle2) } - applyStyles.cardStyle1() + .applyStyles(this.cardStyle2) + .backgroundColor(Color.Red) } } @@ -34,21 +64,83 @@ struct MyButton { @Require content: () => void; - NormalStyles = @Memo (instance: CommonMethod): void => { + NormalStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Red); - } + }; - PressedStyles = @Memo (instance: CommonMethod): void => { + PressedStyles = (instance: CommonMethod): void => { instance.backgroundColor(Color.Green); - } + }; build() { Button() { this.content } .stateStyles({ - normal: this.NormalStyles(), - pressed: this.PressedStyles() + normal: this.NormalStyles, + pressed: this.PressedStyles }) } +} + +const TAG: string = 'common_ImageTest'; + +class MediaItem { + public path: string = ''; + public uri: string = ''; + + public getDateModified(): string { + return '' + } +} + +@Component +struct imageTest { + private mediaItem: MediaItem | undefined; + private previewUri: string | undefined; + private DragBuilder: CustomBuilder | undefined; + + imageStyle = (instance: CommonMethod): void => { + instance.draggable(this.isShowLongPressMenu() && this.isPC()); + instance.onDragStart(() => { + console.info(TAG, 'onDragStart'); + this.touchVibrate(VibrateType.DRAG); + if (this.mediaItem?.path) { + this.previewUri = + this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true); + } + return this.DragBuilder; + }); + instance.accessibilityText(this.isOpenTouchGuide ? this.getImageItemGridAccessibilityText() : ''); + }; + + private isShowLongPressMenu(): boolean { + return true; + } + + private isPC(): boolean { + return true; + } + + private touchVibrate(type: VibrateType): void { + + } + + private isOpenTouchGuide: boolean = true; + + private getImageItemGridAccessibilityText(): string { + return '' + } + + private getPreviewUri(path: string, date: string, isOk: boolean, ready: boolean): string { + return '' + } + + build() { + + } +} + +enum VibrateType { + DRAG } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.args.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.args.json index 5cdfe96f7ad7b6e21562e9a8de3e8de3262d21ce..ee0734c0fc5b9a918bfdd7245e6ef1efeb8ad7e6 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.args.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json index 27d6d9215c8b37166ea38a83e1e8ebe511b08562..7ead10ecf2f79fd56a689b48ec5e545119665be1 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.arkts2.json @@ -15,193 +15,33 @@ ], "result": [ { - "line": 18, - "column": 3, - "endLine": 18, - "endColumn": 15, - "problem": "AnyType", + "line": 22, + "column": 27, + "endLine": 22, + "endColumn": 28, + "problem": "NumericSemantics", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 18, - "column": 48, - "endLine": 18, - "endColumn": 52, - "problem": "LimitedVoidType", + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 14, + "problem": "NumericSemantics", "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 18, - "column": 16, - "endLine": 18, - "endColumn": 46, - "problem": "DecoratorsNotSupported", + "line": 105, + "column": 26, + "endLine": 113, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 3, - "endLine": 37, - "endColumn": 17, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 50, - "endLine": 37, - "endColumn": 54, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 18, - "endLine": 37, - "endColumn": 48, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 19, - "endLine": 41, - "endColumn": 49, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 51, - "endLine": 41, - "endColumn": 55, - "problem": "VoidOperator", - "suggest": "", - "rule": "\"void\" operator is not supported (arkts-no-void-operator)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 2, - "endLine": 16, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 17, - "endLine": 18, - "endColumn": 21, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 33, - "endLine": 18, - "endColumn": 45, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 5, - "endLine": 24, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 7, - "endLine": 25, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 4, - "endLine": 33, - "endColumn": 16, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 4, - "endLine": 34, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 30, - "endLine": 38, - "endColumn": 35, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 5, - "endLine": 46, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 46, - "endLine": 18, - "endColumn": 46, - "problem": "StrictDiagnostic", - "suggest": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 37, - "column": 48, - "endLine": 37, - "endColumn": 48, - "problem": "StrictDiagnostic", - "suggest": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json index 4795d0e08f26244854522d7dd5973fdec4fb7349..524d890233577d219c594060a424967e22f1b257 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.autofix.json @@ -15,207 +15,55 @@ ], "result": [ { - "line": 18, - "column": 3, - "endLine": 18, - "endColumn": 15, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 48, - "endLine": 18, - "endColumn": 52, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 16, - "endLine": 18, - "endColumn": 46, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 3, - "endLine": 37, - "endColumn": 17, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 50, - "endLine": 37, - "endColumn": 54, - "problem": "LimitedVoidType", - "suggest": "", - "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 18, - "endLine": 37, - "endColumn": 48, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 19, - "endLine": 41, - "endColumn": 49, - "problem": "DecoratorsNotSupported", - "suggest": "", - "rule": "Decorators are not supported(arkts-no-ts-decorators)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 51, - "endLine": 41, - "endColumn": 55, - "problem": "VoidOperator", + "line": 22, + "column": 27, + "endLine": 22, + "endColumn": 28, + "problem": "NumericSemantics", "autofix": [ { - "start": 1089, - "end": 1093, - "replacementText": "(() => {\n ;\n return undefined;\n})()" + "start": 873, + "end": 874, + "replacementText": "8.0", + "line": 22, + "column": 27, + "endLine": 22, + "endColumn": 28 } ], "suggest": "", - "rule": "\"void\" operator is not supported (arkts-no-void-operator)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 2, - "endLine": 16, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 18, - "column": 17, - "endLine": 18, - "endColumn": 21, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 33, - "endLine": 18, - "endColumn": 45, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 5, - "endLine": 24, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 25, - "column": 7, - "endLine": 25, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 4, - "endLine": 33, - "endColumn": 16, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 4, - "endLine": 34, - "endColumn": 11, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 30, - "endLine": 38, - "endColumn": 35, - "problem": "UIInterfaceImport", - "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 5, - "endLine": 46, - "endColumn": 11, - "problem": "UIInterfaceImport", + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 14, + "problem": "NumericSemantics", "autofix": [ { - "start": 603, - "end": 603, - "replacementText": "\n\nimport { Component, Memo, CommonMethod, Column, Text, BuilderParam, Require, Color, Button } from '@kits.ArkUI';" + "start": 1358, + "end": 1360, + "replacementText": "10.0", + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 14 } ], "suggest": "", - "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 18, - "column": 46, - "endLine": 18, - "endColumn": 46, - "problem": "StrictDiagnostic", - "suggest": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 37, - "column": 48, - "endLine": 37, - "endColumn": 48, - "problem": "StrictDiagnostic", - "suggest": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", + "line": 105, + "column": 26, + "endLine": 113, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json index 548795bb404d86801b5af03dcc373f9c476795df..0e17a7dad5ec718d7915c535975cf8c692eecda6 100644 --- a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.json @@ -15,43 +15,13 @@ ], "result": [ { - "line": 18, - "column": 3, - "endLine": 18, - "endColumn": 15, - "problem": "AnyType", + "line": 105, + "column": 26, + "endLine": 113, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 3, - "endLine": 37, - "endColumn": 17, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 46, - "endLine": 18, - "endColumn": 46, - "problem": "StrictDiagnostic", - "suggest": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 37, - "column": 48, - "endLine": 37, - "endColumn": 48, - "problem": "StrictDiagnostic", - "suggest": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '(Missing)' has no initializer and is not definitely assigned in the constructor.", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.ets b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..006f34c3422980e169fdbbbb5ca1a633ba585bfb --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.ets @@ -0,0 +1,146 @@ +/* + * 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 { Component, CommonMethod, Column, Text, Color, BuilderParam, Require, Button, CustomBuilder } from '@kit.ArkUI'; + +@Component +struct MyCard1 { + cardStyle1 = (instance: CommonMethod): void => { + instance.backgroundColor('#ffffff'); + instance.borderRadius(8.0); + }; + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle1) + } + .applyStyles(this.cardStyle1) + .backgroundColor(Color.Red) + } +} + +@Component +struct MyCard2 { + cardStyle2 = (instance: CommonMethod): void => { + instance.border({ + color: this.getColor(), + width: this.getWidth() + }); + instance.backgroundColor('#ffffff'); + }; + + private getColor(): Color { + return Color.Red + } + + private getWidth(): number { + return 10.0 + } + + build() { + Column() { + Text('Card').applyStyles(this.cardStyle2) + } + .applyStyles(this.cardStyle2) + .backgroundColor(Color.Red) + } +} + +@Component +struct MyButton { + @BuilderParam + @Require + content: () => void; + + NormalStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Red); + }; + + PressedStyles = (instance: CommonMethod): void => { + instance.backgroundColor(Color.Green); + }; + + build() { + Button() { + this.content + } + .stateStyles({ + normal: this.NormalStyles, + pressed: this.PressedStyles + }) + } +} + +const TAG: string = 'common_ImageTest'; + +class MediaItem { + public path: string = ''; + public uri: string = ''; + + public getDateModified(): string { + return '' + } +} + +@Component +struct imageTest { + private mediaItem: MediaItem | undefined; + private previewUri: string | undefined; + private DragBuilder: CustomBuilder | undefined; + + imageStyle = (instance: CommonMethod): void => { + instance.draggable(this.isShowLongPressMenu() && this.isPC()); + instance.onDragStart(() => { + console.info(TAG, 'onDragStart'); + this.touchVibrate(VibrateType.DRAG); + if (this.mediaItem?.path) { + this.previewUri = + this.getPreviewUri(this.mediaItem?.path, this.mediaItem?.getDateModified?.(), false, true); + } + return this.DragBuilder; + }); + instance.accessibilityText(this.isOpenTouchGuide ? this.getImageItemGridAccessibilityText() : ''); + }; + + private isShowLongPressMenu(): boolean { + return true; + } + + private isPC(): boolean { + return true; + } + + private touchVibrate(type: VibrateType): void { + + } + + private isOpenTouchGuide: boolean = true; + + private getImageItemGridAccessibilityText(): string { + return '' + } + + private getPreviewUri(path: string, date: string, isOk: boolean, ready: boolean): string { + return '' + } + + build() { + + } +} + +enum VibrateType { + DRAG +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..0e17a7dad5ec718d7915c535975cf8c692eecda6 --- /dev/null +++ b/ets2panda/linter/test/main/styles_decorator_struct_2.ets.migrate.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": 105, + "column": 26, + "endLine": 113, + "endColumn": 6, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/subclass_super_call.ets b/ets2panda/linter/test/main/subclass_super_call.ets new file mode 100644 index 0000000000000000000000000000000000000000..d275725c9ced20f3df8eb301562897c1f14e3845 --- /dev/null +++ b/ets2panda/linter/test/main/subclass_super_call.ets @@ -0,0 +1,39 @@ +/* + * 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. + */ +'use static' + +class A { + constructor(a: number) { + } +} + +class B { + constructor() { + } +} + +class C extends A {} // ERROR + +class D extends A { // ERROR super is not called + constructor(a: number) {} +} + +class E extends A { // NO ERROR constructor is called + constructor(a: number) { + super(a); + } +} + +class F extends B {} // NO ERROR diff --git a/ets2panda/linter/test/main/subclass_super_call.ets.args.json b/ets2panda/linter/test/main/subclass_super_call.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/main/subclass_super_call.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/subclass_super_call.ets.arkts2.json b/ets2panda/linter/test/main/subclass_super_call.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..289a83337b8aabfabe08c43a0ade753e39dfbf7b --- /dev/null +++ b/ets2panda/linter/test/main/subclass_super_call.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 27, + "column": 9, + "endLine": 27, + "endColumn": 18, + "problem": "MissingSuperCall", + "suggest": "", + "rule": "The subclass constructor must call the parent class's parametered constructor (arkts-subclass-must-call-super-constructor-with-args)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 9, + "endLine": 29, + "endColumn": 18, + "problem": "MissingSuperCall", + "suggest": "", + "rule": "The subclass constructor must call the parent class's parametered constructor (arkts-subclass-must-call-super-constructor-with-args)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/subclass_super_call.ets.json b/ets2panda/linter/test/main/subclass_super_call.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dd03fcf5442488620bcd4b3447f0fcdd89e1905b --- /dev/null +++ b/ets2panda/linter/test/main/subclass_super_call.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": [] +} diff --git a/ets2panda/linter/test/main/swicth_expr.ets b/ets2panda/linter/test/main/swicth_expr.ets index 8a26d91ef5bc59d2732cb2969a320decf01783eb..45055cf2effb98cfa502ee3854ea24d1305b1372 100755 --- a/ets2panda/linter/test/main/swicth_expr.ets +++ b/ets2panda/linter/test/main/swicth_expr.ets @@ -31,7 +31,7 @@ switch (objValue) { break; default: console.log("Non-matching object"); - +} let arrayValue = [1, 2, 3]; @@ -133,4 +133,282 @@ switch (day) { break; default: dayName = "Unknown"; -} \ No newline at end of file +} + +const number01: number = 100; +function Foo(number01: number) { + switch (number01) { + case 1: + console.log('It\'s 1'); + break; + case 2: + console.log('It\'s 2') + break; + } +} +Foo(number01) + +const num11: number = 2; +switch (num11) { + case 1: { + console.log('One'); + break; + } + case 2: { + console.log('Two'); + break; + } +} + +let num0 = 2; +switch (num0) { + case 1: { + console.log('One'); + break; + } + case 2: { + console.log('Two'); + break; + } +} + +let num00: number = 2; +switch (num00) { + case 1: { + console.log('One'); + break; + } + case 2: { + console.log('Two'); + break; + } +} + +let num1 = 0; +switch (num1) { + case 0: + console.log('One'); + break; + default: + console.log('Other number'); +} + +1.0 +let num111 = 1.0; +switch (num111) { + case 1.0: + console.log('One'); + break; + case 2.0: + console.log('Other number'); +} + +const number134 = 100; +switch (number134) { + case 1: + console.log('It\'s 1'); + break; + case 2: + console.log('It\'s 2') + break; +} + +let str11 = new String("hello"); +switch (str11) { + case "hello": + console.log("Case 1") + break + case "world": + console.log("Default Case") +} + +let isnum1: string | number = 1; +switch (isnum1) { + case 1.1: + console.log('It's num'); + break; + default: + console.log('F'); +} +// 整型 5.2fail +type sw1 = number + +function FunSw4(): sw1 { + return 1 +} + +switch (FunSw4()) { + case 1: + console.log('A'); + break; + default: + console.log('F'); +} + +// 浮点 5.2fail +type sw2 = number | string + +function FunSw5(): sw2 { + return 1.11 +} + +switch (FunSw5()) { + case 1.11: + console.log('A'); + break; + default: + console.log('F'); +} + +let number7 = Math.floor(1.5); +switch (number7) { + case Math.floor(1.5): + console.log("Case 1"); + break; + default: + console.log("Default case"); +} +switch (85 + 5.5) { + case 90.5: + console.log('A'); + break; + default: + console.log('F'); +} +const add = (a: number, b: number): number => a + b; +const result1 = add(10, 5); +switch (result1) { + case 15: + console.log('A'); + break; + case 14: + console.log('B'); + break; + default: + console.log('F'); +} +function FunSw2(): number { + return 1.1 +} + +switch (FunSw2()) { + case 1.1: + console.log('A'); + break; + default: + console.log('F'); +} + +// 正无穷 +let number4 = Infinity; +switch (number4) { + case Infinity: + console.log("Case 1"); + break; + default: + console.log("Default case"); +} + +// 负无穷 +let number5 = -Infinity; +switch (number5) { + case -Infinity: + console.log("Case 1"); + break; + default: + console.log("Default case"); +} + +// NaN +let number6 = NaN; +switch (number6) { + case NaN: + console.log("Case 1"); + break; + default: + console.log("Default case"); +} +// 1.0 +let num111 = 1.0; +switch (num111) { + case 1.0: + console.log('One'); + break; + case 2.0: + console.log('Other number'); +} + +// let声明整型,case浮点 +let number33: number = 1; +switch (number33) { + case 1.1: + console.log("Case 1"); + break; + case 2: + console.log("Case 2"); + break; + case 3: + console.log("Case 3"); + break; + default: + console.log("Default case"); +} + +// const声明,整型number,有类型 +const num11: number = 2; +switch (num11) { + case 1: { + console.log('One'); + break; + } + case 2: { + console.log('Two'); + break; + } +} + +// let声明,整型number,有类型 +let num00: number = 2; +switch (num00) { + case 1: { + console.log('One'); + break; + } + case 2: { + console.log('Two'); + break; + } +} + + +enum Direction1 { + North, + South, + East, + West +} +function funSE() : string | Direction1 { + return 'aaa' +} +switch (funSE()) { // 误报 + case 'aaa': + console.log('aaa'); + break; + case Direction1.North: + console.log('aaa'); + break; + default: + console.log('F'); +} + + +enum H { + RED, + BLUE +} +function foo11(e: H) { // 误报 + switch (e) { + case H.RED: + } +} + diff --git a/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json b/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json index 107072a9c6cf4fec1f3afb2ccc5a1b8c3c0b8e2e..5ce55a54ac3b3b4b94d6b10bf24348f2a15a4a24 100755 --- a/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json +++ b/ets2panda/linter/test/main/swicth_expr.ets.arkts2.json @@ -1,19 +1,19 @@ { - "copyright": [ - "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." - ], - "result": [ + "copyright": [ + "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." + ], + "result": [ { "line": 17, "column": 9, @@ -21,7 +21,7 @@ "endColumn": 15, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 17, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", "severity": "ERROR" }, { @@ -64,6 +64,36 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 36, + "column": 19, + "endLine": 36, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 22, + "endLine": 36, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 25, + "endLine": 36, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 38, "column": 9, @@ -71,7 +101,37 @@ "endColumn": 19, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 9, + "endLine": 39, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 12, + "endLine": 39, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 15, + "endLine": 39, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -84,6 +144,36 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 56, + "column": 17, + "endLine": 56, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 8, + "endLine": 58, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 8, + "endLine": 61, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 70, "column": 7, @@ -111,7 +201,17 @@ "endColumn": 16, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 8, + "endLine": 85, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -131,7 +231,17 @@ "endColumn": 16, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 8, + "endLine": 95, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { @@ -151,7 +261,737 @@ "endColumn": 16, "problem": "SwitchExpression", "suggest": "", - "rule": "The switch expression type must be of type number,string or enum (arkts-switch-expr)", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 8, + "endLine": 105, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 15, + "endLine": 110, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 9, + "endLine": 112, + "endColumn": 12, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 10, + "endLine": 113, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 116, + "column": 10, + "endLine": 116, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 10, + "endLine": 119, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 10, + "endLine": 122, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 10, + "endLine": 125, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 128, + "column": 10, + "endLine": 128, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 131, + "column": 10, + "endLine": 131, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 138, + "column": 26, + "endLine": 138, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 140, + "column": 11, + "endLine": 140, + "endColumn": 19, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 141, + "column": 10, + "endLine": 141, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 144, + "column": 10, + "endLine": 144, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 151, + "column": 23, + "endLine": 151, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 152, + "column": 9, + "endLine": 152, + "endColumn": 14, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 153, + "column": 8, + "endLine": 153, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 157, + "column": 8, + "endLine": 157, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 5, + "endLine": 163, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 163, + "column": 12, + "endLine": 163, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 165, + "column": 8, + "endLine": 165, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 169, + "column": 8, + "endLine": 169, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 175, + "column": 21, + "endLine": 175, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 176, + "column": 9, + "endLine": 176, + "endColumn": 14, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 8, + "endLine": 177, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 181, + "column": 8, + "endLine": 181, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 5, + "endLine": 187, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 12, + "endLine": 187, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 189, + "column": 8, + "endLine": 189, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 197, + "column": 5, + "endLine": 197, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 198, + "column": 9, + "endLine": 198, + "endColumn": 15, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 7, + "endLine": 206, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 206, + "column": 19, + "endLine": 206, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 208, + "column": 8, + "endLine": 208, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 8, + "endLine": 211, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 216, + "column": 13, + "endLine": 216, + "endColumn": 32, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 225, + "column": 31, + "endLine": 225, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 226, + "column": 9, + "endLine": 226, + "endColumn": 15, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 237, + "column": 10, + "endLine": 237, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 240, + "column": 9, + "endLine": 240, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 241, + "column": 8, + "endLine": 241, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 255, + "column": 9, + "endLine": 255, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 263, + "column": 5, + "endLine": 263, + "endColumn": 30, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 264, + "column": 9, + "endLine": 264, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 271, + "column": 9, + "endLine": 271, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 271, + "column": 9, + "endLine": 271, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 279, + "column": 7, + "endLine": 279, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 279, + "column": 21, + "endLine": 279, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 279, + "column": 25, + "endLine": 279, + "endColumn": 26, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 280, + "column": 9, + "endLine": 280, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 281, + "column": 8, + "endLine": 281, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 284, + "column": 8, + "endLine": 284, + "endColumn": 10, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 294, + "column": 9, + "endLine": 294, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 303, + "column": 5, + "endLine": 303, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 304, + "column": 9, + "endLine": 304, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 5, + "endLine": 313, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 314, + "column": 9, + "endLine": 314, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 323, + "column": 5, + "endLine": 323, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 324, + "column": 9, + "endLine": 324, + "endColumn": 16, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 332, + "column": 5, + "endLine": 332, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 333, + "column": 9, + "endLine": 333, + "endColumn": 15, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 342, + "column": 24, + "endLine": 342, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 343, + "column": 9, + "endLine": 343, + "endColumn": 17, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 347, + "column": 8, + "endLine": 347, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 350, + "column": 8, + "endLine": 350, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 358, + "column": 23, + "endLine": 358, + "endColumn": 24, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 359, + "column": 9, + "endLine": 359, + "endColumn": 14, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 360, + "column": 8, + "endLine": 360, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 364, + "column": 8, + "endLine": 364, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 371, + "column": 21, + "endLine": 371, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 372, + "column": 9, + "endLine": 372, + "endColumn": 14, + "problem": "SwitchExpression", + "suggest": "", + "rule": "The switch expression type must be of type char, byte, short, int, long, string or enum (arkts-switch-expr)", + "severity": "ERROR" + }, + { + "line": 373, + "column": 8, + "endLine": 373, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 377, + "column": 8, + "endLine": 377, + "endColumn": 9, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/swicth_expr.ets.json b/ets2panda/linter/test/main/swicth_expr.ets.json index 7131492d55ac2893676a526941eac06c43a2ddb9..9dda12ea9c2e9a4268ae2c72029296496f86eb06 100755 --- a/ets2panda/linter/test/main/swicth_expr.ets.json +++ b/ets2panda/linter/test/main/swicth_expr.ets.json @@ -15,24 +15,24 @@ ], "result": [ { - "line": 26, - "column": 16, - "endLine": 26, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" + "line": 26, + "column": 16, + "endLine": 26, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" }, { - "line": 29, - "column": 8, - "endLine": 29, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" + "line": 29, + "column": 8, + "endLine": 29, + "endColumn": 9, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" } ] } diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets new file mode 100644 index 0000000000000000000000000000000000000000..05ec4e2f14809d6685c63f0ff9c89f60bb817001 --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.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. + */ +'use static' + +let baseInstance1: BaseClass = new BaseClass(); +let array1 = new Array(); +array1.push(baseInstance1); +let task1 = new taskpool.Task(testFunc, array1, 10); +task1.setCloneList(array1); +task1.setTransferList(array1); diff --git a/ets2panda/linter/test/migrate/destructuring_declarations.ts.args.json b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.args.json similarity index 90% rename from ets2panda/linter/test/migrate/destructuring_declarations.ts.args.json rename to ets2panda/linter/test/main/taskpool_deprecated_usages.ets.args.json index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..3ef4496a819a201892114d1c90f78ae32053c334 100644 --- a/ets2panda/linter/test/migrate/destructuring_declarations.ts.args.json +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 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", @@ -14,6 +14,6 @@ "limitations under the License." ], "mode": { - "migrate": "" + "arkts2": "" } } diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.json b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..463c82314fe13513cae7fe2a912b6a62eb98b22b --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.arkts2.json @@ -0,0 +1,78 @@ +{ + "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": 17, + "column": 36, + "endLine": 17, + "endColumn": 45, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 20, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 30, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 49, + "endLine": 20, + "endColumn": 51, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 1, + "endLine": 21, + "endColumn": 28, + "problem": "SetCloneListDeprecated", + "suggest": "", + "rule": "The taskpool setCloneList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setCloneList)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 31, + "problem": "SetTransferListDeprecated", + "suggest": "", + "rule": "The taskpool setTransferList interface is deleted from ArkTS1.2 (arkts-limited-stdlib-no-setTransferList)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.json b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..1c17b59df7a1612ee61e9a9368eed3b136b9bcfc --- /dev/null +++ b/ets2panda/linter/test/main/taskpool_deprecated_usages.ets.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": 20, + "column": 5, + "endLine": 20, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets b/ets2panda/linter/test/main/ts-like-catch-type.ets new file mode 100644 index 0000000000000000000000000000000000000000..76d4be8122a044cab26465f3b6e83eb567e024a6 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets @@ -0,0 +1,30 @@ +/* + * 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 test() { + try { + let a: number = 1; + } catch (e) { + console.log('catch') + } +} + +function test2() { + try { + let a: number = 1; + } catch (e: any) { + console.log('catch') + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets.args.json b/ets2panda/linter/test/main/ts-like-catch-type.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..e2b903f0aa82e6ca4108ff67d5272bf49d6c2a5b --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type.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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json b/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..2956a7461c93662772b93bad5274bb8915f22610 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets.arkts2.json @@ -0,0 +1,78 @@ +{ + "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": 18, + "column": 21, + "endLine": 18, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 5, + "endLine": 21, + "endColumn": 4, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 21, + "endLine": 26, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 12, + "endLine": 27, + "endColumn": 18, + "problem": "CatchWithUnsupportedType", + "suggest": "", + "rule": "Type annotation in catch clause is not supported (arkts-no-types-in-catch)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 5, + "endLine": 29, + "endColumn": 4, + "problem": "TsLikeCatchType", + "suggest": "", + "rule": "TS catch type are not supported (arkts-no-ts-like-catch-type)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 15, + "endLine": 27, + "endColumn": 18, + "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/main/ts-like-catch-type.ets.json b/ets2panda/linter/test/main/ts-like-catch-type.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bd65f7efbe5b1a14b6001506f9a8511cd080d1d1 --- /dev/null +++ b/ets2panda/linter/test/main/ts-like-catch-type.ets.json @@ -0,0 +1,38 @@ +{ + "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": 27, + "column": 12, + "endLine": 27, + "endColumn": 18, + "problem": "CatchWithUnsupportedType", + "suggest": "", + "rule": "Type annotation in catch clause is not supported (arkts-no-types-in-catch)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 15, + "endLine": 27, + "endColumn": 18, + "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/main/ts_overload.ets b/ets2panda/linter/test/main/ts_overload.ets index 25e7ed30eab2c923da03c0a5f640bd66024fb2c0..d6a903fb5b31ca585cdefe3e5a95fefb02c3629d 100644 --- a/ets2panda/linter/test/main/ts_overload.ets +++ b/ets2panda/linter/test/main/ts_overload.ets @@ -13,9 +13,9 @@ * limitations under the License. */ -function makeDate(timestamp: number): Date; -function makeDate(m: number, d: number, y: number): Date; -function makeDate(mOrTimestamp: number, d?: number, y?: number): Date { +function makeDate(timestamp: number): Date; //error +function makeDate(m: number, d: number, y: number): Date; //error +function makeDate(mOrTimestamp: number, d?: number, y?: number): Date { //error if (d !== undefined && y !== undefined) { return new Date(y, mOrTimestamp, d); } else { @@ -27,15 +27,15 @@ const d2 = makeDate(5, 5, 5); const d3 = makeDate(1, 3); class Vector { - abstract foo(): void - abstract foo(x: string): void - abstract foo(x?: string): void { + abstract foo(): void //error + abstract foo(x: string): void //error + abstract foo(x?: string): void { //error /body/ } - public fun(): void - public fun(x: string): void - public fun(x?: string): void { + public fun(): void //error + public fun(x: string): void //error + public fun(x?: string): void { //error /body/ } } @@ -47,11 +47,42 @@ abstract class absClass { /body/ } - constructor(x: number, y: number); + constructor(x: number, y: number); //error - constructor(magnitude: number); + constructor(magnitude: number); //error - constructor(...args: number[]) { + constructor(...args: number[]) { //error /* ... */ } +} +function func(){ + console.log("ArkTs foo4") +} + +func.val = "0xff"; + +@Component +struct B{ + constructor() { + super() + } + build() { + } +} + +struct C{ + constructor() { //error + super() + } + constructor(x:number) //error +} + +class A{ + constructor() { + } +} +class D{ + constructor() { //error + } + constructor(x:number) //error } \ No newline at end of file diff --git a/ets2panda/linter/test/main/ts_overload.ets.arkts2.json b/ets2panda/linter/test/main/ts_overload.ets.arkts2.json index 191fb8f52603ebd1f46ee002643685e68c1df4ef..013ef916fea24fed789c3c5816661b4ad1f9be64 100644 --- a/ets2panda/linter/test/main/ts_overload.ets.arkts2.json +++ b/ets2panda/linter/test/main/ts_overload.ets.arkts2.json @@ -13,7 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [ + "result": [ { "line": 16, "column": 1, @@ -44,6 +44,66 @@ "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", "severity": "ERROR" }, + { + "line": 25, + "column": 21, + "endLine": 25, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 21, + "endLine": 26, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 24, + "endLine": 26, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 27, + "endLine": 26, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 21, + "endLine": 27, + "endColumn": 22, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 24, + "endLine": 27, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 30, "column": 3, @@ -163,6 +223,66 @@ "suggest": "", "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", "severity": "ERROR" + }, + { + "line": 62, + "column": 1, + "endLine": 62, + "endColumn": 5, + "problem": "PropertyDeclOnFunction", + "suggest": "", + "rule": "Declaring properties on functions is not supported (arkts-no-func-props)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 3, + "endLine": 76, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 3, + "endLine": 77, + "endColumn": 24, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 85, + "column": 3, + "endLine": 86, + "endColumn": 4, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 3, + "endLine": 87, + "endColumn": 24, + "problem": "TsOverload", + "suggest": "", + "rule": "Class TS overloading is not supported(arkts-no-ts-overload)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 2, + "endLine": 64, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/type_inference.ets.arkts2.json b/ets2panda/linter/test/main/type_inference.ets.arkts2.json index 3951fd44f41ae7c1d3047062a6dbc9bac4a8b54f..a1d51aff5138499ae588ccb11e0ebb4419b187a1 100644 --- a/ets2panda/linter/test/main/type_inference.ets.arkts2.json +++ b/ets2panda/linter/test/main/type_inference.ets.arkts2.json @@ -24,6 +24,26 @@ "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, + { + "line": 19, + "column": 13, + "endLine": 19, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 16, + "endLine": 19, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 23, "column": 10, diff --git a/ets2panda/linter/test/main/type_literals.ets.args.json b/ets2panda/linter/test/main/type_literals.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/type_literals.ets.args.json +++ b/ets2panda/linter/test/main/type_literals.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/type_literals.ets.autofix.json b/ets2panda/linter/test/main/type_literals.ets.autofix.json index 8d8dc62efee7ec2fda2de183d32eb2061e90835b..16726b33b20be64af9eb341336820b98fff7265c 100644 --- a/ets2panda/linter/test/main/type_literals.ets.autofix.json +++ b/ets2panda/linter/test/main/type_literals.ets.autofix.json @@ -700,16 +700,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 85, - "column": 3, - "endLine": 85, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 93, "column": 3, @@ -782,16 +772,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 101, - "column": 3, - "endLine": 101, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 109, "column": 3, diff --git a/ets2panda/linter/test/main/type_literals.ets.json b/ets2panda/linter/test/main/type_literals.ets.json index 45014a1517832a6548e72c7ecb31c81690fe768d..fe85abf706f643f7cf4285eb2c00c9d03d980f85 100644 --- a/ets2panda/linter/test/main/type_literals.ets.json +++ b/ets2panda/linter/test/main/type_literals.ets.json @@ -394,16 +394,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 85, - "column": 3, - "endLine": 85, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 93, "column": 3, @@ -464,16 +454,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 101, - "column": 3, - "endLine": 101, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 109, "column": 3, diff --git a/ets2panda/linter/test/migrate/type_literals.sts b/ets2panda/linter/test/main/type_literals.ets.migrate.ets similarity index 34% rename from ets2panda/linter/test/migrate/type_literals.sts rename to ets2panda/linter/test/main/type_literals.ets.migrate.ets index b3ec3eea0ff269d03622697328dee1e7a6527f62..a8a0de8970f1123b38e3892c9593a46b77fc34bb 100644 --- a/ets2panda/linter/test/migrate/type_literals.sts +++ b/ets2panda/linter/test/main/type_literals.ets.migrate.ets @@ -13,36 +13,83 @@ * limitations under the License. */ -type Type1 = {}; -type Type2 = {a: number; b: string;}; -type Type3 = {a: number, b: number,}[]; -type Type4 = Type1 | {a: number, b: string} | {c: number, d: string}; -type Type5 = {a: T, b: K, c: number}; -type Type6 = { - a: number - b: string - c: { - x: number - y: string - z: Type1 - } -}; -export type Type7 = {a: number}; - -let var1: {} = {}; -let var2: {a: number, b: string} = {a:1, b:'2'}; -let var3: {a: number, b: number,}[]; -let var4: Type1 | {a: number, b: string} | {c: number, d: string}; -let var5 = var1 as {a: number, b: string}; -let var6: { - a: number - b: string - c: { - x: number - y: string - z: Type2 - } -} = { +interface Type1 { +} +interface Type2 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_1 { + a: number; + b: number; +} +type Type3 = GeneratedTypeLiteralInterface_1[]; +interface GeneratedTypeLiteralInterface_2 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_3 { + c: number; + d: string; +} +type Type4 = Type1 | GeneratedTypeLiteralInterface_2 | GeneratedTypeLiteralInterface_3; +interface Type5 { + a: T; + b: K; + c: number; +} +interface GeneratedTypeLiteralInterface_4 { + x: number; + y: string; + z: Type1; +} +interface Type6 { + a: number; + b: string; + c: GeneratedTypeLiteralInterface_4; +} +export interface Type7 { + a: number; +} + +interface GeneratedTypeLiteralInterface_5 { +} +let var1: GeneratedTypeLiteralInterface_5 = {}; +interface GeneratedTypeLiteralInterface_6 { + a: number; + b: string; +} +let var2: GeneratedTypeLiteralInterface_6 = {a:1, b:'2'}; +interface GeneratedTypeLiteralInterface_7 { + a: number; + b: number; +} +let var3: GeneratedTypeLiteralInterface_7[]; +interface GeneratedTypeLiteralInterface_8 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_9 { + c: number; + d: string; +} +let var4: Type1 | GeneratedTypeLiteralInterface_8 | GeneratedTypeLiteralInterface_9; +interface GeneratedTypeLiteralInterface_10 { + a: number; + b: string; +} +let var5 = var1 as GeneratedTypeLiteralInterface_10; +interface GeneratedTypeLiteralInterface_12 { + x: number; + y: string; + z: Type2; +} +interface GeneratedTypeLiteralInterface_11 { + a: number; + b: string; + c: GeneratedTypeLiteralInterface_12; +} +let var6: GeneratedTypeLiteralInterface_11 = { a: 1, b: '2', c: { @@ -55,67 +102,100 @@ let var6: { } }; -function f(p: {x: number, y: string}): {z: boolean} { +interface GeneratedTypeLiteralInterface_13 { + x: number; + y: string; +} +interface GeneratedTypeLiteralInterface_14 { + z: boolean; +} +function f(p: GeneratedTypeLiteralInterface_13): GeneratedTypeLiteralInterface_14 { return {z: true}; } +interface GeneratedTypeLiteralInterface_15 { + a: number; + b: string; +} +interface GeneratedTypeLiteralInterface_16 { + c: number; + d: string; +} +interface GeneratedTypeLiteralInterface_17 { + e: boolean; +} class C { - f: {a: number, b: string} = {a: 1, b:'2'}; + f: GeneratedTypeLiteralInterface_15 = {a: 1, b:'2'}; - m(p: {c: number, d: string}): {e: boolean} { + m(p: GeneratedTypeLiteralInterface_16): GeneratedTypeLiteralInterface_17 { return {e: true}; } } // Generic types class GC {} -class GC2 extends GC<{ x: 10 }> {} -const gc: GC<{ y: string }> = new GC<{ y: '20' }>(); +interface GeneratedTypeLiteralInterface_18 { + x: 10; +} +class GC2 extends GC {} +interface GeneratedTypeLiteralInterface_19 { + y: string; +} +interface GeneratedTypeLiteralInterface_20 { + y: '20'; +} +const gc: GC = new GC(); -type GType = GC; +interface GeneratedTypeLiteralInterface_21 { + z: number; +} +type GType = GC; function g(t: T): number { return 10; } -g<{ z: boolean }>({ z: true }); - -type TypeMembers = { - a: number; - 'b': string; - 3: boolean; - ['x']: number; - - m: (p: string) => number; - n(p: number): void; - get val(): number; - set val(p: number); - - (p: number): string; - new (p: string): C; - [key: string]: unknown; +interface GeneratedTypeLiteralInterface_22 { + z: boolean; +} +g({ z: true }); + +interface TypeMembers { + a: number; + 'b': string; + __3: boolean; + ['x']: number; + m: (p: string) => number; + n(p: number): void; + get val(): number; + set val(p: number); + (p: number): string; + new (p: string): C; + [key: string]: unknown; } -let typeMembers: { - a: number; - 'b': string; - 3: boolean; - ['x']: number; - - m: (p: string) => number; - n(p: number): void; - get val(): number; - set val(p: number); - - (p: number): string; - new (p: string): C; - [key: string]: unknown; -}; +interface GeneratedTypeLiteralInterface_23 { + a: number; + 'b': string; + __3: boolean; + ['x']: number; + m: (p: string) => number; + n(p: number): void; + get val(): number; + set val(p: number); + (p: number): string; + new (p: string): C; + [key: string]: unknown; +} +let typeMembers: GeneratedTypeLiteralInterface_23; // Capture type from enclosing local scope export function captureFromLocalScope(t: T): {ret: T} { // Non-fixable, type captures type parameter from enclosing declaration let v1: {local: T}; // Non-fixable, type captures type parameter from enclosing declaration - type LocalType = {a: number, b: string}; + interface LocalType { + a: number; + b: string; +} let v2: { x: LocalType } = {x: {a: 1, b: '2'}}; // Non-fixable, type captures another type declared in local scope type LocalType2 = ({k: K}); // Non-fixable, type captures type parameter from enclosing declaration diff --git a/ets2panda/linter/test/main/type_literals.ets.migrate.json b/ets2panda/linter/test/main/type_literals.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..f132876e4826418ec254d0a0e0df92ccca9a3f78 --- /dev/null +++ b/ets2panda/linter/test/main/type_literals.ets.migrate.json @@ -0,0 +1,238 @@ +{ + "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": 171, + "column": 5, + "endLine": 171, + "endColumn": 25, + "problem": "CallSignature", + "suggest": "", + "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "severity": "ERROR" + }, + { + "line": 172, + "column": 5, + "endLine": 172, + "endColumn": 24, + "problem": "ConstructorIface", + "suggest": "", + "rule": "Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 5, + "endLine": 173, + "endColumn": 28, + "problem": "IndexMember", + "suggest": "", + "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", + "severity": "ERROR" + }, + { + "line": 173, + "column": 20, + "endLine": 173, + "endColumn": 27, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 185, + "column": 5, + "endLine": 185, + "endColumn": 25, + "problem": "CallSignature", + "suggest": "", + "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "severity": "ERROR" + }, + { + "line": 186, + "column": 5, + "endLine": 186, + "endColumn": 24, + "problem": "ConstructorIface", + "suggest": "", + "rule": "Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 5, + "endLine": 187, + "endColumn": 28, + "problem": "IndexMember", + "suggest": "", + "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", + "severity": "ERROR" + }, + { + "line": 187, + "column": 20, + "endLine": 187, + "endColumn": 27, + "problem": "UnknownType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 192, + "column": 49, + "endLine": 192, + "endColumn": 50, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 11, + "endLine": 193, + "endColumn": 12, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 11, + "endLine": 199, + "endColumn": 12, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 199, + "column": 30, + "endLine": 199, + "endColumn": 31, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 201, + "column": 25, + "endLine": 201, + "endColumn": 26, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 204, + "column": 11, + "endLine": 204, + "endColumn": 12, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 204, + "column": 12, + "endLine": 204, + "endColumn": 17, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 207, + "column": 11, + "endLine": 207, + "endColumn": 12, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 207, + "column": 31, + "endLine": 207, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 11, + "endLine": 209, + "endColumn": 12, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 209, + "column": 17, + "endLine": 209, + "endColumn": 23, + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 11, + "endLine": 211, + "endColumn": 12, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 211, + "column": 17, + "endLine": 211, + "endColumn": 23, + "problem": "TypeQuery", + "suggest": "", + "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "severity": "ERROR" + }, + { + "line": 213, + "column": 10, + "endLine": 213, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/types.ets.args.json b/ets2panda/linter/test/main/types.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/main/types.ets.args.json +++ b/ets2panda/linter/test/main/types.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/main/types.ets.autofix.json b/ets2panda/linter/test/main/types.ets.autofix.json index f0175f233bd2e110f67e43f76610b9cd3a8c2671..7eb21c4bca928fa17ded06c1872067415840c9b7 100644 --- a/ets2panda/linter/test/main/types.ets.autofix.json +++ b/ets2panda/linter/test/main/types.ets.autofix.json @@ -177,16 +177,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 56, - "column": 3, - "endLine": 56, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 57, "column": 3, @@ -229,28 +219,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 62, - "column": 3, - "endLine": 62, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "autofix": [ - { - "replacementText": "__2", - "start": 1604, - "end": 1605 - }, - { - "replacementText": "__2", - "start": 1684, - "end": 1685 - } - ], - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 67, "column": 3, diff --git a/ets2panda/linter/test/main/types.ets.json b/ets2panda/linter/test/main/types.ets.json index 0e14ef4cbd622d212a29d843e951dbbbb32955c7..9daadb68bf9f73245defa3b2bfc56b71a80ea5b2 100644 --- a/ets2panda/linter/test/main/types.ets.json +++ b/ets2panda/linter/test/main/types.ets.json @@ -144,16 +144,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 56, - "column": 3, - "endLine": 56, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 57, "column": 3, @@ -184,16 +174,6 @@ "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, - { - "line": 62, - "column": 3, - "endLine": 62, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, { "line": 67, "column": 3, diff --git a/ets2panda/linter/test/migrate/types.sts b/ets2panda/linter/test/main/types.ets.migrate.ets similarity index 67% rename from ets2panda/linter/test/migrate/types.sts rename to ets2panda/linter/test/main/types.ets.migrate.ets index 3e6cffadf2f02b790daa1352f657b51b0f3574df..07bcd2036971da481f8dc8867af57126a0f474f2 100644 --- a/ets2panda/linter/test/migrate/types.sts +++ b/ets2panda/linter/test/main/types.ets.migrate.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -13,6 +13,11 @@ * limitations under the License. */ +interface GeneratedObjectLiteralInterface_1 { + name: string; + idx: number; + handler: string; +} export function animations() { let anyvar: any = undefined; let symvar: symbol; @@ -23,13 +28,16 @@ export function animations() { const flag = false; - const status = { name: 'A', idx: 0, handler: 'foo' }; + const status: GeneratedObjectLiteralInterface_1 = { name: 'A', idx: 0, handler: 'foo' }; type Person = [string, number]; const user: Person = ['John', 32]; const age = user[1]; - type Point = { x: number; y: number }; + interface Point { + x: number; + y: number; +} type P = keyof Point; type AxeX = Point['x']; type P_NULL = P | null; @@ -40,9 +48,9 @@ export function animations() { const typeU = typeof user; - function isNumber(x: any): x is number { + let isNumber: (x: any) => x is number = (x: any): x is number => { return typeof x === 'number'; - } +}; const regex = /go*d/; @@ -51,26 +59,26 @@ export function animations() { const c = 'c'; const d = 10; -type ComputedPropertyT = { - a: string; // String-like name - 5: string; // Number-like name - [c]: string; // String-like name - [d]: string; // Number-like name -}; +interface ComputedPropertyT { + a: string; // String-like name + __5: string; // Number-like name + [c]: string; // String-like name + [d]: string; // Number-like name +} class LiteralAsPropertyName { - 2: string; + __2: string; 'Two': number; } const litAsPropName: LiteralAsPropertyName = { - 2: 'two', + __2: 'two', 'Two': 2, }; -type Dictionary = { - [key: string]: unknown; -}; +interface Dictionary { + [key: string]: unknown; +} let dict: Dictionary; function bar(key: string, val: any) { @@ -91,10 +99,10 @@ interface I2 { type IntersectionT = I1 & I2; -type DescribableFunction = { - description: string; - (someArg: number): boolean; -}; +interface DescribableFunction { + description: string; + (someArg: number): boolean; +} function callFunctionObject(fn: DescribableFunction) { console.log(fn.description + ' returned ' + fn(5)); } @@ -108,20 +116,36 @@ class G { return this.val; } } -class H extends G<{ x: 2 }> {} -const g: G<{ y: string }> = new G<{ y: 'constant' }>(); +interface GeneratedTypeLiteralInterface_1 { + x: 2; +} +class H extends G {} +interface GeneratedTypeLiteralInterface_2 { + y: string; +} +interface GeneratedTypeLiteralInterface_3 { + y: 'constant'; +} +const g: G = new G(); function generic(t: T): number { return 10; } -generic<{ z: boolean }>({ z: true }); +interface GeneratedTypeLiteralInterface_4 { + z: boolean; +} +generic({ z: true }); function typeAssertions(): void { - const num = 1; - const myCanvas = document.getElementById('main_canvas'); + const num = 1 as any; + const myCanvas = document.getElementById('main_canvas') as HTMLCanvasElement; } +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: string; +} function dynamicProperties(): void { - const x = { a: 5, b: 'text' }; + const x: GeneratedObjectLiteralInterface_2 = { a: 5, b: 'text' }; x['c'] = 100200; console.log(x['c']); @@ -135,9 +159,9 @@ function genericArrayType(): void { const y: Array = new Array(1, 2, 3); const z: number[] = [1, 2, 3]; - function arrayFunc(array: Array): Array { + let arrayFunc: (array: Array) => Array = (array: Array): Array => { return array.map((x) => x.toString()); - } +}; } class C { diff --git a/ets2panda/linter/test/migrate/types.ts.json b/ets2panda/linter/test/main/types.ets.migrate.json similarity index 51% rename from ets2panda/linter/test/migrate/types.ts.json rename to ets2panda/linter/test/main/types.ets.migrate.json index 69500549d0b9d123e719cb8a48d61c03b61fcacd..9235d4235cf4c7aca6585e704998c63f0030b9a0 100644 --- a/ets2panda/linter/test/migrate/types.ts.json +++ b/ets2panda/linter/test/main/types.ets.migrate.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2022-2024 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", @@ -15,9 +15,9 @@ ], "result": [ { - "line": 17, + "line": 22, "column": 15, - "endLine": 17, + "endLine": 22, "endColumn": 18, "problem": "AnyType", "suggest": "", @@ -25,9 +25,9 @@ "severity": "ERROR" }, { - "line": 18, + "line": 23, "column": 15, - "endLine": 18, + "endLine": 23, "endColumn": 21, "problem": "SymbolType", "suggest": "", @@ -35,9 +35,9 @@ "severity": "ERROR" }, { - "line": 19, + "line": 24, "column": 20, - "endLine": 19, + "endLine": 24, "endColumn": 27, "problem": "UnknownType", "suggest": "", @@ -45,29 +45,9 @@ "severity": "ERROR" }, { - "line": 26, - "column": 18, - "endLine": 26, - "endColumn": 19, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 32, - "column": 16, - "endLine": 32, - "endColumn": 17, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 34, + "line": 42, "column": 15, - "endLine": 34, + "endLine": 42, "endColumn": 25, "problem": "IndexedAccessType", "suggest": "", @@ -75,9 +55,9 @@ "severity": "ERROR" }, { - "line": 36, + "line": 44, "column": 24, - "endLine": 36, + "endLine": 44, "endColumn": 31, "problem": "UnknownType", "suggest": "", @@ -85,9 +65,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 45, "column": 20, - "endLine": 37, + "endLine": 45, "endColumn": 23, "problem": "AnyType", "suggest": "", @@ -95,129 +75,89 @@ "severity": "ERROR" }, { - "line": 43, - "column": 3, - "endLine": 43, - "endColumn": 11, - "problem": "LocalFunction", - "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", - "severity": "ERROR" - }, - { - "line": 43, - "column": 24, - "endLine": 43, - "endColumn": 27, + "line": 51, + "column": 21, + "endLine": 51, + "endColumn": 24, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 43, - "column": 30, - "endLine": 43, - "endColumn": 41, + "line": 51, + "column": 29, + "endLine": 51, + "endColumn": 40, "problem": "IsOperator", "suggest": "", "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", "severity": "ERROR" }, { - "line": 54, - "column": 26, - "endLine": 54, - "endColumn": 27, - "problem": "ObjectTypeLiteral", + "line": 51, + "column": 47, + "endLine": 51, + "endColumn": 50, + "problem": "AnyType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 56, - "column": 3, - "endLine": 56, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 51, + "column": 53, + "endLine": 51, + "endColumn": 64, + "problem": "IsOperator", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Type guarding is supported with \"instanceof\" and \"as\" (arkts-no-is)", "severity": "ERROR" }, { - "line": 57, - "column": 3, - "endLine": 57, - "endColumn": 6, + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 8, "problem": "ComputedPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 58, - "column": 3, - "endLine": 58, - "endColumn": 6, + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 8, "problem": "ComputedPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 62, - "column": 3, - "endLine": 62, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 3, - "endLine": 67, - "endColumn": 4, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 19, - "endLine": 71, - "endColumn": 20, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 3, - "endLine": 72, - "endColumn": 26, + "line": 80, + "column": 5, + "endLine": 80, + "endColumn": 28, "problem": "IndexMember", "suggest": "", "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", "severity": "ERROR" }, { - "line": 72, - "column": 18, - "endLine": 72, - "endColumn": 25, + "line": 80, + "column": 20, + "endLine": 80, + "endColumn": 27, "problem": "UnknownType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 76, + "line": 84, "column": 32, - "endLine": 76, + "endLine": 84, "endColumn": 35, "problem": "AnyType", "suggest": "", @@ -225,9 +165,9 @@ "severity": "ERROR" }, { - "line": 77, + "line": 85, "column": 11, - "endLine": 77, + "endLine": 85, "endColumn": 13, "problem": "InOperator", "suggest": "", @@ -235,9 +175,9 @@ "severity": "ERROR" }, { - "line": 78, + "line": 86, "column": 5, - "endLine": 78, + "endLine": 86, "endColumn": 14, "problem": "PropertyAccessByIndex", "suggest": "", @@ -245,9 +185,9 @@ "severity": "ERROR" }, { - "line": 92, + "line": 100, "column": 22, - "endLine": 92, + "endLine": 100, "endColumn": 29, "problem": "IntersectionType", "suggest": "", @@ -255,129 +195,39 @@ "severity": "ERROR" }, { - "line": 94, - "column": 28, - "endLine": 94, - "endColumn": 29, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 3, - "endLine": 96, - "endColumn": 30, + "line": 104, + "column": 5, + "endLine": 104, + "endColumn": 32, "problem": "CallSignature", "suggest": "", "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", "severity": "ERROR" }, { - "line": 111, - "column": 19, - "endLine": 111, - "endColumn": 20, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 112, - "column": 12, - "endLine": 112, - "endColumn": 13, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 112, - "column": 35, - "endLine": 112, - "endColumn": 36, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 116, + "line": 139, "column": 9, - "endLine": 116, - "endColumn": 10, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 116, - "column": 25, - "endLine": 116, - "endColumn": 26, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 9, - "endLine": 119, - "endColumn": 21, + "endLine": 139, + "endColumn": 23, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 119, - "column": 15, - "endLine": 119, - "endColumn": 21, - "problem": "TypeAssertion", - "suggest": "", - "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", - "severity": "ERROR" - }, - { - "line": 119, - "column": 16, - "endLine": 119, - "endColumn": 19, + "line": 139, + "column": 20, + "endLine": 139, + "endColumn": 23, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 120, - "column": 20, - "endLine": 120, - "endColumn": 77, - "problem": "TypeAssertion", - "suggest": "", - "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", - "severity": "ERROR" - }, - { - "line": 124, - "column": 13, - "endLine": 124, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 125, + "line": 149, "column": 3, - "endLine": 125, + "endLine": 149, "endColumn": 9, "problem": "PropertyAccessByIndex", "suggest": "", @@ -385,9 +235,9 @@ "severity": "ERROR" }, { - "line": 126, + "line": 150, "column": 15, - "endLine": 126, + "endLine": 150, "endColumn": 21, "problem": "PropertyAccessByIndex", "suggest": "", @@ -395,9 +245,9 @@ "severity": "ERROR" }, { - "line": 128, + "line": 152, "column": 12, - "endLine": 128, + "endLine": 152, "endColumn": 15, "problem": "AnyType", "suggest": "", @@ -405,19 +255,9 @@ "severity": "ERROR" }, { - "line": 138, - "column": 3, - "endLine": 138, - "endColumn": 11, - "problem": "LocalFunction", - "suggest": "", - "rule": "Nested functions are not supported (arkts-no-nested-funcs)", - "severity": "ERROR" - }, - { - "line": 157, + "line": 181, "column": 5, - "endLine": 157, + "endLine": 181, "endColumn": 23, "problem": "AnyType", "suggest": "", @@ -425,9 +265,19 @@ "severity": "ERROR" }, { - "line": 106, + "line": 70, "column": 3, - "endLine": 106, + "endLine": 70, + "endColumn": 6, + "problem": "StrictDiagnostic", + "suggest": "Property '__2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property '__2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + }, + { + "line": 114, + "column": 3, + "endLine": 114, "endColumn": 6, "problem": "StrictDiagnostic", "suggest": "Property 'val' has no initializer and is not definitely assigned in the constructor.", @@ -435,9 +285,9 @@ "severity": "ERROR" }, { - "line": 148, + "line": 172, "column": 3, - "endLine": 148, + "endLine": 172, "endColumn": 4, "problem": "StrictDiagnostic", "suggest": "Type 'undefined' is not assignable to type 'string'.", @@ -445,9 +295,9 @@ "severity": "ERROR" }, { - "line": 149, + "line": 173, "column": 18, - "endLine": 149, + "endLine": 173, "endColumn": 27, "problem": "StrictDiagnostic", "suggest": "Argument of type 'undefined' is not assignable to parameter of type 'string'.", @@ -455,9 +305,9 @@ "severity": "ERROR" }, { - "line": 150, + "line": 174, "column": 17, - "endLine": 150, + "endLine": 174, "endColumn": 26, "problem": "StrictDiagnostic", "suggest": "Argument of type 'undefined' is not assignable to parameter of type 'number'.", diff --git a/ets2panda/linter/test/main/void_operator.ets.args.json b/ets2panda/linter/test/main/void_operator.ets.args.json index aaabef1e0a30f23f303a3fcf12ad9bd1973f6aa0..8186a08902bd23b8298befe95fff67730ddf50ab 100644 --- a/ets2panda/linter/test/main/void_operator.ets.args.json +++ b/ets2panda/linter/test/main/void_operator.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/void_operator.ets.arkts2.json b/ets2panda/linter/test/main/void_operator.ets.arkts2.json index 2e051aeddd39bb38b25a34d153be24cfa8812d48..469893a2cc46f124f13220691db35854cfb50ea7 100644 --- a/ets2panda/linter/test/main/void_operator.ets.arkts2.json +++ b/ets2panda/linter/test/main/void_operator.ets.arkts2.json @@ -24,6 +24,16 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 16, + "column": 6, + "endLine": 16, + "endColumn": 7, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 18, "column": 1, @@ -44,6 +54,26 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 11, + "endLine": 20, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 22, "column": 1, @@ -64,6 +94,26 @@ "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 24, "column": 1, @@ -74,6 +124,36 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 8, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 13, + "endLine": 24, + "endColumn": 14, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 26, "column": 1, @@ -94,6 +174,16 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 28, + "column": 30, + "endLine": 28, + "endColumn": 31, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 30, "column": 37, @@ -104,6 +194,16 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 30, + "column": 42, + "endLine": 30, + "endColumn": 43, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 32, "column": 46, @@ -114,6 +214,16 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 32, + "column": 51, + "endLine": 32, + "endColumn": 52, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 34, "column": 1, @@ -134,6 +244,16 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 34, + "column": 11, + "endLine": 34, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 36, "column": 1, @@ -254,6 +374,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 55, + "column": 11, + "endLine": 55, + "endColumn": 12, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 56, "column": 3, @@ -274,6 +404,36 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 58, + "column": 12, + "endLine": 58, + "endColumn": 13, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 15, + "endLine": 58, + "endColumn": 16, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 18, + "endLine": 58, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 59, "column": 3, @@ -284,6 +444,26 @@ "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 59, + "column": 38, + "endLine": 59, + "endColumn": 39, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 44, + "endLine": 59, + "endColumn": 45, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 61, "column": 3, diff --git a/ets2panda/linter/test/main/void_operator.ets.autofix.json b/ets2panda/linter/test/main/void_operator.ets.autofix.json index 7c6a3ab711eae24e1d0610bf854bb25e054d07bd..517ba65f3afc2c9d7aaf7505eed7645eefb1a281 100644 --- a/ets2panda/linter/test/main/void_operator.ets.autofix.json +++ b/ets2panda/linter/test/main/void_operator.ets.autofix.json @@ -24,13 +24,38 @@ { "start": 605, "end": 611, - "replacementText": "(() => {\n 0;\n return undefined;\n})()" + "replacementText": "(() => {\n 0;\n return undefined;\n})()", + "line": 16, + "column": 1, + "endLine": 16, + "endColumn": 5 } ], "suggest": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 16, + "column": 6, + "endLine": 16, + "endColumn": 7, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 610, + "end": 611, + "replacementText": "0.0", + "line": 16, + "column": 6, + "endLine": 16, + "endColumn": 7 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 18, "column": 1, @@ -41,7 +66,11 @@ { "start": 614, "end": 626, - "replacementText": "(() => {\n 'hello';\n return undefined;\n})()" + "replacementText": "(() => {\n 'hello';\n return undefined;\n})()", + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 5 } ], "suggest": "", @@ -58,13 +87,59 @@ { "start": 629, "end": 641, - "replacementText": "(() => {\n (1 + 2);\n return undefined;\n})()" + "replacementText": "(() => {\n (1 + 2);\n return undefined;\n})()", + "line": 20, + "column": 1, + "endLine": 20, + "endColumn": 5 } ], "suggest": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 8, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 635, + "end": 636, + "replacementText": "1.0", + "line": 20, + "column": 7, + "endLine": 20, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 11, + "endLine": 20, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 639, + "end": 640, + "replacementText": "2.0", + "line": 20, + "column": 11, + "endLine": 20, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 22, "column": 1, @@ -75,7 +150,11 @@ { "start": 644, "end": 663, - "replacementText": "(() => {\n ({ a: 1, b: 2 });\n return undefined;\n})()" + "replacementText": "(() => {\n ({ a: 1, b: 2 });\n return undefined;\n})()", + "line": 22, + "column": 1, + "endLine": 22, + "endColumn": 5 } ], "suggest": "", @@ -92,18 +171,68 @@ { "start": 644, "end": 644, - "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n a: number;\n b: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n a: number;\n b: number;\n}\n", + "line": 22, + "column": 6, + "endLine": 22, + "endColumn": 7 }, { "start": 649, "end": 663, - "replacementText": "({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1)" + "replacementText": "({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1)", + "line": 22, + "column": 6, + "endLine": 22, + "endColumn": 7 } ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 654, + "end": 655, + "replacementText": "1.0", + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 18, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 660, + "end": 661, + "replacementText": "2.0", + "line": 22, + "column": 17, + "endLine": 22, + "endColumn": 18 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 24, "column": 1, @@ -114,13 +243,80 @@ { "start": 666, "end": 680, - "replacementText": "(() => {\n [1, 2, 3];\n return undefined;\n})()" + "replacementText": "(() => {\n [1, 2, 3];\n return undefined;\n})()", + "line": 24, + "column": 1, + "endLine": 24, + "endColumn": 5 } ], "suggest": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 8, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 672, + "end": 673, + "replacementText": "1.0", + "line": 24, + "column": 7, + "endLine": 24, + "endColumn": 8 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 11, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 675, + "end": 676, + "replacementText": "2.0", + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 11 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 13, + "endLine": 24, + "endColumn": 14, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 678, + "end": 679, + "replacementText": "3.0", + "line": 24, + "column": 13, + "endLine": 24, + "endColumn": 14 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 26, "column": 1, @@ -131,7 +327,11 @@ { "start": 683, "end": 723, - "replacementText": "(() => {\n console.log('expression evaluated');\n return undefined;\n})()" + "replacementText": "(() => {\n console.log('expression evaluated');\n return undefined;\n})()", + "line": 26, + "column": 1, + "endLine": 26, + "endColumn": 5 } ], "suggest": "", @@ -148,13 +348,38 @@ { "start": 750, "end": 756, - "replacementText": "(() => {\n 1;\n return undefined;\n})()" + "replacementText": "(() => {\n 1;\n return undefined;\n})()", + "line": 28, + "column": 25, + "endLine": 28, + "endColumn": 29 } ], "suggest": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 28, + "column": 30, + "endLine": 28, + "endColumn": 31, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 755, + "end": 756, + "replacementText": "1.0", + "line": 28, + "column": 30, + "endLine": 28, + "endColumn": 31 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 30, "column": 37, @@ -165,13 +390,38 @@ { "start": 795, "end": 801, - "replacementText": "(() => {\n 2;\n return undefined;\n})()" + "replacementText": "(() => {\n 2;\n return undefined;\n})()", + "line": 30, + "column": 37, + "endLine": 30, + "endColumn": 41 } ], "suggest": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 30, + "column": 42, + "endLine": 30, + "endColumn": 43, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 800, + "end": 801, + "replacementText": "2.0", + "line": 30, + "column": 42, + "endLine": 30, + "endColumn": 43 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 32, "column": 46, @@ -182,13 +432,38 @@ { "start": 849, "end": 855, - "replacementText": "(() => {\n 3;\n return undefined;\n})()" + "replacementText": "(() => {\n 3;\n return undefined;\n})()", + "line": 32, + "column": 46, + "endLine": 32, + "endColumn": 50 } ], "suggest": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 32, + "column": 51, + "endLine": 32, + "endColumn": 52, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 854, + "end": 855, + "replacementText": "3.0", + "line": 32, + "column": 51, + "endLine": 32, + "endColumn": 52 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 34, "column": 1, @@ -199,7 +474,11 @@ { "start": 858, "end": 869, - "replacementText": "(() => {\n void 1;\n return undefined;\n})()" + "replacementText": "(() => {\n void 1;\n return undefined;\n})()", + "line": 34, + "column": 1, + "endLine": 34, + "endColumn": 5 } ], "suggest": "", @@ -216,13 +495,38 @@ { "start": 863, "end": 869, - "replacementText": "(() => {\n 1;\n return undefined;\n})()" + "replacementText": "(() => {\n 1;\n return undefined;\n})()", + "line": 34, + "column": 6, + "endLine": 34, + "endColumn": 10 } ], "suggest": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 34, + "column": 11, + "endLine": 34, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 868, + "end": 869, + "replacementText": "1.0", + "line": 34, + "column": 11, + "endLine": 34, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 36, "column": 1, @@ -233,7 +537,11 @@ { "start": 872, "end": 914, - "replacementText": "(() => {\n (function () {\n console.log('foo');\n });\n return undefined;\n})()" + "replacementText": "(() => {\n (function () {\n console.log('foo');\n });\n return undefined;\n})()", + "line": 36, + "column": 1, + "endLine": 36, + "endColumn": 5 } ], "suggest": "", @@ -250,7 +558,11 @@ { "start": 877, "end": 914, - "replacementText": "(() => {\n console.log('foo');\n})" + "replacementText": "(() => {\n console.log('foo');\n})", + "line": 36, + "column": 6, + "endLine": 38, + "endColumn": 2 } ], "suggest": "", @@ -267,7 +579,11 @@ { "start": 917, "end": 962, - "replacementText": "(() => {\n (function () {\n console.log(\"bar!\");\n })();\n return undefined;\n})()" + "replacementText": "(() => {\n (function () {\n console.log(\"bar!\");\n })();\n return undefined;\n})()", + "line": 40, + "column": 1, + "endLine": 40, + "endColumn": 5 } ], "suggest": "", @@ -284,7 +600,11 @@ { "start": 922, "end": 960, - "replacementText": "(() => {\n console.log(\"bar!\");\n})" + "replacementText": "(() => {\n console.log(\"bar!\");\n})", + "line": 40, + "column": 6, + "endLine": 42, + "endColumn": 2 } ], "suggest": "", @@ -301,7 +621,11 @@ { "start": 965, "end": 1012, - "replacementText": "(() => {\n (function () {\n console.log('baz!');\n })();\n return undefined;\n})()" + "replacementText": "(() => {\n (function () {\n console.log('baz!');\n })();\n return undefined;\n})()", + "line": 44, + "column": 1, + "endLine": 44, + "endColumn": 5 } ], "suggest": "", @@ -318,7 +642,11 @@ { "start": 971, "end": 1009, - "replacementText": "() => {\n console.log('baz!');\n}" + "replacementText": "() => {\n console.log('baz!');\n}", + "line": 44, + "column": 7, + "endLine": 46, + "endColumn": 2 } ], "suggest": "", @@ -335,7 +663,11 @@ { "start": 1015, "end": 1028, - "replacementText": "(() => {\n (class {\n });\n return undefined;\n})()" + "replacementText": "(() => {\n (class {\n });\n return undefined;\n})()", + "line": 48, + "column": 1, + "endLine": 48, + "endColumn": 5 } ], "suggest": "", @@ -362,7 +694,11 @@ { "start": 1031, "end": 1046, - "replacementText": "(() => {\n (class {\n });\n return undefined;\n})()" + "replacementText": "(() => {\n (class {\n });\n return undefined;\n})()", + "line": 50, + "column": 1, + "endLine": 50, + "endColumn": 5 } ], "suggest": "", @@ -389,7 +725,11 @@ { "start": 1049, "end": 1064, - "replacementText": "(() => {\n (() => { });\n return undefined;\n})()" + "replacementText": "(() => {\n (() => { });\n return undefined;\n})()", + "line": 52, + "column": 1, + "endLine": 52, + "endColumn": 5 } ], "suggest": "", @@ -406,7 +746,32 @@ { "start": 1090, "end": 1095, - "replacementText": "a: number = 1" + "replacementText": "a: number = 1", + "line": 55, + "column": 7, + "endLine": 55, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 11, + "endLine": 55, + "endColumn": 12, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1094, + "end": 1095, + "replacementText": "1.0", + "line": 55, + "column": 11, + "endLine": 55, + "endColumn": 12 } ], "suggest": "", @@ -423,7 +788,11 @@ { "start": 1099, "end": 1107, - "replacementText": "(() => {\n a++;\n return undefined;\n})()" + "replacementText": "(() => {\n a++;\n return undefined;\n})()", + "line": 56, + "column": 3, + "endLine": 56, + "endColumn": 7 } ], "suggest": "", @@ -440,7 +809,74 @@ { "start": 1116, "end": 1129, - "replacementText": "b: number[] = [1, 2, 3]" + "replacementText": "b: number[] = [1, 2, 3]", + "line": 58, + "column": 7, + "endLine": 58, + "endColumn": 20 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 12, + "endLine": 58, + "endColumn": 13, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1121, + "end": 1122, + "replacementText": "1.0", + "line": 58, + "column": 12, + "endLine": 58, + "endColumn": 13 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 15, + "endLine": 58, + "endColumn": 16, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1124, + "end": 1125, + "replacementText": "2.0", + "line": 58, + "column": 15, + "endLine": 58, + "endColumn": 16 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 18, + "endLine": 58, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1127, + "end": 1128, + "replacementText": "3.0", + "line": 58, + "column": 18, + "endLine": 58, + "endColumn": 19 } ], "suggest": "", @@ -457,13 +893,59 @@ { "start": 1133, "end": 1177, - "replacementText": "(() => {\n console.log(b.filter(x => x % 2 !== 0));\n return undefined;\n})()" + "replacementText": "(() => {\n console.log(b.filter(x => x % 2 !== 0));\n return undefined;\n})()", + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 7 } ], "suggest": "", "rule": "\"void\" operator is not supported (arkts-no-void-operator)", "severity": "ERROR" }, + { + "line": 59, + "column": 38, + "endLine": 59, + "endColumn": 39, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1168, + "end": 1169, + "replacementText": "2.0", + "line": 59, + "column": 38, + "endLine": 59, + "endColumn": 39 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 44, + "endLine": 59, + "endColumn": 45, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1174, + "end": 1175, + "replacementText": "0.0", + "line": 59, + "column": 44, + "endLine": 59, + "endColumn": 45 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 61, "column": 3, @@ -474,7 +956,11 @@ { "start": 1184, "end": 1229, - "replacementText": "(() => {\n (function () {\n console.log('foo');\n });\n return undefined;\n})()" + "replacementText": "(() => {\n (function () {\n console.log('foo');\n });\n return undefined;\n})()", + "line": 61, + "column": 3, + "endLine": 61, + "endColumn": 7 } ], "suggest": "", @@ -491,7 +977,11 @@ { "start": 1189, "end": 1229, - "replacementText": "(() => {\n console.log('foo');\n})" + "replacementText": "(() => {\n console.log('foo');\n})", + "line": 61, + "column": 8, + "endLine": 63, + "endColumn": 4 } ], "suggest": "", @@ -508,7 +998,11 @@ { "start": 1234, "end": 1288, - "replacementText": "(() => {\n (function localFun() {\n console.log('foo');\n });\n return undefined;\n})()" + "replacementText": "(() => {\n (function localFun() {\n console.log('foo');\n });\n return undefined;\n})()", + "line": 65, + "column": 3, + "endLine": 65, + "endColumn": 7 } ], "suggest": "", @@ -525,7 +1019,11 @@ { "start": 1239, "end": 1288, - "replacementText": "(() => {\n console.log('foo');\n})" + "replacementText": "(() => {\n console.log('foo');\n})", + "line": 65, + "column": 8, + "endLine": 67, + "endColumn": 4 } ], "suggest": "", @@ -542,7 +1040,11 @@ { "start": 1295, "end": 1308, - "replacementText": "(() => {\n (class {\n });\n return undefined;\n})()" + "replacementText": "(() => {\n (class {\n });\n return undefined;\n})()", + "line": 69, + "column": 3, + "endLine": 69, + "endColumn": 7 } ], "suggest": "", @@ -569,7 +1071,11 @@ { "start": 1313, "end": 1336, - "replacementText": "(() => {\n (class localClass {\n });\n return undefined;\n})()" + "replacementText": "(() => {\n (class localClass {\n });\n return undefined;\n})()", + "line": 71, + "column": 3, + "endLine": 71, + "endColumn": 7 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/void_operator.ets.migrate.ets b/ets2panda/linter/test/main/void_operator.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..72f556c1fa68db896507fd69939ecd6bcda3030f --- /dev/null +++ b/ets2panda/linter/test/main/void_operator.ets.migrate.ets @@ -0,0 +1,149 @@ +/* + * 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.0; + return undefined; +})(); + +(() => { + 'hello'; + return undefined; +})(); + +(() => { + (1.0 + 2.0); + return undefined; +})(); + +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: number; +} +(() => { + ({ a: 1.0, b: 2.0 } as GeneratedObjectLiteralInterface_1); + return undefined; +})(); + +(() => { + [1.0, 2.0, 3.0]; + return undefined; +})(); + +(() => { + console.log('expression evaluated'); + return undefined; +})(); + +const undefined_value = (() => { + 1.0; + return undefined; +})(); + +const undefined_value2: undefined = (() => { + 2.0; + return undefined; +})(); + +const undefined_value3: number | undefined = (() => { + 3.0; + return undefined; +})(); + +(() => { + (() => { + 1.0; + return undefined; +})(); + return undefined; +})(); + +(() => { + (() => { + console.log('foo'); +}); + return undefined; +})(); + +(() => { + (() => { + console.log("bar!"); +})(); + return undefined; +})(); + +(() => { + (() => { + console.log('baz!'); +})(); + return undefined; +})(); + +(() => { + (class { + }); + return undefined; +})(); + +(() => { + (class { + }); + return undefined; +})(); + +(() => { + (() => { }); + return undefined; +})(); + +function foo() { + let a: number = 1.0; + (() => { + a++; + return undefined; +})(); + + let b: number[] = [1.0, 2.0, 3.0]; + (() => { + console.log(b.filter(x => x % 2.0 !== 0.0)); + return undefined; +})(); + + (() => { + (() => { + console.log('foo'); +}); + return undefined; +})(); + + (() => { + (() => { + console.log('foo'); +}); + return undefined; +})(); + + (() => { + (class { + }); + return undefined; +})(); + + (() => { + (class localClass { + }); + return undefined; +})(); +} diff --git a/ets2panda/linter/test/main/void_operator.ets.migrate.json b/ets2panda/linter/test/main/void_operator.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..12de68ea372eb83f2257518b738f63f6fa6fa397 --- /dev/null +++ b/ets2panda/linter/test/main/void_operator.ets.migrate.json @@ -0,0 +1,58 @@ +{ + "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": 95, + "column": 6, + "endLine": 95, + "endColumn": 11, + "problem": "ClassExpression", + "suggest": "", + "rule": "Class literals are not supported (arkts-no-class-literals)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 6, + "endLine": 101, + "endColumn": 11, + "problem": "ClassExpression", + "suggest": "", + "rule": "Class literals are not supported (arkts-no-class-literals)", + "severity": "ERROR" + }, + { + "line": 139, + "column": 6, + "endLine": 139, + "endColumn": 11, + "problem": "ClassExpression", + "suggest": "", + "rule": "Class literals are not supported (arkts-no-class-literals)", + "severity": "ERROR" + }, + { + "line": 145, + "column": 6, + "endLine": 145, + "endColumn": 11, + "problem": "ClassExpression", + "suggest": "", + "rule": "Class literals are not supported (arkts-no-class-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/worker_module.sts b/ets2panda/linter/test/main/worker_module.ets similarity index 100% rename from ets2panda/linter/test/main/worker_module.sts rename to ets2panda/linter/test/main/worker_module.ets diff --git a/ets2panda/linter/test/main/worker_module.ets.args.json b/ets2panda/linter/test/main/worker_module.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/main/worker_module.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/worker_module.ets.arkts2.json b/ets2panda/linter/test/main/worker_module.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..535d022afdc58f18c353c35b8ca2d43213f138e0 --- /dev/null +++ b/ets2panda/linter/test/main/worker_module.ets.arkts2.json @@ -0,0 +1,148 @@ +{ + "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": 10, + "endLine": 16, + "endColumn": 16, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 10, + "endLine": 18, + "endColumn": 16, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 20, + "endLine": 18, + "endColumn": 31, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 16, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 20, + "endLine": 20, + "endColumn": 29, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 10, + "endLine": 24, + "endColumn": 16, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 18, + "endLine": 28, + "endColumn": 24, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 44, + "endLine": 28, + "endColumn": 50, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 23, + "endLine": 30, + "endColumn": 34, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 23, + "endLine": 32, + "endColumn": 32, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 16, + "endLine": 34, + "endColumn": 27, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 18, + "endLine": 36, + "endColumn": 29, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 49, + "endLine": 36, + "endColumn": 60, + "problem": "NoNeedStdlibWorker", + "suggest": "", + "rule": "Worker are not supported(arkts-no-need-stdlib-worker)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/worker_module.ets.json b/ets2panda/linter/test/main/worker_module.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/worker_module.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/migrate/func_return_type.ts.migrate.json b/ets2panda/linter/test/migrate/func_return_type.ts.migrate.json deleted file mode 100644 index 567dd757ee06a50bc311a9a0a0bb0f09817bef33..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/func_return_type.ts.migrate.json +++ /dev/null @@ -1,264 +0,0 @@ -{ - "result": [ - { - "line": 16, - "column": 10, - "endLine": 16, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 10, - "endLine": 23, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 10, - "endLine": 33, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 10, - "endLine": 40, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 10, - "endLine": 46, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 54, - "column": 10, - "endLine": 54, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 10, - "endLine": 57, - "endColumn": 11, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 57, - "column": 15, - "endLine": 57, - "endColumn": 18, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 62, - "column": 12, - "endLine": 64, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 12, - "endLine": 67, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 12, - "endLine": 71, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 73, - "column": 12, - "endLine": 75, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 76, - "column": 12, - "endLine": 78, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 12, - "endLine": 82, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 12, - "endLine": 82, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 86, - "column": 12, - "endLine": 88, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 97, - "column": 12, - "endLine": 99, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 104, - "column": 12, - "endLine": 106, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 110, - "column": 3, - "endLine": 110, - "endColumn": 4, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 114, - "column": 3, - "endLine": 114, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 122, - "column": 3, - "endLine": 122, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 126, - "column": 3, - "endLine": 126, - "endColumn": 5, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 131, - "column": 10, - "endLine": 131, - "endColumn": 30, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 135, - "column": 18, - "endLine": 135, - "endColumn": 40, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 139, - "column": 3, - "endLine": 139, - "endColumn": 10, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - }, - { - "line": 144, - "column": 3, - "endLine": 144, - "endColumn": 7, - "problem": "LimitedReturnTypeInference", - "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/function_expression.ts.args.json b/ets2panda/linter/test/migrate/function_expression.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/function_expression.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 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": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.args.json b/ets2panda/linter/test/migrate/literals_as_prop_names.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 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": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.args.json b/ets2panda/linter/test/migrate/object_literals_autofixes.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 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": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.migrate.json b/ets2panda/linter/test/migrate/object_literals_autofixes.ts.migrate.json deleted file mode 100644 index 8757f86ed2a8cf7900b5451b1ebb13a44b2e64a4..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/object_literals_autofixes.ts.migrate.json +++ /dev/null @@ -1,694 +0,0 @@ -{ - "result": [ - { - "line": 29, - "column": 14, - "endLine": 29, - "endColumn": 15, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 33, - "column": 12, - "endLine": 33, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 12, - "endLine": 34, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 7, - "endLine": 35, - "endColumn": 25, - "problem": "DefiniteAssignment", - "suggest": "", - "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", - "severity": "WARNING" - }, - { - "line": 35, - "column": 13, - "endLine": 35, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 12, - "endLine": 36, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 46, - "column": 12, - "endLine": 46, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 51, - "column": 8, - "endLine": 51, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 52, - "column": 8, - "endLine": 52, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 53, - "column": 8, - "endLine": 53, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 58, - "column": 12, - "endLine": 58, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 8, - "endLine": 61, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 63, - "column": 8, - "endLine": 63, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 12, - "endLine": 67, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 67, - "column": 29, - "endLine": 67, - "endColumn": 30, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 68, - "column": 12, - "endLine": 68, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 9, - "endLine": 71, - "endColumn": 10, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 12, - "endLine": 72, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 72, - "column": 27, - "endLine": 72, - "endColumn": 28, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 77, - "column": 10, - "endLine": 77, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 78, - "column": 11, - "endLine": 78, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 79, - "column": 5, - "endLine": 79, - "endColumn": 24, - "problem": "DefiniteAssignment", - "suggest": "", - "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", - "severity": "WARNING" - }, - { - "line": 79, - "column": 11, - "endLine": 79, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 80, - "column": 11, - "endLine": 80, - "endColumn": 12, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 10, - "endLine": 81, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 81, - "column": 21, - "endLine": 81, - "endColumn": 22, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 84, - "column": 17, - "endLine": 84, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 85, - "column": 17, - "endLine": 85, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 90, - "column": 22, - "endLine": 90, - "endColumn": 23, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 91, - "column": 19, - "endLine": 91, - "endColumn": 42, - "problem": "DestructuringParameter", - "suggest": "", - "rule": "Destructuring parameter declarations are not supported (arkts-no-destruct-params)", - "severity": "ERROR" - }, - { - "line": 91, - "column": 28, - "endLine": 91, - "endColumn": 29, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 95, - "column": 13, - "endLine": 95, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 96, - "column": 13, - "endLine": 96, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 99, - "column": 17, - "endLine": 99, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 13, - "endLine": 102, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 27, - "endLine": 102, - "endColumn": 28, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 102, - "column": 41, - "endLine": 102, - "endColumn": 42, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 105, - "column": 12, - "endLine": 105, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 105, - "column": 14, - "endLine": 105, - "endColumn": 15, - "problem": "LiteralAsPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 106, - "column": 13, - "endLine": 106, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 106, - "column": 15, - "endLine": 106, - "endColumn": 18, - "problem": "ComputedPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 107, - "column": 13, - "endLine": 107, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 107, - "column": 15, - "endLine": 107, - "endColumn": 25, - "problem": "ComputedPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 109, - "column": 15, - "endLine": 109, - "endColumn": 18, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 110, - "column": 13, - "endLine": 110, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 113, - "column": 13, - "endLine": 113, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 114, - "column": 13, - "endLine": 114, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 114, - "column": 15, - "endLine": 114, - "endColumn": 20, - "problem": "SpreadOperator", - "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", - "severity": "ERROR" - }, - { - "line": 115, - "column": 13, - "endLine": 115, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 117, - "column": 13, - "endLine": 117, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 120, - "column": 8, - "endLine": 120, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 130, - "column": 14, - "endLine": 130, - "endColumn": 15, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 131, - "column": 14, - "endLine": 131, - "endColumn": 15, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 132, - "column": 14, - "endLine": 132, - "endColumn": 15, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 134, - "column": 22, - "endLine": 134, - "endColumn": 23, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 135, - "column": 35, - "endLine": 135, - "endColumn": 36, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 136, - "column": 14, - "endLine": 136, - "endColumn": 15, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 139, - "column": 14, - "endLine": 139, - "endColumn": 15, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 141, - "column": 14, - "endLine": 141, - "endColumn": 15, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 141, - "column": 19, - "endLine": 141, - "endColumn": 29, - "problem": "ClassAsObject", - "suggest": "", - "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", - "severity": "WARNING" - }, - { - "line": 145, - "column": 26, - "endLine": 145, - "endColumn": 29, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 145, - "column": 33, - "endLine": 145, - "endColumn": 34, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 151, - "column": 35, - "endLine": 151, - "endColumn": 38, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 151, - "column": 42, - "endLine": 151, - "endColumn": 43, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 160, - "column": 35, - "endLine": 160, - "endColumn": 38, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 160, - "column": 42, - "endLine": 160, - "endColumn": 43, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 164, - "column": 5, - "endLine": 164, - "endColumn": 10, - "problem": "ComputedPropertyName", - "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", - "severity": "ERROR" - }, - { - "line": 170, - "column": 28, - "endLine": 170, - "endColumn": 29, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 171, - "column": 13, - "endLine": 171, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/parameter_properties.ts.args.json b/ets2panda/linter/test/migrate/parameter_properties.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/parameter_properties.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 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": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/parameter_properties.ts.migrate.json b/ets2panda/linter/test/migrate/parameter_properties.ts.migrate.json deleted file mode 100644 index ea6dab7c47ca3563e1141bb5d9375d46fa8b6c47..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/parameter_properties.ts.migrate.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "result": [ - { - "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 11, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 5, - "endLine": 19, - "endColumn": 14, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 20, - "column": 5, - "endLine": 20, - "endColumn": 12, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 26, - "endLine": 34, - "endColumn": 32, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 60, - "endLine": 34, - "endColumn": 67, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 43, - "column": 15, - "endLine": 43, - "endColumn": 21, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 43, - "column": 25, - "endLine": 43, - "endColumn": 28, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 15, - "endLine": 47, - "endColumn": 21, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 33, - "endLine": 47, - "endColumn": 40, - "problem": "ParameterProperties", - "suggest": "", - "rule": "Declaring fields in \"constructor\" is not supported (arkts-no-ctor-prop-decls)", - "severity": "ERROR" - }, - { - "line": 47, - "column": 44, - "endLine": 47, - "endColumn": 45, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/type_literals.ts.args.json b/ets2panda/linter/test/migrate/type_literals.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/type_literals.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 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": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/types.ts.args.json b/ets2panda/linter/test/migrate/types.ts.args.json deleted file mode 100644 index 66b623df60053ad3ac340dcb82ff7eaff3d9a8dc..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/types.ts.args.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2024 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": { - "migrate": "" - } -} diff --git a/ets2panda/linter/test/migrate/void_operator.ts.migrate.json b/ets2panda/linter/test/migrate/void_operator.ts.migrate.json deleted file mode 100644 index e1644e2d8d5f78ed1b06f5be8b157586408ce8fd..0000000000000000000000000000000000000000 --- a/ets2panda/linter/test/migrate/void_operator.ts.migrate.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "result": [ - { - "line": 22, - "column": 6, - "endLine": 22, - "endColumn": 7, - "problem": "ObjectLiteralNoContextType", - "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 6, - "endLine": 38, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 40, - "column": 6, - "endLine": 42, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 44, - "column": 7, - "endLine": 46, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 48, - "column": 6, - "endLine": 48, - "endColumn": 11, - "problem": "ClassExpression", - "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", - "severity": "ERROR" - }, - { - "line": 50, - "column": 7, - "endLine": 50, - "endColumn": 12, - "problem": "ClassExpression", - "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", - "severity": "ERROR" - }, - { - "line": 61, - "column": 8, - "endLine": 63, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 65, - "column": 8, - "endLine": 67, - "endColumn": 4, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 69, - "column": 8, - "endLine": 69, - "endColumn": 13, - "problem": "ClassExpression", - "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", - "severity": "ERROR" - }, - { - "line": 71, - "column": 8, - "endLine": 71, - "endColumn": 13, - "problem": "ClassExpression", - "suggest": "", - "rule": "Class literals are not supported (arkts-no-class-literals)", - "severity": "ERROR" - } - ] -} \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets b/ets2panda/linter/test/migration/mixed_problems.ets new file mode 100644 index 0000000000000000000000000000000000000000..617d37acf69f2724ad293882a5b967e7062b6e28 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.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. + */ + +// destructuring declaration + untyped object literal +let { a, b } = { a: 1, b: 2 }; + +// destructuring declaration + untyped object literal + type literal +let { a2, b2 } = { + a2: 1, + b2: { + c2: 1, + d2: '2' + } as { c2: number, d2: string } +}; + +// untyped object literal + 'in' operator +console.log('a' in { a: 1, b: 2 }); + +// untyped object literal + var declaration + literal as property name + function expression +var fun = function() { + var o = { + 'a': 1, + 'b': 2 + }; + + var o2 = { + 'c': 3, + 'd': 4, + 5: { + x1: 10, + x2: 20 + } + }; +}; + +// private identifier + definite assignment +class A { + #a!: number; +} + +// type assertion + as 'const' +const t = 'hello'; \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.args.json b/ets2panda/linter/test/migration/mixed_problems.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..65eb728b5df03fbf77be432348751a6c1518904c --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.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": { + "autofix": "", + "migrate": "" + } +} diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.autofix.json b/ets2panda/linter/test/migration/mixed_problems.ets.autofix.json new file mode 100644 index 0000000000000000000000000000000000000000..57f25df2f307782186bdc847598ce6a21d60dae0 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets.autofix.json @@ -0,0 +1,303 @@ +{ + "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": 17, + "column": 5, + "endLine": 17, + "endColumn": 30, + "problem": "DestructuringDeclaration", + "autofix": [ + { + "replacementText": "GeneratedDestructObj_1", + "start": 663, + "end": 671 + }, + { + "replacementText": "\nlet a = GeneratedDestructObj_1.a;\nlet b = GeneratedDestructObj_1.b;\n", + "start": 689, + "end": 689 + } + ], + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 26, + "endColumn": 2, + "problem": "DestructuringDeclaration", + "autofix": [ + { + "replacementText": "GeneratedDestructObj_2", + "start": 764, + "end": 774 + }, + { + "replacementText": "\nlet a2 = GeneratedDestructObj_2.a2;\nlet b2 = GeneratedDestructObj_2.b2;\n", + "start": 869, + "end": 869 + } + ], + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 18, + "endLine": 20, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 9, + "endLine": 22, + "endColumn": 10, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 11, + "problem": "ObjectTypeLiteral", + "autofix": [ + { + "start": 760, + "end": 760, + "replacementText": "interface GeneratedTypeLiteralInterface_1 {\n c2: number;\n d2: string;\n}\n" + }, + { + "start": 840, + "end": 866, + "replacementText": "GeneratedTypeLiteralInterface_1" + } + ], + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 17, + "endLine": 29, + "endColumn": 19, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 20, + "endLine": 29, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 913, + "end": 913, + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n a: number;\n b: number;\n}\n" + }, + { + "start": 932, + "end": 946, + "replacementText": "({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1)" + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 4, + "problem": "VarDeclaration", + "autofix": [ + { + "start": 1043, + "end": 1238, + "replacementText": "let fun = function () {\n var o = {\n 'a': 1,\n 'b': 2\n };\n var o2 = {\n 'c': 3,\n 'd': 4,\n 5: {\n x1: 10,\n x2: 20\n }\n };\n}" + } + ], + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 11, + "endLine": 46, + "endColumn": 2, + "problem": "FunctionExpression", + "autofix": [ + { + "start": 1053, + "end": 1238, + "replacementText": "() => {\n var o = {\n 'a': 1,\n 'b': 2\n };\n var o2 = {\n 'c': 3,\n 'd': 4,\n 5: {\n x1: 10,\n x2: 20\n }\n };\n}" + } + ], + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 8, + "problem": "VarDeclaration", + "autofix": [ + { + "start": 1071, + "end": 1117, + "replacementText": "let o = {\n 'a': 1,\n 'b': 2\n}" + } + ], + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 13, + "endLine": 33, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 8, + "problem": "VarDeclaration", + "autofix": [ + { + "start": 1124, + "end": 1235, + "replacementText": "let o2 = {\n 'c': 3,\n 'd': 4,\n 5: {\n x1: 10,\n x2: 20\n }\n}" + } + ], + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 9, + "endLine": 41, + "endColumn": 10, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "autofix": [ + { + "start": 1043, + "end": 1043, + "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n x1: number;\n x2: number;\n}\n" + }, + { + "start": 1178, + "end": 1228, + "replacementText": "({ x1: 10,\n x2: 20 } as GeneratedObjectLiteralInterface_2)" + } + ], + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 17, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 7, + "problem": "PrivateIdentifier", + "autofix": [ + { + "start": 1299, + "end": 1311, + "replacementText": "private a!: number;" + } + ], + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 27, + "endLine": 54, + "endColumn": 18, + "problem": "ConstAssertion", + "suggest": "", + "rule": "\"as const\" assertions are not supported (arkts-no-as-const)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.json b/ets2panda/linter/test/migration/mixed_problems.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..dbb09ef3dc5bcac13242fb8caaa6b0e6f809b349 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets.json @@ -0,0 +1,208 @@ +{ + "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": 17, + "column": 5, + "endLine": 17, + "endColumn": 30, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 16, + "endLine": 17, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 5, + "endLine": 26, + "endColumn": 2, + "problem": "DestructuringDeclaration", + "suggest": "", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 18, + "endLine": 20, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 9, + "endLine": 22, + "endColumn": 10, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 11, + "problem": "ObjectTypeLiteral", + "suggest": "", + "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 17, + "endLine": 29, + "endColumn": 19, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 20, + "endLine": 29, + "endColumn": 21, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 1, + "endLine": 32, + "endColumn": 4, + "problem": "VarDeclaration", + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 11, + "endLine": 46, + "endColumn": 2, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 8, + "problem": "VarDeclaration", + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 13, + "endLine": 33, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 5, + "endLine": 38, + "endColumn": 8, + "problem": "VarDeclaration", + "suggest": "", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 9, + "endLine": 41, + "endColumn": 10, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 12, + "endLine": 41, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 17, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 50, + "column": 5, + "endLine": 50, + "endColumn": 7, + "problem": "PrivateIdentifier", + "suggest": "", + "rule": "Private \"#\" identifiers are not supported (arkts-no-private-identifiers)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 27, + "endLine": 54, + "endColumn": 18, + "problem": "ConstAssertion", + "suggest": "", + "rule": "\"as const\" assertions are not supported (arkts-no-as-const)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.migrate.ets b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1ffb82d2ebf46615bb1be1ef8704f1e58d5e95c7 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.ets @@ -0,0 +1,77 @@ +/* + * 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. + */ + +// destructuring declaration + untyped object literal +interface GeneratedObjectLiteralInterface_2 { + a: number; + b: number; +} +let GeneratedDestructObj_1: GeneratedObjectLiteralInterface_2 = { a: 1, b: 2 }; +let a = GeneratedDestructObj_1.a; +let b = GeneratedDestructObj_1.b; + + +// destructuring declaration + untyped object literal + type literal +interface GeneratedTypeLiteralInterface_1 { + c2: number; + d2: string; +} +interface GeneratedObjectLiteralInterface_3 { + a2: number; + b2: GeneratedTypeLiteralInterface_1; +} +let GeneratedDestructObj_2: GeneratedObjectLiteralInterface_3 = { + a2: 1, + b2: { + c2: 1, + d2: '2' + } as GeneratedTypeLiteralInterface_1 +}; +let a2 = GeneratedDestructObj_2.a2; +let b2 = GeneratedDestructObj_2.b2; + + +// untyped object literal + 'in' operator +interface GeneratedObjectLiteralInterface_1 { + a: number; + b: number; +} +console.log('a' in ({ a: 1, b: 2 } as GeneratedObjectLiteralInterface_1)); + +// untyped object literal + var declaration + literal as property name + function expression +interface GeneratedObjectLiteralInterface_4 { + x1: number; + x2: number; +} +let fun = () => { + let o = { + 'a': 1, + 'b': 2 +}; + let o2 = { + 'c': 3, + 'd': 4, + 5: ({ x1: 10, + x2: 20 } as GeneratedObjectLiteralInterface_4) +}; +}; + +// private identifier + definite assignment +class A { + private a!: number; +} + +// type assertion + as 'const' +const t = 'hello'; \ No newline at end of file diff --git a/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..bfb7a82f089b08ec604a536fff2ac426e2896312 --- /dev/null +++ b/ets2panda/linter/test/migration/mixed_problems.ets.migrate.json @@ -0,0 +1,78 @@ +{ + "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": 51, + "column": 17, + "endLine": 51, + "endColumn": 19, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 13, + "endLine": 59, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 63, + "column": 14, + "endLine": 63, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 5, + "endLine": 66, + "endColumn": 6, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 5, + "endLine": 73, + "endColumn": 24, + "problem": "DefiniteAssignment", + "suggest": "", + "rule": "Definite assignment assertions are not supported (arkts-no-definite-assignment)", + "severity": "WARNING" + }, + { + "line": 77, + "column": 27, + "endLine": 77, + "endColumn": 18, + "problem": "ConstAssertion", + "suggest": "", + "rule": "\"as const\" assertions are not supported (arkts-no-as-const)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets b/ets2panda/linter/test/ohmurl/ohmurl_import.ets index 4edb2cfed5fd10e6a64ea355b3cf77167eeaeeba..c5fd4aab8d8a7c47751ceb736019f9f4be56740c 100644 --- a/ets2panda/linter/test/ohmurl/ohmurl_import.ets +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets @@ -14,8 +14,10 @@ */ import { MainPage } from "library/ets/components/MainPage" // Should fail on ArkTS 1.2 - import { Something1 } from "library/ets/src/main/components/Something1" // Valid - import { Something2 } from "ets/components/Something2" // Should Fail but no auto complete + import { Something1 } from "library/src/main/ets/components/Something1" // Valid + import { Something2 } from "ets/components/Something2" // Should Fail import { Valid } from "normal/path/to/import/MainPage" // Valid import { RelativeImport } from "../components/MainPage" // Valid - + import { Something } from "ets/pages/test1" //should fail + import { SomethingElse } from "ets/pages/testing"; //should fail + import { Test } from "module/ets/random/test"; //should fail diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.args.json b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.args.json index db044a3dff705d84beabaa2d833b7cf1b2debd01..a89d885810708ad03d96e3e14bb6590efd1a7547 100644 --- a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.args.json +++ b/ets2panda/linter/test/ohmurl/ohmurl_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/ohmurl/ohmurl_import.ets.arkts2.json b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json index 773cd321bd13e44de8a9c2014b818aff0a42d7f4..04102fd8c9c1695de263ff569ff15438f1733240 100644 --- a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json @@ -33,6 +33,36 @@ "suggest": "", "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 45, + "problem": "OhmUrlFullPath", + "suggest": "", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 52, + "problem": "OhmUrlFullPath", + "suggest": "", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 2, + "endLine": 23, + "endColumn": 48, + "problem": "OhmUrlFullPath", + "suggest": "", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "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 0e40d65227a39411c16fb6b20001bff95d24cde0..dee154796f4b5da718f83077fbfc2a4fc38b6984 100644 --- a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json @@ -14,7 +14,7 @@ "limitations under the License." ], "result": [ - { + { "line": 16, "column": 2, "endLine": 16, @@ -37,6 +37,64 @@ "endLine": 18, "endColumn": 56, "problem": "OhmUrlFullPath", + "autofix": [ + { + "start": 808, + "end": 835, + "replacementText": "'entry/src/main/ets/components/Something2'" + } + ], + "suggest": "", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 45, + "problem": "OhmUrlFullPath", + "autofix": [ + { + "start": 1009, + "end": 1026, + "replacementText": "'entry/src/main/ets/pages/test1'" + } + ], + "suggest": "", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 2, + "endLine": 22, + "endColumn": 52, + "problem": "OhmUrlFullPath", + "autofix": [ + { + "start": 1072, + "end": 1091, + "replacementText": "'entry/src/main/ets/pages/testing'" + } + ], + "suggest": "", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 2, + "endLine": 23, + "endColumn": 48, + "problem": "OhmUrlFullPath", + "autofix": [ + { + "start": 1129, + "end": 1153, + "replacementText": "'module/src/main/ets/random/test'" + } + ], "suggest": "", "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", "severity": "ERROR" diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.ets b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..1d67bf9461153ad005437a1f1c5c0e0454039bc6 --- /dev/null +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ + + import { MainPage } from 'library/src/main/ets/components/MainPage' // Should fail on ArkTS 1.2 + import { Something1 } from "library/src/main/ets/components/Something1" // Valid + import { Something2 } from 'entry/src/main/ets/components/Something2' // Should Fail + import { Valid } from "normal/path/to/import/MainPage" // Valid + import { RelativeImport } from "../components/MainPage" // Valid + import { Something } from 'entry/src/main/ets/pages/test1' //should fail + import { SomethingElse } from 'entry/src/main/ets/pages/testing'; //should fail + import { Test } from 'module/src/main/ets/random/test'; //should fail diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.json b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/ohmurl/ohmurl_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 diff --git a/ets2panda/linter/test/rules/rule1.ets.args.json b/ets2panda/linter/test/rules/rule1.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule1.ets.args.json +++ b/ets2panda/linter/test/rules/rule1.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule1.ets.autofix.json b/ets2panda/linter/test/rules/rule1.ets.autofix.json index 7a9e068c21ccc994a440185452e32954b1e35a3a..4418693726fc8d2fee1ef9a555ecaf70b8925a1e 100644 --- a/ets2panda/linter/test/rules/rule1.ets.autofix.json +++ b/ets2panda/linter/test/rules/rule1.ets.autofix.json @@ -37,18 +37,6 @@ "endLine": 16, "endColumn": 10, "problem": "ObjectLiteralNoContextType", - "autofix": [ - { - "start": 610, - "end": 610, - "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n \"name\": number;\n 2: number;\n}\n" - }, - { - "start": 615, - "end": 615, - "replacementText": ": GeneratedObjectLiteralInterface_1" - } - ], "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" @@ -93,12 +81,12 @@ { "start": 719, "end": 719, - "replacementText": "interface GeneratedObjectLiteralInterface_2 {\n name: number;\n}\n" + "replacementText": "interface GeneratedObjectLiteralInterface_1 {\n name: number;\n}\n" }, { "start": 724, "end": 724, - "replacementText": ": GeneratedObjectLiteralInterface_2" + "replacementText": ": GeneratedObjectLiteralInterface_1" } ], "suggest": "", diff --git a/ets2panda/linter/test/rules/rule1.ets.migrate.ets b/ets2panda/linter/test/rules/rule1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e78c2703ba999713c90ccdb16243c99e39005aa9 --- /dev/null +++ b/ets2panda/linter/test/rules/rule1.ets.migrate.ets @@ -0,0 +1,58 @@ +/* + * 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. + */ + +let x = { "name": 1, 2: 3 } + +console.log(x["name"]) +console.log(x[2]) + +class X { + public name: number = 0 +} +interface GeneratedObjectLiteralInterface_1 { + name: number; +} +let y: GeneratedObjectLiteralInterface_1 = {name: 1} +console.log(x.name) + +let z = [1, 2, 3] +console.log(y[2]) + +enum S1 { + s1 = "qwqwq", +} + +enum S2 { + s2 = 123, +} + +interface A1 { + [S1.s1]: string; +} + +interface A2 { + [S2.s2]: string; +} + +const a1: A1 = { + [S1.s1]: "fld1", +}; + +const a2: A2 = { + [S2.s2]: "fld2", +}; + +S1["s1"]; +S2["s2"]; diff --git a/ets2panda/linter/test/rules/rule1.ets.migrate.json b/ets2panda/linter/test/rules/rule1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..a6b59e880c252dc5f29c2e55d97ff6242a0ba012 --- /dev/null +++ b/ets2panda/linter/test/rules/rule1.ets.migrate.json @@ -0,0 +1,88 @@ +{ + "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": 9, + "endLine": 16, + "endColumn": 10, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 22, + "endLine": 16, + "endColumn": 23, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 13, + "endLine": 18, + "endColumn": 22, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 13, + "endLine": 19, + "endColumn": 17, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 13, + "endLine": 31, + "endColumn": 17, + "problem": "PropertyAccessByIndex", + "suggest": "", + "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 3, + "endLine": 46, + "endColumn": 10, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 3, + "endLine": 54, + "endColumn": 10, + "problem": "ComputedPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule113.ets.args.json b/ets2panda/linter/test/rules/rule113.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule113.ets.args.json +++ b/ets2panda/linter/test/rules/rule113.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule113.ets.migrate.ets b/ets2panda/linter/test/rules/rule113.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..67b6f18276903ddc39b27de96765f0cd3e2a9457 --- /dev/null +++ b/ets2panda/linter/test/rules/rule113.ets.migrate.ets @@ -0,0 +1,69 @@ +/* + * 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. + */ + + +// fixable +enum Color { + RED, + GREEN, + YELLOW = 2, + BLACK = 3, + BLUE +} + + +// ------ + +// not fixable +enum C { + A = 1 +} + +const x = 6 +let y = C.A + +enum C{ + B = x +} +// ------ + +// not fixable +const d = 6 + +enum D { + A = 1 +} + +enum D{ + B = d +} +// ------ + +// fixable +enum Str { + A = 1, + B = "abc", + C = 2, + D, + E = "qwerty" +} + + +// ------ + +enum Empty { +} + + diff --git a/ets2panda/linter/test/rules/rule113.ets.migrate.json b/ets2panda/linter/test/rules/rule113.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..93a274b2575f7986b4bbce5dd4a3747b711da618 --- /dev/null +++ b/ets2panda/linter/test/rules/rule113.ets.migrate.json @@ -0,0 +1,78 @@ +{ + "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": 30, + "column": 1, + "endLine": 32, + "endColumn": 2, + "problem": "EnumMerging", + "suggest": "", + "rule": "\"enum\" declaration merging is not supported (arkts-no-enum-merging)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 1, + "endLine": 39, + "endColumn": 2, + "problem": "EnumMerging", + "suggest": "", + "rule": "\"enum\" declaration merging is not supported (arkts-no-enum-merging)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 1, + "endLine": 47, + "endColumn": 2, + "problem": "EnumMerging", + "suggest": "", + "rule": "\"enum\" declaration merging is not supported (arkts-no-enum-merging)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 1, + "endLine": 51, + "endColumn": 2, + "problem": "EnumMerging", + "suggest": "", + "rule": "\"enum\" declaration merging is not supported (arkts-no-enum-merging)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 5, + "endLine": 57, + "endColumn": 14, + "problem": "EnumMemberNonConstInit", + "suggest": "", + "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 5, + "endLine": 60, + "endColumn": 17, + "problem": "EnumMemberNonConstInit", + "suggest": "", + "rule": "Enumeration members can be initialized only with compile time expressions of the same type (arkts-no-enum-mixed-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule140.ets.args.json b/ets2panda/linter/test/rules/rule140.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule140.ets.args.json +++ b/ets2panda/linter/test/rules/rule140.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule140.ets.migrate.ets b/ets2panda/linter/test/rules/rule140.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..eee3cc75c5d5cc8811cc1c44d6de9b1ed04a0b26 --- /dev/null +++ b/ets2panda/linter/test/rules/rule140.ets.migrate.ets @@ -0,0 +1,30 @@ +/* + * 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. + */ + +const person = { + firstName: "aa", + fullName: function (): string { + return this.firstName + } +} +interface GeneratedObjectLiteralInterface_1 { + firstName: string; +} +const person1: GeneratedObjectLiteralInterface_1 = { + firstName: "Mary" +} +// This will log "Mary": +const boundFullName = person.fullName.bind(person1) +console.log(boundFullName()) \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule140.ets.migrate.json b/ets2panda/linter/test/rules/rule140.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c2f9a120a54037ab14e5ff490ccf9af0d9472296 --- /dev/null +++ b/ets2panda/linter/test/rules/rule140.ets.migrate.json @@ -0,0 +1,68 @@ +{ + "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": 16, + "endLine": 16, + "endColumn": 17, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 15, + "endLine": 20, + "endColumn": 6, + "problem": "FunctionExpression", + "suggest": "", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 16, + "endLine": 19, + "endColumn": 20, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 52, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 39, + "endLine": 29, + "endColumn": 52, + "problem": "FunctionBind", + "suggest": "", + "rule": "'Function.bind' is not supported (arkts-no-func-bind)", + "severity": "WARNING" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule151.ets b/ets2panda/linter/test/rules/rule151.ets index 573c6a523a8f4324ac87ca9460a87897b11f3c56..61241cdf08795eda3006ac574e35c78201cd3f3c 100644 --- a/ets2panda/linter/test/rules/rule151.ets +++ b/ets2panda/linter/test/rules/rule151.ets @@ -13,47 +13,47 @@ * limitations under the License. */ import { fooOh, barOh } from './oh_modules/ohos_lib' -type ESObject = any +type ESValue = any class A {} -let g1: ESObject -let g2: ESObject[] -let g3: A +let g1: ESValue +let g2: ESValue[] +let g3: A class B { - f1: ESObject - f2: ESObject[] - f3: A + f1: ESValue + f2: ESValue[] + f3: A - constructor(p1: ESObject, p2: ESObject[], p3: A) { + constructor(p1: ESValue, p2: ESValue[], p3: A) { this.f1 = p1 this.f2 = p2 this.f3 = p3 } - foo1(p1: ESObject, p2: ESObject[], p3: A): ESObject { + foo1(p1: ESValue, p2: ESValue[], p3: A): ESValue { return p1 } - foo2(p1: ESObject, p2: ESObject[], p3: A): ESObject[] { + foo2(p1: ESValue, p2: ESValue[], p3: A): ESValue[] { return p2 } - foo3(p1: ESObject, p2: ESObject[], p3: A): A { + foo3(p1: ESValue, p2: ESValue[], p3: A): A { return p3 } } -function bar1(p1: ESObject, p2: ESObject[], p3: A): ESObject { +function bar1(p1: ESValue, p2: ESValue[], p3: A): ESValue { return p1 } -function bar2(p1: ESObject, p2: ESObject[], p3: A): ESObject[] { +function bar2(p1: ESValue, p2: ESValue[], p3: A): ESValue[] { return p2 } -function bar3(p1: ESObject, p2: ESObject[], p3: A): A { +function bar3(p1: ESValue, p2: ESValue[], p3: A): A { return p3 } @@ -61,14 +61,14 @@ function ff(): {x: number} { return {x: 10} } -function baz(p1: ESObject, p2: ESObject[], p3: A): void { - const c1: ESObject = p1; - const c2: ESObject[] = p2 - const c3: A = p3 +function baz(p1: ESValue, p2: ESValue[], p3: A): void { + const c1: ESValue = p1; + const c2: ESValue[] = p2 + const c3: A = p3 - let v1: ESObject = p1 - let v2: ESObject[] = p2 - let v3: A = p3 + let v1: ESValue = p1 + let v2: ESValue[] = p2 + let v3: A = p3 v1 = c1 v2 = c2 @@ -87,36 +87,36 @@ function baz(p1: ESObject, p2: ESObject[], p3: A): void { v1 = [p1, c1, "abc"] v1 = new A() - let v11: ESObject = {} - let v12: ESObject = "abc" - let v13: ESObject = ff() - let v14: ESObject = [1, 2] - let v15: ESObject = [p1, c1] - let v16: ESObject = [p1, c1, "abc"] - let v17: ESObject = new A() + let v11: ESValue = {} + let v12: ESValue = "abc" + let v13: ESValue = ff() + let v14: ESValue = [1, 2] + let v15: ESValue = [p1, c1] + let v16: ESValue = [p1, c1, "abc"] + let v17: ESValue = new A() let n1: number = v1 n1 = v1 let n2: number = p1 as number } -export let obj = new ESObject(); +export let obj = new ESValue(); -type t1 = ESObject -type t2 = ESObject[] +type t1 = ESValue +type t2 = ESValue[] -export type t3 = ESObject -export type t4 = ESObject[] +export type t3 = ESValue +export type t4 = ESValue[] export type t5 = t3 export type t6 = t4[] export function foo1(): any { - let a: ESObject = "STRING"; + let a: ESValue = "STRING"; return a } -export function foo2(a: ESObject): ESObject { +export function foo2(a: ESValue): ESValue { return a; } @@ -133,7 +133,7 @@ foo3(null) foo2(undefined) foo3(undefined) -export function foo4(a: ESObject[]): ESObject { +export function foo4(a: ESValue[]): ESValue { return a; } @@ -145,13 +145,13 @@ foo4([2, 3]) foo5([2, 3]) foo4(["str1", "str2"]) foo5(["str1", "str2"]) -let n: ESObject +let n: ESValue n = null foo4(n) foo5(n) -export function foo6(a: ESObject[]): ESObject { +export function foo6(a: ESValue[]): ESValue { return a; } @@ -159,7 +159,7 @@ export function foo7(a: t3[]): t3 { return a; } -export function foo8(a: ESObject[]): ESObject { +export function foo8(a: ESValue[]): ESValue { return a; } @@ -167,27 +167,27 @@ export function foo9(a: t3[]): t3 { return a; } -export class Cls {} +export class Cls {} -interface CL extends ESObject {} +interface CL extends ESValue {} -export interface CLS extends ESObject {} +export interface CLS extends ESValue {} foo2({ k: 'k', h: {t: 1}}) // we can assign anything to the esobject, even untyped literal -let q1: ESObject = 1; // CTE - ``ESObject`` typed variable can only be local -let q2: ESObject = fooOh(); // CTE - ``ESObject`` typed variable can only be local -let q3: ESObject = q2; // CTE - ``ESObject`` typed variable can only be local +let q1: ESValue = 1; // CTE - ``ESValue`` typed variable can only be local +let q2: ESValue = fooOh(); // CTE - ``ESValue`` typed variable can only be local +let q3: ESValue = q2; // CTE - ``ESValue`` typed variable can only be local function f() { let e1 = fooOh(); // CTE - type of e1 is `any` - let e2: ESObject = 1; // CTE - can't initialize ESObject with not dynamic values - let e3: ESObject = {}; // CTE - can't initialize ESObject with not dynamic values - let e4: ESObject = []; // CTE - can't initialize ESObject with not dynamic values - let e5: ESObject = ""; // CTE - can't initialize ESObject with not dynamic values - let e6: ESObject = fooOh(); // OK - explicitly annotaded as ESObject - let e7: ESObject = e6; // OK - initialize ESObject with ESObject - e6['prop'] // CTE - can't access dynamic properties of ESObject - e6[1] // CTE - can't access dynamic properties of ESObject - e6.prop // CTE - can't access dynamic properties of ESObject - barOh(e6) // OK - ESObject is passed to interop call - e6 = e7 // OK - ESObject is assigned to ESObject + let e2: ESValue = 1; // CTE - can't initialize ESValue with not dynamic values + let e3: ESValue = {}; // CTE - can't initialize ESValue with not dynamic values + let e4: ESValue = []; // CTE - can't initialize ESValue with not dynamic values + let e5: ESValue = ""; // CTE - can't initialize ESValue with not dynamic values + let e6: ESValue = fooOh(); // OK - explicitly annotaded as ESValue + let e7: ESValue = e6; // OK - initialize ESValue with ESValue + e6['prop'] // CTE - can't access dynamic properties of ESValue + e6[1] // CTE - can't access dynamic properties of ESValue + e6.prop // CTE - can't access dynamic properties of ESValue + barOh(e6) // OK - ESValue is passed to interop call + e6 = e7 // OK - ESValue is assigned to ESValue } diff --git a/ets2panda/linter/test/rules/rule151.ets.json b/ets2panda/linter/test/rules/rule151.ets.json index f4bf11de9b0c5aed2acb63721287dd8c6fff19da..536dc90f885170757c01f40a3484b0fee5c61938 100644 --- a/ets2panda/linter/test/rules/rule151.ets.json +++ b/ets2panda/linter/test/rules/rule151.ets.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2023-2024 Huawei Device Co., Ltd.", + "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", @@ -16,9 +16,9 @@ "result": [ { "line": 16, - "column": 17, + "column": 16, "endLine": 16, - "endColumn": 20, + "endColumn": 19, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,330 +28,330 @@ "line": 20, "column": 5, "endLine": 20, - "endColumn": 17, - "problem": "EsObjectType", + "endColumn": 16, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 21, "column": 9, "endLine": 21, - "endColumn": 17, - "problem": "EsObjectType", + "endColumn": 16, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 22, "column": 11, "endLine": 22, - "endColumn": 19, - "problem": "EsObjectType", + "endColumn": 18, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 25, "column": 9, "endLine": 25, - "endColumn": 17, - "problem": "EsObjectType", + "endColumn": 16, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 26, "column": 9, "endLine": 26, - "endColumn": 17, - "problem": "EsObjectType", + "endColumn": 16, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 27, "column": 11, "endLine": 27, - "endColumn": 19, - "problem": "EsObjectType", + "endColumn": 18, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 29, "column": 21, "endLine": 29, - "endColumn": 29, - "problem": "EsObjectType", + "endColumn": 28, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 29, - "column": 35, + "column": 34, "endLine": 29, - "endColumn": 43, - "problem": "EsObjectType", + "endColumn": 41, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 29, - "column": 53, + "column": 51, "endLine": 29, - "endColumn": 61, - "problem": "EsObjectType", + "endColumn": 58, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 35, "column": 14, "endLine": 35, - "endColumn": 22, - "problem": "EsObjectType", + "endColumn": 21, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 35, - "column": 28, + "column": 27, "endLine": 35, - "endColumn": 36, - "problem": "EsObjectType", + "endColumn": 34, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 35, - "column": 46, + "column": 44, "endLine": 35, - "endColumn": 54, - "problem": "EsObjectType", + "endColumn": 51, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 35, - "column": 58, + "column": 55, "endLine": 35, - "endColumn": 66, - "problem": "EsObjectType", + "endColumn": 62, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 39, "column": 14, "endLine": 39, - "endColumn": 22, - "problem": "EsObjectType", + "endColumn": 21, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 39, - "column": 28, + "column": 27, "endLine": 39, - "endColumn": 36, - "problem": "EsObjectType", + "endColumn": 34, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 39, - "column": 46, + "column": 44, "endLine": 39, - "endColumn": 54, - "problem": "EsObjectType", + "endColumn": 51, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 39, - "column": 58, + "column": 55, "endLine": 39, - "endColumn": 66, - "problem": "EsObjectType", + "endColumn": 62, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 43, "column": 14, "endLine": 43, - "endColumn": 22, - "problem": "EsObjectType", + "endColumn": 21, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 43, - "column": 28, + "column": 27, "endLine": 43, - "endColumn": 36, - "problem": "EsObjectType", + "endColumn": 34, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 43, - "column": 46, + "column": 44, "endLine": 43, - "endColumn": 54, - "problem": "EsObjectType", + "endColumn": 51, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 43, - "column": 60, + "column": 57, "endLine": 43, - "endColumn": 68, - "problem": "EsObjectType", + "endColumn": 64, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 48, "column": 19, "endLine": 48, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 48, - "column": 33, + "column": 32, "endLine": 48, - "endColumn": 41, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 48, - "column": 51, + "column": 49, "endLine": 48, - "endColumn": 59, - "problem": "EsObjectType", + "endColumn": 56, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 48, - "column": 63, + "column": 60, "endLine": 48, - "endColumn": 71, - "problem": "EsObjectType", + "endColumn": 67, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 52, "column": 19, "endLine": 52, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 52, - "column": 33, + "column": 32, "endLine": 52, - "endColumn": 41, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 52, - "column": 51, + "column": 49, "endLine": 52, - "endColumn": 59, - "problem": "EsObjectType", + "endColumn": 56, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 52, - "column": 63, + "column": 60, "endLine": 52, - "endColumn": 71, - "problem": "EsObjectType", + "endColumn": 67, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 56, "column": 19, "endLine": 56, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 56, - "column": 33, + "column": 32, "endLine": 56, - "endColumn": 41, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 56, - "column": 51, + "column": 49, "endLine": 56, - "endColumn": 59, - "problem": "EsObjectType", + "endColumn": 56, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 56, - "column": 65, + "column": 62, "endLine": 56, - "endColumn": 73, - "problem": "EsObjectType", + "endColumn": 69, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -378,70 +378,70 @@ "line": 64, "column": 18, "endLine": 64, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 64, - "column": 32, + "column": 31, "endLine": 64, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 38, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 64, - "column": 50, + "column": 48, "endLine": 64, - "endColumn": 58, - "problem": "EsObjectType", + "endColumn": 55, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 66, "column": 15, "endLine": 66, - "endColumn": 23, - "problem": "EsObjectType", + "endColumn": 22, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 67, "column": 17, "endLine": 67, - "endColumn": 25, - "problem": "EsObjectType", + "endColumn": 24, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 70, "column": 13, "endLine": 70, - "endColumn": 21, - "problem": "EsObjectType", + "endColumn": 20, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 71, "column": 15, "endLine": 71, - "endColumn": 23, - "problem": "EsObjectType", + "endColumn": 22, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -449,9 +449,9 @@ "column": 5, "endLine": 77, "endColumn": 9, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -459,9 +459,9 @@ "column": 5, "endLine": 78, "endColumn": 13, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -469,9 +469,9 @@ "column": 5, "endLine": 79, "endColumn": 11, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -479,9 +479,9 @@ "column": 5, "endLine": 80, "endColumn": 11, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -489,9 +489,9 @@ "column": 5, "endLine": 82, "endColumn": 12, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -499,9 +499,9 @@ "column": 5, "endLine": 83, "endColumn": 15, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -509,9 +509,9 @@ "column": 5, "endLine": 85, "endColumn": 16, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -519,9 +519,9 @@ "column": 5, "endLine": 86, "endColumn": 18, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -529,9 +529,9 @@ "column": 5, "endLine": 87, "endColumn": 25, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -539,69 +539,69 @@ "column": 5, "endLine": 88, "endColumn": 25, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 90, "column": 9, "endLine": 90, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 91, "column": 9, "endLine": 91, - "endColumn": 30, - "problem": "EsObjectType", + "endColumn": 29, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 93, "column": 9, "endLine": 93, - "endColumn": 31, - "problem": "EsObjectType", + "endColumn": 30, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 94, "column": 9, "endLine": 94, - "endColumn": 33, - "problem": "EsObjectType", + "endColumn": 32, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 95, "column": 9, "endLine": 95, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 96, "column": 9, "endLine": 96, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -609,9 +609,9 @@ "column": 9, "endLine": 98, "endColumn": 24, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -619,16 +619,16 @@ "column": 5, "endLine": 99, "endColumn": 12, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 103, "column": 12, "endLine": 103, - "endColumn": 32, + "endColumn": 31, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -638,40 +638,40 @@ "line": 105, "column": 11, "endLine": 105, - "endColumn": 19, - "problem": "EsObjectType", + "endColumn": 18, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 106, "column": 11, "endLine": 106, - "endColumn": 19, - "problem": "EsObjectType", + "endColumn": 18, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 108, "column": 18, "endLine": 108, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 109, "column": 18, "endLine": 109, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -688,60 +688,60 @@ "line": 115, "column": 9, "endLine": 115, - "endColumn": 31, - "problem": "EsObjectType", + "endColumn": 30, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 119, "column": 25, "endLine": 119, - "endColumn": 33, - "problem": "EsObjectType", + "endColumn": 32, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 119, - "column": 36, + "column": 35, "endLine": 119, - "endColumn": 44, - "problem": "EsObjectType", + "endColumn": 42, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 136, "column": 25, "endLine": 136, - "endColumn": 33, - "problem": "EsObjectType", + "endColumn": 32, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 136, - "column": 38, + "column": 37, "endLine": 136, - "endColumn": 46, - "problem": "EsObjectType", + "endColumn": 44, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 148, "column": 5, "endLine": 148, - "endColumn": 16, - "problem": "EsObjectType", + "endColumn": 15, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -749,99 +749,99 @@ "column": 1, "endLine": 149, "endColumn": 9, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 154, "column": 32, "endLine": 154, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 154, - "column": 45, + "column": 44, "endLine": 154, - "endColumn": 53, - "problem": "EsObjectType", + "endColumn": 51, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 154, - "column": 58, + "column": 56, "endLine": 154, - "endColumn": 66, - "problem": "EsObjectType", + "endColumn": 63, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 162, "column": 32, "endLine": 162, - "endColumn": 40, - "problem": "EsObjectType", + "endColumn": 39, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 162, - "column": 47, + "column": 46, "endLine": 162, - "endColumn": 55, - "problem": "EsObjectType", + "endColumn": 53, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 162, - "column": 60, + "column": 58, "endLine": 162, - "endColumn": 68, - "problem": "EsObjectType", + "endColumn": 65, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 170, "column": 28, "endLine": 170, - "endColumn": 36, - "problem": "EsObjectType", + "endColumn": 35, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 172, "column": 22, "endLine": 172, - "endColumn": 30, - "problem": "EsObjectType", + "endColumn": 29, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 174, "column": 30, "endLine": 174, - "endColumn": 38, - "problem": "EsObjectType", + "endColumn": 37, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -858,30 +858,30 @@ "line": 177, "column": 5, "endLine": 177, - "endColumn": 21, - "problem": "EsObjectType", + "endColumn": 20, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 178, "column": 5, "endLine": 178, - "endColumn": 27, - "problem": "EsObjectType", + "endColumn": 26, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 179, "column": 5, "endLine": 179, - "endColumn": 22, - "problem": "EsObjectType", + "endColumn": 21, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -898,40 +898,40 @@ "line": 182, "column": 9, "endLine": 182, - "endColumn": 25, - "problem": "EsObjectType", + "endColumn": 24, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 183, "column": 9, "endLine": 183, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 184, "column": 9, "endLine": 184, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { "line": 185, "column": 9, "endLine": 185, - "endColumn": 26, - "problem": "EsObjectType", + "endColumn": 25, + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -939,9 +939,9 @@ "column": 5, "endLine": 188, "endColumn": 15, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -949,9 +949,9 @@ "column": 5, "endLine": 189, "endColumn": 10, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" }, { @@ -959,10 +959,10 @@ "column": 5, "endLine": 190, "endColumn": 12, - "problem": "EsObjectType", + "problem": "EsValueType", "suggest": "", - "rule": "Usage of 'ESObject' type is restricted (arkts-limited-esobj)", + "rule": "Usage of 'ESValue' type is restricted (arkts-limited-esobj)", "severity": "WARNING" } ] -} \ No newline at end of file +} diff --git a/ets2panda/linter/test/rules/rule16.ets.args.json b/ets2panda/linter/test/rules/rule16.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule16.ets.args.json +++ b/ets2panda/linter/test/rules/rule16.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule16.ets.migrate.ets b/ets2panda/linter/test/rules/rule16.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..7b8bdd8a50341aeb624686942f19223e7a8961a5 --- /dev/null +++ b/ets2panda/linter/test/rules/rule16.ets.migrate.ets @@ -0,0 +1,33 @@ +/* + * 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. + */ + +class C { + static s: string + + static { + C.s = "aa"; + C.s = C.s + "bb"; +} + +} + +class D { + static s: string + + static { + D.s = "aa" + D.s = D.s + "bb" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule16.ets.migrate.json b/ets2panda/linter/test/rules/rule16.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule16.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 diff --git a/ets2panda/linter/test/rules/rule207.ets.arkts2.json b/ets2panda/linter/test/rules/rule207.ets.arkts2.json index 625924f2609834583615644f85222a937f10db3e..aa91c408bda45c78d3616bb897d132572d8372e1 100644 --- a/ets2panda/linter/test/rules/rule207.ets.arkts2.json +++ b/ets2panda/linter/test/rules/rule207.ets.arkts2.json @@ -50,6 +50,16 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 25, + "column": 18, + "endLine": 25, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 25, "column": 25, @@ -230,6 +240,16 @@ "rule": "Special arguments object inside functions are not supported (arkts-no-arguments-obj)", "severity": "ERROR" }, + { + "line": 57, + "column": 28, + "endLine": 57, + "endColumn": 29, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, { "line": 58, "column": 45, diff --git a/ets2panda/linter/test/rules/rule25.ets.args.json b/ets2panda/linter/test/rules/rule25.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule25.ets.args.json +++ b/ets2panda/linter/test/rules/rule25.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule25.ets.migrate.ets b/ets2panda/linter/test/rules/rule25.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..51395c45d2fd17fb4b93446dd019fe53e7c5d985 --- /dev/null +++ b/ets2panda/linter/test/rules/rule25.ets.migrate.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. + */ + +class Person { + protected ssn: string; +private firstName: string; +private lastName: string; +constructor( + ssn: string, + firstName: string, + lastName: string + ) { + this.ssn = ssn; + this.firstName = firstName; + this.lastName = lastName; + this.ssn = ssn; + this.firstName = firstName; + this.lastName = lastName; +} + + getFullName(): string { + return this.firstName + " " + this.lastName + } +} + +class Person2{ + protected ssn: string + private firstName: string + private lastName: string + + constructor(ssn: string, firstName: string, lastName: string) { + this.ssn = ssn + this.firstName = firstName + this.lastName = lastName + } + + getFullName(): string { + return this.firstName + " " + this.lastName + } +} + +class A { + constructor(readonly a: A) { + this.a = a; + } +} + \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule25.ets.migrate.json b/ets2panda/linter/test/rules/rule25.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule25.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 diff --git a/ets2panda/linter/test/rules/rule29.ets.args.json b/ets2panda/linter/test/rules/rule29.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule29.ets.args.json +++ b/ets2panda/linter/test/rules/rule29.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule29.ets.migrate.ets b/ets2panda/linter/test/rules/rule29.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..284d21dac74036aef884a94888814edf8c49bd7e --- /dev/null +++ b/ets2panda/linter/test/rules/rule29.ets.migrate.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. + */ + +class Point {x: number = 0; y: number = 0} +let p: Point = {x: 1, y: 2} +let x = p.x + +class Point2 {x: number = 0; y: number = 0} +let p2: Point2 = {x: 1, y: 2} +let x2 = p.x \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule29.ets.migrate.json b/ets2panda/linter/test/rules/rule29.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule29.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 diff --git a/ets2panda/linter/test/rules/rule3.ets.args.json b/ets2panda/linter/test/rules/rule3.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule3.ets.args.json +++ b/ets2panda/linter/test/rules/rule3.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule3.ets.migrate.ets b/ets2panda/linter/test/rules/rule3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d67266f1810625c091a72beb0990d974dd841f3a --- /dev/null +++ b/ets2panda/linter/test/rules/rule3.ets.migrate.ets @@ -0,0 +1,36 @@ +/* + * 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 C { + private foo: number = 42; +} + +class X { + private foo: number = 42 +} + +class D { + private a: number = 1; + private b: number = 2; + + foo(): number { + return this.a + this.b + } + + bar(): number { + return this.a + this.b - this.a - this.b + } +} diff --git a/ets2panda/linter/test/rules/rule3.ets.migrate.json b/ets2panda/linter/test/rules/rule3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule3.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 diff --git a/ets2panda/linter/test/rules/rule37.ets b/ets2panda/linter/test/rules/rule37.ets index 4839a90823344ca855c20957a7cf21e585590b4e..a1d8a329aca0978ea0b86998c6902c4ae37580e0 100644 --- a/ets2panda/linter/test/rules/rule37.ets +++ b/ets2panda/linter/test/rules/rule37.ets @@ -64,4 +64,12 @@ let regex12: RegExp = RegExp("ab*c") - let regex13: RegExp = RegExp("ab*c","i") \ No newline at end of file + let regex13: RegExp = RegExp("ab*c","i") + + let a27: RegExp = RegExp('dawfgr'+'12345') + + let a25: RegExp = RegExp('.∗?(?:(?:元宵|三八|妇女|母亲|父亲|七夕|重阳|情人|儿童|六一'+'|愚人|复活|青年|护士|建军|教师|建党|万圣|感恩|秘书|七一|五四|八一|腊八|光棍|植树|中元)节|除夕|大年三十|大年30|七夕'+'|平安夜|六一|七一|五四|八一|三八|腊八|双十一|双十二).∗'); + + let regex20: RegExp = RegExp('dawfgr'.concat('12345')) + + let a28: RegExp = RegExp('dawfgr'+'12345' + '789') diff --git a/ets2panda/linter/test/rules/rule37.ets.args.json b/ets2panda/linter/test/rules/rule37.ets.args.json index 60cb1832f2a8c7ca0bc97055212d784e2860448b..30973c00a22aa0a072616f644b02c89a4a4dd4fa 100644 --- a/ets2panda/linter/test/rules/rule37.ets.args.json +++ b/ets2panda/linter/test/rules/rule37.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule37.ets.arkts2.json b/ets2panda/linter/test/rules/rule37.ets.arkts2.json index ffad898af941561a93cd16e6bcca3574f1cf8fc4..e07b57d6dfb8725687fadcdc4937e02927228535 100644 --- a/ets2panda/linter/test/rules/rule37.ets.arkts2.json +++ b/ets2panda/linter/test/rules/rule37.ets.arkts2.json @@ -143,6 +143,46 @@ "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" + }, + { + "line": 69, + "column": 20, + "endLine": 69, + "endColumn": 44, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 20, + "endLine": 71, + "endColumn": 176, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 24, + "endLine": 73, + "endColumn": 56, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 21, + "endLine": 75, + "endColumn": 53, + "problem": "RegularExpressionLiteral", + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule37.ets.autofix.json b/ets2panda/linter/test/rules/rule37.ets.autofix.json index bd396f0bda1a03374e4ff9887af2dcd32898e0ee..3cad91ca09415031931a0886e1e44b09b2ec7132 100644 --- a/ets2panda/linter/test/rules/rule37.ets.autofix.json +++ b/ets2panda/linter/test/rules/rule37.ets.autofix.json @@ -234,6 +234,74 @@ "suggest": "", "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", "severity": "ERROR" + }, + { + "line": 69, + "column": 20, + "endLine": 69, + "endColumn": 44, + "problem": "RegularExpressionLiteral", + "autofix": [ + { + "start": 1968, + "end": 1992, + "replacementText": "new RegExp('dawfgr' + '12345')" + } + ], + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 20, + "endLine": 71, + "endColumn": 176, + "problem": "RegularExpressionLiteral", + "autofix": [ + { + "start": 2013, + "end": 2169, + "replacementText": "new RegExp('.∗?(?:(?:元宵|三八|妇女|母亲|父亲|七夕|重阳|情人|儿童|六一' + '|愚人|复活|青年|护士|建军|教师|建党|万圣|感恩|秘书|七一|五四|八一|腊八|光棍|植树|中元)节|除夕|大年三十|大年30|七夕' + '|平安夜|六一|七一|五四|八一|三八|腊八|双十一|双十二).∗')" + } + ], + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 24, + "endLine": 73, + "endColumn": 56, + "problem": "RegularExpressionLiteral", + "autofix": [ + { + "start": 2195, + "end": 2227, + "replacementText": "new RegExp('dawfgr'.concat('12345'))" + } + ], + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" + }, + { + "line": 75, + "column": 21, + "endLine": 75, + "endColumn": 53, + "problem": "RegularExpressionLiteral", + "autofix": [ + { + "start": 2250, + "end": 2282, + "replacementText": "new RegExp('dawfgr' + '12345' + '789')" + } + ], + "suggest": "", + "rule": "RegExp literals are not supported (arkts-no-regexp-literals)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule37.ets.migrate.ets b/ets2panda/linter/test/rules/rule37.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..6cd09a1b8bd06b035a6b8a1d47df9bf984d2ab76 --- /dev/null +++ b/ets2panda/linter/test/rules/rule37.ets.migrate.ets @@ -0,0 +1,75 @@ +/* + * 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. + */ + + let regex: RegExp = new RegExp("bc*d"); + + let regex2: RegExp = new RegExp("bc*d"); + + const regex3 = new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$"); + const regex4: RegExp = new RegExp('^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$'); + + let regex5: RegExp = new RegExp("bc*d", "ig"); + + let regex6: RegExp = new RegExp("bc*d", "ig"); + + let regex7: RegExp = new RegExp(new RegExp("bc*d", "i"), "g"); + + let regex8: RegExp = new RegExp(new RegExp("bc*d", "i"), "g"); + + let regex9: RegExp = new RegExp("a\\\\"); + + let regex10: RegExp = new RegExp("a\\\\"); + + class A { + static readonly classregex0: RegExp = new RegExp("bc*d") + + static readonly classregex2 = new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$"); + + classregex3: RegExp = new RegExp("bc*d"); + + static staticMethodOne() { + let regex = new RegExp("bc*d") + } + + static staticMethodTwo() { + let regex: RegExp = new RegExp("/bc*d/"); + } + + methodOne() { + let regex = new RegExp("bc*d") + } + + methodTwo() { + let regex: RegExp = new RegExp("/bc*d/"); + } + + methodRet(): RegExp { + return new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$"); + } + } + + const regexLambda = () => new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)*$"); + + let regex12: RegExp = new RegExp("ab*c") + + let regex13: RegExp = new RegExp("ab*c", "i") + + let a27: RegExp = new RegExp('dawfgr' + '12345') + + let a25: RegExp = new RegExp('.∗?(?:(?:元宵|三八|妇女|母亲|父亲|七夕|重阳|情人|儿童|六一' + '|愚人|复活|青年|护士|建军|教师|建党|万圣|感恩|秘书|七一|五四|八一|腊八|光棍|植树|中元)节|除夕|大年三十|大年30|七夕' + '|平安夜|六一|七一|五四|八一|三八|腊八|双十一|双十二).∗'); + + let regex20: RegExp = new RegExp('dawfgr'.concat('12345')) + + let a28: RegExp = new RegExp('dawfgr' + '12345' + '789') diff --git a/ets2panda/linter/test/rules/rule37.ets.migrate.json b/ets2panda/linter/test/rules/rule37.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule37.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 diff --git a/ets2panda/linter/test/rules/rule38.ets.args.json b/ets2panda/linter/test/rules/rule38.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule38.ets.args.json +++ b/ets2panda/linter/test/rules/rule38.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule38.ets.migrate.ets b/ets2panda/linter/test/rules/rule38.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..59cb4761aa50e3cf26d9a7fbff2c633157a32584 --- /dev/null +++ b/ets2panda/linter/test/rules/rule38.ets.migrate.ets @@ -0,0 +1,69 @@ +/* + * 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. + */ + +interface GeneratedObjectLiteralInterface_1 { + n: number; + s: string; +} +let o1: GeneratedObjectLiteralInterface_1 = {n: 42, s: "foo"} +let o2: Object = {n: 42, s: "foo"} +let o3: object = {n: 42, s: "foo"} + +let oo: Object[] = [{n: 1, s: "1"}, {n: 2, s: "2"}] + +class C2 { + s: string + constructor(s: string) { + this.s = "s =" + s + } +} +let o4: C2 = {s: "foo"} + +class C3 { + readonly n: number = 0 + readonly s: string = "" +} +let o5: C3 = {n: 42, s: "foo"} + +abstract class A {} +let o6: A = {} + +class C4 { + n: number = 0 + s: string = "" + f() { + console.log("Hello") + } +} +let o7: C4 = {n: 42, s: "foo", f : () => {}} + +class Point { + x: number = 0 + y: number = 0 +} +function id_x_y(o: Point): Point { + return o +} + +// Structural typing is used to deduce that p is Point: +interface GeneratedObjectLiteralInterface_2 { + x: number; + y: number; +} +let p: GeneratedObjectLiteralInterface_2 = {x: 5, y: 10} +id_x_y(p) + +// A literal can be contextually (i.e., implicitly) typed as Point: +id_x_y({x: 5, y: 10}) \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule38.ets.migrate.json b/ets2panda/linter/test/rules/rule38.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..c7161779dac42c50a664c11aaa8a89191afb0a60 --- /dev/null +++ b/ets2panda/linter/test/rules/rule38.ets.migrate.json @@ -0,0 +1,118 @@ +{ + "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": 21, + "column": 18, + "endLine": 21, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 18, + "endLine": 22, + "endColumn": 19, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 20, + "endLine": 24, + "endColumn": 52, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 21, + "endLine": 24, + "endColumn": 22, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 37, + "endLine": 24, + "endColumn": 38, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 14, + "endLine": 32, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 14, + "endLine": 38, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 13, + "endLine": 41, + "endColumn": 14, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 14, + "endLine": 50, + "endColumn": 15, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 66, + "column": 8, + "endLine": 66, + "endColumn": 9, + "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/rules/rule40.ets.args.json b/ets2panda/linter/test/rules/rule40.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule40.ets.args.json +++ b/ets2panda/linter/test/rules/rule40.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule40.ets.migrate.ets b/ets2panda/linter/test/rules/rule40.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..b98111045312a07ad6278ec84fed06b4621357e3 --- /dev/null +++ b/ets2panda/linter/test/rules/rule40.ets.migrate.ets @@ -0,0 +1,38 @@ +/* + * 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. + */ + +interface GeneratedTypeLiteralInterface_1 { + x: number; + y: number; +} +let o: GeneratedTypeLiteralInterface_1 = { + x: 2, + y: 3 +} + +interface GeneratedTypeLiteralInterface_2 { + x: number; + y: number; +} +type S = Set + +class C { + x: number = 0 + y: number = 0 +} + +let c: C = {x: 2, y: 3} + +type t = Set \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule40.ets.migrate.json b/ets2panda/linter/test/rules/rule40.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule40.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 diff --git a/ets2panda/linter/test/rules/rule46.ets.args.json b/ets2panda/linter/test/rules/rule46.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule46.ets.args.json +++ b/ets2panda/linter/test/rules/rule46.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/test/runtime/ets/user_defined_2.ets b/ets2panda/linter/test/rules/rule46.ets.migrate.ets similarity index 84% rename from ets2panda/test/runtime/ets/user_defined_2.ets rename to ets2panda/linter/test/rules/rule46.ets.migrate.ets index e96781534538477c045ec6ed0d589d2b75005ca3..d05a5787397d2bd5447be008301272074c187053 100644 --- a/ets2panda/test/runtime/ets/user_defined_2.ets +++ b/ets2panda/linter/test/rules/rule46.ets.migrate.ets @@ -13,9 +13,10 @@ * limitations under the License. */ -let boolean : boolean = true; - -function main() { - let boolean : boolean = false; - assertEQ(boolean, false) +let f = (s: string) => { + console.log(s); } + +let foo = (s: string) => { + console.log(s) +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule46.ets.migrate.json b/ets2panda/linter/test/rules/rule46.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule46.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 diff --git a/ets2panda/linter/test/rules/rule5.ets.args.json b/ets2panda/linter/test/rules/rule5.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule5.ets.args.json +++ b/ets2panda/linter/test/rules/rule5.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule5.ets.migrate.ets b/ets2panda/linter/test/rules/rule5.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..4be90ab7194bb4ce6eb8891a949c6f212b7f508f --- /dev/null +++ b/ets2panda/linter/test/rules/rule5.ets.migrate.ets @@ -0,0 +1,124 @@ +/* + * 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. + */ + +// fixable +let bar1 = 1; +let foo1 = bar1; + +let bar2 = 1; +let most2 = 1; +let foo2 = bar2, toast2 = most2; + +let bar3 = 1; +let most3 = 1; +let foo3 = bar3; let toast3 = most3; + +let b4 = []; +for (let a4 of b4) { console.log(a4); } + +let b5 = []; +for (let a5 in b5) { console.log(a5); } + +let b6 = []; +for (let a6 of b6) { let c6 = 1; console.log(c6); } + +let list7 = []; +for (let i7 = 0; i7 < list7.length; ++i7) { foo(i7) } + +var {a8, b8 = a8} = {} // not fixable + +let a9 = b9; var b9 = 1 + +let foo10 = 1 + +declare let foo11 = 2; + +// not fixable +var fx12 = function (i12 = 0) { if (i12 < 5) { return fx12(i12 + 1); } console.log(i12); }; fx12(); + +var foo13 = () => { foo13(); }; + +var foo14 = () => foo14(); + +// fixable +let bar15 = foo15; var foo15 = () => { foo15(); }; + +let bar16 = () => { foo16(); }; var foo16 = () => { }; + +// not fixable +for (var i17 = 0, i17 = 0; false;); + +var i18 = 0; for (var i18 = 1; false;); console.log(i18); + +var a19, b19, c19; var a19; + +let b20 = 1; +var a20; if (b20) { var a20; } + +let foo21 = 1; +if (foo21) { var a21, b21, c21; } a21; + +for (var i22 = 0; i22 < 10; ++i22) {} i22; + +let obj23 = []; +for (var a23 in obj23) {} a23; + +let list24 = []; +for (var a24 of list24) {} a24; + +let a25 = 1; +switch (a25) { case 0: var b25 = 1 } + +let b26 = []; +let arr26 = []; +for (var a26 of b26) { arr26.push(() => a26); } + +let b27 = []; +for (let a27 of b27) { var c27; console.log(c27); c27 = 'hello'; } + +var a28 = a28 + +var {a29 = a29} = {} + +var {a30 = b30, b30} = {} + +var a31 = b31, b31 = 1 + +function foo32() { a32 } var a32 = 1; foo32() + +let foo33 = 1; +if (foo33) var bar33 = 1; + +// var foo34 = 1 + +// { var foo35 = 1 } + +if (true) { var foo36 = 1 } + +function foo37() { var let; } + +// how to test it, let keyword should stay let keyword +// function foo38() { var { let } = {}; } + +var foo39 = (() => { foo39(); })(); + +let bar40 = (a) => { }; +var foo40 = bar40(() => { foo40(); }); + +var bar41 = foo41, foo41 = () => { foo41(); }; + +var { foo42 = foo42 } = () => { foo42(); }; + +var { bar43 = foo43, foo43 } = () => { foo43(); }; diff --git a/ets2panda/linter/test/migrate/destructuring_assignments.ts.migrate.json b/ets2panda/linter/test/rules/rule5.ets.migrate.json similarity index 37% rename from ets2panda/linter/test/migrate/destructuring_assignments.ts.migrate.json rename to ets2panda/linter/test/rules/rule5.ets.migrate.json index 05a9b858c91e689b4354c0ced816adf6e9be7843..d5974e4a39550fafd4da3e905d701096a8416c04 100644 --- a/ets2panda/linter/test/migrate/destructuring_assignments.ts.migrate.json +++ b/ets2panda/linter/test/rules/rule5.ets.migrate.json @@ -1,623 +1,687 @@ { + "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": 18, - "column": 5, - "endLine": 18, - "endColumn": 9, - "problem": "AnyType", + "line": 32, + "column": 13, + "endLine": 32, + "endColumn": 15, + "problem": "ForInStatement", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "\"for .. in\" is not supported (arkts-no-for-in)", "severity": "ERROR" }, { - "line": 18, - "column": 11, - "endLine": 18, - "endColumn": 16, - "problem": "AnyType", + "line": 40, + "column": 1, + "endLine": 40, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 19, - "column": 2, - "endLine": 19, - "endColumn": 44, - "problem": "DestructuringAssignment", + "line": 40, + "column": 5, + "endLine": 40, + "endColumn": 23, + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { - "line": 19, - "column": 16, - "endLine": 19, - "endColumn": 17, + "line": 40, + "column": 21, + "endLine": 40, + "endColumn": 22, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 20, - "column": 2, - "endLine": 20, - "endColumn": 18, - "problem": "DestructuringAssignment", + "line": 42, + "column": 14, + "endLine": 42, + "endColumn": 17, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 20, - "column": 16, - "endLine": 20, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", + "line": 49, + "column": 1, + "endLine": 49, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 21, - "column": 2, - "endLine": 21, - "endColumn": 33, - "problem": "DestructuringAssignment", + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 91, + "problem": "FunctionExpression", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", "severity": "ERROR" }, { - "line": 21, - "column": 7, - "endLine": 21, - "endColumn": 14, - "problem": "SpreadOperator", + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 91, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 22, - "column": 2, - "endLine": 22, - "endColumn": 56, - "problem": "DestructuringAssignment", + "line": 51, + "column": 1, + "endLine": 51, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 22, - "column": 26, - "endLine": 22, - "endColumn": 27, - "problem": "ObjectLiteralNoContextType", + "line": 53, + "column": 1, + "endLine": 53, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 22, - "column": 37, - "endLine": 22, - "endColumn": 38, - "problem": "ObjectLiteralNoContextType", + "line": 53, + "column": 13, + "endLine": 53, + "endColumn": 26, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 23, - "column": 2, - "endLine": 23, - "endColumn": 56, - "problem": "DestructuringAssignment", + "line": 56, + "column": 20, + "endLine": 56, + "endColumn": 23, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 23, - "column": 12, - "endLine": 23, - "endColumn": 19, - "problem": "SpreadOperator", + "line": 58, + "column": 33, + "endLine": 58, + "endColumn": 36, + "problem": "VarDeclaration", "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 23, - "column": 26, - "endLine": 23, - "endColumn": 27, - "problem": "ObjectLiteralNoContextType", + "line": 61, + "column": 6, + "endLine": 61, + "endColumn": 9, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 26, - "column": 10, - "endLine": 26, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", + "line": 63, + "column": 1, + "endLine": 63, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 28, - "column": 2, - "endLine": 28, - "endColumn": 24, - "problem": "DestructuringAssignment", + "line": 63, + "column": 19, + "endLine": 63, + "endColumn": 22, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 31, + "line": 65, "column": 1, - "endLine": 31, - "endColumn": 25, - "problem": "DestructuringAssignment", + "endLine": 65, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 32, - "column": 1, - "endLine": 32, - "endColumn": 15, - "problem": "DestructuringAssignment", + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 8, + "problem": "AnyType", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 33, - "column": 1, - "endLine": 33, - "endColumn": 58, - "problem": "DestructuringAssignment", + "line": 65, + "column": 10, + "endLine": 65, + "endColumn": 13, + "problem": "AnyType", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 34, - "column": 1, - "endLine": 34, - "endColumn": 16, - "problem": "DestructuringAssignment", + "line": 65, + "column": 15, + "endLine": 65, + "endColumn": 18, + "problem": "AnyType", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 35, - "column": 1, - "endLine": 35, - "endColumn": 39, - "problem": "DestructuringAssignment", + "line": 65, + "column": 20, + "endLine": 65, + "endColumn": 23, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 35, - "column": 8, - "endLine": 35, - "endColumn": 15, - "problem": "SpreadOperator", + "line": 65, + "column": 24, + "endLine": 65, + "endColumn": 27, + "problem": "AnyType", "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 36, + "line": 68, "column": 1, - "endLine": 36, - "endColumn": 42, - "problem": "DestructuringAssignment", + "endLine": 68, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 37, - "column": 1, - "endLine": 37, - "endColumn": 46, - "problem": "DestructuringAssignment", + "line": 68, + "column": 5, + "endLine": 68, + "endColumn": 8, + "problem": "AnyType", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 37, - "column": 12, - "endLine": 37, - "endColumn": 19, - "problem": "SpreadOperator", + "line": 68, + "column": 21, + "endLine": 68, + "endColumn": 24, + "problem": "VarDeclaration", "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 40, - "column": 1, - "endLine": 40, + "line": 68, + "column": 25, + "endLine": 68, + "endColumn": 28, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 14, + "endLine": 71, "endColumn": 17, - "problem": "DestructuringAssignment", + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 41, - "column": 1, - "endLine": 41, + "line": 71, + "column": 18, + "endLine": 71, "endColumn": 21, - "problem": "DestructuringAssignment", + "problem": "AnyType", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 41, - "column": 5, - "endLine": 41, - "endColumn": 12, - "problem": "SpreadOperator", + "line": 71, + "column": 23, + "endLine": 71, + "endColumn": 26, + "problem": "AnyType", "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 44, - "column": 1, - "endLine": 44, - "endColumn": 20, - "problem": "DestructuringAssignment", + "line": 71, + "column": 28, + "endLine": 71, + "endColumn": 31, + "problem": "AnyType", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 47, - "column": 1, - "endLine": 47, - "endColumn": 16, - "problem": "DestructuringAssignment", + "line": 73, + "column": 6, + "endLine": 73, + "endColumn": 9, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 50, - "column": 1, - "endLine": 50, - "endColumn": 23, - "problem": "DestructuringAssignment", + "line": 76, + "column": 14, + "endLine": 76, + "endColumn": 16, + "problem": "ForInStatement", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "\"for .. in\" is not supported (arkts-no-for-in)", "severity": "ERROR" }, { - "line": 53, - "column": 30, - "endLine": 53, - "endColumn": 31, - "problem": "ObjectTypeLiteral", + "line": 76, + "column": 6, + "endLine": 76, + "endColumn": 9, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 53, - "column": 45, - "endLine": 53, - "endColumn": 46, - "problem": "AnyType", + "line": 79, + "column": 6, + "endLine": 79, + "endColumn": 9, + "problem": "VarDeclaration", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 54, - "column": 1, - "endLine": 54, - "endColumn": 51, - "problem": "DestructuringAssignment", + "line": 82, + "column": 24, + "endLine": 82, + "endColumn": 27, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 54, - "column": 29, - "endLine": 54, - "endColumn": 50, - "problem": "ArrayLiteralNoContextType", + "line": 86, + "column": 6, + "endLine": 86, + "endColumn": 9, + "problem": "VarDeclaration", "suggest": "", - "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 54, - "column": 30, - "endLine": 54, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", + "line": 89, + "column": 24, + "endLine": 89, + "endColumn": 27, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 54, - "column": 41, - "endLine": 54, - "endColumn": 42, - "problem": "ObjectLiteralNoContextType", + "line": 89, + "column": 28, + "endLine": 89, + "endColumn": 31, + "problem": "AnyType", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 55, + "line": 91, "column": 1, - "endLine": 55, - "endColumn": 42, - "problem": "DestructuringAssignment", + "endLine": 91, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 55, - "column": 18, - "endLine": 55, - "endColumn": 22, - "problem": "SpreadOperator", + "line": 91, + "column": 5, + "endLine": 91, + "endColumn": 14, + "problem": "AnyType", "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 56, + "line": 93, "column": 1, - "endLine": 56, - "endColumn": 38, - "problem": "DestructuringAssignment", + "endLine": 93, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 56, - "column": 8, - "endLine": 56, - "endColumn": 19, - "problem": "SpreadOperator", + "line": 93, + "column": 5, + "endLine": 93, + "endColumn": 21, + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { - "line": 56, - "column": 23, - "endLine": 56, - "endColumn": 38, - "problem": "ArrayLiteralNoContextType", + "line": 93, + "column": 19, + "endLine": 93, + "endColumn": 20, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 56, - "column": 30, - "endLine": 56, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", + "line": 95, + "column": 1, + "endLine": 95, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 58, - "column": 2, - "endLine": 58, - "endColumn": 41, - "problem": "DestructuringAssignment", + "line": 95, + "column": 5, + "endLine": 95, + "endColumn": 26, + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { - "line": 58, - "column": 22, - "endLine": 58, - "endColumn": 23, + "line": 95, + "column": 24, + "endLine": 95, + "endColumn": 25, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 59, - "column": 2, - "endLine": 65, - "endColumn": 44, - "problem": "DestructuringAssignment", + "line": 97, + "column": 1, + "endLine": 97, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 65, - "column": 5, - "endLine": 65, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", + "line": 99, + "column": 26, + "endLine": 99, + "endColumn": 29, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 65, - "column": 17, - "endLine": 65, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", + "line": 102, + "column": 12, + "endLine": 102, + "endColumn": 15, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 68, - "column": 2, - "endLine": 68, - "endColumn": 48, - "problem": "DestructuringAssignment", + "line": 108, + "column": 13, + "endLine": 108, + "endColumn": 16, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 68, + "line": 110, "column": 20, - "endLine": 68, - "endColumn": 21, - "problem": "ObjectLiteralNoContextType", + "endLine": 110, + "endColumn": 23, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 69, - "column": 2, - "endLine": 69, - "endColumn": 60, - "problem": "DestructuringAssignment", + "line": 110, + "column": 24, + "endLine": 110, + "endColumn": 27, + "problem": "AnyType", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 69, - "column": 30, - "endLine": 69, - "endColumn": 31, - "problem": "ObjectLiteralNoContextType", + "line": 115, + "column": 1, + "endLine": 115, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 69, - "column": 41, - "endLine": 69, - "endColumn": 42, - "problem": "ObjectLiteralNoContextType", + "line": 117, + "column": 14, + "endLine": 117, + "endColumn": 15, + "problem": "AnyType", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 70, - "column": 2, - "endLine": 70, - "endColumn": 45, - "problem": "DestructuringAssignment", + "line": 118, + "column": 1, + "endLine": 118, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 70, - "column": 26, - "endLine": 70, - "endColumn": 27, - "problem": "ObjectLiteralNoContextType", + "line": 120, + "column": 1, + "endLine": 120, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 71, - "column": 2, - "endLine": 77, - "endColumn": 44, - "problem": "DestructuringAssignment", + "line": 122, + "column": 1, + "endLine": 122, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 77, + "line": 122, "column": 5, - "endLine": 77, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", + "endLine": 122, + "endColumn": 43, + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { - "line": 77, - "column": 17, - "endLine": 77, - "endColumn": 18, - "problem": "ObjectLiteralNoContextType", + "line": 124, + "column": 1, + "endLine": 124, + "endColumn": 4, + "problem": "VarDeclaration", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Use \"let\" instead of \"var\" (arkts-no-var)", "severity": "ERROR" }, { - "line": 87, - "column": 2, - "endLine": 87, - "endColumn": 23, - "problem": "DestructuringAssignment", + "line": 124, + "column": 5, + "endLine": 124, + "endColumn": 50, + "problem": "DestructuringDeclaration", "suggest": "", - "rule": "Destructuring assignment is not supported (arkts-no-destruct-assignment)", + "rule": "Destructuring variable declarations are not supported (arkts-no-destruct-decls)", "severity": "ERROR" }, { - "line": 32, - "column": 2, - "endLine": 32, - "endColumn": 3, + "line": 42, + "column": 10, + "endLine": 42, + "endColumn": 12, "problem": "StrictDiagnostic", - "suggest": "Type 'undefined' is not assignable to type 'number'.", - "rule": "Type 'undefined' is not assignable to type 'number'.", + "suggest": "Variable 'b9' is used before being assigned.", + "rule": "Variable 'b9' is used before being assigned.", "severity": "ERROR" }, { - "line": 32, - "column": 5, - "endLine": 32, - "endColumn": 6, + "line": 56, + "column": 13, + "endLine": 56, + "endColumn": 18, "problem": "StrictDiagnostic", - "suggest": "Type 'undefined' is not assignable to type 'number'.", - "rule": "Type 'undefined' is not assignable to type 'number'.", + "suggest": "Variable 'foo15' is used before being assigned.", + "rule": "Variable 'foo15' is used before being assigned.", "severity": "ERROR" }, { - "line": 32, - "column": 8, - "endLine": 32, - "endColumn": 9, + "line": 76, + "column": 27, + "endLine": 76, + "endColumn": 30, + "problem": "StrictDiagnostic", + "suggest": "Variable 'a23' is used before being assigned.", + "rule": "Variable 'a23' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 79, + "column": 28, + "endLine": 79, + "endColumn": 31, + "problem": "StrictDiagnostic", + "suggest": "Variable 'a24' is used before being assigned.", + "rule": "Variable 'a24' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 86, + "column": 35, + "endLine": 86, + "endColumn": 44, + "problem": "StrictDiagnostic", + "suggest": "Argument of type '() => never' is not assignable to parameter of type 'never'.", + "rule": "Argument of type '() => never' is not assignable to parameter of type 'never'.", + "severity": "ERROR" + }, + { + "line": 97, + "column": 11, + "endLine": 97, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'b31' is used before being assigned.", + "rule": "Variable 'b31' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 120, + "column": 13, + "endLine": 120, + "endColumn": 18, "problem": "StrictDiagnostic", - "suggest": "Type 'undefined' is not assignable to type 'number'.", - "rule": "Type 'undefined' is not assignable to type 'number'.", + "suggest": "Variable 'foo41' is used before being assigned.", + "rule": "Variable 'foo41' is used before being assigned.", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/rules/rule53.ets.args.json b/ets2panda/linter/test/rules/rule53.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule53.ets.args.json +++ b/ets2panda/linter/test/rules/rule53.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule53.ets.migrate.ets b/ets2panda/linter/test/rules/rule53.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..616623d38749ee75d8c84b784dca402a8bbab2ec --- /dev/null +++ b/ets2panda/linter/test/rules/rule53.ets.migrate.ets @@ -0,0 +1,39 @@ +/* + * 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. + */ + +class Shape {} +class Circle extends Shape {x: number = 5} +class Square extends Shape {y: string = "a"} + +function createShape(): Shape { + return new Circle() +} + +let c1 = createShape() as Circle + +let c2 = createShape() as Circle + +// No report is provided during compilation +// nor during runtime if cast is wrong: +let c3 = createShape() as Square +console.log(c3.y) // undefined + +// Important corner case for casting primitives to the boxed counterparts: +// The left operand is not properly boxed here in in runtime +// because "as" has no runtime effect in TypeScript +let e1 = (5.0 as Number) instanceof Number // false + +// Number object is created and instanceof works as expected: +let e2 = (new Number(5.0)) instanceof Number // true \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule53.ets.migrate.json b/ets2panda/linter/test/rules/rule53.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..e1ec7aa8a9fb6d16b66482200a831120b45860a3 --- /dev/null +++ b/ets2panda/linter/test/rules/rule53.ets.migrate.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": 36, + "column": 11, + "endLine": 36, + "endColumn": 24, + "problem": "TypeAssertion", + "suggest": "", + "rule": "Only \"as T\" syntax is supported for type casts (arkts-as-casts)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule71.ets.args.json b/ets2panda/linter/test/rules/rule71.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule71.ets.args.json +++ b/ets2panda/linter/test/rules/rule71.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule71.ets.migrate.ets b/ets2panda/linter/test/rules/rule71.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e7b82ded6d1100b8d02e3be65e833e3bf435ccb3 --- /dev/null +++ b/ets2panda/linter/test/rules/rule71.ets.migrate.ets @@ -0,0 +1,112 @@ +/* + * 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. + */ + +for (let i = 0, j = 0; i < 10; ++i, j += 2) { + console.log(i) + console.log(j) +} + +let x = 0 + +// Error, no autofix +x = (++x, x++) + +// No error +for (let i = 0, j = 0; i < 10; ++i, j += 2) { + console.log(i) + console.log(j) +} + +let x2 = 0 +++x2 +x2 = x2++ + +let c = () => 33; + +// Error, no autofix +const a = (1, b = 2, c()); + +// Error, no autofix +const r = (c(), b, 1) + +class Test { + // Error, no autofix + static readonly sr = (1, c(), 2); + + // Error, no autofix + field1 = (1, 2, c()); + + method() { + // Error, no autofix + this.field1 = (c(), sr, 1); + } +} + +// Error, autofix +x++; + x--; + +// Error, autofix +x++; + x--; + ++x; + --x; + x; + +// Error, no autofix +if (x++, x === 1) { + // Error, autofix + x++; + x--; + ++x; + --x; + x; +} + +// Error, autofix +x++ + x--; + ++x; + --x; + +// Error, autofix +++x; + x-- + x++; + --x; + +// Error, autofix +++x; + --x; + x-- + x++; + +// Error, autofix +x === x; + --x; + x === x; + x++; + x === x; + +// Error, autofix +x instanceof number; + --x; + x instanceof number; + x++; + x instanceof number; + +// Error, autofix +x in x; + --x; + x in x; + x++; + x in x; diff --git a/ets2panda/linter/test/rules/rule71.ets.migrate.json b/ets2panda/linter/test/rules/rule71.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..b3add27cb17b820db267c1c3c1c36a600d729761 --- /dev/null +++ b/ets2panda/linter/test/rules/rule71.ets.migrate.json @@ -0,0 +1,148 @@ +{ + "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": 24, + "column": 6, + "endLine": 24, + "endColumn": 14, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 12, + "endLine": 39, + "endColumn": 25, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 12, + "endLine": 42, + "endColumn": 21, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 27, + "endLine": 46, + "endColumn": 36, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 15, + "endLine": 49, + "endColumn": 24, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 24, + "endLine": 53, + "endColumn": 34, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 5, + "endLine": 69, + "endColumn": 17, + "problem": "CommaOperator", + "suggest": "", + "rule": "The comma operator \",\" is supported only in \"for\" loops (arkts-no-comma-outside-loops)", + "severity": "ERROR" + }, + { + "line": 101, + "column": 3, + "endLine": 101, + "endColumn": 13, + "problem": "InstanceofUnsupported", + "suggest": "", + "rule": "\"instanceof\" operator is partially supported (arkts-instanceof-ref-types)", + "severity": "ERROR" + }, + { + "line": 103, + "column": 4, + "endLine": 103, + "endColumn": 14, + "problem": "InstanceofUnsupported", + "suggest": "", + "rule": "\"instanceof\" operator is partially supported (arkts-instanceof-ref-types)", + "severity": "ERROR" + }, + { + "line": 105, + "column": 4, + "endLine": 105, + "endColumn": 14, + "problem": "InstanceofUnsupported", + "suggest": "", + "rule": "\"instanceof\" operator is partially supported (arkts-instanceof-ref-types)", + "severity": "ERROR" + }, + { + "line": 108, + "column": 3, + "endLine": 108, + "endColumn": 5, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 4, + "endLine": 110, + "endColumn": 6, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + }, + { + "line": 112, + "column": 4, + "endLine": 112, + "endColumn": 6, + "problem": "InOperator", + "suggest": "", + "rule": "\"in\" operator is not supported (arkts-no-in)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule79.ets.args.json b/ets2panda/linter/test/rules/rule79.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule79.ets.args.json +++ b/ets2panda/linter/test/rules/rule79.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule79.ets.migrate.ets b/ets2panda/linter/test/rules/rule79.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..e31b555a881d4ddc4858e6654af9f8fb2ca265c8 --- /dev/null +++ b/ets2panda/linter/test/rules/rule79.ets.migrate.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. + */ + +try { + // some code +} +catch (a) { + // handle error +} + + +try { + // some code +} +catch (a) { + // handle error +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule79.ets.migrate.json b/ets2panda/linter/test/rules/rule79.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule79.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 diff --git a/ets2panda/linter/test/rules/rule84.ets.json b/ets2panda/linter/test/rules/rule84.ets.json index b5974d6293a9d957b1ebcbe048e25b090354c4b3..55a787dc30b5699cbc9a9f30081eb6949888dcf8 100644 --- a/ets2panda/linter/test/rules/rule84.ets.json +++ b/ets2panda/linter/test/rules/rule84.ets.json @@ -23,6 +23,16 @@ "suggest": "", "rule": "\"with\" statement is not supported (arkts-no-with)", "severity": "ERROR" + }, + { + "line": 16, + "column": 7, + "endLine": 16, + "endColumn": 11, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule90.ets.args.json b/ets2panda/linter/test/rules/rule90.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90.ets.args.json +++ b/ets2panda/linter/test/rules/rule90.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90.ets.migrate.ets b/ets2panda/linter/test/rules/rule90.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3e97208530afa5e81aa4d0b018c73efacb84c4cd --- /dev/null +++ b/ets2panda/linter/test/rules/rule90.ets.migrate.ets @@ -0,0 +1,52 @@ +/* + * 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. + */ + + // Compile-time error with noImplicitAny + function f(x: number) { + if (x <= 0) { + return x + } + return g(x) + } + + // Compile-time error with noImplicitAny + function g(x: number) { + return f(x - 1) + } + + function doOperation(x: number, y: number) { + return x + y + } + + console.log(f(10)) + console.log(doOperation(2, 3)) + + function f1(x: number) : number { + if (x <= 0) { + return x + } + return g1(x) + } + + function g1(x: number) { + return f1(x - 1) + } + + function doOperation1(x: number, y: number) { + return x + y + } + + console.log(f1(10)) + console.log(doOperation1(2, 3)) diff --git a/ets2panda/linter/test/rules/rule90.ets.migrate.json b/ets2panda/linter/test/rules/rule90.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..0ca7cc20930ab46dec04ef3c0545841b97c51cde --- /dev/null +++ b/ets2panda/linter/test/rules/rule90.ets.migrate.json @@ -0,0 +1,38 @@ +{ + "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": 17, + "column": 14, + "endLine": 17, + "endColumn": 15, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 14, + "endLine": 25, + "endColumn": 15, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/rules/rule90_1.ets.args.json b/ets2panda/linter/test/rules/rule90_1.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_1.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_1.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_1.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_1.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..a4dc9107fc019a7f1d652cda0329307e7920f2b2 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_1.ets.migrate.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ + + function f(x: number) { + return 0; + } + + function f1(): number { + return 0; + } + diff --git a/ets2panda/linter/test/rules/rule90_1.ets.migrate.json b/ets2panda/linter/test/rules/rule90_1.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_1.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 diff --git a/ets2panda/linter/test/rules/rule90_2.ets.args.json b/ets2panda/linter/test/rules/rule90_2.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_2.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_2.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_2.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_2.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..d25831ff19e99082fb5c3f2cdf4a0b741d1d81a7 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_2.ets.migrate.ets @@ -0,0 +1,26 @@ +/* + * 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. + */ + + class A { + public foo: number = 0; + } + + function f() { + return new A; + } + + function f1(): A{ + return new A; + } diff --git a/ets2panda/linter/test/rules/rule90_2.ets.migrate.json b/ets2panda/linter/test/rules/rule90_2.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_2.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 diff --git a/ets2panda/linter/test/rules/rule90_3.ets.args.json b/ets2panda/linter/test/rules/rule90_3.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_3.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_3.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_3.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_3.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..168ead9c1e906bf664431fd0902c7010e7bdd6f2 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_3.ets.migrate.ets @@ -0,0 +1,46 @@ +/* + * 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 { + public foo: number = 0; + + public bar_no_return_def() { + return 0 + } + + public bar_with_return_def() : number { + return 0 + } +} + +function f(): number { + let a = new A(); + return a.bar_no_return_def(); +} + +function f2() { + let a = new A(); + return a.bar_with_return_def(); +} + +function f3(): number{ + let a = new A(); + return a.bar_no_return_def(); +} + +function f2(): number{ + let a = new A(); + return a.bar_with_return_def(); +} diff --git a/ets2panda/linter/test/rules/rule90_3.ets.migrate.json b/ets2panda/linter/test/rules/rule90_3.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_3.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 diff --git a/ets2panda/linter/test/rules/rule90_4.ets.args.json b/ets2panda/linter/test/rules/rule90_4.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_4.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_4.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_4.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_4.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..cc5ebb1c6073dae1a8d4506b37792888d3df1222 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_4.ets.migrate.ets @@ -0,0 +1,39 @@ +/* + * 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 { + public foo: number = 0; + + public bar_no_return_def() { + return this.bar_with_return_def(); + } + + public bar_with_return_def() : number { + return (2 + 2) + } +} + +class B { + public foo: number = 0; + + public bar_no_return_def() { + return (2 + 2) + } + + public bar_with_return_def() : number { + return this.bar_with_return_def(); + } +} + diff --git a/ets2panda/linter/test/rules/rule90_4.ets.migrate.json b/ets2panda/linter/test/rules/rule90_4.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_4.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 diff --git a/ets2panda/linter/test/rules/rule90_5.ets.args.json b/ets2panda/linter/test/rules/rule90_5.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule90_5.ets.args.json +++ b/ets2panda/linter/test/rules/rule90_5.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule90_5.ets.migrate.ets b/ets2panda/linter/test/rules/rule90_5.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c3ac9d3bc2394d9ccc6a972b22ba0f39a0de71b --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_5.ets.migrate.ets @@ -0,0 +1,32 @@ +/* + * 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. + */ + +class Data1 { + public foo: number = 0; +} + +class Data2 extends Data1{ + public foo: number = 0; + +} + + +function dataFactory1() : Data1 { + return new Data2(); +} + +function dataFactory2() : Data2 { + return new Data1(); +} diff --git a/ets2panda/linter/test/rules/rule90_5.ets.migrate.json b/ets2panda/linter/test/rules/rule90_5.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/rules/rule90_5.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 diff --git a/ets2panda/linter/test/rules/rule92.ets.args.json b/ets2panda/linter/test/rules/rule92.ets.args.json index 5a7e115070021999c3103ec60e3433769b7c1fbb..410c5c189e9914c2d5372b15cdbf3c16501a76e2 100644 --- a/ets2panda/linter/test/rules/rule92.ets.args.json +++ b/ets2panda/linter/test/rules/rule92.ets.args.json @@ -1,6 +1,6 @@ { "copyright": [ - "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", @@ -14,6 +14,7 @@ "limitations under the License." ], "mode": { - "autofix": "" + "autofix": "", + "migrate": "" } } diff --git a/ets2panda/linter/test/rules/rule92.ets.migrate.ets b/ets2panda/linter/test/rules/rule92.ets.migrate.ets new file mode 100644 index 0000000000000000000000000000000000000000..b50118770b778e5dc925fd5a627de2478cef2cec --- /dev/null +++ b/ets2panda/linter/test/rules/rule92.ets.migrate.ets @@ -0,0 +1,90 @@ +/* + * 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. + */ + +// Fixable + +function addNum(a: number, b: number): void { + let logToConsole: (message: String) => void = (message: String): void => { + console.log(message); +}; + + let result = a + b + + logToConsole("result is " + result) +} + + +function addNum2(a: number, b: number): void { + // Use lambda instead of a nested function: + let logToConsole: (message: string) => void = (message: string): void => { + console.log(message) + } + + let result = a + b + + logToConsole("result is " + result) +} + + +function NestedOne(a: number, b: number): void { + let NestedTwo: (message: String) => void = (message: String): void => { + let NestedThree: (message: String) => void = (message: String): void => { + console.log("NestedThree"); +}; +}; +} + + +function NestedOne1(a: number, b: number): void { + let NestedTwo: (message: String) => void = (message: String): void => { + console.log("NestedTwo"); +}; + + let NestedTooToo: (message: String) => void = (message: String): void => { + console.log("NestedTooToo"); +}; +} + +function NestedOne2(a: number, b: number): void { + let NestedTwo: (message: String) => void = (message: String): void => { + let NestedThree: (message: String) => void = (message: String): void => { + console.log("NestedThree"); +}; + let NestedThreeToo: (message: String) => void = (message: String): void => { + console.log("NestedThreeToo"); +}; +}; +} + +// Not fixable +function decoratorFoo(): void { + @decorator + function decorated(): void { + } + + function* generatorFunction() { + return 3; + } + + function thisFoo() { + return this.what; + } + + notFixable(); + + function notFixable(): void { + } +} + diff --git a/ets2panda/linter/test/rules/rule92.ets.migrate.json b/ets2panda/linter/test/rules/rule92.ets.migrate.json new file mode 100644 index 0000000000000000000000000000000000000000..4c5918f4ba712a4ef98b04aba13fbf6561f54669 --- /dev/null +++ b/ets2panda/linter/test/rules/rule92.ets.migrate.json @@ -0,0 +1,88 @@ +{ + "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": 73, + "column": 5, + "endLine": 73, + "endColumn": 13, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 5, + "endLine": 77, + "endColumn": 13, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 77, + "column": 5, + "endLine": 79, + "endColumn": 6, + "problem": "GeneratorFunction", + "suggest": "", + "rule": "Generator functions are not supported (arkts-no-generators)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 14, + "endLine": 81, + "endColumn": 21, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 16, + "endLine": 82, + "endColumn": 20, + "problem": "FunctionContainsThis", + "suggest": "", + "rule": "Using \"this\" inside stand-alone functions is not supported (arkts-no-standalone-this)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 13, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + }, + { + "line": 87, + "column": 5, + "endLine": 87, + "endColumn": 13, + "problem": "LocalFunction", + "suggest": "", + "rule": "Nested functions are not supported (arkts-no-nested-funcs)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.args.json b/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..9c3d9734324a7b8b9c89fa7f62dce43ac44888ca --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/LimitedVoidType3.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5d0e2d9cb631c646033d268395725ece2391e0d6 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/LimitedVoidType3.ets.arkts2.json @@ -0,0 +1,118 @@ +{ + "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": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 48, + "endLine": 18, + "endColumn": 52, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 26, + "endLine": 24, + "endColumn": 50, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 54, + "endLine": 24, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 44, + "endLine": 30, + "endColumn": 48, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 9, + "endLine": 32, + "endColumn": 10, + "problem": "OptionalMethod", + "suggest": "", + "rule": "Optional methods are not supported (arkts-optional-methods)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 43, + "endLine": 32, + "endColumn": 47, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 28, + "endLine": 37, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 26, + "endLine": 41, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets new file mode 100755 index 0000000000000000000000000000000000000000..4584cafa7b4940bab8a405ecae1f87d510783d5a --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets @@ -0,0 +1,60 @@ +/* + * 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. + */ +'use static' + +import { TextStyle } from './sdk/declarations/styled_string' +import { HyperlinkAttribute, HyperlinkInterface } from './sdk/declarations/hyperlink' + +@Entry +@Component +struct Index { + fontStyleAttr1: TextStyle = new TextStyle({fontColor: Color.Blue}); // Error(2) + fontStyleAttr2: TextStyle; // Error + + @State styleList: Array = new Array(); // Error + aboutToAppear() { + for (let i = 15; i < 50; i++) + this.styleList.push(new TextStyle({})); // Error + } + + build() { + List() { + ForEach(this.styleList, (item: TextStyle) => { // Error + ListItem() { + Text("Hello World") + .fontSize(item.fontSize) + } + }) + } + } +} + +class TextStyleDemo2 extends TextStyle { // Error + constructor() { + super(); + } +} + +let hyperlinkAttr1: HyperlinkAttribute = HyperlinkInterface; +let hyperlinkAttr2: HyperlinkAttribute = HyperlinkInterface.color(''); +class HyperlinkTest { + prop1: HyperlinkAttribute = HyperlinkInterface; + prop2: HyperlinkAttribute = HyperlinkInterface.color(''); +} +let hyperlinkAttr3: HyperlinkAttribute; +hyperlinkAttr3 = HyperlinkInterface; +function func(x = HyperlinkInterface) { + +} diff --git a/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.args.json b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.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/sdkwhite/decl_with_duplicate_name_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..327b8e844f97bd5fb7074d01b52905840f6b3416 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.arkts2.json @@ -0,0 +1,298 @@ +{ + "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": 17, + "column": 1, + "endLine": 17, + "endColumn": 61, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 86, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 19, + "endLine": 23, + "endColumn": 28, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 35, + "endLine": 23, + "endColumn": 44, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 19, + "endLine": 24, + "endColumn": 28, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 27, + "endLine": 26, + "endColumn": 36, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 40, + "endLine": 26, + "endColumn": 51, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 14, + "endLine": 28, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 18, + "endLine": 28, + "endColumn": 20, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 26, + "endLine": 28, + "endColumn": 28, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 31, + "endLine": 29, + "endColumn": 40, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 38, + "endLine": 34, + "endColumn": 47, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 30, + "endLine": 44, + "endColumn": 39, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 42, + "endLine": 50, + "endColumn": 60, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 42, + "endLine": 51, + "endColumn": 60, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 31, + "endLine": 53, + "endColumn": 49, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 31, + "endLine": 54, + "endColumn": 49, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 18, + "endLine": 57, + "endColumn": 36, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 19, + "endLine": 58, + "endColumn": 37, + "problem": "DuplicateDeclNameFromSdk", + "suggest": "", + "rule": "API path have changed - please update your imports accordingly (sdk-no-decl-with-duplicate-name)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 2, + "endLine": 20, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 57, + "endLine": 23, + "endColumn": 62, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 4, + "endLine": 26, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 5, + "endLine": 33, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 7, + "endLine": 34, + "endColumn": 14, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 9, + "endLine": 35, + "endColumn": 17, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 11, + "endLine": 36, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 17, + "problem": "StrictDiagnostic", + "suggest": "Property 'fontStyleAttr2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'fontStyleAttr2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.json b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..489a1474b5a6f1db71bdf86fbf3b06b773ea21c8 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/decl_with_duplicate_name_sdk.ets.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": 17, + "column": 1, + "endLine": 17, + "endColumn": 61, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 1, + "endLine": 18, + "endColumn": 86, + "problem": "ImportAfterStatement", + "suggest": "", + "rule": "\"import\" statements after other statements are not allowed (arkts-no-misplaced-imports)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 3, + "endLine": 24, + "endColumn": 17, + "problem": "StrictDiagnostic", + "suggest": "Property 'fontStyleAttr2' has no initializer and is not definitely assigned in the constructor.", + "rule": "Property 'fontStyleAttr2' has no initializer and is not definitely assigned in the constructor.", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets new file mode 100644 index 0000000000000000000000000000000000000000..a2886cecbb321ff0954b2fed4e1aa89181faec9e --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets @@ -0,0 +1,80 @@ +/* + * 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 { IDataSourcePrefetching } from '@kit.ArkUI'; +import DataSource from './limit_void_type_sdk2'; +import { prefetchTest as preTest } from './limit_void_type_sdk2'; +import { res } from './limit_void_type_sdk2'; +import { LocalDataSource } from './LimitedVoidType3'; +class DS implements IDataSourcePrefetching { + cancel(index: number): void | Promise { //report error + throw new Error('Method not implemented.'); + } + + totalCount(): number { + throw new Error('Method not implemented.'); + } + + getData(index: number): number { + throw new Error('Method not implemented.'); + } + + registerDataChangeListener(): void { + throw new Error('Method not implemented.'); + } + + unregisterDataChangeListener(): void { + throw new Error('Method not implemented.'); + } + prefetch(index: number): void | Promise { //report error + + } + + prefetch2(index: number): void | Promise { + + } +} +const ds = new DataSource(); +let num:number=ds.totalCount(); +function testDataSource(){ + console.log(`${num}=num`); + ds.cancel(66); //report error +} +function testPrefetch() { + preTest(); +} + +function testCancel(){ + return res; +} + +class localDemo{ + dataSource:DS|undefined=undefined; + constructor() { + this.dataSource = new DS(); + } + test(){ + this.dataSource?.getData(111); + this.dataSource?.registerDataChangeListener(); + this.dataSource?.unregisterDataChangeListener(); + this.dataSource?.cancel(111); //report error + } +} +function localTest(){ + return ds.cancel(222); //report error +} +const lds = new LocalDataSource(); +lds.prefetch(999); +lds.cancel(222); diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.args.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.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/sdkwhite/limit_void_type_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..d6b0d31865a62a09f14a7eec9668c73ea66a3172 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.arkts2.json @@ -0,0 +1,188 @@ +{ + "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": 41, + "column": 3, + "endLine": 43, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 3, + "endLine": 24, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 3, + "endLine": 24, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 26, + "endLine": 22, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 28, + "endLine": 41, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 29, + "endLine": 45, + "endColumn": 33, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 3, + "endLine": 53, + "endColumn": 12, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 13, + "endLine": 53, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 69, + "column": 30, + "endLine": 69, + "endColumn": 33, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 5, + "endLine": 72, + "endColumn": 28, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 72, + "column": 29, + "endLine": 72, + "endColumn": 32, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 10, + "endLine": 76, + "endColumn": 19, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 20, + "endLine": 76, + "endColumn": 23, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 7, + "endLine": 78, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 78, + "column": 17, + "endLine": 78, + "endColumn": 32, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 79, + "column": 14, + "endLine": 79, + "endColumn": 17, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 80, + "column": 12, + "endLine": 80, + "endColumn": 15, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..e25d43a0573eae5706cacaa9a08e000fec8b89f1 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk.ets.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": 78, + "column": 7, + "endLine": 78, + "endColumn": 34, + "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/sdkwhite/limit_void_type_sdk2.ets b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets new file mode 100644 index 0000000000000000000000000000000000000000..4592f1a4799a13d1597042fb3e9c3ffc11598285 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.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. + */ +import { IDataSourcePrefetching } from '@kit.ArkUI'; +import { rcp } from '@kit.RemoteCommunicationKit'; +class LI implements rcp.WriteFile { + write(buffer: ArrayBuffer): Promise { + throw new Error() + } +} + +const sp:rcp.IncomingDataCallback = (incomingData) => { + console.log(''); +} +export default class MyDataSource implements IDataSourcePrefetching { + constructor() {} + prefetch(index: number): void | Promise { //report error + throw new Error('MyDataSource Method not implemented.'); + } + + cancel(index: number): void | Promise { //report error + throw new Error('MyDataSource Method not implemented.'); + } + + totalCount(): number { + throw new Error('MyDataSource Method not implemented.'); + } + + getData(index: number): number { + throw new Error('MyDataSource Method not implemented.'); + } + + registerDataChangeListener(listener?: DataChangeListener): void { + throw new Error('MyDataSource Method not implemented.'); + } + + unregisterDataChangeListener(listener?: DataChangeListener): void { + throw new Error('MyDataSource Method not implemented.'); + } +} +const ds = new MyDataSource(); +export function prefetchTest(){ + return new MyDataSource().prefetch(666); //report error +} +function prefetchTest2(){ + return ds.prefetch(666); //report error +} + +export const res = new MyDataSource().cancel(222); //report error +export const res2 = ds.cancel(222); //report error \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.args.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.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/sdkwhite/limit_void_type_sdk2.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5b41bb7baa2ffce5dba97d60b7e91be608ad92c4 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json @@ -0,0 +1,218 @@ +{ + "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": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 48, + "endLine": 18, + "endColumn": 52, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 10, + "endLine": 23, + "endColumn": 34, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 38, + "endLine": 23, + "endColumn": 50, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 3, + "endLine": 30, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 34, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 3, + "endLine": 34, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 28, + "endLine": 28, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 26, + "endLine": 32, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 10, + "endLine": 54, + "endColumn": 37, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 38, + "endLine": 54, + "endColumn": 41, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 10, + "endLine": 57, + "endColumn": 21, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 22, + "endLine": 57, + "endColumn": 25, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 20, + "endLine": 60, + "endColumn": 45, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 46, + "endLine": 60, + "endColumn": 49, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 21, + "endLine": 61, + "endColumn": 30, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 31, + "endLine": 61, + "endColumn": 34, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 41, + "endLine": 44, + "endColumn": 59, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 43, + "endLine": 48, + "endColumn": 61, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "ArkUI interface should be imported before using (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/class_static_block.ts.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.json similarity index 75% rename from ets2panda/linter/test/migrate/class_static_block.ts.json rename to ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.json index 487f1000c4583c3b0507ec169649e62827b942cb..67fe0d197ff09a4233444d238b62da95800f9384 100644 --- a/ets2panda/linter/test/migrate/class_static_block.ts.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.json @@ -1,10 +1,12 @@ { "copyright": [ - "Copyright (c) 2022-2024 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", + "", "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.", @@ -14,12 +16,12 @@ "result": [ { "line": 23, - "column": 3, + "column": 38, "endLine": 23, - "endColumn": 9, - "problem": "MultipleStaticBlocks", + "endColumn": 50, + "problem": "AnyType", "suggest": "", - "rule": "Only one static block is supported (arkts-no-multiple-static-blocks)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets new file mode 100644 index 0000000000000000000000000000000000000000..e05617b2ffb84ecbd04c71f0dc7b94f63b0f1138 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets @@ -0,0 +1,44 @@ +/* + * 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 { rcp } from '@kit.RemoteCommunicationKit'; +class LI implements rcp.WriteFile{ + write(buffer: ArrayBuffer): Promise { // Error + throw new Error('Method not implemented.'); + } +} + + +const simpleDataHandler: rcp.IncomingDataCallback = (incomingData) => { + console.log(`Received ${incomingData.byteLength} bytes of data`); + // Error +}; + +interface IDataSourcePrefetching { + prefetch(index: number): Promise | void; + + cancel?(index: number): Promise | void; +} +export class LocalDataSource implements IDataSourcePrefetching { + constructor() {} + + prefetch(index: number): void | Promise { + throw new Error("LocalDataSource Method not implemented."); + } + + cancel(index: number): void | Promise { + throw new Error("LocalDataSource Method not implemented."); + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.args.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.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/sdkwhite/limit_void_type_sdk3.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5d0e2d9cb631c646033d268395725ece2391e0d6 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.arkts2.json @@ -0,0 +1,118 @@ +{ + "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": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 3, + "endLine": 20, + "endColumn": 4, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 18, + "column": 48, + "endLine": 18, + "endColumn": 52, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 26, + "endLine": 24, + "endColumn": 50, + "problem": "LimitedVoidTypeFromSdk", + "suggest": "", + "rule": "Type \"void\" has no instances.(sdk-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 54, + "endLine": 24, + "endColumn": 66, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 44, + "endLine": 30, + "endColumn": 48, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 9, + "endLine": 32, + "endColumn": 10, + "problem": "OptionalMethod", + "suggest": "", + "rule": "Optional methods are not supported (arkts-optional-methods)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 43, + "endLine": 32, + "endColumn": 47, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 28, + "endLine": 37, + "endColumn": 32, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 26, + "endLine": 41, + "endColumn": 30, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..266fcc7d892f3be0b09af745cfec76118aa591f5 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk3.ets.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": 24, + "column": 54, + "endLine": 24, + "endColumn": 66, + "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/sdkwhite/literal_as_property_name_sdk.ets b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets new file mode 100644 index 0000000000000000000000000000000000000000..299f58ac32421b3cfc1a55e78746e097358754a4 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.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. + */ + +import { rcp } from '@kit.RemoteCommunicationKit'; +const basicHeaders: rcp.RequestHeaders = { + 'authorization': 'Bearer abc123', // Error + 'content-type': 'application/json' // Error +}; + +function createHeaders(authToken?: string): rcp.RequestHeaders { + return { + 'authorization': authToken ? `Bearer ${authToken}` : undefined, // Error + 'accept': 'application/json', // Error + 'cache-control': 'no-cache', // Error + 'user-agent': 'MyApp/2.0' // Error + }; +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.args.json b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.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/migrate/literals_as_prop_names.ts.migrate.json b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.arkts2.json similarity index 36% rename from ets2panda/linter/test/migrate/literals_as_prop_names.ts.migrate.json rename to ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.arkts2.json index 3d8279213f7e6b6e1cb59d349bda24d65f2af02c..aafa0c6dae965cc263d030a379c4a0c741e7e03a 100644 --- a/ets2panda/linter/test/migrate/literals_as_prop_names.ts.migrate.json +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.arkts2.json @@ -1,174 +1,138 @@ { + "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": 11, - "endLine": 20, - "endColumn": 12, - "problem": "LiteralAsPropertyName", + "line": 18, + "column": 3, + "endLine": 18, + "endColumn": 35, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 26, + "line": 18, "column": 3, - "endLine": 26, - "endColumn": 4, + "endLine": 18, + "endColumn": 18, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 30, - "column": 13, - "endLine": 30, - "endColumn": 33, - "problem": "PropertyAccessByIndex", - "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 13, - "endLine": 31, - "endColumn": 29, - "problem": "PropertyAccessByIndex", + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 37, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 32, - "column": 13, - "endLine": 32, - "endColumn": 33, - "problem": "PropertyAccessByIndex", + "line": 19, + "column": 3, + "endLine": 19, + "endColumn": 17, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 51, - "column": 9, - "endLine": 51, - "endColumn": 10, - "problem": "ObjectLiteralNoContextType", + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 67, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 51, - "column": 22, - "endLine": 51, - "endColumn": 23, + "line": 24, + "column": 5, + "endLine": 24, + "endColumn": 20, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 53, - "column": 13, - "endLine": 53, - "endColumn": 22, - "problem": "PropertyAccessByIndex", + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 33, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 54, - "column": 13, - "endLine": 54, - "endColumn": 17, - "problem": "PropertyAccessByIndex", + "line": 25, + "column": 5, + "endLine": 25, + "endColumn": 13, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 61, - "column": 13, - "endLine": 61, - "endColumn": 14, - "problem": "ObjectLiteralNoContextType", + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 32, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 69, - "column": 3, - "endLine": 69, - "endColumn": 4, + "line": 26, + "column": 5, + "endLine": 26, + "endColumn": 20, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 74, - "column": 3, - "endLine": 74, - "endColumn": 4, - "problem": "LiteralAsPropertyName", + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 30, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 78, - "column": 36, - "endLine": 78, - "endColumn": 37, + "line": 27, + "column": 5, + "endLine": 27, + "endColumn": 17, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" - }, - { - "line": 36, - "column": 11, - "endLine": 36, - "endColumn": 13, - "problem": "StrictDiagnostic", - "suggest": "Property '_2' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '_2' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 37, - "column": 3, - "endLine": 37, - "endColumn": 6, - "problem": "StrictDiagnostic", - "suggest": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property 'Two' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 57, - "column": 12, - "endLine": 57, - "endColumn": 16, - "problem": "StrictDiagnostic", - "suggest": "Property 'name' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property 'name' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" - }, - { - "line": 58, - "column": 12, - "endLine": 58, - "endColumn": 14, - "problem": "StrictDiagnostic", - "suggest": "Property '_2' has no initializer and is not definitely assigned in the constructor.", - "rule": "Property '_2' has no initializer and is not definitely assigned in the constructor.", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.json b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/literal_as_property_name_sdk.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/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets new file mode 100644 index 0000000000000000000000000000000000000000..af08caf9520714594a8755e401c1cd47b12d465b --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets @@ -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 { rcp } from '@kit.RemoteCommunicationKit'; +import { externalRequestHeaders,externalRequestHeadersInterface } from './quoted_hyphen_props_deprecated_sdk2'; +import { externalResponseHeaders,externalResponseHeadersInterface } from './quoted_hyphen_props_deprecated_sdk2'; +export interface internalRequestHeaders { + rcpHeaders: rcp.RequestHeaders; + additionalHeaders: T; +} +interface AdditionalHeaders { + customHeader: string; +} +type CustomRequestHeaders = internalRequestHeaders; +const cusRequestHeaders: CustomRequestHeaders = { + rcpHeaders: { + 'content-type': 'application/json', // Error + range: 'bytes=0-1023' // Error + }, + additionalHeaders: { + customHeader: 'custom value' + } +}; +const basicHeaders: rcp.RequestHeaders = { + 'authorization': 'Bearer abc123', // Error + 'content-type': 'application/json' // Error +}; +basicHeaders.cookie =''; // Error +function createHeaders(cookie:string,authToken?: string): rcp.RequestHeaders { + return { + 'authorization': authToken ? `Bearer ${authToken}` : undefined, // Error + 'accept': 'application/json', // Error + 'cache-control': 'no-cache', // Error + 'user-agent': 'MyApp/2.0' // Error + }; +} +createHeaders(basicHeaders.cookie); // Error +function getRange(){ + return basicHeaders.range; // Error +} + +export type localRequestHeaders = rcp.RequestHeaders; +let localHeaders:localRequestHeaders = { + 'accept-charset': 'UTF-8', // Error + 'accept-encoding': 'gzip, deflate', // Error + 'accept-language': 'en-US,en;q=0.9', // Error + 'cookie': 'session_id=123456', // Error + 'range': 'bytes=0-1023', // Error + 'upgrade': 'websocket', // Error + 'content-type':'application/json' // Error +} +let externalHeaders:externalRequestHeaders = { + cookie: 'session_id=123456', // Error + range: 'bytes=0-1023', // Error + 'content-type':'application/json' // Error +} +const setRequestHeaders1 = (headers: externalRequestHeaders) => { + headers.authorization =''; // Error +} +class RemoteTest{ + setCookie(cookie:string){ + cookie = 'cookie' + } + createHeaders(cookie:string,authToken?: string): rcp.RequestHeaders { + return { + authorization: authToken ? `Bearer ${authToken}` : undefined, // Error + accept: 'application/json', // Error + "cache-control": 'no-cache', + "user-agent": 'MyApp/2.0', + upgrade:'web', // Error + range:'' // Error + }; + } + constructor() { + createHeaders(basicHeaders.authorization!); // Error + } +} +const exRequestHeadersInterface: externalRequestHeadersInterface = { + authorization: 'Bearer token', //Error + customHeader1: 'value1' +}; +function processHeaders(headers: externalRequestHeadersInterface) { + console.log(headers.authorization); //Error + console.log(headers.customHeader1); +} +function createExHeaders(): externalRequestHeadersInterface { + return { + authorization: 'Bearer token', //Error + customHeader1: 'value1' + }; +} +typeof exRequestHeadersInterface.authorization; //Error +console.log('accept='+exRequestHeadersInterface.accept) //Error +function printHeaders(exheaders: externalRequestHeadersInterface) { + console.log(exheaders.authorization); //Error +} +const headersArray: externalRequestHeadersInterface[] = [ + { + authorization: 'application/json', //Error + customHeader1: 'header1Value1' + }, + { + 'cookie': 'sss', //Error + customHeader1: 'header1Value2' + } +]; +interface RequestConfig { + headers: externalRequestHeadersInterface; + url: string; + method: 'GET' | 'POST'; +} + +const config: RequestConfig = { + headers: { + 'authorization': 'application/json', //Error + customHeader1: 'configHeaderValue' + }, + url: 'https://example.com/api', + method: 'GET' +}; +export const headers:string[]=[ + 'authorization', + 'accept', + 'cache-control', + 'user-agent', + 'accept-charset', + 'accept-encoding', + 'accept-language', + 'cookie', + 'range', + 'upgrade', + 'content-type' +] + +//ResponseHeader part +let externalResponseHeader:externalResponseHeaders = { + 'accept-ranges':'', // Error + 'allow': '', // Error + 'cache-control': '', // Error + 'content-encoding': '' // Error +} +const setResponseHeaders = (headers: externalResponseHeaders) => { + headers.expires =''; // Error +} + +const exResponseHeadersInterface: externalResponseHeadersInterface = { + "www-authenticate": 'Bearer token', + customHeader2: 'value1' +}; +function processResponseHeaders(responseHeaders: externalResponseHeadersInterface) { + console.log(responseHeaders.date); // Error + console.log(responseHeaders.customHeader2); +} +function createExResponseHeaders(): externalResponseHeadersInterface { + return { + date: '2025', //Error + customHeader2: 'value1' + }; +} +typeof exResponseHeadersInterface.authorization; //Error +console.log('accept='+exResponseHeadersInterface.accept) //Error +function printResponseHeaders(exHeaders: externalResponseHeadersInterface) { + console.log(exHeaders.etag); //Error +} +const responseHeadersArray: externalResponseHeadersInterface[] = [ + { + "cache-control": 'application/json', + customHeader2: 'header1Value1' + }, + { + 'server': 'sss', //Error + customHeader2: 'header1Value2' + } +]; +interface ResponseConfig { + headers: externalResponseHeadersInterface; + url: string; + method: 'GET' | 'POST'; +} + +const config2: ResponseConfig = { + headers: { + 'content-encoding': 'application/json', //Error + customHeader2: 'configHeaderValue' + }, + url: 'https://example.com/api', + method: 'GET' +}; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.args.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..1b80aa9e7367c4d206bb53f8fc43c77fc24045d7 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.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": "" + } + } \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/type_literals.ts.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json similarity index 40% rename from ets2panda/linter/test/migrate/type_literals.ts.json rename to ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json index 45191b82e30c33c2b17335a0ceec474892e0dc17..3a348d3c8350c18237159008eeb22f282ceceb46 100644 --- a/ets2panda/linter/test/migrate/type_literals.ts.json +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.arkts2.json @@ -1,6 +1,6 @@ { "copyright": [ - "Copyright (c) 2024 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", @@ -15,643 +15,653 @@ ], "result": [ { - "line": 16, - "column": 14, - "endLine": 16, - "endColumn": 15, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 17, - "column": 14, - "endLine": 17, - "endColumn": 15, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 14, - "endLine": 18, - "endColumn": 15, - "problem": "ObjectTypeLiteral", - "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", - "severity": "ERROR" - }, - { - "line": 19, - "column": 22, - "endLine": 19, - "endColumn": 23, - "problem": "ObjectTypeLiteral", + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 39, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 19, - "column": 47, - "endLine": 19, - "endColumn": 48, - "problem": "ObjectTypeLiteral", + "line": 29, + "column": 5, + "endLine": 29, + "endColumn": 19, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 20, - "column": 20, - "endLine": 20, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "line": 37, + "column": 3, + "endLine": 37, + "endColumn": 35, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 21, - "column": 14, - "endLine": 21, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "line": 37, + "column": 3, + "endLine": 37, + "endColumn": 18, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 24, - "column": 6, - "endLine": 24, - "endColumn": 7, - "problem": "ObjectTypeLiteral", + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 37, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 30, - "column": 21, - "endLine": 30, - "endColumn": 22, - "problem": "ObjectTypeLiteral", + "line": 38, + "column": 3, + "endLine": 38, + "endColumn": 17, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 32, - "column": 11, - "endLine": 32, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 43, + "column": 5, + "endLine": 43, + "endColumn": 67, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 32, - "column": 16, - "endLine": 32, - "endColumn": 17, - "problem": "ObjectLiteralNoContextType", + "line": 43, + "column": 5, + "endLine": 43, + "endColumn": 20, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 33, - "column": 11, - "endLine": 33, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 33, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 33, - "column": 36, - "endLine": 33, - "endColumn": 37, - "problem": "ObjectLiteralNoContextType", + "line": 44, + "column": 5, + "endLine": 44, + "endColumn": 13, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 34, - "column": 11, - "endLine": 34, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 45, + "column": 5, + "endLine": 45, + "endColumn": 32, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 35, - "column": 19, - "endLine": 35, + "line": 45, + "column": 5, + "endLine": 45, "endColumn": 20, - "problem": "ObjectTypeLiteral", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 35, - "column": 44, - "endLine": 35, - "endColumn": 45, - "problem": "ObjectTypeLiteral", + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 30, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 36, - "column": 20, - "endLine": 36, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "line": 46, + "column": 5, + "endLine": 46, + "endColumn": 17, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 37, - "column": 11, - "endLine": 37, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 50, + "column": 10, + "endLine": 50, + "endColumn": 18, + "problem": "LimitedReturnTypeInference", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", "severity": "ERROR" }, { - "line": 40, - "column": 6, - "endLine": 40, - "endColumn": 7, - "problem": "ObjectTypeLiteral", + "line": 56, + "column": 3, + "endLine": 56, + "endColumn": 28, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 45, - "column": 5, - "endLine": 45, - "endColumn": 6, - "problem": "ObjectLiteralNoContextType", + "line": 56, + "column": 3, + "endLine": 56, + "endColumn": 19, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 48, - "column": 6, - "endLine": 48, - "endColumn": 7, - "problem": "ObjectLiteralNoContextType", + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 37, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 51, - "column": 8, - "endLine": 51, - "endColumn": 9, - "problem": "ObjectLiteralNoContextType", + "line": 57, + "column": 3, + "endLine": 57, + "endColumn": 20, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { "line": 58, - "column": 15, + "column": 3, "endLine": 58, - "endColumn": 16, - "problem": "ObjectTypeLiteral", + "endColumn": 38, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { "line": 58, - "column": 40, + "column": 3, "endLine": 58, - "endColumn": 41, - "problem": "ObjectTypeLiteral", + "endColumn": 20, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { "line": 59, - "column": 10, + "column": 3, "endLine": 59, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", + "endColumn": 32, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 63, - "column": 6, - "endLine": 63, - "endColumn": 7, - "problem": "ObjectTypeLiteral", + "line": 59, + "column": 3, + "endLine": 59, + "endColumn": 11, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 63, - "column": 31, - "endLine": 63, - "endColumn": 32, - "problem": "ObjectLiteralNoContextType", + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 26, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 65, - "column": 8, - "endLine": 65, - "endColumn": 9, - "problem": "ObjectTypeLiteral", + "line": 60, + "column": 3, + "endLine": 60, + "endColumn": 10, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 65, - "column": 33, - "endLine": 65, - "endColumn": 34, - "problem": "ObjectTypeLiteral", + "line": 61, + "column": 3, + "endLine": 61, + "endColumn": 25, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 66, - "column": 12, - "endLine": 66, - "endColumn": 13, - "problem": "ObjectLiteralNoContextType", + "line": 61, + "column": 3, + "endLine": 61, + "endColumn": 12, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 72, - "column": 22, - "endLine": 72, - "endColumn": 23, - "problem": "ObjectTypeLiteral", + "line": 62, + "column": 3, + "endLine": 62, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 73, - "column": 14, - "endLine": 73, - "endColumn": 15, - "problem": "ObjectTypeLiteral", + "line": 62, + "column": 3, + "endLine": 62, + "endColumn": 17, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 73, - "column": 38, - "endLine": 73, - "endColumn": 39, - "problem": "ObjectTypeLiteral", + "line": 67, + "column": 3, + "endLine": 67, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 75, - "column": 16, - "endLine": 75, + "line": 67, + "column": 3, + "endLine": 67, "endColumn": 17, - "problem": "ObjectTypeLiteral", + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { "line": 80, - "column": 3, + "column": 7, "endLine": 80, - "endColumn": 4, - "problem": "ObjectTypeLiteral", + "endColumn": 22, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 80, - "column": 19, - "endLine": 80, - "endColumn": 20, + "line": 81, + "column": 7, + "endLine": 81, + "endColumn": 19, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 68, + "endLine": 90, + "endColumn": 69, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 82, - "column": 20, - "endLine": 82, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "line": 99, + "column": 10, + "endLine": 99, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 57, + "endLine": 118, + "endColumn": 2, + "problem": "ArrayLiteralNoContextType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", "severity": "ERROR" }, { - "line": 85, + "line": 110, "column": 3, - "endLine": 85, + "endLine": 110, "endColumn": 4, - "problem": "LiteralAsPropertyName", + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 93, + "line": 114, "column": 3, - "endLine": 93, - "endColumn": 23, - "problem": "CallSignature", + "endLine": 114, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 94, - "column": 3, - "endLine": 94, - "endColumn": 22, - "problem": "ConstructorType", + "line": 115, + "column": 5, + "endLine": 115, + "endColumn": 20, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 95, - "column": 3, - "endLine": 95, - "endColumn": 26, - "problem": "IndexMember", + "line": 115, + "column": 5, + "endLine": 115, + "endColumn": 13, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 95, - "column": 18, - "endLine": 95, - "endColumn": 25, - "problem": "UnknownType", + "line": 125, + "column": 31, + "endLine": 125, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 98, - "column": 18, - "endLine": 98, - "endColumn": 19, - "problem": "ObjectTypeLiteral", + "line": 126, + "column": 12, + "endLine": 126, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 101, - "column": 3, - "endLine": 101, - "endColumn": 4, + "line": 127, + "column": 5, + "endLine": 127, + "endColumn": 40, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 127, + "column": 5, + "endLine": 127, + "endColumn": 20, "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 109, + "line": 149, "column": 3, - "endLine": 109, - "endColumn": 23, - "problem": "CallSignature", + "endLine": 149, + "endColumn": 21, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Use \"class\" instead of a type with call signature (arkts-no-call-signatures)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 110, + "line": 149, "column": 3, - "endLine": 110, - "endColumn": 22, - "problem": "ConstructorType", + "endLine": 149, + "endColumn": 18, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Use \"class\" instead of a type with constructor signature (arkts-no-ctor-signatures-type)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 111, + "line": 150, "column": 3, - "endLine": 111, - "endColumn": 26, - "problem": "IndexMember", + "endLine": 150, + "endColumn": 14, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Indexed signatures are not supported (arkts-no-indexed-signatures)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 111, - "column": 18, - "endLine": 111, - "endColumn": 25, - "problem": "UnknownType", + "line": 150, + "column": 3, + "endLine": 150, + "endColumn": 10, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 115, - "column": 49, - "endLine": 115, - "endColumn": 50, - "problem": "ObjectTypeLiteral", + "line": 151, + "column": 3, + "endLine": 151, + "endColumn": 22, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 116, - "column": 11, - "endLine": 116, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 151, + "column": 3, + "endLine": 151, + "endColumn": 18, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 118, - "column": 20, - "endLine": 118, - "endColumn": 21, - "problem": "ObjectTypeLiteral", + "line": 152, + "column": 3, + "endLine": 152, + "endColumn": 25, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 119, - "column": 11, - "endLine": 119, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 152, + "column": 3, + "endLine": 152, + "endColumn": 21, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 119, - "column": 30, - "endLine": 119, - "endColumn": 31, + "line": 158, + "column": 70, + "endLine": 158, + "endColumn": 71, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 119, - "column": 34, - "endLine": 119, - "endColumn": 35, + "line": 159, + "column": 3, + "endLine": 159, + "endColumn": 21, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 10, + "endLine": 167, + "endColumn": 11, "problem": "ObjectLiteralNoContextType", "suggest": "", "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 121, - "column": 25, - "endLine": 121, - "endColumn": 26, - "problem": "ObjectTypeLiteral", + "line": 177, + "column": 66, + "endLine": 186, + "endColumn": 2, + "problem": "ArrayLiteralNoContextType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", "severity": "ERROR" }, { - "line": 124, - "column": 11, - "endLine": 124, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 178, + "column": 3, + "endLine": 178, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 124, - "column": 12, - "endLine": 124, - "endColumn": 17, - "problem": "ComputedPropertyName", + "line": 179, + "column": 5, + "endLine": 179, + "endColumn": 20, + "problem": "LiteralAsPropertyName", "suggest": "", "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 127, - "column": 11, - "endLine": 127, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 182, + "column": 3, + "endLine": 182, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 127, - "column": 31, - "endLine": 127, - "endColumn": 32, - "problem": "ObjectLiteralNoContextType", + "line": 183, + "column": 5, + "endLine": 183, + "endColumn": 20, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 129, - "column": 11, - "endLine": 129, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 183, + "column": 5, + "endLine": 183, + "endColumn": 13, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" }, { - "line": 129, - "column": 17, - "endLine": 129, - "endColumn": 23, - "problem": "TypeQuery", + "line": 193, + "column": 33, + "endLine": 193, + "endColumn": 34, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 131, - "column": 11, - "endLine": 131, - "endColumn": 12, - "problem": "ObjectTypeLiteral", + "line": 194, + "column": 12, + "endLine": 194, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", "suggest": "", - "rule": "Object literals cannot be used as type declarations (arkts-no-obj-literals-as-types)", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", "severity": "ERROR" }, { - "line": 131, - "column": 17, - "endLine": 131, - "endColumn": 23, - "problem": "TypeQuery", + "line": 195, + "column": 5, + "endLine": 195, + "endColumn": 43, + "problem": "QuotedHyphenPropsDeprecated", "suggest": "", - "rule": "\"typeof\" operator is allowed only in expression contexts (arkts-no-type-query)", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", "severity": "ERROR" }, { - "line": 133, - "column": 10, - "endLine": 133, - "endColumn": 11, - "problem": "ObjectLiteralNoContextType", + "line": 195, + "column": 5, + "endLine": 195, + "endColumn": 23, + "problem": "LiteralAsPropertyName", "suggest": "", - "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..eaeaa7697684c7a6a6ecffddcb301018911f035e --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk.ets.json @@ -0,0 +1,168 @@ +{ + "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": 50, + "column": 10, + "endLine": 50, + "endColumn": 18, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 90, + "column": 68, + "endLine": 90, + "endColumn": 69, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 99, + "column": 10, + "endLine": 99, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 57, + "endLine": 118, + "endColumn": 2, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 110, + "column": 3, + "endLine": 110, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 114, + "column": 3, + "endLine": 114, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 125, + "column": 31, + "endLine": 125, + "endColumn": 32, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 12, + "endLine": 126, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 158, + "column": 70, + "endLine": 158, + "endColumn": 71, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 167, + "column": 10, + "endLine": 167, + "endColumn": 11, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 177, + "column": 66, + "endLine": 186, + "endColumn": 2, + "problem": "ArrayLiteralNoContextType", + "suggest": "", + "rule": "Array literals must contain elements of only inferrable types (arkts-no-noninferrable-arr-literals)", + "severity": "ERROR" + }, + { + "line": 178, + "column": 3, + "endLine": 178, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 182, + "column": 3, + "endLine": 182, + "endColumn": 4, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 193, + "column": 33, + "endLine": 193, + "endColumn": 34, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + }, + { + "line": 194, + "column": 12, + "endLine": 194, + "endColumn": 13, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets new file mode 100755 index 0000000000000000000000000000000000000000..18c729ed2e0d4d28d323d113401ff39648303096 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets @@ -0,0 +1,117 @@ +/* + * 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 { rcp } from "@kit.RemoteCommunicationKit"; +export type externalRequestHeaders = rcp.RequestHeaders; +export type externalResponseHeaders = rcp.ResponseHeaders; +export interface externalRequestHeadersInterface extends rcp.RequestHeaders { + customHeader1: string; +} +export interface externalResponseHeadersInterface extends rcp.ResponseHeaders { + customHeader2: string; +} +export const headers:string[]=[ + 'accept-ranges', + 'allow', + 'cache-control', + 'content-encoding', + 'content-range', + 'content-type', + 'date', + 'etag', + 'expires', + 'location', + 'retry-after', + 'set-cookie', + 'server', + 'www-authenticate', +] + +export default function getCookie():string{ + return headers[7]; +} +export const generateRange = () => 'range'; +export let localUpgrade:string = 'upgrade'; +export let localRange:string = generateRange(); +export class Header{ + acceptLanguage = headers[6]; + cookie = 'cookie'; + getUpgrade(){ + return localUpgrade; + } +} + +export interface internalResponseHeaders { + rcpHeaders: rcp.ResponseHeaders; + additionalHeaders: T; +} +interface AdditionalHeaders { + customHeader: string; +} +type CustomResponseHeaders = internalResponseHeaders; +const cusRequestHeaders: CustomResponseHeaders = { + rcpHeaders: { + 'content-range': 'json', // Error + server: 'bytes=0-1023' // Error + }, + additionalHeaders: { + customHeader: 'custom value' + } +}; +const basicHeaders: rcp.ResponseHeaders = { + "set-cookie": 'Bearer abc123', + 'retry-after': 'application/json' // Error +}; +basicHeaders.allow =''; // Error +function createHeaders(cookie:string,authToken?: string): rcp.ResponseHeaders { + return { + server: undefined, + expires: 'application/json', + 'accept-ranges': 'no-cache', // Error + 'www-authenticate': 'MyApp/2.0' // Error + }; +} +createHeaders(basicHeaders.date!); // Error +function getRange(){ + return basicHeaders?.["content-range"]; // Error +} + +export type localResponseHeaders = rcp.ResponseHeaders; +let localHeaders:localResponseHeaders = { + 'content-encoding': 'UTF-8', // Error + 'content-range': 'gzip, deflate', // Error + 'location': 'en-US,en;q=0.9', // Error + 'set-cookie': 'session_id=123456', // Error + 'accept-ranges': 'bytes=0-1023', // Error + 'www-authenticate': 'websocket', // Error + 'content-type':'application/json' // Error +} +class RemoteTest{ + setCookie(cookie:string){ + cookie = 'cookie' + } + createHeaders(cookie:string,authToken?: string): rcp.ResponseHeaders { + return { + 'accept-ranges': undefined, // Error + 'content-encoding': 'application/json', // Error + date: '2025', // Error + "cache-control": 'no', + allow:'web', // Error + 'www-authenticate':'' // Error + }; + } + constructor() { + createHeaders(basicHeaders.date!); // Error + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.args.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.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/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..f2d125c5784100f6d7f32f00cfe38427f50a997b --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.arkts2.json @@ -0,0 +1,328 @@ +{ + "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": 65, + "column": 5, + "endLine": 65, + "endColumn": 28, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 5, + "endLine": 65, + "endColumn": 20, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 73, + "column": 3, + "endLine": 73, + "endColumn": 15, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 3, + "endLine": 74, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 74, + "column": 3, + "endLine": 74, + "endColumn": 16, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 32, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 81, + "column": 5, + "endLine": 81, + "endColumn": 20, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 5, + "endLine": 82, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 82, + "column": 5, + "endLine": 82, + "endColumn": 23, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 86, + "column": 10, + "endLine": 86, + "endColumn": 18, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 3, + "endLine": 92, + "endColumn": 30, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 92, + "column": 3, + "endLine": 92, + "endColumn": 21, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 3, + "endLine": 93, + "endColumn": 35, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 93, + "column": 3, + "endLine": 93, + "endColumn": 18, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 31, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 94, + "column": 3, + "endLine": 94, + "endColumn": 13, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 3, + "endLine": 95, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 95, + "column": 3, + "endLine": 95, + "endColumn": 15, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 3, + "endLine": 96, + "endColumn": 34, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 96, + "column": 3, + "endLine": 96, + "endColumn": 18, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 34, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 97, + "column": 3, + "endLine": 97, + "endColumn": 21, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 3, + "endLine": 98, + "endColumn": 36, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 98, + "column": 3, + "endLine": 98, + "endColumn": 17, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 7, + "endLine": 106, + "endColumn": 34, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 106, + "column": 7, + "endLine": 106, + "endColumn": 22, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 45, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 107, + "column": 7, + "endLine": 107, + "endColumn": 25, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 109, + "column": 7, + "endLine": 109, + "endColumn": 22, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 7, + "endLine": 111, + "endColumn": 28, + "problem": "QuotedHyphenPropsDeprecated", + "suggest": "", + "rule": "Object property names must be valid identifiers.Single-quoted and hyphenated properties are not supported. (sdk-no-literal-as-property-name)", + "severity": "ERROR" + }, + { + "line": 111, + "column": 7, + "endLine": 111, + "endColumn": 25, + "problem": "LiteralAsPropertyName", + "suggest": "", + "rule": "Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.json b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..fe966ab865f8e5a1816ebf8e86731c56e1a9d321 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/quoted_hyphen_props_deprecated_sdk2.ets.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": 86, + "column": 10, + "endLine": 86, + "endColumn": 18, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/return_new_interface.ets b/ets2panda/linter/test/sdkwhite/return_new_interface.ets new file mode 100644 index 0000000000000000000000000000000000000000..3bbb797d6da8522b3b4d9e7f8a0a641eb1fdedd5 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.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. + */ +'use static' + +interface CircleInterface { + config: any; +} + +interface RectInterface { + config: any; +} + +function makeCI(c: CircleInterface) { + return new c({}); // ERROR: using `new` with interface +} + +function makeRe(r: RectInterface) { + return new r({}); // ERROR +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/return_new_interface.ets.args.json b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..bc4d2071daf6e9354e711c3b74b6be2b56659066 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.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/sdkwhite/return_new_interface.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..7b974d3450d22c88c7a7dedab6df6e5722470b8d --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.arkts2.json @@ -0,0 +1,98 @@ +{ + "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": 18, + "column": 11, + "endLine": 18, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 14, + "endLine": 26, + "endColumn": 15, + "problem": "ConstructorIfaceFromSdk", + "suggest": "", + "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 14, + "endLine": 26, + "endColumn": 15, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 10, + "endLine": 29, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 14, + "endLine": 30, + "endColumn": 15, + "problem": "ConstructorIfaceFromSdk", + "suggest": "", + "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 14, + "endLine": 30, + "endColumn": 15, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/sdkwhite/return_new_interface.ets.json b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..4cc659e3fd9ae63ec5cd793c2863ebdebb471e3c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/return_new_interface.ets.json @@ -0,0 +1,58 @@ +{ + "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": 18, + "column": 11, + "endLine": 18, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 11, + "endLine": 22, + "endColumn": 14, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 10, + "endLine": 25, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 10, + "endLine": 29, + "endColumn": 16, + "problem": "LimitedReturnTypeInference", + "suggest": "", + "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk/@kit.AccessibilityKit.d.ts b/ets2panda/linter/test/sdkwhite/sdk/@kit.AccessibilityKit.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..d4147faf0560b34c7fd70b7f5e84edebdc307267 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk/@kit.AccessibilityKit.d.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. + */ + +import { AccessibilityElement, NotAccessibilityElement } from './api/application/AccessibilityExtensionContext'; + +interface Simulate { + getFocusElement(): Promise; + getFocusElementNotAccessibilityElement(): Promise; +} + +export class AccessibilityExtensionAbility { + context: Simulate; +} diff --git a/ets2panda/linter/test/sdkwhite/sdk/api/application/AccessibilityExtensionContext.d.ts b/ets2panda/linter/test/sdkwhite/sdk/api/application/AccessibilityExtensionContext.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b217c95359779c81d9b968e639c2fd9134f792a --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk/api/application/AccessibilityExtensionContext.d.ts @@ -0,0 +1,30 @@ +/* + * 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. + */ + +// save it in api/application/AccessibilityExtensionContext.d.ts +export interface AccessibilityElement { + attributeValue( + attributeName: T, + callback: AsyncCallback + ): void; + attributeValue(attributeName: T): Promise; +} +export interface NotAccessibilityElement { + attributeValue( + attributeName: T, + callback: AsyncCallback + ): void; + attributeValue(attributeName: T): Promise; +} diff --git a/ets2panda/linter/test/sdkwhite/sdk/declarations/alert_dialog.d.ts b/ets2panda/linter/test/sdkwhite/sdk/declarations/alert_dialog.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..1093278402c540a6f11290f961cd8fb0f2a6b89c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk/declarations/alert_dialog.d.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. + */ + +export declare interface TextStyle { + wordBreak?: WordBreak; +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk/declarations/hyperlink.d.ts b/ets2panda/linter/test/sdkwhite/sdk/declarations/hyperlink.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..aaf5150b5ec7b2da083865d0208ad8b9a60609f7 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk/declarations/hyperlink.d.ts @@ -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. + */ + +export declare class HyperlinkAttribute { + color(value: Color | number | string | Resource): HyperlinkAttribute; +} +export declare const HyperlinkInterface: HyperlinkAttribute; \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk/declarations/styled_string.d.ts b/ets2panda/linter/test/sdkwhite/sdk/declarations/styled_string.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..fbdd125c2fd5088cd96ff46a38a58faf94d6d8bf --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk/declarations/styled_string.d.ts @@ -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. + */ + +export declare class TextStyle { + constructor(value?: TextStyleInterface); + readonly fontColor?: ResourceColor; + readonly fontFamily?: string; + readonly fontSize?: number; + readonly fontWeight?: number; + readonly fontStyle?: FontStyle; +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets new file mode 100755 index 0000000000000000000000000000000000000000..c50d5885dafbfff29cadcffe094db980bf764b07 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.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. + */ + +import {cloudDatabase} from '@hms.core.deviceCloudGateway.cloudDatabase'; +class Test extends cloudDatabase.DatabaseObject{ + +} +new cloudDatabase.DatabaseQuery(Test); // NOT OK \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.args.json b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..9c3d9734324a7b8b9c89fa7f62dce43ac44888ca --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.arkts2.json new file mode 100755 index 0000000000000000000000000000000000000000..745ab994b23232173122f6924c1d6ca84dd291a9 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.arkts2.json @@ -0,0 +1,38 @@ +{ + "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": 5, + "endLine": 20, + "endColumn": 32, + "problem": "DynamicCtorCall", + "suggest": "", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 19, + "endLine": 20, + "endColumn": 32, + "problem": "ConstructorTypesDeprecated", + "suggest": "", + "rule": "Constructor types are not supported - use lambda functions instead. (sdk-constructor-funcs)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.json b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..9f305c86d7ff705098b1e480818e125d5e6e3a4a --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_constructor_funcs.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": [] +} diff --git a/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets new file mode 100644 index 0000000000000000000000000000000000000000..1f6135015a539ca2b5bf9dd9eb3ea23e41077521 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.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. + */ + +import { rcp } from '@kit.RemoteCommunicationKit'; + + +const MyNetworkOutputQueueConstructor: rcp.NetworkOutputQueueConstructor = rcp.NetworkOutputQueue; // Error + + diff --git a/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.args.json b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.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/sdkwhite/sdk_ctor_signatures_iface.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..aef924b6e99027892ff9683c87cae9241ad725bb --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.arkts2.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": 19, + "column": 40, + "endLine": 19, + "endColumn": 73, + "problem": "ConstructorIfaceFromSdk", + "suggest": "", + "rule": "Construct signatures are not supported in interfaces.(sdk-ctor-signatures-iface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.json b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_ctor_signatures_iface.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/sdkwhite/sdk_optional_methods.ets b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets new file mode 100644 index 0000000000000000000000000000000000000000..c7a1a79f36e06a784aa220519b33a7433f8da96e --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets @@ -0,0 +1,112 @@ +/* + * 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 { webview } from '@kit.ArkWeb'; +import { AbilityLifecycleCallback, UIAbility } from '@kit.AbilityKit'; + +class OptionalMethod implements webview.NativeMediaPlayerBridge { + updateRect(x: number, y: number, width: number, height: number): void { + throw new Error('Method not implemented.'); + } + + play(): void { + throw new Error('Method not implemented.'); + } + + pause(): void { + throw new Error('Method not implemented.'); + } + + seek(targetTime: number): void { + throw new Error('Method not implemented.'); + } + + setVolume(volume: number): void { + throw new Error('Method not implemented.'); + } + + setMuted(muted: boolean): void { + throw new Error('Method not implemented.'); + } + + setPlaybackRate(playbackRate: number): void { + throw new Error('Method not implemented.'); + } + + release(): void { + throw new Error('Method not implemented.'); + } + + enterFullscreen(): void { + throw new Error('Method not implemented.'); + } + + exitFullscreen(): void { + throw new Error('Method not implemented.'); + } + + resumePlayer?(): void { // Error + throw new Error('Method not implemented.'); + } + + suspendPlayer?(type: webview.SuspendType): void { // Error + throw new Error('Method not implemented.'); + } +} + +class MyAbilityLifecycleCallback extends AbilityLifecycleCallback { + // 用例1: 重写为必选方法 预期报错 用例结果--Error 未识别 + onWillNewWant(ability: UIAbility) { + console.log('AbilityLifecycleCallback onWillNewWant.'); + } + + // 用例2: 重写为可选方法 预期报错 用例结果--Pass + onAbilityWillCreate?(ability: UIAbility) { + console.log('AbilityLifecycleCallback onAbilityWillCreate.'); + } + + // 用例3:使用必选属性重写父类方法 预期无报错 用例结果--Pass + onAbilityWillForeground: (ability: UIAbility) => void = + (ability: UIAbility) => { + console.log('AbilityLifecycleCallback onAbilityWillForeground'); + } + // 用例4:使用可选属性重写父类方法 预期无报错 用例结果--Pass + onAbilityWillBackground?: (ability: UIAbility) => void = + (ability: UIAbility) => { + console.log('AbilityLifecycleCallback onAbilityWillBackground'); + } +} + +// 用例5 类型断言 预期无报错 用例结果--Pass +const callback: AbilityLifecycleCallback = { + onAbilityWillForeground: (ability: UIAbility): void => { + console.log('AbilityLifecycleCallback onAbilityWillForeground'); + } +} as AbilityLifecycleCallback; + +// 用例6 泛型类拓展 +class GenericHandler extends AbilityLifecycleCallback { + // 预期报错 用例结果--Error 未识别 + onAbilityWillCreate(ability: T): void { /*...*/ } + // 预期无报错 用例结果--Pass + onAbilityWillForeground: (ability: T) => void = + (ability: T) => { + console.log('AbilityLifecycleCallback onAbilityWillForeground'); + } +} + +// 接口不能继承类;不能使用交叉类型扩展;不能声明合并 + + diff --git a/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.args.json b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.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/sdkwhite/sdk_optional_methods.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..bd2e0891ba67adb5782d1b211a72411babec8158 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.arkts2.json @@ -0,0 +1,98 @@ +{ + "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": 60, + "column": 3, + "endLine": 62, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 3, + "endLine": 66, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 60, + "column": 15, + "endLine": 60, + "endColumn": 16, + "problem": "OptionalMethod", + "suggest": "", + "rule": "Optional methods are not supported (arkts-optional-methods)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 16, + "endLine": 64, + "endColumn": 17, + "problem": "OptionalMethod", + "suggest": "", + "rule": "Optional methods are not supported (arkts-optional-methods)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 3, + "endLine": 78, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 71, + "column": 3, + "endLine": 73, + "endColumn": 4, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + }, + { + "line": 76, + "column": 22, + "endLine": 76, + "endColumn": 23, + "problem": "OptionalMethod", + "suggest": "", + "rule": "Optional methods are not supported (arkts-optional-methods)", + "severity": "ERROR" + }, + { + "line": 102, + "column": 3, + "endLine": 102, + "endColumn": 52, + "problem": "OptionalMethodFromSdk", + "suggest": "", + "rule": "API no longer supports optional methods (sdk-optional-methods)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.json b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_optional_methods.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/sdkwhite/sdk_props_by_index.ets b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets new file mode 100644 index 0000000000000000000000000000000000000000..04afb6c7b88742cd183417b32e81585ca9a9dbfc --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets @@ -0,0 +1,51 @@ +/* + * 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. + */ + +// if in real env, remvoe './sdk/' +import { AccessibilityExtensionAbility } from './sdk/@kit.AccessibilityKit'; + +class EntryAbility extends AccessibilityExtensionAbility { + onConnect(): void { + let axContext = this.context; + let accessibilityElement = axContext.getFocusElement(); + accessibilityElement.then((data) => { + data.attributeValue<'accessibilityFocused'>('accessibilityFocused'); // error + }); + } + + noErrorCase(): void { + let localAccessibilityElement = customFoo(); + localAccessibilityElement.then((data) => { + data.attributeValue<'accessibilityFocused'>('accessibilityFocused'); // ok + }); + + let axContext = this.context; + let notAccessibilityElement = axContext.getFocusElementNotAccessibilityElement(); + notAccessibilityElement.then((data) => { + data.attributeValue<'accessibilityFocused'>('accessibilityFocused'); // ok + }); + } +} +interface AccessibilityElement { + attributeValue( + attributeName: T, + callback: AsyncCallback + ): void; + attributeValue(attributeName: T): Promise; +} + +async function customFoo(): Promise { + return (await {}) as AccessibilityElement; +} diff --git a/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.args.json b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..948b846fe04969bf5ccbe8bd9dc4a18559ce0c2c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.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/sdkwhite/sdk_props_by_index.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..2e3d6073f6806f77595a8fbbc209882f804ff66f --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.arkts2.json @@ -0,0 +1,58 @@ +{ + "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": 24, + "column": 7, + "endLine": 24, + "endColumn": 26, + "problem": "PropertyAccessByIndexFromSdk", + "suggest": "", + "rule": "Indexed access is not supported for fields (sdk-no-props-by-index)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 29, + "endLine": 44, + "endColumn": 54, + "problem": "IndexedAccessType", + "suggest": "", + "rule": "Indexed access types are not supported (arkts-no-aliases-by-index)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 85, + "endLine": 46, + "endColumn": 110, + "problem": "IndexedAccessType", + "suggest": "", + "rule": "Indexed access types are not supported (arkts-no-aliases-by-index)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 17, + "endLine": 50, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.json b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..0ffe95853a538316cc07a24717f8476ac2e06216 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_props_by_index.ets.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": 44, + "column": 29, + "endLine": 44, + "endColumn": 54, + "problem": "IndexedAccessType", + "suggest": "", + "rule": "Indexed access types are not supported (arkts-no-aliases-by-index)", + "severity": "ERROR" + }, + { + "line": 46, + "column": 85, + "endLine": 46, + "endColumn": 110, + "problem": "IndexedAccessType", + "suggest": "", + "rule": "Indexed access types are not supported (arkts-no-aliases-by-index)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 17, + "endLine": 50, + "endColumn": 18, + "problem": "ObjectLiteralNoContextType", + "suggest": "", + "rule": "Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets new file mode 100755 index 0000000000000000000000000000000000000000..a8d6e79d57859051401d12d0dc37f02441ffc749 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets @@ -0,0 +1,55 @@ +/* + * 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. + */ + +import {worker} from '@kit.ArkTS'; // sdk-type-query report in real env +// // test1 +import sendablePhotoAccessHelper from '@ohos.file.sendablePhotoAccessHelper' // 报错 PASS + +// test2 +import mySendablePhotoAccessHelper from '@ohos.file.sendablePhotoAccessHelper' // 报错 PASS + +import { dataSharePredicates } from '@kit.ArkData'; +import { photoAccessHelper } from '@kit.MediaLibraryKit'; +import spHelper from '@ohos.file.sendablePhotoAccessHelper'; // Error-sendable不再支持 + +worker.parentPort.self; + +const self = worker.parentPort.self; + +console.log(worker.parentPort.self) + +const parentPort = worker.parentPort; +parentPort.self.name; +parentPort.self.clearTimeout; + +const workerport = worker.workerPort; +workerport.self.name; +workerport.self.clearTimeout; + +let sHelper = spHelper.getPhotoAccessHelper(globalThis.abilityContext); +let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates(); +let fetchOptions: photoAccessHelper.FetchOptions = { + fetchColumns: [], + predicates: predicates +}; +// Array +export const sharedPhotoAssetList = sHelper.getSharedPhotoAssets(fetchOptions); +sharedPhotoAssetList.forEach((asset, index) => { + let pt = asset.position // Error-position:PositionType不再可用-未识别 + let ps = asset.subtype // Error-subtype:PhotoSubtype不再可用-未识别 + let aa = asset.movingPhotoEffectMode // Error-movingPhotoEffectMode:MovingPhotoEffectMode 不再可用-未识别 + let bb = asset.dynamicRangeType // Error-dynamicRangeType:DynamicRangeType 不再可用-未识别 + let cc = asset.thumbnailVisible // Error-thumbnailVisible:ThumbnailVisibility 不再可用-未识别 +}); \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.args.json b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.args.json new file mode 100755 index 0000000000000000000000000000000000000000..3ef4496a819a201892114d1c90f78ae32053c334 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_type_query.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/migrate/function_expression.ts.migrate.json b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json old mode 100644 new mode 100755 similarity index 32% rename from ets2panda/linter/test/migrate/function_expression.ts.migrate.json rename to ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json index 7d294016f97ab9956de77d29efc4a7dab1474c1d..67a42975bf378b67bc2de3e51dd05fa085910e55 --- a/ets2panda/linter/test/migrate/function_expression.ts.migrate.json +++ b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.arkts2.json @@ -1,333 +1,307 @@ { + "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": 15, - "endLine": 16, - "endColumn": 29, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 18, - "endLine": 20, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, { "line": 18, "column": 39, "endLine": 18, - "endColumn": 40, - "problem": "AnyType", + "endColumn": 77, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 23, - "column": 10, - "endLine": 25, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 21, + "column": 41, + "endLine": 21, + "endColumn": 79, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 28, - "column": 17, - "endLine": 30, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 25, + "column": 22, + "endLine": 25, + "endColumn": 60, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 32, - "column": 2, - "endLine": 34, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 27, + "column": 19, + "endLine": 27, + "endColumn": 23, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 36, + "line": 29, "column": 7, - "endLine": 38, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 41, - "column": 26, - "endLine": 43, - "endColumn": 2, - "problem": "FunctionExpression", - "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", - "severity": "ERROR" - }, - { - "line": 44, - "column": 27, - "endLine": 46, - "endColumn": 2, - "problem": "FunctionExpression", + "endLine": 29, + "endColumn": 36, + "problem": "AnyType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 48, - "column": 22, - "endLine": 50, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 29, + "column": 32, + "endLine": 29, + "endColumn": 36, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 48, - "column": 22, - "endLine": 50, - "endColumn": 2, - "problem": "LimitedReturnTypeInference", + "line": 31, + "column": 31, + "endLine": 31, + "endColumn": 35, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Function return type inference is limited (arkts-no-implicit-return-types)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 48, - "column": 35, - "endLine": 48, - "endColumn": 38, + "line": 33, + "column": 7, + "endLine": 33, + "endColumn": 37, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 52, - "column": 19, - "endLine": 54, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 34, + "column": 17, + "endLine": 34, + "endColumn": 21, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 52, - "column": 19, - "endLine": 54, - "endColumn": 2, - "problem": "GeneratorFunction", + "line": 35, + "column": 17, + "endLine": 35, + "endColumn": 29, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Generator functions are not supported (arkts-no-generators)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 53, - "column": 3, - "endLine": 53, - "endColumn": 10, - "problem": "YieldExpression", + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 37, + "problem": "AnyType", "suggest": "", - "rule": "Generator functions are not supported (arkts-no-generators)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 56, + "line": 38, "column": 17, - "endLine": 58, - "endColumn": 2, - "problem": "FunctionExpression", + "endLine": 38, + "endColumn": 21, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 60, - "column": 18, - "endLine": 62, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 39, + "column": 17, + "endLine": 39, + "endColumn": 29, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 64, - "column": 19, - "endLine": 66, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 71, + "problem": "AnyType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 71, - "column": 25, - "endLine": 76, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 41, + "column": 45, + "endLine": 41, + "endColumn": 70, + "problem": "GlobalThisError", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", "severity": "ERROR" }, { - "line": 78, - "column": 12, - "endLine": 80, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 42, + "column": 63, + "endLine": 42, + "endColumn": 102, + "problem": "DynamicCtorCall", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "\"new\" expression with dynamic constructor type is not supported (arkts-no-dynamic-ctor-call)", "severity": "ERROR" }, { - "line": 82, - "column": 5, - "endLine": 84, - "endColumn": 5, + "line": 48, + "column": 14, + "endLine": 48, + "endColumn": 79, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 82, - "column": 19, - "endLine": 84, - "endColumn": 5, - "problem": "PropertyAccessByIndex", + "line": 49, + "column": 31, + "endLine": 49, + "endColumn": 36, + "problem": "AnyType", "suggest": "", - "rule": "Indexed access is not supported for fields (arkts-no-props-by-index)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 82, - "column": 19, - "endLine": 84, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 49, + "column": 38, + "endLine": 49, + "endColumn": 43, + "problem": "AnyType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 86, - "column": 6, - "endLine": 88, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 50, + "column": 7, + "endLine": 50, + "endColumn": 26, + "problem": "AnyType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 91, - "column": 9, - "endLine": 93, - "endColumn": 4, - "problem": "FunctionExpression", + "line": 50, + "column": 18, + "endLine": 50, + "endColumn": 26, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 96, - "column": 25, - "endLine": 98, - "endColumn": 2, - "problem": "FunctionExpression", + "line": 51, + "column": 7, + "endLine": 51, + "endColumn": 25, + "problem": "AnyType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 102, - "column": 9, - "endLine": 104, - "endColumn": 17, - "problem": "AnyType", + "line": 51, + "column": 18, + "endLine": 51, + "endColumn": 25, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 104, + "line": 52, "column": 7, - "endLine": 104, - "endColumn": 17, - "problem": "FunctionBind", + "endLine": 52, + "endColumn": 39, + "problem": "AnyType", "suggest": "", - "rule": "'Function.bind' is not supported (arkts-no-func-bind)", - "severity": "WARNING" + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" }, { - "line": 102, - "column": 15, - "endLine": 104, - "endColumn": 6, - "problem": "FunctionExpression", + "line": 52, + "column": 18, + "endLine": 52, + "endColumn": 39, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 108, - "column": 16, - "endLine": 108, - "endColumn": 55, - "problem": "FunctionExpression", + "line": 53, + "column": 7, + "endLine": 53, + "endColumn": 34, + "problem": "AnyType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 109, - "column": 24, - "endLine": 109, - "endColumn": 75, - "problem": "FunctionExpression", + "line": 53, + "column": 18, + "endLine": 53, + "endColumn": 34, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" }, { - "line": 112, - "column": 5, - "endLine": 112, - "endColumn": 45, - "problem": "FunctionExpression", + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 34, + "problem": "AnyType", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 113, - "column": 10, - "endLine": 113, - "endColumn": 50, - "problem": "FunctionExpression", + "line": 54, + "column": 18, + "endLine": 54, + "endColumn": 34, + "problem": "SdkTypeQuery", "suggest": "", - "rule": "Use arrow functions instead of function expressions (arkts-no-func-expressions)", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.json b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.json new file mode 100755 index 0000000000000000000000000000000000000000..0ab8ef5d47eb572b0c10ce268978a5d243d049e2 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sdk_type_query.ets.json @@ -0,0 +1,178 @@ +{ + "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": 18, + "column": 39, + "endLine": 18, + "endColumn": 77, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 41, + "endLine": 21, + "endColumn": 79, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 22, + "endLine": 25, + "endColumn": 60, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 36, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 7, + "endLine": 33, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 7, + "endLine": 37, + "endColumn": 37, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 5, + "endLine": 41, + "endColumn": 71, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 45, + "endLine": 41, + "endColumn": 55, + "problem": "GlobalThis", + "suggest": "", + "rule": "\"globalThis\" is not supported (arkts-no-globalthis)", + "severity": "WARNING" + }, + { + "line": 48, + "column": 14, + "endLine": 48, + "endColumn": 79, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 31, + "endLine": 49, + "endColumn": 36, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 38, + "endLine": 49, + "endColumn": 43, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 7, + "endLine": 50, + "endColumn": 26, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 7, + "endLine": 51, + "endColumn": 25, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 7, + "endLine": 52, + "endColumn": 39, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 7, + "endLine": 53, + "endColumn": 34, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 7, + "endLine": 54, + "endColumn": 34, + "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/sdkwhite/sendable_class_interface_property_sdk.ets b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets new file mode 100644 index 0000000000000000000000000000000000000000..6b0535ba89c5308ed33473b5be9a1c4014bf4bb0 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.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. + */ + +// they both is not in sdkwhitelist after updated sdkwhitelist. +import { SharedPhotoAsset } from '@ohos.file.sendablePhotoAccessHelper'; +import { SharedPhotoAsset } from '@ohos.file.photoAccessHelper'; diff --git a/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.args.json b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..d8d3390ad9befeca9b595017d9eea0f5ada3d049 --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.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": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..c65d038d23121eefab8e368259656f68644e6d6c --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.arkts2.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": 17, + "column": 34, + "endLine": 17, + "endColumn": 72, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.json b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..eecd9ba0f40e73a2d8f6749d55ebaecbcb859c2f --- /dev/null +++ b/ets2panda/linter/test/sdkwhite/sendable_class_interface_property_sdk.ets.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": 17, + "column": 34, + "endLine": 17, + "endColumn": 72, + "problem": "SdkTypeQuery", + "suggest": "", + "rule": "Using typeof as a type is not allowed in this API (sdk-type-query)", + "severity": "ERROR" + } + ] +} diff --git a/ets2panda/linter/tsconfig.json b/ets2panda/linter/tsconfig.json index 17e27ba6f74434635613947d84f5fbb45179c9ed..8f1b7267043d5fefb643b5431a53d7c856508daf 100644 --- a/ets2panda/linter/tsconfig.json +++ b/ets2panda/linter/tsconfig.json @@ -9,7 +9,10 @@ "preserveConstEnums": true, "sourceMap": true, "outDir": "build", - "strict": true + "strict": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true }, "include": ["src/**/*"] diff --git a/ets2panda/linter/webpack.config.js b/ets2panda/linter/webpack.config.js index f8269189a80967835f80206f755b39047cc40945..15ee37c29b5dc1cf0dd3e6ae4468a81a5e4a514d 100644 --- a/ets2panda/linter/webpack.config.js +++ b/ets2panda/linter/webpack.config.js @@ -25,5 +25,10 @@ module.exports = { }, output: { filename: 'tslinter.js' - } + }, + resolve: { + alias: { + json5: require.resolve('json5/dist/index.js'), + } + } }; diff --git a/ets2panda/lsp/BUILD.gn b/ets2panda/lsp/BUILD.gn index 08ec8fd1b92d23d9ca5553625bcff7ca53b1dc1a..db6d280f279002c4aa638dc72e3914b645d132a5 100644 --- a/ets2panda/lsp/BUILD.gn +++ b/ets2panda/lsp/BUILD.gn @@ -41,22 +41,54 @@ config("libes2panda_lsp_config") { ohos_source_set("libes2panda_lsp_static") { sources = [ "src/api.cpp", + "src/applicable_refactors.cpp", "src/brace_matching.cpp", "src/cancellation_token.cpp", + "src/class_hierarchy.cpp", + "src/class_hierarchy_info.cpp", "src/classifier.cpp", + "src/code_fix_provider.cpp", "src/completions.cpp", + "src/completions_details.cpp", + "src/create_type_help_items.cpp", "src/find_references.cpp", "src/find_rename_locations.cpp", + "src/find_safe_delete_location.cpp", + "src/formatting/formatting.cpp", + "src/formatting/formatting_context.cpp", + "src/formatting/formatting_settings.cpp", + "src/formatting/rules.cpp", + "src/formatting/rules_map.cpp", + "src/generate_constructor.cpp", "src/get_adjusted_location.cpp", + "src/get_class_property_info.cpp", + "src/get_definition_and_bound_span.cpp", + "src/get_safe_delete_info.cpp", + "src/inlay_hints.cpp", "src/internal_api.cpp", + "src/isolated_declaration.cpp", "src/line_column_offset.cpp", + "src/navigate_to.cpp", + "src/organize_imports.cpp", "src/quick_info.cpp", + "src/refactors/convert_function.cpp", "src/references.cpp", + "src/register_code_fix/add_missing_declare_property.cpp", + "src/register_code_fix/fix_missing_call_parantheses.cpp", + "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/rename.cpp", + "src/script_element_kind.cpp", "src/services/services.cpp", + "src/services/text_change/change_tracker.cpp", "src/services/utilities.cpp", + "src/signature_help.cpp", + "src/signature_help_items.cpp", "src/string_completions.cpp", "src/suggestion_diagnostics.cpp", + "src/todo_comments.cpp", + "src/types.cpp", ] configs = [ "$ark_root/assembler:arkassembler_public_config", diff --git a/ets2panda/lsp/CMakeLists.txt b/ets2panda/lsp/CMakeLists.txt index f242fbb8762e38f7fd18047d86dfb536cdc49655..601ab7f0c91b23087d172bd7b6311a28485713fc 100644 --- a/ets2panda/lsp/CMakeLists.txt +++ b/ets2panda/lsp/CMakeLists.txt @@ -13,23 +13,55 @@ set(ES2PANDA_LSP_SRC ./src/api.cpp + ./src/class_hierarchy.cpp + ./src/class_hierarchy_info.cpp ./src/classifier.cpp ./src/internal_api.cpp + ./src/isolated_declaration.cpp ./src/cancellation_token.cpp ./src/completions.cpp + ./src/organize_imports.cpp ./src/quick_info.cpp + ./src/completions_details.cpp ./src/references.cpp ./src/get_adjusted_location.cpp + ./src/get_safe_delete_info.cpp ./src/find_rename_locations.cpp + ./src/find_safe_delete_location.cpp ./src/find_references.cpp + ./src/applicable_refactors.cpp + ./src/refactors/convert_function.cpp + ./src/formatting/formatting_context.cpp + ./src/formatting/formatting_settings.cpp + ./src/formatting/formatting.cpp + ./src/formatting/rules_map.cpp + ./src/formatting/rules.cpp ./src/string_completions.cpp ./src/rename.cpp + ./src/generate_constructor.cpp ./src/suggestion_diagnostics.cpp ./src/brace_matching.cpp ./src/services/services.cpp ./src/services/utilities.cpp ./src/line_column_offset.cpp + ./src/services/text_change/change_tracker.cpp + ./src/code_fix_provider.cpp ./src/inlay_hints.cpp + ./src/get_class_property_info.cpp + ./src/create_type_help_items.cpp + ./src/script_element_kind.cpp + ./src/signature_help_items.cpp + ./src/signature_help.cpp + ./src/todo_comments.cpp + ./src/get_definition_and_bound_span.cpp + ./src/types.cpp + ./src/navigate_to.cpp + ./src/code_fix_provider.cpp + ./src/register_code_fix/add_missing_declare_property.cpp + ./src/register_code_fix/fix_missing_call_parantheses.cpp + ./src/register_code_fix/fix_nan_equality.cpp + ./src/register_code_fix/forgetten_this_property_access.cpp + ./src/register_code_fix/import_fixes.cpp ) panda_add_library(${LSP_LIB} SHARED ${ES2PANDA_LSP_SRC}) diff --git a/ets2panda/lsp/include/api.h b/ets2panda/lsp/include/api.h index d6fe06bc3984c8b040f1c72447675516f73b4500..099982127c45b40ab6df761b055fd33b5c276e82 100644 --- a/ets2panda/lsp/include/api.h +++ b/ets2panda/lsp/include/api.h @@ -28,14 +28,27 @@ #include "line_column_offset.h" #include "public/es2panda_lib.h" #include "cancellation_token.h" +#include "class_hierarchies.h" #include "find_references.h" #include "find_rename_locations.h" +#include "class_hierarchy_info.h" #include "completions.h" +#include "applicable_refactors.h" +#include "todo_comments.h" +#include "types.h" +#include "formatting/formatting_settings.h" +#include "user_preferences.h" #ifdef __cplusplus extern "C" { #endif +typedef struct SafeDeleteLocation { + std::string uri; + size_t start; + size_t length; +} SafeDeleteLocation; + typedef struct DefinitionInfo { DefinitionInfo() = default; DefinitionInfo(std::string f, size_t s, size_t l) : fileName(f), start(s), length(l) {} @@ -56,20 +69,6 @@ typedef struct References { std::vector referenceInfos; } References; -typedef struct TextSpan { - size_t start; - size_t length; - TextSpan(size_t s, size_t l) : start(s), length(l) {} - bool operator==(const TextSpan &other) const - { - return start == other.start && length == other.length; - } - bool operator!=(const TextSpan &other) const - { - return !(*this == other); - } -} TextSpan; - typedef struct Position { size_t line_; // Line number size_t character_; // Character position in the line @@ -198,40 +197,39 @@ typedef struct DocumentHighlights { } } DocumentHighlights; -typedef struct DocumentHighlightsReferences { - std::vector documentHighlights_; -} DocumentHighlightsReferences; - -struct SymbolDisplayPart { -private: - std::string text_; - std::string kind_; +struct FieldListProperty { + std::string kind; + std::optional> modifierKinds; + std::string displayName; + size_t start; + size_t end; -public: - explicit SymbolDisplayPart(std::string text = "", std::string kind = "") - : text_ {std::move(text)}, kind_ {std::move(kind)} + FieldListProperty(std::string k, std::optional> m, std::string d, size_t s, size_t e) + : kind(std::move(k)), modifierKinds(std::move(m)), displayName(std::move(d)), start(s), end(e) { } +}; - std::string GetText() const +struct FieldsInfo { + std::string name; + std::vector properties; + bool operator<(const FieldsInfo &other) const { - return text_; - } - std::string GetKind() const - { - return kind_; + return name < other.name; } + FieldsInfo() = default; + FieldsInfo(const FieldsInfo &fi) : name(fi.name), properties(fi.properties) {} +}; - bool operator==(const SymbolDisplayPart &other) const - { - return text_ == other.text_ && kind_ == other.kind_; - } - bool operator!=(const SymbolDisplayPart &other) const - { - return !(*this == other); - } +struct LspClassPropertyInfo { + FieldsInfo fieldsInfo; + LspClassPropertyInfo(FieldsInfo f) : fieldsInfo(std::move(f)) {} }; +typedef struct DocumentHighlightsReferences { + std::vector documentHighlights_; +} DocumentHighlightsReferences; + struct DocTagInfo { private: std::string name_; @@ -261,6 +259,22 @@ public: } }; +struct RefactorEditInfo { +private: + std::vector fileTextChanges_; + +public: + explicit RefactorEditInfo(std::vector fileTextChanges = {}) + : fileTextChanges_(std::move(fileTextChanges)) + { + } + + std::vector &GetFileTextChanges() + { + return fileTextChanges_; + } +}; + struct QuickInfo { private: std::string kind_; @@ -326,6 +340,79 @@ public: } }; +struct CompletionEntryDetails { +private: + std::string name_; + std::string kind_; + std::string kindModifiers_; + std::vector displayParts_; + std::vector document_; + std::vector source_; + std::vector sourceDisplay_; + std::string fileName_; + +public: + explicit CompletionEntryDetails(std::string name = "", std::string kind = "", std::string kindModifiers = "", + std::vector displayParts = {}, + std::vector document = {}, + std::vector source = {}, + std::vector sourceDisplay = {}, std::string fileName = "") + : name_ {std::move(name)}, + kind_ {std::move(kind)}, + kindModifiers_ {std::move(kindModifiers)}, + displayParts_ {std::move(displayParts)}, + document_ {std::move(document)}, + source_ {std::move(source)}, + sourceDisplay_ {std::move(sourceDisplay)}, + fileName_ {std::move(fileName)} + { + } + + std::string GetName() const + { + return name_; + } + std::string GetKind() const + { + return kind_; + } + std::string GetKindModifiers() const + { + return kindModifiers_; + } + std::vector GetDisplayParts() const + { + return displayParts_; + } + std::vector GetDocument() const + { + return document_; + } + std::vector GetSource() const + { + return source_; + } + std::vector GetSourceDisplay() const + { + return sourceDisplay_; + } + std::string GetFileName() const + { + return fileName_; + } + + bool operator==(const CompletionEntryDetails &other) const + { + return name_ == other.name_ && kind_ == other.kind_ && kindModifiers_ == other.kindModifiers_ && + displayParts_ == other.displayParts_ && document_ == other.document_ && source_ == other.source_ && + sourceDisplay_ == other.sourceDisplay_ && fileName_ == other.fileName_; + } + bool operator!=(const CompletionEntryDetails &other) const + { + return !(*this == other); + } +}; + typedef struct FileDiagnostic { es2panda_AstNode *node; Diagnostic diagnostic; @@ -343,43 +430,137 @@ typedef struct DeclInfo { std::string fileText; } DeclInfo; +enum class HierarchyType { OTHERS, INTERFACE, CLASS }; + +struct TypeHierarchies { + TypeHierarchies() = default; + TypeHierarchies(std::string f, std::string n, HierarchyType t, size_t p) + : fileName(std::move(f)), name(std::move(n)), type(t), pos(p) + { + } + bool operator==(const TypeHierarchies &other) const + { + return fileName == other.fileName && name == other.name && type == other.type && pos == other.pos; + } + bool operator!=(const TypeHierarchies &other) const + { + return !(*this == other); + } + bool operator<(const TypeHierarchies &other) const + { + return std::tie(fileName, name, type, pos) < std::tie(other.fileName, other.name, other.type, other.pos); + } + std::string fileName; + std::string name; + HierarchyType type = HierarchyType::OTHERS; + size_t pos = 0; + std::vector subOrSuper; +}; + +struct TypeHierarchiesInfo { + TypeHierarchiesInfo() = default; + TypeHierarchiesInfo(std::string f, std::string n, HierarchyType t, size_t p) + : fileName(std::move(f)), name(std::move(n)), type(t), pos(p) + { + } + std::string fileName; + std::string name; + HierarchyType type = HierarchyType::OTHERS; + size_t pos = 0; + TypeHierarchies superHierarchies; + TypeHierarchies subHierarchies; +}; + +struct InstallPackageActionInfo { + std::string type_; + std::optional file; + std::optional packageName; +}; + +struct CodeActionInfo { + std::string description_; + std::vector changes_; + std::vector commands_; +}; + +struct CombinedCodeActionsInfo { + std::vector changes_; + std::vector commands_; +}; + +struct CodeFixActionInfo : CodeActionInfo { + std::string fixName_; + std::string fixId_ = {}; + std::string fixAllDescription_ = {}; +}; + +struct CodeFixOptions { + ark::es2panda::lsp::CancellationToken token; + ark::es2panda::lsp::FormatCodeSettings options; + ark::es2panda::lsp::UserPreferences preferences; +}; + typedef struct LSPAPI { DefinitionInfo (*getDefinitionAtPosition)(es2panda_Context *context, size_t position); + ark::es2panda::lsp::ApplicableRefactorInfo (*getApplicableRefactors)(es2panda_Context *context, const char *kind, + size_t position); DefinitionInfo (*getImplementationAtPosition)(es2panda_Context *context, size_t position); bool (*isPackageModule)(es2panda_Context *context); + ark::es2panda::lsp::CompletionEntryKind (*getAliasScriptElementKind)(es2panda_Context *context, size_t position); References (*getFileReferences)(char const *fileName, es2panda_Context *context, bool isPackageModule); DeclInfo (*getDeclInfo)(es2panda_Context *context, size_t position); + std::vector (*getClassHierarchiesImpl)(es2panda_Context *context, + const char *fileName, + size_t pos); + bool (*getSafeDeleteInfo)(es2panda_Context *context, size_t position, const char *path); References (*getReferencesAtPosition)(es2panda_Context *context, DeclInfo *declInfo); es2panda_AstNode *(*getPrecedingToken)(es2panda_Context *context, const size_t pos); std::string (*getCurrentTokenValue)(es2panda_Context *context, size_t position); + std::vector (*OrganizeImportsImpl)(es2panda_Context *context, char const *fileName); QuickInfo (*getQuickInfoAtPosition)(const char *fileName, es2panda_Context *context, size_t position); - TextSpan (*getSpanOfEnclosingComment)(char const *fileName, size_t pos, bool onlyMultiLine); + CompletionEntryDetails (*getCompletionEntryDetails)(const char *entryName, const char *fileName, + es2panda_Context *context, size_t position); + TextSpan (*getSpanOfEnclosingComment)(es2panda_Context *context, size_t pos, bool onlyMultiLine); DiagnosticReferences (*getSemanticDiagnostics)(es2panda_Context *context); DiagnosticReferences (*getSyntacticDiagnostics)(es2panda_Context *context); DiagnosticReferences (*getCompilerOptionsDiagnostics)(char const *fileName, ark::es2panda::lsp::CancellationToken cancellationToken); + TypeHierarchiesInfo (*getTypeHierarchies)(es2panda_Context *searchContext, es2panda_Context *context, + size_t position); DocumentHighlightsReferences (*getDocumentHighlights)(es2panda_Context *context, size_t position); std::vector (*findRenameLocations)( const std::vector &files, const ark::es2panda::SourceFile &file, size_t position); std::vector (*findRenameLocationsWithCancellationToken)( ark::es2panda::lsp::CancellationToken *tkn, const std::vector &files, const ark::es2panda::SourceFile &file, size_t position); + std::vector (*FindSafeDeleteLocation)(es2panda_Context *ctx, + const std::tuple *declInfo); std::vector (*findReferences)( ark::es2panda::lsp::CancellationToken *tkn, const std::vector &srcFiles, const ark::es2panda::SourceFile &srcFile, size_t position); + std::vector (*getClassPropertyInfo)(es2panda_Context *context, size_t pos, bool shouldCollectInherited); DiagnosticReferences (*getSuggestionDiagnostics)(es2panda_Context *context); ark::es2panda::lsp::CompletionInfo (*getCompletionsAtPosition)(es2panda_Context *context, size_t position); + ark::es2panda::lsp::ClassHierarchy (*getClassHierarchyInfo)(es2panda_Context *context, size_t position); std::vector (*getBraceMatchingAtPosition)(char const *fileName, size_t position); + RefactorEditInfo (*getClassConstructorInfo)(es2panda_Context *context, size_t position, + const std::vector &properties); std::vector (*getImplementationLocationAtPosition)(es2panda_Context *context, int position); ark::es2panda::lsp::LineAndCharacter (*toLineColumnOffset)(es2panda_Context *context, size_t position); + std::vector (*getTodoComments)( + char const *fileName, std::vector &descriptors, + ark::es2panda::lsp::CancellationToken *cancellationToken); + InlayHintList (*provideInlayHints)(es2panda_Context *context, const TextSpan *span); + SignatureHelpItems (*getSignatureHelpItems)(es2panda_Context *context, size_t position); + std::vector (*getCodeFixesAtPosition)(const char *fileName, size_t start_position, + size_t end_position, std::vector &errorCodes, + CodeFixOptions &codeFixOptions); + CombinedCodeActionsInfo (*getCombinedCodeFix)(const char *fileName, const std::string &fixId, + CodeFixOptions &codeFixOptions); } LSPAPI; - CAPI_EXPORT LSPAPI const *GetImpl(); - // NOLINTEND - #ifdef __cplusplus } #endif - -#endif +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/applicable_refactors.h b/ets2panda/lsp/include/applicable_refactors.h new file mode 100644 index 0000000000000000000000000000000000000000..3329f8891f2f4a3ef31fd613789fd4cb9e541f3a --- /dev/null +++ b/ets2panda/lsp/include/applicable_refactors.h @@ -0,0 +1,72 @@ +/** + * 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 APPLICABLE_REFACTORS_H +#define APPLICABLE_REFACTORS_H + +#include "public/es2panda_lib.h" +#include +#include +#include + +namespace ark::es2panda::lsp { + +using RefactorActionView = struct RefactorActionView { + std::string_view name; + std::string_view description; + std::string_view kind; +}; + +using RefactorAction = struct RefactorAction { + std::string name; + std::string description; + std::string kind; +}; + +using ApplicableRefactorInfo = struct ApplicableRefactorInfo { + std::string name; + std::string description; + RefactorAction action; +}; + +namespace refactor_name { +constexpr std::string_view CONVERT_FUNCTION_REFACTOR_NAME = "Convert arrow function or function expression"; +} // namespace refactor_name + +namespace refactor_description { +constexpr std::string_view CONVERT_FUNCTION_REFACTOR_DESC = "Convert arrow function or function expression"; +} // namespace refactor_description + +class Refactor { +private: + std::vector kinds_; + +public: + bool IsKind(const std::string &kind); + void AddKind(const std::string &kind); + virtual ApplicableRefactorInfo GetAvailableActions(es2panda_Context *context, std::string kind, + size_t position) = 0; + virtual ~Refactor() = default; + Refactor() = default; + Refactor &operator=(const Refactor &other); + Refactor &operator=(Refactor &&other); + Refactor(const Refactor &other); + Refactor(Refactor &&other); +}; + +ApplicableRefactorInfo GetApplicableRefactorsImpl(es2panda_Context *context, const char *kind, size_t position); +} // namespace ark::es2panda::lsp + +#endif // APPLICABLE_REFACTORS_H \ No newline at end of file diff --git a/ets2panda/lsp/include/brace_matching.h b/ets2panda/lsp/include/brace_matching.h index 10722fb15fd965e96c31999d27677a638919befb..c4d1672f0a6ff70092405c966feaf702452fefed 100644 --- a/ets2panda/lsp/include/brace_matching.h +++ b/ets2panda/lsp/include/brace_matching.h @@ -21,6 +21,7 @@ #include "internal_api.h" namespace ark::es2panda::lsp { +bool CheckNodeKindForBraceMatching(ark::es2panda::ir::AstNode *node); std::vector GetBraceMatchingAtPosition(es2panda_Context *context, size_t position); } // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/include/class_hierarchies.h b/ets2panda/lsp/include/class_hierarchies.h new file mode 100644 index 0000000000000000000000000000000000000000..a4856d2060e180d4af16a1293f05ec595fb9f7bf --- /dev/null +++ b/ets2panda/lsp/include/class_hierarchies.h @@ -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. + */ + +#ifndef ES2PANDA_LSP_CLASS_HIERARCHIES_INFO_H +#define ES2PANDA_LSP_CLASS_HIERARCHIES_INFO_H + +#include +#include +#include +#include +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { + +enum class ClassRelationKind { UNKNOWN, INTERFACE, CLASS, FIELD, METHOD, PROPERTY }; + +// NOLINTBEGIN(misc-non-private-member-variables-in-classes) +struct ClassRelationDetails { + ClassRelationDetails() = default; + ClassRelationDetails(std::string f, size_t p, ClassRelationKind k) : fileName(std::move(f)), pos(p), kind(k) {} + std::string fileName; + size_t pos = 0; + ClassRelationKind kind = ClassRelationKind::UNKNOWN; +}; + +struct ClassHierarchyItemInfo { + ClassHierarchyItemInfo() = default; + ClassHierarchyItemInfo(std::string d, ClassRelationKind k, size_t p) : pos(p), kind(k), description(std::move(d)) {} + size_t pos = 0; + ClassRelationKind kind = ClassRelationKind::UNKNOWN; + std::vector overridden; + std::vector overriding; + std::vector implemented; + std::vector implementing; + std::string description; +}; +// NOLINTEND(misc-non-private-member-variables-in-classes) + +/** + * @brief Returns class/interface hierarchys at a specific source position. + * + * @param context Parsing context for AST access. + * @param fileName Source file name. + * @param pos Character offset in source code. + */ +std::vector GetClassHierarchiesImpl(es2panda_Context *context, const std::string &fileName, + size_t pos); +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/class_hierarchy.h b/ets2panda/lsp/include/class_hierarchy.h new file mode 100644 index 0000000000000000000000000000000000000000..009944b9f428dc001b7147fde0228a2632ee94c0 --- /dev/null +++ b/ets2panda/lsp/include/class_hierarchy.h @@ -0,0 +1,36 @@ +/** + * 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 ES2PANDA_LSP_INCLUDE_CLASSHIERARCHY_H +#define ES2PANDA_LSP_INCLUDE_CLASSHIERARCHY_H + +#include +#include +#include "api.h" +#include "ir/astNode.h" +#include "line_column_offset.h" +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { +ir::AstNode *GetTargetDeclarationNodeByPosition(es2panda_Context *context, size_t pos); +// NOLINTBEGIN(misc-non-private-member-variables-in-classes) +const ir::AstNode *GetEffectiveBaseTypeNode(const ir::AstNode *node); +// NOLINTEND(misc-non-private-member-variables-in-classes) +void GetSuperTypeHierarchies(const ir::AstNode *node, TypeHierarchies &typeHierarchies, + std::set &superLists); +TypeHierarchiesInfo GetTypeHierarchiesImpl(es2panda_Context *context, size_t pos, + const ir::AstNode *declaration = nullptr); +} // namespace ark::es2panda::lsp +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/class_hierarchy_info.h b/ets2panda/lsp/include/class_hierarchy_info.h new file mode 100644 index 0000000000000000000000000000000000000000..f7730151ede001b7006a22b2b6df3ba85a471e43 --- /dev/null +++ b/ets2panda/lsp/include/class_hierarchy_info.h @@ -0,0 +1,202 @@ +/** + * 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 ES2PANDA_LSP_CLASS_HIERARCHY_INFO_H +#define ES2PANDA_LSP_CLASS_HIERARCHY_INFO_H + +#include +#include +#include +#include +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { +class FunctionParamStyle { +public: + FunctionParamStyle(std::string paramName, std::string paramKind) + : name_(std::move(paramName)), kind_(std::move(paramKind)) + { + } + + std::string GetParamName() const + { + return name_; + } + + std::string GetParamKind() const + { + return kind_; + } + +private: + std::string name_; + std::string kind_; +}; + +enum class SetterStyle { METHOD = 0, SETTER, GETTER }; + +enum class AccessModifierStyle { PUBLIC = 0, PROTECTED, PRIVATE }; + +class ClassMethodItem { +public: + ClassMethodItem(std::string detail, SetterStyle setter, AccessModifierStyle access) + : detail_(std::move(detail)), setter_(setter), accessModifier_(access) + { + } + + virtual ~ClassMethodItem() = default; + + ClassMethodItem(const ClassMethodItem &other) = default; + ClassMethodItem(ClassMethodItem &&other) = default; + ClassMethodItem &operator=(const ClassMethodItem &other) = default; + ClassMethodItem &operator=(ClassMethodItem &&other) = default; + + void SetFunctionName(const std::string &functionName) + { + if (functionName.empty()) { + return; + } + funcName_ = functionName; + } + + const std::string &GetFunctionName() const + { + return funcName_; + } + + const std::string &GetFunctionDetail() const + { + return detail_; + } + + SetterStyle GetSetterStyle() const + { + return setter_; + } + + AccessModifierStyle GetAccessModifierStyle() const + { + return accessModifier_; + } + +private: + std::string funcName_; + std::string detail_; + SetterStyle setter_; + AccessModifierStyle accessModifier_; +}; + +class ClassHierarchyInfo { +public: + ClassHierarchyInfo() = default; + + virtual ~ClassHierarchyInfo() = default; + + ClassHierarchyInfo(const ClassHierarchyInfo &other) = default; + ClassHierarchyInfo(ClassHierarchyInfo &&other) = default; + ClassHierarchyInfo &operator=(const ClassHierarchyInfo &other) = default; + ClassHierarchyInfo &operator=(ClassHierarchyInfo &&other) = default; + + void SetClassName(const std::string &className) + { + if (className.empty()) { + return; + } + className_ = className; + } + + const std::string &GetClassName() const + { + return className_; + } + + const std::unordered_map> &GetMethodList() const + { + return methods_; + } + + bool AddClassMethodItem(const std::shared_ptr &item) + { + if (item == nullptr || IsItemExist(item)) { + return false; + } + auto funcDetail = item->GetFunctionDetail(); + methods_[funcDetail] = item; + return true; + } + + void DeleteClassMethodItem(const std::shared_ptr &item) + { + if (item == nullptr) { + return; + } + auto funcDetail = item->GetFunctionDetail(); + methods_.erase(funcDetail); + } + + void DeleteAllClassMethodItem() + { + methods_.clear(); + } + + bool IsItemExist(const std::shared_ptr &item) const + { + if (item == nullptr) { + return false; + } + auto func = item->GetFunctionDetail(); + auto iter = methods_.find(func); + return iter != methods_.end(); + } + +private: + std::string className_; + std::unordered_map> methods_; +}; + +using ClassHierarchy = std::vector; + +/** + * Retrieve the list of undefined virtual functions in the parent class. + * + * such as ets: + * class Animal { + * private body_: string = ''; + * + * public action(): void { + * console.log("need Animal action"); + * } + * public sleep(): void { + * console.log("need sleep"); + * } + * } + * + * class Bird extends Animal { + * action(): void { + * console.log("need Bird action"); + * } + * + * Drink(): void { + * console.log("need Bird Drink"); + * } + * } + * + * when clicking 'Bird'. + * ClassHierarchy is [ { "Animal", { detail: sleep(), SetterStyle: METHOD, AccessModifierStyle: PUBLIC } } ]. + */ +ClassHierarchy GetClassHierarchyInfoImpl(es2panda_Context *context, size_t position); +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/lsp/include/code_fix_provider.h b/ets2panda/lsp/include/code_fix_provider.h new file mode 100644 index 0000000000000000000000000000000000000000..7d18b2d7c4166d209d831d8fa0ef82d90c37821f --- /dev/null +++ b/ets2panda/lsp/include/code_fix_provider.h @@ -0,0 +1,85 @@ +/** + * 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 CODE_FIX_PROVIDER_H +#define CODE_FIX_PROVIDER_H +#include +#include +#include +#include +#include "services/text_change/change_tracker.h" +#include "code_fixes/code_fix_types.h" +#include "es2panda.h" + +namespace ark::es2panda::lsp { + +class CodeFixProvider { +private: + std::unordered_map> errorCodeToFixes_; + std::unordered_map> fixIdToRegistration_; + +public: + std::unordered_map> GetErrorCodeToFixes() const + { + return errorCodeToFixes_; + } + std::unordered_map> GetFixIdToRegistration() const + { + return fixIdToRegistration_; + } + + void RegisterCodeFix(const std::string &aliasName, std::unique_ptr registration); + static CodeFixProvider &Instance(); + + std::string FormatWithArgs(const std::string &text); + std::string DiagnosticToString(const DiagnosticAndArguments &diag); + CodeFixAction CreateCodeFixActionWorker(std::string &fixName, std::string &description, + std::vector &changes, std::string &fixId, + std::string &fixAllDescription, std::vector command); + + CodeFixAction CreateCodeFixActionWithoutFixAll(std::string &fixName, std::vector &changes, + DiagnosticAndArguments &description); + CodeFixAction CreateCodeFixAction(std::string fixName, std::vector changes, + DiagnosticAndArguments &description, std::string fixId, + DiagnosticAndArguments &fixAllDescription, + std::vector &command); + std::string GetFileName(const std::string &filePath); + std::vector GetSupportedErrorCodes(); + DiagnosticReferences *GetDiagnostics(const CodeFixContextBase &context); + + bool ShouldIncludeFixAll(const CodeFixRegistration ®istration, const std::vector &diagnostics); + std::vector GetFixes(const CodeFixContext &context); + void EachDiagnostic(const CodeFixAllContext &context, const std::vector &errorCodes, + const std::function &cb); + CombinedCodeActions CodeFixAll(const CodeFixAllContext &context, const std::vector &errorCodes, + std::function use); + FileTextChanges CreateFileTextChanges(const std::string &fileName, const std::vector &textChanges); + + CombinedCodeActions GetAllFixes(const CodeFixAllContext &context); +}; + +template +struct AutoCodeFixRegister { + constexpr explicit AutoCodeFixRegister(const std::string &name, std::unique_ptr registration) + { + CodeFixProvider::Instance().RegisterCodeFix(name, std::move(registration)); + } + + constexpr explicit AutoCodeFixRegister(const std::string &name) : AutoCodeFixRegister(name, std::make_unique()) + { + } +}; +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/code_fixes/code_fix_types.h b/ets2panda/lsp/include/code_fixes/code_fix_types.h new file mode 100644 index 0000000000000000000000000000000000000000..1e38c16cb7165ebe86e051f26c6f880188052c83 --- /dev/null +++ b/ets2panda/lsp/include/code_fixes/code_fix_types.h @@ -0,0 +1,120 @@ +/** + * 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 CODE_FIX_TYPES_H +#define CODE_FIX_TYPES_H + +#include +#include +#include +#include +#include +#include "../user_preferences.h" +#include "../cancellation_token.h" +#include "../types.h" +#include "../api.h" +#include "es2panda.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "../get_class_property_info.h" + +namespace ark::es2panda::lsp { + +enum DiagnosticCategory { WARNING, ERROR, SUGGESTION, MESSAGE }; + +struct DiagnosticMessage { + std::string key; + DiagnosticCategory category; + size_t code; + std::string message; + std::string reportsUnnecessary = {}; + std::string reportsDeprecated = {}; + bool elidedInCompatabilityPyramid; +}; +struct DiagnosticAndArguments { + DiagnosticMessage message; + std::vector arguments; +}; + +struct CodeAction { + std::string description; + std::vector changes; + std::vector commands; +}; +struct CombinedCodeActions { + std::vector changes; + std::vector commands; +}; +struct CodeFixAction : CodeAction { + std::string fixName; + std::string fixId = {}; + std::string fixAllDescription = {}; +}; + +struct CodeFixContextBase : TextChangesContext { + es2panda_Context *context; + CancellationToken cancellationToken; +}; + +struct CodeFixAllContext : CodeFixContextBase { + std::string fixId = {}; +}; + +struct DiagnosticWithLocation : Diagnostic { + SourceFile file; + size_t start = 0; + size_t length = 0; +}; + +struct CodeFixContext : CodeFixContextBase { + int errorCode = 0; + TextSpan span = {0, 0}; +}; + +class CodeFixRegistration { +private: + std::vector errorCodes_; + std::vector fixIds_; + +public: + std::vector GetErrorCodes() const + { + return errorCodes_; + } + std::vector GetFixIds() const + { + return fixIds_; + } + void SetErrorCodes(const std::vector &codes) + { + errorCodes_ = codes; + } + void SetFixIds(const std::vector &ids) + { + fixIds_ = ids; + } + virtual std::vector GetCodeActions(const CodeFixContext &) = 0; + virtual CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &) = 0; + CodeFixRegistration() = default; + CodeFixRegistration(const CodeFixRegistration &) = delete; + CodeFixRegistration &operator=(const CodeFixRegistration &) = delete; + CodeFixRegistration(CodeFixRegistration &&) = delete; + CodeFixRegistration &operator=(CodeFixRegistration &&) = delete; + virtual ~CodeFixRegistration() = default; +}; + +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/lsp/include/completions.h b/ets2panda/lsp/include/completions.h index df8c4480a1dfb676e6c67d7506dcbe67ffa753eb..1f5ddc21e239801b370c512d6a502297e5fecb7d 100644 --- a/ets2panda/lsp/include/completions.h +++ b/ets2panda/lsp/include/completions.h @@ -205,9 +205,15 @@ std::optional CompletionEntryDataToOriginInfo(ark::es2panda const std::string &name); std::optional IsCompletionEntryDataResolved(ark::es2panda::lsp::CompletionEntryData *data, const std::shared_ptr &config); +std::vector FilterFromBody(const ark::ArenaVector &bodyNodes, + const std::string &triggerWord); bool StartsWith(const std::string &str, const std::string &prefix); +bool IsDefinedClassOrStruct(ir::AstNode *preNode); std::shared_ptr GetArkTsConfigFromFile(const char *fileName); +std::vector GetPropertyCompletions(ir::AstNode *preNode, const std::string &triggerWord); +std::string GetClassPropertyName(ir::AstNode *node); +ir::AstNode *GetIdentifierFromTSInterfaceHeritage(ir::AstNode *node); } // namespace ark::es2panda::lsp #endif diff --git a/ets2panda/lsp/include/completions_details.h b/ets2panda/lsp/include/completions_details.h new file mode 100644 index 0000000000000000000000000000000000000000..7c197b80b09b3227d4c6939e3dd09a65db3c086b --- /dev/null +++ b/ets2panda/lsp/include/completions_details.h @@ -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. + */ + +#ifndef ES2PANDA_LSP_COMPLETIONS_DETAILS_H +#define ES2PANDA_LSP_COMPLETIONS_DETAILS_H + +#include "ir/astNode.h" +#include "public/es2panda_lib.h" +#include "api.h" + +namespace ark::es2panda::lsp::details { + +CompletionEntryDetails GetCompletionEntryDetails(ir::AstNode *node, const std::string &entryName, + const std::string &fileName); +CompletionEntryDetails GetCompletionEntryDetailsImpl(es2panda_Context *context, size_t position, const char *fileName, + const char *entryName); + +} // namespace ark::es2panda::lsp::details +#endif diff --git a/ets2panda/lsp/include/create_type_help_items.h b/ets2panda/lsp/include/create_type_help_items.h new file mode 100644 index 0000000000000000000000000000000000000000..6ac398db55a56381914df290a44fd3d633f9dd14 --- /dev/null +++ b/ets2panda/lsp/include/create_type_help_items.h @@ -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. + */ + +#ifndef ES2PANDA_LSP_CREATE_TYPE_HELP_ITEMS_H +#define ES2PANDA_LSP_CREATE_TYPE_HELP_ITEMS_H + +#include "types.h" +#include +#include "ir/astNode.h" +#include "lexer/token/sourceLocation.h" +#include "utils/arena_containers.h" +#include +#include +#include +#include +#include + +namespace ark::es2panda::lsp { + +enum class InvocationKind { CALL, TYPE_ARGS, CONTEXTUAL }; + +struct CallInvocation { + InvocationKind kind = InvocationKind::CALL; + ir::AstNode *callExpressionNode = nullptr; +}; + +struct TypeArgsInvocation { + InvocationKind kind = InvocationKind::TYPE_ARGS; + ir::AstNode *identifierNode = nullptr; +}; + +struct ContextualInvocation { + InvocationKind kind = InvocationKind::CONTEXTUAL; + checker::Signature *signature = nullptr; + ir::AstNode *node = nullptr; +}; + +using Invocation = std::variant; + +void GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(const ir::AstNode *node, std::vector &result); +std::vector GetEffectiveTypeParameterDeclarations(const ir::AstNode *node, + std::vector &result); + +void GetTypeHelpItem(std::vector *typeParameters, const ir::AstNode *node, SignatureHelpItem &result); + +SignatureHelpItems CreateTypeHelpItems(const ir::AstNode *node, lexer::SourceRange location, TextSpan applicableSpan); + +} // namespace ark::es2panda::lsp + +#endif // ES2PANDA_LSP_CREATE_TYPE_HELP_ITEMS_H \ No newline at end of file diff --git a/ets2panda/lsp/include/find_safe_delete_location.h b/ets2panda/lsp/include/find_safe_delete_location.h new file mode 100644 index 0000000000000000000000000000000000000000..fccad526fe8c6838edf31eb70676a953452b281a --- /dev/null +++ b/ets2panda/lsp/include/find_safe_delete_location.h @@ -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. + */ + +#ifndef ETS2PANDA_LSP_SAFE_DELETE_H +#define ETS2PANDA_LSP_SAFE_DELETE_H + +#include "public/es2panda_lib.h" +#include "api.h" +#include +#include + +namespace ark::es2panda::lsp { + +/** + * Finds all reference locations for a given symbol. + * @param ctx Pointer to the es2panda context. + * @param declInfo Declaration information (typically includes file name and symbol name). + * @return A list of reference locations. + */ +std::vector FindSafeDeleteLocationImpl(es2panda_Context *ctx, + const std::tuple &declInfo); + +} // namespace ark::es2panda::lsp + +#endif // ETS2PANDA_LSP_SAFE_DELETE_H diff --git a/ets2panda/lsp/include/formatting/formatting.h b/ets2panda/lsp/include/formatting/formatting.h new file mode 100644 index 0000000000000000000000000000000000000000..32a89e7eab5c0dce253b24d8e33032fc25c9030a --- /dev/null +++ b/ets2panda/lsp/include/formatting/formatting.h @@ -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. + */ + +#ifndef FORMATTING_H +#define FORMATTING_H + +#include "formatting_settings.h" +#include "rules_map.h" + +namespace ark::es2panda::lsp { + +struct FormatContext { +public: + explicit FormatContext(FormatCodeSettings &formatCodeSetting, RulesMap &rulesMap) + : options_(formatCodeSetting), getRules_(rulesMap) + { + } + + FormatCodeSettings &GetFormatCodeSettings() + { + return options_; + } + + RulesMap &GetRulesMap() + { + return getRules_; + } + +private: + FormatCodeSettings options_; + RulesMap getRules_; +}; + +FormatContext GetFormatContext(FormatCodeSettings &options); + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/formatting/formatting_context.h b/ets2panda/lsp/include/formatting/formatting_context.h new file mode 100644 index 0000000000000000000000000000000000000000..0748a440fbda948fd4d639c5573d64f3eca25ba3 --- /dev/null +++ b/ets2panda/lsp/include/formatting/formatting_context.h @@ -0,0 +1,117 @@ +/** + * 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 FORMATTING_CONTEXT_H +#define FORMATTING_CONTEXT_H + +#include "ir/astNode.h" +#include "formatting_settings.h" + +namespace ark::es2panda::lsp { + +enum class FormattingRequestKind { + FORMAT_DOCUMENT, + FORMAT_SELECTION, + FORMAT_ON_ENTER, + FORMAT_ON_SEMICOLON, + FORMAT_ON_OPENING_CURLY_BRACE, + FORMAT_ON_CLOSING_CURLY_BRACE, +}; + +struct RangeWithKind : lexer::SourceRange { +private: + ir::AstNodeType kind_; + +public: + explicit RangeWithKind(lexer::SourcePosition startPos = lexer::SourcePosition(), + lexer::SourcePosition endPos = lexer::SourcePosition(), + ir::AstNodeType nodeKind = ir::AstNodeType::DUMMYNODE) + : lexer::SourceRange(startPos, endPos), kind_(nodeKind) + { + } + + const ir::AstNodeType &GetKind() + { + return kind_; + } +}; + +struct FormattingContext { +public: + explicit FormattingContext(FormattingRequestKind requestKind, FormatCodeSettings &formatSettings); + + void UpdateContext(es2panda_Context *context, RangeWithKind ¤tToken, RangeWithKind &nextToken); + + bool ContextNodeAllOnSameLine() const; + bool NextNodeAllOnSameLine() const; + bool TokensAreOnSameLine() const; + bool ContextNodeBlockIsOnOneLine() const; + bool NextNodeBlockIsOnOneLine() const; + + const RangeWithKind &GetCurrentTokenSpan() const + { + return currentTokenSpan_; + } + const RangeWithKind &GetNextTokenSpan() const + { + return nextTokenSpan_; + } + + ir::AstNode *GetContextNode() const + { + return contextNode_; + } + ir::AstNode *GetCurrentTokenParent() const + { + return currentTokenParent_; + } + ir::AstNode *GetNextTokenParent() const + { + return nextTokenParent_; + } + + FormatCodeSettings GetFormatCodeSettings() + { + return formatCodeSettings_; + } + + FormattingRequestKind GetformattingRequestKind() + { + return formattingRequestKind_; + } + +private: + bool NodeIsOnOneLine(ir::AstNode *node) const; + bool BlockIsOnOneLine(ir::AstNode *node) const; + + bool contextNodeAllOnSameLine_ = false; + bool nextNodeAllOnSameLine_ = false; + bool tokensAreOnSameLine_ = false; + bool contextNodeBlockIsOnOneLine_ = false; + bool nextNodeBlockIsOnOneLine_ = false; + + RangeWithKind currentTokenSpan_; + RangeWithKind nextTokenSpan_; + ir::AstNode *contextNode_ = nullptr; + ir::AstNode *currentTokenParent_ = nullptr; + ir::AstNode *nextTokenParent_ = nullptr; + + FormatCodeSettings formatCodeSettings_; + FormattingRequestKind formattingRequestKind_; +}; + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/formatting/formatting_settings.h b/ets2panda/lsp/include/formatting/formatting_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..4ade8404156fca4a0538fb38595dda334c588e9a --- /dev/null +++ b/ets2panda/lsp/include/formatting/formatting_settings.h @@ -0,0 +1,320 @@ +/** + * 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 FORMATTING_SETTINGS_H +#define FORMATTING_SETTINGS_H + +#include + +namespace ark::es2panda::lsp { + +enum class IndentStyle { NONE, BLOCK, SMART }; + +enum class SemicolonPreference { IGNORE, INSERT, REMOVE }; + +struct EditorSettings { +public: + explicit EditorSettings() = default; + + size_t GetBaseIndentSize() const + { + return baseIndentSize_; + } + + size_t GetIndentSize() const + { + return indentSize_; + } + + size_t GetTabSize() const + { + return tabSize_; + } + + std::string GetNewLineCharacter() const + { + return newLineCharacter_; + } + + bool GetConvertTabsToSpaces() const + { + return convertTabsToSpaces_; + } + + IndentStyle GetIndentStyle() const + { + return indentStyle_; + } + + bool GetTrimTrailingWhitespace() const + { + return trimTrailingWhitespace_; + } + + void SetBaseIndentSize(size_t value) + { + baseIndentSize_ = value; + } + + void SetIndentSize(size_t value) + { + indentSize_ = value; + } + + void SetTabSize(size_t value) + { + tabSize_ = value; + } + + void SetNewLineCharacter(const std::string &value) + { + newLineCharacter_ = value; + } + + void SetConvertTabsToSpaces(bool value) + { + convertTabsToSpaces_ = value; + } + + void SetIndentStyle(IndentStyle value) + { + indentStyle_ = value; + } + + void SetTrimTrailingWhitespace(bool value) + { + trimTrailingWhitespace_ = value; + } + +private: + size_t baseIndentSize_ = 4; + size_t indentSize_ = 4; + size_t tabSize_ = 4; + std::string newLineCharacter_ = "\n"; + bool convertTabsToSpaces_ = true; + IndentStyle indentStyle_ = IndentStyle::SMART; + bool trimTrailingWhitespace_ = true; +}; + +struct FormatCodeSettings : public EditorSettings { +public: + explicit FormatCodeSettings() = default; + + bool GetInsertSpaceAfterCommaDelimiter() const + { + return insertSpaceAfterCommaDelimiter_; + } + + bool GetInsertSpaceAfterSemicolonInForStatements() const + { + return insertSpaceAfterSemicolonInForStatements_; + } + + bool GetInsertSpaceBeforeAndAfterBinaryOperators() const + { + return insertSpaceBeforeAndAfterBinaryOperators_; + } + + bool GetInsertSpaceAfterConstructor() const + { + return insertSpaceAfterConstructor_; + } + + bool GetInsertSpaceAfterKeywordsInControlFlowStatements() const + { + return insertSpaceAfterKeywordsInControlFlowStatements_; + } + + bool GetInsertSpaceAfterFunctionKeywordForAnonymousFunctions() const + { + return insertSpaceAfterFunctionKeywordForAnonymousFunctions_; + } + + bool GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis() const + { + return insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis_; + } + + bool GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets() const + { + return insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets_; + } + + bool GetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces() const + { + return insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces_; + } + + bool GetInsertSpaceAfterOpeningAndBeforeClosingEmptyBraces() const + { + return insertSpaceAfterOpeningAndBeforeClosingEmptyBraces_; + } + + bool GetInsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces() const + { + return insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces_; + } + + bool GetInsertSpaceAfterTypeAssertion() const + { + return insertSpaceAfterTypeAssertion_; + } + + bool GetInsertSpaceBeforeFunctionParenthesis() const + { + return insertSpaceBeforeFunctionParenthesis_; + } + + bool GetPlaceOpenBraceOnNewLineForFunctions() const + { + return placeOpenBraceOnNewLineForFunctions_; + } + + bool GetPlaceOpenBraceOnNewLineForControlBlocks() const + { + return placeOpenBraceOnNewLineForControlBlocks_; + } + + bool GetInsertSpaceBeforeTypeAnnotation() const + { + return insertSpaceBeforeTypeAnnotation_; + } + + bool GetIndentMultiLineObjectLiteralBeginningOnBlankLine() const + { + return indentMultiLineObjectLiteralBeginningOnBlankLine_; + } + + SemicolonPreference GetSemicolons() const + { + return semicolons_; + } + + void SetInsertSpaceAfterCommaDelimiter(bool value) + { + insertSpaceAfterCommaDelimiter_ = value; + } + + void SetInsertSpaceAfterSemicolonInForStatements(bool value) + { + insertSpaceAfterSemicolonInForStatements_ = value; + } + + void SetInsertSpaceBeforeAndAfterBinaryOperators(bool value) + { + insertSpaceBeforeAndAfterBinaryOperators_ = value; + } + + void SetInsertSpaceAfterConstructor(bool value) + { + insertSpaceAfterConstructor_ = value; + } + + void SetInsertSpaceAfterKeywordsInControlFlowStatements(bool value) + { + insertSpaceAfterKeywordsInControlFlowStatements_ = value; + } + + void SetInsertSpaceAfterFunctionKeywordForAnonymousFunctions(bool value) + { + insertSpaceAfterFunctionKeywordForAnonymousFunctions_ = value; + } + + void SetInsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis(bool value) + { + insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis_ = value; + } + + void SetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets(bool value) + { + insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets_ = value; + } + + void SetInsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces(bool value) + { + insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces_ = value; + } + + void SetInsertSpaceAfterOpeningAndBeforeClosingEmptyBraces(bool value) + { + insertSpaceAfterOpeningAndBeforeClosingEmptyBraces_ = value; + } + + void SetInsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces(bool value) + { + insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces_ = value; + } + + void SetInsertSpaceAfterTypeAssertion(bool value) + { + insertSpaceAfterTypeAssertion_ = value; + } + + void SetInsertSpaceBeforeFunctionParenthesis(bool value) + { + insertSpaceBeforeFunctionParenthesis_ = value; + } + + void SetPlaceOpenBraceOnNewLineForFunctions(bool value) + { + placeOpenBraceOnNewLineForFunctions_ = value; + } + + void SetPlaceOpenBraceOnNewLineForControlBlocks(bool value) + { + placeOpenBraceOnNewLineForControlBlocks_ = value; + } + + void SetInsertSpaceBeforeTypeAnnotation(bool value) + { + insertSpaceBeforeTypeAnnotation_ = value; + } + + void SetIndentMultiLineObjectLiteralBeginningOnBlankLine(bool value) + { + indentMultiLineObjectLiteralBeginningOnBlankLine_ = value; + } + + void SetSemicolons(SemicolonPreference value) + { + semicolons_ = value; + } + +private: + bool insertSpaceAfterCommaDelimiter_ = true; + bool insertSpaceAfterSemicolonInForStatements_ = true; + bool insertSpaceBeforeAndAfterBinaryOperators_ = true; + bool insertSpaceAfterConstructor_ = false; + bool insertSpaceAfterKeywordsInControlFlowStatements_ = true; + bool insertSpaceAfterFunctionKeywordForAnonymousFunctions_ = false; + bool insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis_ = false; + bool insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets_ = false; + bool insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces_ = true; + bool insertSpaceAfterOpeningAndBeforeClosingEmptyBraces_ = false; + bool insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces_ = false; + bool insertSpaceAfterTypeAssertion_ = false; + bool insertSpaceBeforeFunctionParenthesis_ = false; + bool placeOpenBraceOnNewLineForFunctions_ = false; + bool placeOpenBraceOnNewLineForControlBlocks_ = false; + bool insertSpaceBeforeTypeAnnotation_ = false; + bool indentMultiLineObjectLiteralBeginningOnBlankLine_ = false; + SemicolonPreference semicolons_ = SemicolonPreference::IGNORE; +}; + +FormatCodeSettings GetDefaultFormatCodeSettings(const std::string &newLineCharacter); + +} // namespace ark::es2panda::lsp + +#endif // FORMATTING_CODE_SETTINGS_H \ No newline at end of file diff --git a/ets2panda/lsp/include/formatting/rule.h b/ets2panda/lsp/include/formatting/rule.h new file mode 100644 index 0000000000000000000000000000000000000000..3e9e10a1098557e29582ea6a5326546773ab67ca --- /dev/null +++ b/ets2panda/lsp/include/formatting/rule.h @@ -0,0 +1,93 @@ +/** + * 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 RULE_H +#define RULE_H + +#include +#include +#include "ir/astNode.h" +#include "formatting_context.h" + +namespace ark::es2panda::lsp { + +using ContextPredicate = std::function; + +enum class RuleAction : uint16_t { + NONE = 0U, + STOP_PROCESSING_SPACE_ACTIONS = 1U << 0U, + STOP_PROCESSING_TOKEN_ACTIONS = 1U << 1U, + INSERT_SPACE = 1U << 2U, + INSERT_NEWLINE = 1U << 3U, + DELETE_SPACE = 1U << 4U, + DELETE_TOKEN = 1U << 5U, + INSERT_TRAILING_SEMICOLON = 1U << 6U +}; + +enum class RuleFlags { NONE, CAN_DELETE_NEWLINES }; + +struct Rule { +public: + explicit Rule(std::vector &cb, RuleAction action, RuleFlags flag) + : context_(std::move(cb)), action_(action), flags_(flag) + { + } + + std::vector &GetContext() + { + return context_; + } + + RuleAction GetRuleAction() + { + return action_; + } + + RuleFlags GetRuleFlags() + { + return flags_; + } + +private: + std::vector context_; + RuleAction action_; + RuleFlags flags_; +}; + +struct TokenRange { +public: + explicit TokenRange(std::vector &tokens, bool isSpecific) + : tokens_(std::move(tokens)), isSpecific_(isSpecific) + { + } + + std::vector &GetTokens() + { + return tokens_; + } + + bool GetIsSpecifier() + { + return isSpecific_; + } + +private: + std::vector tokens_; + bool isSpecific_; +}; + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/formatting/rules.h b/ets2panda/lsp/include/formatting/rules.h new file mode 100644 index 0000000000000000000000000000000000000000..89e86396cabefbb2debe4a6804a468af41d7dcc5 --- /dev/null +++ b/ets2panda/lsp/include/formatting/rules.h @@ -0,0 +1,71 @@ +/** + * 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 RULES_H +#define RULES_H + +#include +#include "rule.h" + +namespace ark::es2panda::lsp { + +struct RuleSpec { +public: + explicit RuleSpec(Rule &rule, std::vector &leftTokenRange, std::vector &rightTokenRange) + : rule_(rule), leftTokenRange_(leftTokenRange), rightTokenRange_(rightTokenRange) + { + } + + Rule &GetRule() + { + return rule_; + } + + const Rule &GetRule() const + { + return rule_; + } + + std::vector &GetLeftTokenRange() + { + return leftTokenRange_; + } + + const std::vector &GetLeftTokenRange() const + { + return leftTokenRange_; + } + + std::vector &GetRightTokenRange() + { + return rightTokenRange_; + } + + const std::vector &GetRightTokenRange() const + { + return rightTokenRange_; + } + +private: + Rule rule_; + std::vector leftTokenRange_; + std::vector rightTokenRange_; +}; + +std::vector GetAllRules(); + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/formatting/rules_map.h b/ets2panda/lsp/include/formatting/rules_map.h new file mode 100644 index 0000000000000000000000000000000000000000..402b805216be1361f28fa3b22865f84a54d7b2af --- /dev/null +++ b/ets2panda/lsp/include/formatting/rules_map.h @@ -0,0 +1,47 @@ +/** + * 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 RULES_MAP_H +#define RULES_MAP_H + +#include +#include +#include "rules.h" + +namespace ark::es2panda::lsp { + +using RulesMap = std::function(const FormattingContext &)>; + +class RulesMapCache { +public: + static RulesMapCache &Instance(); + + static RulesMap &GetRulesMap(); + + ~RulesMapCache() = default; + NO_COPY_SEMANTIC(RulesMapCache); + NO_MOVE_SEMANTIC(RulesMapCache); + +private: + RulesMapCache() = default; + + static RulesMap rulesMap_; + + static RulesMap CreateRulesMap(std::vector ruleSpec); +}; + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/generate_constructor.h b/ets2panda/lsp/include/generate_constructor.h new file mode 100644 index 0000000000000000000000000000000000000000..7f84dbb118be44da7416c626706d1785165b2b60 --- /dev/null +++ b/ets2panda/lsp/include/generate_constructor.h @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at* + * + * http://www.apache.org/licenses/LICENSE-2.0* + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GENERATE_CONSTRUCTOR_H +#define GENERATE_CONSTRUCTOR_H + +#include "api.h" +#include +#include +#include "user_preferences.h" +#include "ir/astNode.h" +#include "es2panda.h" + +namespace ark::es2panda::lsp { + +std::vector GetRefactorActionsToGenerateConstructor(es2panda_Context *context, size_t position, + const std::vector &properties); + +} // namespace ark::es2panda::lsp +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/get_class_property_info.h b/ets2panda/lsp/include/get_class_property_info.h new file mode 100644 index 0000000000000000000000000000000000000000..5dcc804ef0f68d68cc07f71540452c2ed9ce5db5 --- /dev/null +++ b/ets2panda/lsp/include/get_class_property_info.h @@ -0,0 +1,64 @@ +/** + * 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 GET_CLASS_PROPERTY_INFO_H +#define GET_CLASS_PROPERTY_INFO_H + +#include +#include +#include +#include + +#include "ast_verifier/helpers.h" +#include "cancellation_token.h" +#include "es2panda.h" +#include "class_hierarchy.h" +#include "api.h" +#include "internal_api.h" +#include "public/public.h" +#include "types.h" + +namespace ark::es2panda::lsp { +// NOLINTBEGIN(misc-non-private-member-variables-in-classes) +struct InstallPackageAction { + std::string type; + std::optional file; + std::optional packageName; + + InstallPackageAction() : type("install package") {} +}; + +using CodeActionCommand = InstallPackageAction; + +struct RefactorEditInfoes { + std::vector edits; + std::optional renameFilename; + std::optional renameNumber; + std::optional> commands; +}; + +// NOLINTEND(misc-non-private-member-variables-in-classes) +/** + * @brief Get class property info at position, optionally including inherited. + * @param context Parser context (es2panda_Context*). + * @param pos Position to locate class declaration. + * @param shouldCollectInherited Collect inherited properties if true (default: false). + * @return Vector of FieldsInfo. Empty if context/position invalid or class not found. + */ +std::vector GetClassPropertyInfo(es2panda_Context *context, size_t pos, + bool shouldCollectInherited = false); +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/get_definition_and_bound_span.h b/ets2panda/lsp/include/get_definition_and_bound_span.h new file mode 100644 index 0000000000000000000000000000000000000000..73e18e3176bb615a2025fbdaff9ef22b2b50e7f7 --- /dev/null +++ b/ets2panda/lsp/include/get_definition_and_bound_span.h @@ -0,0 +1,39 @@ +/** + * 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 ES2PANDA_LSP_GET_DEFINITION_AND_BOUND_SPAN_H +#define ES2PANDA_LSP_GET_DEFINITION_AND_BOUND_SPAN_H + +#include "api.h" +#include +#include "public/public.h" +#include "internal_api.h" +#include "get_adjusted_location.h" +#include "signature_help.h" +#include "public/es2panda_lib.h" +#include "ir/astNode.h" + +namespace ark::es2panda::lsp { + +struct DefinitionInfoAndBoundSpan { + DefinitionInfo definitionInfo; + TextSpan boundSpan {0, 0}; +}; + +DefinitionInfoAndBoundSpan GetDefinitionAndBoundSpan(es2panda_Context *referenceFileContext, size_t offset); + +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/lsp/include/get_safe_delete_info.h b/ets2panda/lsp/include/get_safe_delete_info.h new file mode 100644 index 0000000000000000000000000000000000000000..8988c5b14ebceb072da62c45107eca78a37d8787 --- /dev/null +++ b/ets2panda/lsp/include/get_safe_delete_info.h @@ -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. + */ +#ifndef GET_SAFE_DELETE_INFO_H +#define GET_SAFE_DELETE_INFO_H +#include "public/es2panda_lib.h" +namespace ark::es2panda::lsp { +// This function judge whether indicated part can be deleted. +bool GetSafeDeleteInfoImpl(es2panda_Context *context, size_t position, const std::string &path); +} // namespace ark::es2panda::lsp +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/inlay_hints.h b/ets2panda/lsp/include/inlay_hints.h index a9abc10b5f9a8a2c0879369ca0b6b854cfa75f65..f3c78e0ef6f3baea8155405187e501c74d69fb96 100644 --- a/ets2panda/lsp/include/inlay_hints.h +++ b/ets2panda/lsp/include/inlay_hints.h @@ -30,24 +30,6 @@ struct ParamInfoObj { bool isFirstVariadicArgument; }; -enum class InlayHintKind { - TYPE, - PARAMETER, - ENUM, -}; - -struct InlayHint { - std::string text; - int number; - InlayHintKind kind; - bool whitespaceBefore; - bool whitespaceAfter; -}; - -struct InlayHintList { - std::vector hints; -}; - int GetFullWidth(const ir::AstNode *node); void AddEnumMemberValueHints(const std::string &text, const int position, InlayHintList *result); void AddTypeHints(const std::string &text, const int position, InlayHintList *result); @@ -66,7 +48,8 @@ void GetFunctionParameterTypeForHints(const ir::AstNode *node, InlayHintList *re bool IsSignatureSupportingReturnAnnotation(const ir::AstNode *node); void Visitor(const ir::AstNode *node, const TextSpan *span, const ir::AstNode *parent, CancellationToken cancellationToken, InlayHintList *result); -InlayHintList ProvideInlayHints(const char *file, const TextSpan *span, CancellationToken cancellationToken); +InlayHintList ProvideInlayHintsImpl(es2panda_Context *context, const TextSpan *span, + CancellationToken &cancellationToken, UserPreferences &preferences); } // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/include/internal_api.h b/ets2panda/lsp/include/internal_api.h index ff481a8fac188f627d2a865f83a883acec0ecd22..9d1f8ff9b669def2e1c67fc8f40f65fad351df29 100644 --- a/ets2panda/lsp/include/internal_api.h +++ b/ets2panda/lsp/include/internal_api.h @@ -65,6 +65,7 @@ ir::AstNode *GetTouchingToken(es2panda_Context *context, size_t pos, bool flagFi References GetFileReferencesImpl(es2panda_Context *referenceFileContext, char const *searchFileName, bool isPackageModule); ir::AstNode *FindPrecedingToken(const size_t pos, const ir::AstNode *startNode, ArenaAllocator *allocator); +ir::AstNode *GetIdentifierFromSuper(ir::AstNode *super); ir::AstNode *GetOriginalNode(ir::AstNode *astNode); checker::VerifiedType GetTypeOfSymbolAtLocation(checker::ETSChecker *checker, ir::AstNode *astNode); FileDiagnostic CreateDiagnosticForNode(es2panda_AstNode *node, Diagnostic diagnostic, @@ -82,10 +83,16 @@ DocumentHighlights GetDocumentHighlightsImpl(es2panda_Context *context, size_t p void GetReferenceLocationAtPositionImpl(FileNodeInfo fileNodeInfo, es2panda_Context *referenceFileContext, ReferenceLocationList *list); void RemoveFromFiles(std::vector &files, const std::vector &autoGenerateFolders); +ir::AstNode *FindRightToken(const size_t pos, const ArenaVector &nodes); std::string GetOwnerId(ir::AstNode *node); std::string GetIdentifierName(ir::AstNode *node); bool NodeHasTokens(const ir::AstNode *node); void FindAllChild(const ir::AstNode *ast, const ir::NodePredicate &cb, ArenaVector &results); +std::vector GetCodeFixesAtPositionImpl(es2panda_Context *context, size_t startPosition, + size_t endPosition, std::vector &errorCodes, + CodeFixOptions &codeFixOptions); +CombinedCodeActionsInfo GetCombinedCodeFixImpl(es2panda_Context *context, const std::string &fixId, + CodeFixOptions &codeFixOptions); } // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/include/isolated_declaration.h b/ets2panda/lsp/include/isolated_declaration.h new file mode 100644 index 0000000000000000000000000000000000000000..7c1ac4d65c407d58d4fea9c43989c24f712c5099 --- /dev/null +++ b/ets2panda/lsp/include/isolated_declaration.h @@ -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. + */ + +#ifndef ES2PANDA_LSP_INCLUDE_ISOLATED_DECLARATION_H +#define ES2PANDA_LSP_INCLUDE_ISOLATED_DECLARATION_H + +#include "api.h" + +namespace ark::es2panda::lsp { +std::optional ProcessIdentifier(ir::Identifier *identifier, checker::ETSChecker *checker, + parser::Program *program); +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/navigate_to.h b/ets2panda/lsp/include/navigate_to.h new file mode 100644 index 0000000000000000000000000000000000000000..e7721d25b6c755d4473a8aaa746b53e9b0194e20 --- /dev/null +++ b/ets2panda/lsp/include/navigate_to.h @@ -0,0 +1,71 @@ +/** + * 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 NAVIGATE_TO_H +#define NAVIGATE_TO_H + +#include +#include +#include +#include +#include "es2panda.h" +#include "ir/astNode.h" +#include + +namespace ark::es2panda::lsp { + +enum class MatchKind { EXACT, PREFIX, SUBSTRING, CAMELCASE, NONE }; + +struct TextSpan { + size_t start; + size_t length; +}; + +struct NavigateToItem { + std::string name; + std::string_view kind; + MatchKind matchKind = MatchKind::NONE; + bool isCaseSensitive = false; + std::string fileName; + std::string containerName; + std::string_view containerKind; +}; + +class PatternMatcher { +public: + PatternMatcher(const std::string &pattern, bool isCaseSensitive); + + bool IsPatternValid() const; + bool MatchesExact(const std::string &candidate) const; + bool MatchesPrefix(const std::string &candidate) const; + bool MatchesSubstring(const std::string &candidate) const; + +private: + std::string pattern_; + std::optional regexPattern_; + bool isCaseSensitive_; +}; + +std::vector GetNavigateToItems(es2panda_Context *context, + const std::vector &srcFiles, + size_t maxResultCount, const std::string &searchValue, + bool isCaseSensitive); + +ir::AstNode *GetContainerNodes(ir::AstNode *node); +std::vector GetItemsFromNamedDeclaration(const SourceFile &file, const PatternMatcher &matcher); + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/linter/test/migrate/void_operator.sts b/ets2panda/lsp/include/organize_imports.h similarity index 45% rename from ets2panda/linter/test/migrate/void_operator.sts rename to ets2panda/lsp/include/organize_imports.h index 1d0ace9453ceb6c8cba8f1ff007d5f2c89cabe84..a178033a459ffa1cc71fe834d5bcb65c790df320 100644 --- a/ets2panda/linter/test/migrate/void_operator.sts +++ b/ets2panda/lsp/include/organize_imports.h @@ -1,4 +1,4 @@ -/* +/** * 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. @@ -13,60 +13,38 @@ * limitations under the License. */ -void 0; +#ifndef ES2PANDA_LSP_ORGANIZE_IMPORTS_H +#define ES2PANDA_LSP_ORGANIZE_IMPORTS_H -void 'hello'; +#include +#include +#include "public/es2panda_lib.h" -void (1 + 2); +struct FileTextChanges; -void { a: 1, b: 2 }; +namespace ark::es2panda::lsp { -void [1, 2, 3]; +enum class ImportType { NORMAL, DEFAULT, NAMESPACE, TYPE_ONLY }; -void console.log('expression evaluated'); - -const undefined_value = void 1; - -const undefined_value2: undefined = void 2; - -const undefined_value3: number | undefined = void 3; - -void void 1; - -void function () { - console.log('foo'); +struct ImportSpecifier { + std::string importedName; + std::string localName; + ImportType type; + size_t start; + size_t length; }; -void function () { - console.log("bar!"); -}(); - -void (function () { - console.log('baz!'); -})(); - -void class {}; - -void (class {}); - -void (() => {}); - -function foo() { - let a = 1; - void a++; +struct ImportInfo { + std::string moduleName; + std::vector namedImports; + size_t startIndex; + size_t endIndex; +}; - let b = [1, 2, 3]; - void console.log(b.filter(x => x % 2 !== 0)); - - void function() { - console.log('foo'); - }; +struct OrganizeImports { + static std::vector Organize(es2panda_Context *context, const std::string &fileName); +}; - void function localFun() { - console.log('foo'); - }; - - void class {}; +} // namespace ark::es2panda::lsp - void class localClass{}; -} +#endif diff --git a/ets2panda/lsp/include/quick_info.h b/ets2panda/lsp/include/quick_info.h index 0c758407817c19eac33bb8b3c9cf043415939c45..f234a884b3bf88b6a84fe72dc7da582842e60c38 100644 --- a/ets2panda/lsp/include/quick_info.h +++ b/ets2panda/lsp/include/quick_info.h @@ -19,6 +19,7 @@ #include "ir/astNode.h" #include "public/es2panda_lib.h" #include "api.h" +#include "types.h" namespace ark::es2panda::lsp { @@ -39,7 +40,14 @@ std::vector CreateDisplayForMethodDefinition(ir::AstNode *nod std::vector CreateDisplayForClassProperty(ir::AstNode *node, const std::string &kindModifier); std::vector CreateDisplayForETSParameterExpression(ir::AstNode *node); QuickInfo GetQuickInfoAtPositionImpl(es2panda_Context *context, size_t position, std::string fileName); +std::string GetNameForTypeReference(const ir::TypeNode *typeReference); std::string GetNameForTypeNode(const ir::TypeNode *typeAnnotation); +std::vector CreateDisplayForImportDeclaration(ir::AstNode *node); +ir::AstNode *GetEnumMemberByName(ir::AstNode *node, const util::StringView &name); +std::string ModifiersToString(ir::ModifierFlags flags); +std::string GetKindModifiers(ir::AstNode *node); +bool IsClass(ir::AstNode *node); +ir::AstNode *GetContainerNode(ir::AstNode *node); } // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/include/refactors/convert_function.h b/ets2panda/lsp/include/refactors/convert_function.h new file mode 100644 index 0000000000000000000000000000000000000000..2b9767164bc3209a865ff62c93337bc295354924 --- /dev/null +++ b/ets2panda/lsp/include/refactors/convert_function.h @@ -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. + */ + +#ifndef CONVERT_FUNCTION_H +#define CONVERT_FUNCTION_H + +#include "lsp/include/applicable_refactors.h" + +namespace ark::es2panda::lsp { + +constexpr RefactorActionView TO_ANONYMOUS_FUNCTION_ACTION { + "Convert to anonymous function", "Convert to anonymous function", "refactor.rewrite.function.anonymous"}; +constexpr RefactorActionView TO_NAMED_FUNCTION_ACTION {"Convert to named function", "Convert to named function", + "refactor.rewrite.function.named"}; +constexpr RefactorActionView TO_ARROW_FUNCTION_ACTION {"Convert to arrow function", "Convert to arrow function", + "refactor.rewrite.function.arrow"}; + +class ConvertFunctionRefactor : public Refactor { +public: + ConvertFunctionRefactor(); + ApplicableRefactorInfo GetAvailableActions(es2panda_Context *context, std::string kind, size_t position) override; +}; +} // namespace ark::es2panda::lsp + +#endif // CONVERT_FUNCTION_H \ No newline at end of file diff --git a/ets2panda/lsp/include/register_code_fix/add_missing_declare_property.h b/ets2panda/lsp/include/register_code_fix/add_missing_declare_property.h new file mode 100644 index 0000000000000000000000000000000000000000..304f15ee4cbf075ba0a7b47dc929ba7b2177c224 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/add_missing_declare_property.h @@ -0,0 +1,42 @@ +/** + * 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 ADD_MISSING_DECLARE_PROPERTY_H +#define ADD_MISSING_DECLARE_PROPERTY_H + +#include +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/services/text_change/change_tracker.h" +#include "lsp/include/types.h" + +namespace ark::es2panda::lsp { + +void MakeChange(ChangeTracker changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes); + +std::vector GetCodeActionsToAddMissingDeclareOnProperty(const CodeFixContext &context); + +class AddMissingDeclareProperty : public CodeFixRegistration { +public: + AddMissingDeclareProperty(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; +}; + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/register_code_fix/fix_missing_call_parantheses.h b/ets2panda/lsp/include/register_code_fix/fix_missing_call_parantheses.h new file mode 100644 index 0000000000000000000000000000000000000000..c2c50e1dde12c3e57939fda73a7be0de8d5bb572 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_missing_call_parantheses.h @@ -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. + */ + +#ifndef FIX_MISSING_CALL_PARANTHESES_H +#define FIX_MISSING_CALL_PARANTHESES_H + +#include +#include +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/services/text_change/change_tracker.h" +#include "lsp/include/types.h" + +namespace ark::es2panda::lsp { + +class FixMissingCallParantheses : public CodeFixRegistration { +public: + FixMissingCallParantheses(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; +}; + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/register_code_fix/fix_nan_equality.h b/ets2panda/lsp/include/register_code_fix/fix_nan_equality.h new file mode 100644 index 0000000000000000000000000000000000000000..b88fbe5287806bca9e808ccb43a4834ae5df2997 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/fix_nan_equality.h @@ -0,0 +1,43 @@ +/** + * 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_NAN_EQUALITY_H +#define FIX_NAN_EQUALITY_H + +#include +#include +#include "code_fixes/code_fix_types.h" +#include "services/text_change/change_tracker.h" +#include "lsp/include/types.h" + +namespace ark::es2panda::lsp { + +class FixNaNEquality : public CodeFixRegistration { +public: + FixNaNEquality(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + +private: + void MakeChangeForNaNEquality(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes); + + std::vector GetCodeActionsToFixNaNEquality(const CodeFixContext &context); +}; + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/register_code_fix/forgetten_this_property_access.h b/ets2panda/lsp/include/register_code_fix/forgetten_this_property_access.h new file mode 100644 index 0000000000000000000000000000000000000000..d5ea48b3195fad2cff697cf846cecb0af4919067 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/forgetten_this_property_access.h @@ -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. + */ + +#ifndef FORGOTTEN_THIS_PROPERTY_ACCESS_H +#define FORGOTTEN_THIS_PROPERTY_ACCESS_H + +#include +#include +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/services/text_change/change_tracker.h" +#include "lsp/include/types.h" + +namespace ark::es2panda::lsp { + +class ForgettenThisPropertyAccess : public CodeFixRegistration { +public: + ForgettenThisPropertyAccess(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; +}; + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/register_code_fix/import_fixes.h b/ets2panda/lsp/include/register_code_fix/import_fixes.h new file mode 100644 index 0000000000000000000000000000000000000000..97da8872f2b60bdd7a5d1567171b827b3565c62a --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/import_fixes.h @@ -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. + */ + +#ifndef IMPORT_FIXES_H +#define IMPORT_FIXES_H + +#include +#include +#include "code_fixes/code_fix_types.h" +#include "services/text_change/change_tracker.h" +#include "types.h" + +namespace ark::es2panda::lsp { + +class ImportFixes : public CodeFixRegistration { +public: + ImportFixes(); + + std::vector GetCodeActions(const CodeFixContext &context) override; + + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; +}; + +} // namespace ark::es2panda::lsp +#endif diff --git a/ets2panda/lsp/include/script_element_kind.h b/ets2panda/lsp/include/script_element_kind.h new file mode 100644 index 0000000000000000000000000000000000000000..8e699b5ea127bcbc679d12677e0729e3a5970cc6 --- /dev/null +++ b/ets2panda/lsp/include/script_element_kind.h @@ -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. + */ + +#ifndef ES2PANDA_SCRIPT_ELEMENT_KIND_H +#define ES2PANDA_SCRIPT_ELEMENT_KIND_H + +#include "public/es2panda_lib.h" +#include "completions.h" + +namespace ark::es2panda::lsp { + +CompletionEntryKind GetAliasScriptElementKindImpl(es2panda_Context *context, size_t position); + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/services/text_change/change_tracker.h b/ets2panda/lsp/include/services/text_change/change_tracker.h new file mode 100644 index 0000000000000000000000000000000000000000..168c1f36b310a1bc84dc4c8f161bc9d624052fbf --- /dev/null +++ b/ets2panda/lsp/include/services/text_change/change_tracker.h @@ -0,0 +1,258 @@ +/** + * 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 ES2PANDA_LSP_CHANGE_TRACKER_H +#define ES2PANDA_LSP_CHANGE_TRACKER_H +#include +#include +#include +#include +#include +#include "es2panda.h" +#include "public/public.h" +#include +#include "lsp/include/api.h" +#include "ir/astNode.h" +#include "lsp/include/user_preferences.h" +#include "lsp/include/formatting/formatting_context.h" +#include "lsp/include/formatting/formatting.h" +#include "lsp/include/internal_api.h" +#include "util.h" +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { + +enum class LeadingTriviaOption { EXCLUDE, INCLUDEALL, STARTLINE }; + +enum class TrailingTriviaOption { EXCLUDE, EXCLUDEWHITESPACE, INCLUDE }; + +struct ConfigurableStart { + std::optional leadingTriviaOption; +}; + +struct ConfigurableEnd { + std::optional trailingTriviaOption; +}; + +struct TextRange { + size_t pos; + size_t end; +}; + +struct ConfigurableStartEnd { + std::optional leadingTriviaOption; + std::optional trailingTriviaOption; +}; + +struct InsertNodeOptions { + std::optional prefix; + std::optional suffix; + std::optional indentation; + std::optional delta; +}; + +struct ReplaceWithMultipleNodesOptions : InsertNodeOptions { + std::optional joiner; +}; + +struct ChangeNodeOptions { + std::optional configurableStartEnd; + std::optional insertNodeOptions; +}; + +enum class ChangeKind { REMOVE, REPLACEWITHSINGLENODE, REPLACEWITHMULTIPLENODES, TEXT }; + +struct ChangeText { + const SourceFile *sourceFile; + TextRange range; + ChangeKind kind = ChangeKind::TEXT; + std::string text; +}; + +struct ReplaceWithSingleNode { + const SourceFile *sourceFile; + TextRange range; + ChangeKind kind = ChangeKind::REPLACEWITHSINGLENODE; + const ir::AstNode *node; + std::optional options; +}; + +struct ReplaceWithMultipleNodes { + const SourceFile *sourceFile; + TextRange range; + ChangeKind kind = ChangeKind::REPLACEWITHMULTIPLENODES; + std::vector nodes; + std::optional options; +}; +struct RemoveNode { + const SourceFile *sourceFile; + TextRange range; + ChangeKind kind = ChangeKind::REMOVE; +}; + +struct NewFile { + std::optional oldFile; + std::string fileName; + std::vector statements; +}; + +using Change = std::variant; + +struct DeletedNode { + const SourceFile *sourceFile; + const std::variant> &node; +}; + +struct NewFileStruct { + std::optional oldFile; + std::string fileName; + std::vector> statements; +}; + +using ValidateNonFormattedText = std::function; + +struct ClassInsertInfo { + ir::AstNode *node; + SourceFile *sourceFile; +}; + +class ChangeTracker { +private: + FormatContext formatContext_; + std::string newLineCharacter_; + + ChangeTracker(FormatContext &formatContext, std::string newLineCharacter) + : formatContext_(formatContext), newLineCharacter_(std::move(newLineCharacter)) {}; + + ir::AstNode *GetAstFromContext(const es2panda_Context *context); + size_t GetStartPositionOfLine(size_t line, const es2panda_Context *context); + bool RangeContainsPosition(TextRange r, size_t pos); + void ReplaceRangeWithNodes(es2panda_Context *context, const TextRange range, std::vector &newNodes, + ReplaceWithMultipleNodesOptions options = {}); + ir::AstNode *NextCommaToken(es2panda_Context *context, const ir::AstNode *node); + void InsertNodesAt(es2panda_Context *context, size_t pos, std::vector &newNodes, + ReplaceWithMultipleNodesOptions options = {}); + void InsertAtTopOfFile(es2panda_Context *context, + const std::variant> &insert, + bool blankLineBetween); + InsertNodeOptions GetOptionsForInsertNodeBefore(const ir::AstNode *before, const ir::AstNode *inserted, + bool blankLineBetween); + std::vector GetMembersOrProperties(const ir::AstNode *node); + InsertNodeOptions GetInsertNodeAtStartInsertOptions(const ir::AstNode *node); + void InsertNodeAtStartWorker(es2panda_Context *context, const ir::AstNode *node, const ir::AstNode *newElement); + bool NeedSemicolonBetween(const ir::AstNode *a, const ir::AstNode *b); + size_t InsertNodeAfterWorker(es2panda_Context *context, ir::AstNode *after, const ir::AstNode *newNode); + InsertNodeOptions GetInsertNodeAfterOptionsWorker(const ir::AstNode *node); + void InsertNodeInListAfterMultiLine(bool multilineList, es2panda_Context *context, const SourceFile *sourceFile, + size_t end, const ir::AstNode *newNode); + std::vector GetTextChangesFromChanges(std::vector &changes, std::string &newLineCharacter, + const FormatCodeSettings &formatCodeSettings); + std::vector deletedNodes_; + std::vector changes_; + std::vector newFiles_; + std::map classesWithNodesInsertedAtStart_; + +public: + std::vector GetDeletedNodesList() const + { + return deletedNodes_; + } + std::vector GetChangeList() const + { + return changes_; + } + std::vector GetNewFilesList() const + { + return newFiles_; + } + std::map GetClassesWithNodesInsertedAtStartList() const + { + return classesWithNodesInsertedAtStart_; + } + + static ChangeTracker FromContext(TextChangesContext &context); + static std::vector With(TextChangesContext &context, + const std::function &cb); + + void PushRaw(const SourceFile *sourceFile, const FileTextChanges &change); + void DeleteRange(const SourceFile *sourceFile, TextRange range); + std::vector GetChanges(); + void Delete(const SourceFile *sourceFile, + std::variant> &node); + TextRange GetAdjustedRange(es2panda_Context *context, ir::AstNode *startNode, ir::AstNode *endNode); + + void FinishDeleteDeclarations(); + void DeleteNode(es2panda_Context *context, const SourceFile *sourceFile, ir::AstNode *node); + + void DeleteNodeRange(es2panda_Context *context, ir::AstNode *startNode, ir::AstNode *endNode); + + void DeleteModifier(es2panda_Context *context, ir::AstNode *modifier); + void DeleteNodeRangeExcludingEnd(es2panda_Context *context, ir::AstNode *startNode, ir::AstNode *afterEndNode); + void ReplaceRange(es2panda_Context *context, TextRange range, const ir::AstNode *newNode, + InsertNodeOptions &options); + void ReplaceNode(es2panda_Context *context, ir::AstNode *oldNode, ir::AstNode *newNode, ChangeNodeOptions options); + void ReplaceNodeRange(es2panda_Context *context, ir::AstNode *startNode, ir::AstNode *endNode, + ir::AstNode *newNode); + void ReplaceNodeWithNodes(es2panda_Context *context, ir::AstNode *oldNode, std::vector &newNodes); + void ReplaceNodeWithText(es2panda_Context *context, ir::AstNode *oldNode, const std::string &text); + void ReplaceRangeWithText(const SourceFile *sourceFile, TextRange range, const std::string &text); + void ReplaceNodeRangeWithNodes(es2panda_Context *context, ir::AstNode *startNode, ir::AstNode *endNode, + std::vector &newNodes); + TextRange CreateRange(size_t pos, size_t end = 0); + void ReplacePropertyAssignment(es2panda_Context *context, ir::AstNode *oldNode, ir::AstNode *newNode); + void InsertNodeAt(es2panda_Context *context, size_t pos, const ir::AstNode *newNode, InsertNodeOptions &options); + bool IsLineBreak(char ch); + void FinishClassesWithNodesInsertedAtStart(); + size_t GetInsertionPositionAtSourceFileTop(ir::AstNode *sourceFileAst); + void InsertNodeAtTopOfFile(es2panda_Context *context, ir::AstNode *newNode, bool blankLineBetween); + void InsertNodesAtTopOfFile(es2panda_Context *context, const std::vector newNodes, + bool blankLineBetween); + void InsertNodeBefore(es2panda_Context *context, ir::AstNode *before, ir::AstNode *newNode, + bool blankLineBetween = false); + void InsertModifierAt(es2panda_Context *context, size_t pos, const ir::AstNode *modifier, + InsertNodeOptions &options); + void InsertModifierBefore(es2panda_Context *context, const ir::AstNode *modifier, ir::AstNode *before); + void InsertText(const SourceFile *sourceFile, size_t pos, const std::string &text); + bool TryInsertTypeAnnotation(es2panda_Context *context, ir::AstNode *node, ir::AstNode *type); + void TryInsertThisTypeAnnotation(es2panda_Context *context, ir::AstNode *node, ir::AstNode *type); + void InsertTypeParameters(es2panda_Context *context, const ir::AstNode *node, + std::vector &typeParameters); + void ReplaceConstructorBody(es2panda_Context *context, ir::AstNode *ctr, + const std::vector &statements); + void InsertNodeAtConstructorStart(es2panda_Context *context, ir::AstNode *ctr, ir::Statement *newStatement); + void InsertNodeAfter(es2panda_Context *context, ir::AstNode *after, ir::AstNode *newNode); + void InsertNodeAtConstructorEnd(es2panda_Context *context, ir::AstNode *ctr, ir::Statement *newStatement); + void InsertNodeAtEndOfScope(es2panda_Context *context, ir::AstNode *scope, ir::AstNode *newNode); + void InsertMemberAtStart(es2panda_Context *context, ir::AstNode *node, ir::AstNode *newElement); + void InsertNodeAtObjectStart(es2panda_Context *context, ir::ObjectExpression *obj, ir::AstNode *newElement); + void InsertNodeAfterComma(es2panda_Context *context, ir::AstNode *after, ir::AstNode *newNode); + void InsertNodeAtEndOfList(es2panda_Context *context, std::vector &list, ir::AstNode *newNode); + InsertNodeOptions GetInsertNodeAfterOptions(const ir::AstNode *after); + void InsertNodesAfter(es2panda_Context *context, ir::AstNode *after, std::vector newNodes); + void InsertFirstParameter(es2panda_Context *context, std::vector parameters, + ir::TSTypeParameterDeclaration newParam); + void InsertExportModifier(const SourceFile *sourceFile, ir::Statement *node); + std::vector GetContainingList(ir::AstNode *node); + void InsertNodeInListAfter(es2panda_Context *context, ir::AstNode *after, ir::AstNode *newNode, + std::vector &containingList); + void InsertImportSpecifierAtIndex(es2panda_Context *context, ir::AstNode *importSpecifier, + std::vector &namedImports, size_t index); + void CreateNewFile(SourceFile *oldFile, const std::string &fileName, + std::vector &statements); +}; + +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/lsp/include/signature_help.h b/ets2panda/lsp/include/signature_help.h new file mode 100644 index 0000000000000000000000000000000000000000..6933ca168ac859e5b823abf7ff308bcb21bbdb4f --- /dev/null +++ b/ets2panda/lsp/include/signature_help.h @@ -0,0 +1,316 @@ +/** + * 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 ES2PANDA_LSP_INCLUDE_SIGNATURE_HELP_H +#define ES2PANDA_LSP_INCLUDE_SIGNATURE_HELP_H + +#include "create_type_help_items.h" +#include +#include +#include +#include +#include +#include "cancellation_token.h" +#include "ir/astNode.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "signature_help_items.h" + +namespace ark::es2panda::lsp { + +enum class SignatureHelpTriggerCharacter { + COMMA, // Represents "," + OPENPAREN, // Represents "(" + LESSTHAN // Represents "<" +}; +enum class SignatureHelpRetriggerCharacter { + COMMA, // Represents "," + OPENPAREN, // Represents "(" + LESSTHAN, // Represents "<" + CLOSEPAREN // Represents ")" +}; + +enum CandidateOrTypeKind { CANDIDATE, TYPEENUM }; +struct TypeInfo { +private: + CandidateOrTypeKind kind_; + const ir::AstNode *symbol_; + +public: + TypeInfo(CandidateOrTypeKind kind, const ir::AstNode *symbol) : kind_(kind), symbol_(symbol) {} + + void SetKind(CandidateOrTypeKind newKind) + { + kind_ = newKind; + } + void SetSymbol(const ir::AstNode *newSymbol) + { + symbol_ = newSymbol; + } + CandidateOrTypeKind GetKind() const + { + return kind_; + } + const ir::AstNode *GetSymbol() const + { + return symbol_; + } + + TypeInfo() = default; +}; + +struct CandidateInfo { +private: + CandidateOrTypeKind kind_; + std::vector signatures_; + checker::Signature *resolvedSignature_; + +public: + CandidateInfo(CandidateOrTypeKind kind, std::vector &signatures, + checker::Signature *resolvedSignature) + : kind_(kind), signatures_(signatures), resolvedSignature_(resolvedSignature) + { + } + + void SetKind(CandidateOrTypeKind newKind) + { + kind_ = newKind; + } + void SetSignatures(const std::vector &newSignatures) + { + signatures_ = newSignatures; + } + void SetResolvedSignature(checker::Signature *newResolvedSignature) + { + resolvedSignature_ = newResolvedSignature; + } + CandidateOrTypeKind GetKind() const + { + return kind_; + } + std::vector &GetSignatures() + { + return signatures_; + } + checker::Signature *GetResolvedSignature() + { + return resolvedSignature_; + } + CandidateInfo() : kind_(CandidateOrTypeKind::CANDIDATE), resolvedSignature_(nullptr) {} +}; + +using InfoType = std::variant; + +struct SignatureHelpInvokedReason { +private: + const char *kind_ = "invoked"; + SignatureHelpTriggerCharacter triggerCharacter_; + +public: + explicit SignatureHelpInvokedReason(SignatureHelpTriggerCharacter trigger) : triggerCharacter_(trigger) {} + SignatureHelpInvokedReason() : triggerCharacter_(SignatureHelpTriggerCharacter::LESSTHAN) {} + + const char *GetKind() const + { + return kind_; + } + + SignatureHelpTriggerCharacter GetTriggerCharacter() const + { + return triggerCharacter_; + } + + void SetTriggerCharacter(SignatureHelpTriggerCharacter newTriggerCharacter) + { + triggerCharacter_ = newTriggerCharacter; + } +}; + +struct SignatureHelpCharacterTypedReason { +private: + const char *kind_ = "characterTyped"; + SignatureHelpTriggerCharacter triggerCharacter_; + +public: + explicit SignatureHelpCharacterTypedReason() : triggerCharacter_(SignatureHelpTriggerCharacter::LESSTHAN) {} + + const char *GetKind() const + { + return kind_; + } + SignatureHelpTriggerCharacter GetTriggerCharacter() const + { + return triggerCharacter_; + } + void SetTriggerCharacter(SignatureHelpTriggerCharacter newTriggerCharacter) + { + triggerCharacter_ = newTriggerCharacter; + } + explicit SignatureHelpCharacterTypedReason(SignatureHelpTriggerCharacter trigger) : triggerCharacter_(trigger) {} +}; + +struct SignatureHelpRetriggeredReason { +private: + const char *kind_ = "retrigger"; + SignatureHelpRetriggerCharacter triggerCharacter_; + +public: + SignatureHelpRetriggeredReason() : triggerCharacter_(SignatureHelpRetriggerCharacter::LESSTHAN) {} + explicit SignatureHelpRetriggeredReason(SignatureHelpRetriggerCharacter trigger) : triggerCharacter_(trigger) {} + + const char *GetKind() const + { + return kind_; + } + SignatureHelpRetriggerCharacter GetTriggerCharacter() const + { + return triggerCharacter_; + } + void SetTriggerCharacter(SignatureHelpRetriggerCharacter newTriggerCharacter) + { + triggerCharacter_ = newTriggerCharacter; + } +}; + +using SignatureHelpTriggerReason = + std::variant; + +struct ContextualSignatureLocationInfo { +private: + std::vector list_; + size_t argumentIndex_; + size_t argumentCount_; + TextSpan argumentsSpan_ = {0, 0}; + +public: + ContextualSignatureLocationInfo(std::vector &list, const size_t argumentIndex, + const size_t argumentCount, const TextSpan argumentsSpan) + : list_(list), argumentIndex_(argumentIndex), argumentCount_(argumentCount), argumentsSpan_(argumentsSpan) + { + } + + void SetList(const std::vector &newList) + { + list_ = newList; + } + void SetArgumentIndex(size_t newArgumentIndex) + { + argumentIndex_ = newArgumentIndex; + } + void SetArgumentCount(size_t newArgumentCount) + { + argumentCount_ = newArgumentCount; + } + void SetArgumentsSpan(TextSpan newArgumentsSpan) + { + argumentsSpan_ = newArgumentsSpan; + } + const std::vector &GetList() const + { + return list_; + } + size_t GetArgumentIndex() const + { + return argumentIndex_; + } + size_t GetArgumentCount() const + { + return argumentCount_; + } + const TextSpan &GetArgumentsSpan() const + { + return argumentsSpan_; + } + ContextualSignatureLocationInfo() : argumentIndex_(0), argumentCount_(0) {} +}; + +struct ContextualSignatureLocationInfoWithNode { +private: + ir::AstNode *node_; + size_t argumentIndex_; + size_t argumentCount_; + TextSpan argumentsSpan_ = {0, 0}; + +public: + ContextualSignatureLocationInfoWithNode(ir::AstNode *node, const size_t argumentIndex, const size_t argumentCount, + const TextSpan argumentsSpan) + : node_(node), argumentIndex_(argumentIndex), argumentCount_(argumentCount), argumentsSpan_(argumentsSpan) + { + } + + void SetNode(ir::AstNode *newNode) + { + node_ = newNode; + } + void SetArgumentIndex(size_t newArgumentIndex) + { + argumentIndex_ = newArgumentIndex; + } + void SetArgumentCount(size_t newArgumentCount) + { + argumentCount_ = newArgumentCount; + } + void SetArgumentsSpan(TextSpan newArgumentsSpan) + { + argumentsSpan_ = newArgumentsSpan; + } + ir::AstNode *GetNode() const + { + return node_; + } + size_t GetArgumentIndex() const + { + return argumentIndex_; + } + size_t GetArgumentCount() const + { + return argumentCount_; + } + const TextSpan &GetArgumentsSpan() const + { + return argumentsSpan_; + } +}; + +bool IsSyntacticOwner(const ir::AstNode *node); +size_t GetArgumentCount(ir::AstNode *node, bool ignoreTrailingComma); +ir::AstNode *GetHighestBinary(const ir::AstNode *node); +TextSpan CreateTextSpanForNode(const ir::AstNode *node); +size_t CountBinaryExpressionParameters(ir::AstNode *node); +std::vector GetArgumentOrParameterListAndIndex(ir::AstNode *node, + std::vector &list); +std::optional GetContextualSignatureLocationInfo(ir::AstNode *node); +std::optional GetImmediatelyContainingArgumentInfo(ir::AstNode *node, size_t position); +std::optional TryGetParameterInfo(ir::AstNode *node); +std::optional GetImmediatelyContainingArgumentOrContextualParameterInfo(ir::AstNode *node, + size_t position, + ir::AstNode *parent); +std::optional GetContainingArgumentInfo(ir::AstNode *node, size_t position, bool isManuallyInvoked); +size_t GetArgumentIndexForTemplatePiece(size_t spanIndex, ir::AstNode *node, size_t position); +ir::AstNode *GetChildListThatStartsWithOpenerToken(ir::AstNode *parent, ir::AstNode *openerToken); +ir::AstNode *FindTokenOnLeftOfPosition(es2panda_Context *context, size_t position); + +SignatureHelpItems GetSignatureHelpItems(es2panda_Context *ctx, size_t position, + SignatureHelpTriggerReason triggeredReason, + CancellationToken cancellationToken); +std::optional GetCandidateOrTypeInfo(const std::optional info, ir::AstNode *parent, + const bool onlyUseSyntacticOwners); +checker::Signature *GetResolvedSignatureForSignatureHelp(const ir::AstNode *call, const ir::AstNode *parent, + std::vector &candidates); + +} // namespace ark::es2panda::lsp + +#endif diff --git a/ets2panda/lsp/include/signature_help_items.h b/ets2panda/lsp/include/signature_help_items.h new file mode 100644 index 0000000000000000000000000000000000000000..0d94d1ae16c086bf50d2ba12a4f711d8b5f2488e --- /dev/null +++ b/ets2panda/lsp/include/signature_help_items.h @@ -0,0 +1,88 @@ +/** + * 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 ES2PANDA_LSP_INCLUDE_SIGNATURE_HELP_ITEMS_H +#define ES2PANDA_LSP_INCLUDE_SIGNATURE_HELP_ITEMS_H + +#include +#include +#include +#include "create_type_help_items.h" + +namespace ark::es2panda::lsp { + +inline constexpr std::string_view const GENSYM_CORE = "gensym%%_"; +inline constexpr std::string_view const DUMMY_ID = "_"; + +struct ArgumentListInfo { +private: + TextSpan applicableSpan_ {0, 0}; + uint32_t argumentCount_ {0}; + size_t argumentIndex_ {0}; + Invocation invocation_; + +public: + void SetApplicableSpan(TextSpan applicableSpan) + { + applicableSpan_ = applicableSpan; + } + + void SetArgumentCount(uint32_t argumentCount) + { + argumentCount_ = argumentCount; + } + + void SetArgumentIndex(size_t argumentIndex) + { + argumentIndex_ = argumentIndex; + } + + TextSpan GetApplicableSpan() + { + return applicableSpan_; + } + + uint32_t GetArgumentCount() + { + return argumentCount_; + } + + size_t GetArgumentIndex() + { + return argumentIndex_; + } + void SetInvocation(Invocation invocation) + { + invocation_ = invocation; + } + const Invocation &GetInvocation() const + { + return invocation_; + } +}; + +SignatureHelpItems CreateSignatureHelpItems(std::vector &signatures, + checker::Signature *signature, + std::optional argumentListInfo); + +std::vector GetSignatureHelpItem(const std::vector &signatures); + +SignatureHelpItem CreateSignatureHelpItem(checker::Signature &signature); + +void SetSignatureHelpParameter(const checker::SignatureInfo *signatureInfo, SignatureHelpItem &signatureHelpItem); + +} // namespace ark::es2panda::lsp + +#endif // ES2PANDA_LSP_INCLUDE_SIGNATURE_HELP_ITEMS_H \ No newline at end of file diff --git a/ets2panda/lsp/include/suggestion_diagnostics.h b/ets2panda/lsp/include/suggestion_diagnostics.h index ccaa957a53f8cc9526e0f5669c4746a30d20b7db..735d88ef0b1e3705292d1f097ec662bff531b036 100644 --- a/ets2panda/lsp/include/suggestion_diagnostics.h +++ b/ets2panda/lsp/include/suggestion_diagnostics.h @@ -38,6 +38,7 @@ bool HasSupportedNumberOfArguments(ir::AstNode *node); bool IsFixablePromiseArgument(ir::AstNode *node, std::unordered_map &visitedFunc); std::string GetKeyFromNode(ir::AstNode *node); bool CanBeConvertedToAsync(ir::AstNode *node); +bool HasPropertyAccessExpressionWithName(ir::AstNode *node, const std::string &func); } // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/include/todo_comments.h b/ets2panda/lsp/include/todo_comments.h new file mode 100644 index 0000000000000000000000000000000000000000..be70dfce41f074b797312a328e9c3724721f3a5b --- /dev/null +++ b/ets2panda/lsp/include/todo_comments.h @@ -0,0 +1,89 @@ +/** + * 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 TODO_COMMENTS_H +#define TODO_COMMENTS_H + +#include +#include +#include +#include +#include "cancellation_token.h" +#include "public/es2panda_lib.h" + +namespace ark::es2panda::lsp { +struct TodoCommentDescriptor { +private: + std::string text_; + int priority_; + +public: + TodoCommentDescriptor(std::string text, int priority) : text_(std::move(text)), priority_(priority) {} + + std::string GetText() const + { + return text_; + } + + int GetPriority() const + { + return priority_; + } +}; + +struct TodoComment { +private: + TodoCommentDescriptor commentDescriptor_; + std::string message_; + size_t position_; + +public: + TodoComment(TodoCommentDescriptor descriptor, std::string message, size_t position) + : commentDescriptor_(std::move(descriptor)), message_(std::move(message)), position_(position) + { + } + + TodoCommentDescriptor GetCommentDescriptor() const + { + return commentDescriptor_; + } + + std::string GetMessage() const + { + return message_; + } + + int GetPosition() const + { + return position_; + } +}; + +struct TodoMatchContext { + es2panda_Context *context; + const std::vector &descriptors; + size_t lineStart; + const std::string *line; + std::string_view fileContents; + std::vector &result; +}; + +std::vector GetTodoCommentsImpl( + es2panda_Context *context, std::vector &descriptors, + CancellationToken *cancellationToken); + +} // namespace ark::es2panda::lsp + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/include/types.h b/ets2panda/lsp/include/types.h new file mode 100644 index 0000000000000000000000000000000000000000..438144e733adeacb158b09c643bef25431661f35 --- /dev/null +++ b/ets2panda/lsp/include/types.h @@ -0,0 +1,326 @@ +/** + * 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 ES2PANDA_LSP_INCLUDE_TYPES_H +#define ES2PANDA_LSP_INCLUDE_TYPES_H + +#include +#include +#include +#include "formatting/formatting.h" +#include "user_preferences.h" + +// NOLINTBEGIN + +#ifdef __cplusplus +extern "C" { +#endif + +struct TextSpan { + size_t start; + size_t length; + TextSpan(size_t s, size_t l) : start(s), length(l) {} + bool operator==(const TextSpan &other) const + { + return start == other.start && length == other.length; + } + bool operator!=(const TextSpan &other) const + { + return !(*this == other); + } +}; + +struct SymbolDisplayPart { +private: + std::string text_; + std::string kind_; + +public: + explicit SymbolDisplayPart(std::string text = "", std::string kind = "") + : text_ {std::move(text)}, kind_ {std::move(kind)} + { + } + + void SetText(const std::string &newText) + { + text_ = newText; + } + void SetKind(const std::string &newKind) + { + kind_ = newKind; + } + std::string GetText() const + { + return text_; + } + std::string GetKind() const + { + return kind_; + } + + bool operator==(const SymbolDisplayPart &other) const + { + return text_ == other.text_ && kind_ == other.kind_; + } + bool operator!=(const SymbolDisplayPart &other) const + { + return !(*this == other); + } +}; + +struct TextChange { + TextSpan span; + std::string newText; + TextChange(TextSpan s, const std::string &t) : span(s), newText(t) {} +}; + +struct FileTextChanges { + std::string fileName; + std::vector textChanges; + FileTextChanges(const std::string &f, const std::vector &t) : fileName(f), textChanges(t) {} + FileTextChanges() = default; +}; + +enum class InlayHintKind { + TYPE, + PARAMETER, + ENUM, +}; + +struct InlayHint { + std::string text; + int number; + InlayHintKind kind; + bool whitespaceBefore; + bool whitespaceAfter; +}; + +struct InlayHintList { + std::vector hints; +}; + +struct SignatureHelpParameter { +private: + std::string name_; + std::vector documentation_; + std::vector displayParts_; + +public: + void SetName(const std::string &newName) + { + this->name_ = newName; + } + void SetDocumentation(const SymbolDisplayPart &part) + { + documentation_.push_back(part); + } + + void SetDisplayParts(const SymbolDisplayPart &part) + { + displayParts_.push_back(part); + } + const std::string &GetName() const + { + return name_; + } + std::string &GetName() + { + return name_; + } + const std::vector &GetDocumentation() const + { + return documentation_; + } + const std::vector &GetDisplayParts() const + { + return displayParts_; + } + void Clear() + { + displayParts_.clear(); + documentation_.clear(); + } +}; +struct SignatureHelpItem { +private: + std::vector prefixDisplayParts_; + std::vector suffixDisplayParts_; + std::vector separatorDisplayParts_; + std::vector parameters_; + std::vector documentation_; + +public: + void SetPrefixDisplayParts(const SymbolDisplayPart &part) + { + prefixDisplayParts_.push_back(part); + } + + void SetSuffixDisplayParts(const SymbolDisplayPart &part) + { + suffixDisplayParts_.push_back(part); + } + void SetSeparatorDisplayParts(const SymbolDisplayPart &part) + { + separatorDisplayParts_.push_back(part); + } + void SetPrefixDisplayParts(const std::string &text, const std::string &kind) + { + prefixDisplayParts_.emplace_back(SymbolDisplayPart(text, kind)); + } + + void SetParameters(SignatureHelpParameter ¶meter) + { + parameters_.push_back(parameter); + } + void SetDocumentation(const std::string &text, const std::string &kind) + { + documentation_.emplace_back(SymbolDisplayPart(text, kind)); + } + + const std::vector &GetPrefixDisplayParts() const + { + return prefixDisplayParts_; + } + const std::vector &GetSuffixDisplayParts() const + { + return suffixDisplayParts_; + } + const std::vector &GetSeparatorDisplayParts() const + { + return separatorDisplayParts_; + } + const std::vector &GetParameters() const + { + return parameters_; + } + const std::vector &GetDocumentation() const + { + return documentation_; + } + void Clear() + { + prefixDisplayParts_.clear(); + suffixDisplayParts_.clear(); + separatorDisplayParts_.clear(); + for (auto parameter : parameters_) { + parameter.Clear(); + } + parameters_.clear(); + documentation_.clear(); + } +}; + +struct LanguageServiceHost { + std::string name = "lsp"; +}; + +struct TextChangesContext { + LanguageServiceHost host = {}; + ark::es2panda::lsp::FormatContext formatContext; + ark::es2panda::lsp::UserPreferences preferences; +}; + +struct SignatureHelpItems { +private: + std::vector items_; + TextSpan applicableSpan_ {0, 0}; + size_t selectedItemIndex_ {0}; + size_t argumentIndex_ {0}; + size_t argumentCount_ {0}; + +public: + void SetItems(const SignatureHelpItem &item) + { + items_.push_back(item); + } + void SetApplicableSpan(const size_t &start, const size_t &line) + { + applicableSpan_.start = start; + applicableSpan_.length = line; + applicableSpan_.start = start; + applicableSpan_.length = line; + } + void SetSelectedItemIndex(const size_t &index) + { + selectedItemIndex_ = index; + } + void SetArgumentIndex(const size_t &index) + { + argumentIndex_ = index; + } + void SetArgumentCount(const size_t &count) + { + argumentCount_ = count; + } + + SignatureHelpItem &GetItem(size_t index) + { + return items_[index]; + } + const std::vector &GetItems() const + { + return items_; + } + const TextSpan &GetApplicableSpan() const + { + return applicableSpan_; + } + size_t GetSelectedItemIndex() const + { + return selectedItemIndex_; + } + size_t GetArgumentIndex() const + { + return argumentIndex_; + } + size_t GetArgumentCount() const + { + return argumentCount_; + } + void Clear() + { + for (auto item : items_) { + item.Clear(); + } + items_.clear(); + } +}; + +#ifdef __cplusplus +} +#endif + +SymbolDisplayPart CreatePunctuation(std::string punc); +SymbolDisplayPart CreateKeyword(std::string keyword); +SymbolDisplayPart CreateSpace(); +SymbolDisplayPart CreateText(std::string text); +SymbolDisplayPart CreateClassName(std::string className); +SymbolDisplayPart CreateFunctionName(std::string functionName); +SymbolDisplayPart CreateTypeName(std::string typeName); +SymbolDisplayPart CreateEnumName(std::string enumName); +SymbolDisplayPart CreateEnumMember(std::string enumMember); +SymbolDisplayPart CreateInterface(std::string interface); +SymbolDisplayPart CreateTypeParameter(std::string typeParameter); +SymbolDisplayPart CreateFunctionParameter(std::string functionParameter); +SymbolDisplayPart CreateOperator(std::string oper); +SymbolDisplayPart CreateReturnType(std::string returnType); +SymbolDisplayPart CreateProperty(std::string property); +SymbolDisplayPart CreateNamespace(std::string name); +SymbolDisplayPart SignatureCreateStructName(const std::string &name); +SymbolDisplayPart SignatureCreateParameterName(std::string &type); + +// NOLINTEND + +#endif \ No newline at end of file diff --git a/ets2panda/lsp/src/api.cpp b/ets2panda/lsp/src/api.cpp index 71ed8879ad389f8f0a572b66328c0d9e67ec31cb..9c9b2179527036257278edf70cd38a61bd0436cf 100644 --- a/ets2panda/lsp/src/api.cpp +++ b/ets2panda/lsp/src/api.cpp @@ -17,19 +17,31 @@ #include #include #include +#include "class_hierarchy.h" +#include "lsp/include/organize_imports.h" #include "compiler/lowering/util.h" +#include "get_safe_delete_info.h" #include "internal_api.h" #include "ir/astNode.h" +#include "find_safe_delete_location.h" #include "references.h" #include "public/es2panda_lib.h" #include "cancellation_token.h" +#include "generate_constructor.h" #include "public/public.h" #include "util/options.h" #include "quick_info.h" #include "suggestion_diagnostics.h" #include "brace_matching.h" #include "line_column_offset.h" +#include "script_element_kind.h" #include "services/services.h" +#include "get_class_property_info.h" +#include "inlay_hints.h" +#include "signature_help.h" +#include "completions_details.h" + +using ark::es2panda::lsp::details::GetCompletionEntryDetailsImpl; extern "C" { namespace ark::es2panda::lsp { @@ -65,6 +77,12 @@ bool IsPackageModule(es2panda_Context *context) return reinterpret_cast(context)->parserProgram->IsPackage(); } +CompletionEntryKind GetAliasScriptElementKind(es2panda_Context *context, size_t position) +{ + auto result = GetAliasScriptElementKindImpl(context, position); + return result; +} + References GetFileReferences(char const *fileName, es2panda_Context *context, bool isPackageModule) { return GetFileReferencesImpl(context, fileName, isPackageModule); @@ -83,6 +101,16 @@ DeclInfo GetDeclInfo(es2panda_Context *context, size_t position) return result; } +std::vector GetClassHierarchies(es2panda_Context *context, const char *fileName, size_t pos) +{ + return GetClassHierarchiesImpl(context, std::string(fileName), pos); +} + +bool GetSafeDeleteInfo(es2panda_Context *context, size_t position, const char *path) +{ + return GetSafeDeleteInfoImpl(context, position, path); +} + References GetReferencesAtPosition(es2panda_Context *context, DeclInfo *declInfo) { auto result = GetReferencesAtPositionImpl(context, {declInfo->fileName, declInfo->fileText}); @@ -112,19 +140,31 @@ std::string GetCurrentTokenValue(es2panda_Context *context, size_t position) return result; } +std::vector OrganizeImportsImpl(es2panda_Context *context, char const *fileName) +{ + auto result = OrganizeImports::Organize(context, fileName); + return result; +} + QuickInfo GetQuickInfoAtPosition(const char *fileName, es2panda_Context *context, size_t position) { auto res = GetQuickInfoAtPositionImpl(context, position, fileName); return res; } -TextSpan GetSpanOfEnclosingComment(char const *fileName, size_t pos, bool onlyMultiLine) +// find the Definition node by using the entryname And return CompletionEntryDetails +CompletionEntryDetails GetCompletionEntryDetails(const char *entryName, const char *fileName, es2panda_Context *context, + size_t position) { - Initializer initializer = Initializer(); - auto ctx = initializer.CreateContext(fileName, ES2PANDA_STATE_CHECKED); - auto *range = initializer.Allocator()->New(); - GetRangeOfEnclosingComment(ctx, pos, range); - initializer.DestroyContext(ctx); + auto result = GetCompletionEntryDetailsImpl(context, position, fileName, entryName); + return result; +} + +TextSpan GetSpanOfEnclosingComment(es2panda_Context *context, size_t pos, bool onlyMultiLine) +{ + auto ctx = reinterpret_cast(context); + auto *range = ctx->allocator->New(); + GetRangeOfEnclosingComment(context, pos, range); return (range != nullptr) && (!onlyMultiLine || range->kind_ == CommentKind::MULTI_LINE) ? TextSpan(range->pos_, range->end_ - range->pos_) : TextSpan(0, 0); @@ -179,6 +219,12 @@ DiagnosticReferences GetCompilerOptionsDiagnostics(char const *fileName, Cancell return result; } +TypeHierarchiesInfo GetTypeHierarchies(es2panda_Context *searchContext, es2panda_Context *context, const size_t pos) +{ + auto declaration = GetTargetDeclarationNodeByPosition(context, pos); + return GetTypeHierarchiesImpl(searchContext, pos, declaration); +} + DocumentHighlightsReferences GetDocumentHighlights(es2panda_Context *context, size_t position) { DocumentHighlightsReferences result = {}; @@ -186,6 +232,17 @@ DocumentHighlightsReferences GetDocumentHighlights(es2panda_Context *context, si return result; } +std::vector FindSafeDeleteLocation(es2panda_Context *ctx, + const std::tuple *declInfo) +{ + std::vector result; + if (declInfo == nullptr) { + return result; + } + result = FindSafeDeleteLocationImpl(ctx, *declInfo); + return result; +} + std::vector FindReferencesWrapper( ark::es2panda::lsp::CancellationToken *tkn, const std::vector &srcFiles, const ark::es2panda::SourceFile &srcFile, size_t position) @@ -230,6 +287,12 @@ std::vector FindRenameLocationsWithCancellat return res; } +std::vector GetClassPropertyInfoWrapper(es2panda_Context *context, size_t position, + bool shouldCollectInherited) +{ + return GetClassPropertyInfo(context, position, shouldCollectInherited); +} + DiagnosticReferences GetSuggestionDiagnostics(es2panda_Context *context) { DiagnosticReferences res {}; @@ -249,39 +312,124 @@ ark::es2panda::lsp::CompletionInfo GetCompletionsAtPosition(es2panda_Context *co return result; } +ClassHierarchy GetClassHierarchyInfo(es2panda_Context *context, size_t position) +{ + auto result = GetClassHierarchyInfoImpl(context, position); + return result; +} + std::vector GetImplementationLocationAtPositionWrapper(es2panda_Context *context, int position) { return GetImplementationLocationAtPosition(context, position); } +RefactorEditInfo GetClassConstructorInfo(es2panda_Context *context, size_t position, + const std::vector &properties) +{ + auto result = RefactorEditInfo(GetRefactorActionsToGenerateConstructor(context, position, properties)); + return result; +} + LineAndCharacter ToLineColumnOffsetWrapper(es2panda_Context *context, size_t position) { auto result = ToLineColumnOffset(context, position); return result; } +// Returns type of refactoring and action that can be performed based +// on the input kind information and cursor position +ApplicableRefactorInfo GetApplicableRefactors(es2panda_Context *context, const char *kind, size_t position) +{ + auto result = GetApplicableRefactorsImpl(context, kind, position); + return result; +} + +std::vector GetTodoComments( + char const *fileName, std::vector &descriptors, + CancellationToken *cancellationToken) +{ + Initializer initializer = Initializer(); + auto context = initializer.CreateContext(fileName, ES2PANDA_STATE_CHECKED); + auto result = GetTodoCommentsImpl(context, descriptors, cancellationToken); + initializer.DestroyContext(context); + return result; +} + +InlayHintList ProvideInlayHints(es2panda_Context *context, const TextSpan *span) +{ + const size_t defaultTime = 20; + auto cancellationToken = CancellationToken(defaultTime, nullptr); + UserPreferences preferences = UserPreferences::GetDefaultUserPreferences(); + preferences.SetIncludeInlayParameterNameHints(UserPreferences::IncludeInlayParameterNameHints::ALL); + return ProvideInlayHintsImpl(context, span, cancellationToken, preferences); +} + +SignatureHelpItems GetSignatureHelpItems(es2panda_Context *context, size_t position) +{ + const size_t defaultTime = 20; + auto invokedReason = ark::es2panda::lsp::SignatureHelpInvokedReason(); + auto cancellationToken = ark::es2panda::lsp::CancellationToken(defaultTime, nullptr); + return ark::es2panda::lsp::GetSignatureHelpItems(context, position, invokedReason, cancellationToken); +} +std::vector GetCodeFixesAtPosition(const char *fileName, size_t startPosition, size_t endPosition, + std::vector &errorCodes, CodeFixOptions &codeFixOptions) +{ + Initializer initializer = Initializer(); + auto context = initializer.CreateContext(fileName, ES2PANDA_STATE_CHECKED); + auto result = + ark::es2panda::lsp::GetCodeFixesAtPositionImpl(context, startPosition, endPosition, errorCodes, codeFixOptions); + initializer.DestroyContext(context); + return result; +} + +CombinedCodeActionsInfo GetCombinedCodeFix(const char *fileName, const std::string &fixId, + CodeFixOptions &codeFixOptions) +{ + Initializer initializer = Initializer(); + auto context = initializer.CreateContext(fileName, ES2PANDA_STATE_CHECKED); + auto result = ark::es2panda::lsp::GetCombinedCodeFixImpl(context, fixId, codeFixOptions); + initializer.DestroyContext(context); + return result; +} + LSPAPI g_lspImpl = {GetDefinitionAtPosition, + GetApplicableRefactors, GetImplementationAtPosition, IsPackageModule, + GetAliasScriptElementKind, GetFileReferences, GetDeclInfo, + GetClassHierarchies, + GetSafeDeleteInfo, GetReferencesAtPosition, GetPrecedingToken, GetCurrentTokenValue, + OrganizeImportsImpl, GetQuickInfoAtPosition, + GetCompletionEntryDetails, GetSpanOfEnclosingComment, GetSemanticDiagnostics, GetSyntacticDiagnostics, GetCompilerOptionsDiagnostics, + GetTypeHierarchies, GetDocumentHighlights, FindRenameLocationsWrapper, FindRenameLocationsWithCancellationWrapper, + FindSafeDeleteLocation, FindReferencesWrapper, + GetClassPropertyInfoWrapper, GetSuggestionDiagnostics, GetCompletionsAtPosition, + GetClassHierarchyInfo, GetBraceMatchingAtPositionWrapper, + GetClassConstructorInfo, GetImplementationLocationAtPositionWrapper, - ToLineColumnOffsetWrapper}; + ToLineColumnOffsetWrapper, + GetTodoComments, + ProvideInlayHints, + GetSignatureHelpItems, + GetCodeFixesAtPosition, + GetCombinedCodeFix}; } // namespace ark::es2panda::lsp CAPI_EXPORT LSPAPI const *GetImpl() diff --git a/ets2panda/lsp/src/applicable_refactors.cpp b/ets2panda/lsp/src/applicable_refactors.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20a8994900bba09f10a938eacc52b96b9e5ab99a --- /dev/null +++ b/ets2panda/lsp/src/applicable_refactors.cpp @@ -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. + */ + +#include +#include +#include "applicable_refactors.h" +#include "refactors/convert_function.h" + +namespace ark::es2panda::lsp { +Refactor::Refactor(const Refactor &other) +{ + kinds_.insert(kinds_.end(), other.kinds_.begin(), other.kinds_.end()); +} + +Refactor &Refactor::operator=(const Refactor &other) +{ + kinds_.insert(kinds_.end(), other.kinds_.begin(), other.kinds_.end()); + return *this; +} + +Refactor &Refactor::operator=(Refactor &&other) +{ + kinds_.insert(kinds_.end(), other.kinds_.begin(), other.kinds_.end()); + return *this; +} + +Refactor::Refactor(Refactor &&other) +{ + kinds_.insert(kinds_.end(), other.kinds_.begin(), other.kinds_.end()); +} + +bool Refactor::IsKind(const std::string &kind) +{ + for (const std::string &rKind : kinds_) { + if (rKind.substr(0, kind.length()) == kind) { + return true; + } + } + return false; +} + +void Refactor::AddKind(const std::string &kind) +{ + kinds_.push_back(kind); +} + +ApplicableRefactorInfo GetApplicableRefactorsImpl(es2panda_Context *context, const char *kind, size_t position) +{ + ApplicableRefactorInfo result; + std::unordered_map> refactors; + Refactor *convertFunctionRefactor = new ConvertFunctionRefactor(); + refactors[std::string(refactor_name::CONVERT_FUNCTION_REFACTOR_NAME)] = + std::shared_ptr(convertFunctionRefactor); + for (const auto &[refactorName, refactor] : refactors) { + if (refactor->IsKind(std::string(kind))) { + return refactor->GetAvailableActions(context, std::string(kind), position); + } + } + + return result; +} +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/brace_matching.cpp b/ets2panda/lsp/src/brace_matching.cpp index 0c0bf30ff8122e6d9b77ad25ff7540103b7c79f1..1ddb618a890ea331cecfcb2cabcae5d10b5ed9f4 100644 --- a/ets2panda/lsp/src/brace_matching.cpp +++ b/ets2panda/lsp/src/brace_matching.cpp @@ -17,7 +17,7 @@ #include #include "public/public.h" -namespace { +namespace ark::es2panda::lsp { bool CheckNodeKindForBraceMatching(ark::es2panda::ir::AstNode *node) { switch (node->Type()) { @@ -31,9 +31,7 @@ bool CheckNodeKindForBraceMatching(ark::es2panda::ir::AstNode *node) return false; } } -} // namespace -namespace ark::es2panda::lsp { std::vector GetBraceMatchingAtPosition(es2panda_Context *context, size_t position) { auto token = GetTouchingToken(context, position, false); diff --git a/ets2panda/lsp/src/class_hierarchy.cpp b/ets2panda/lsp/src/class_hierarchy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7022639d66af7b6a25c7686724a7ddf2bb71c857 --- /dev/null +++ b/ets2panda/lsp/src/class_hierarchy.cpp @@ -0,0 +1,826 @@ +/** + * 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 "class_hierarchy.h" +#include +#include +#include "class_hierarchies.h" +#include "compiler/lowering/util.h" +#include "public/public.h" +#include "lsp/include/internal_api.h" +#include "lsp/include/completions.h" + +namespace ark::es2panda::lsp { + +std::string GetHierarchyDeclarationFileName(const ir::AstNode *node) +{ + if (node == nullptr) { + return ""; + } + if (node->IsClassDeclaration()) { + if (node->AsClassDeclaration()->Definition()->Ident()->Range().start.Program() == nullptr) { + return ""; + } + return std::string(node->AsClassDeclaration()->Definition()->Ident()->Range().start.Program()->AbsoluteName()); + } + if (node->IsTSInterfaceDeclaration()) { + if (node->AsTSInterfaceDeclaration()->Id()->Range().start.Program() == nullptr) { + return ""; + } + return std::string(node->AsTSInterfaceDeclaration()->Id()->Range().start.Program()->AbsoluteName()); + } + return ""; +} + +std::string GetHierarchyDeclarationName(const ir::AstNode *node) +{ + if (node == nullptr) { + return ""; + } + if (node->IsClassDeclaration()) { + return std::string(node->AsClassDeclaration()->Definition()->Ident()->Name()); + } + if (node->IsTSInterfaceDeclaration()) { + return std::string(node->AsTSInterfaceDeclaration()->Id()->Name()); + } + return ""; +} + +HierarchyType GetHierarchyType(const ir::AstNode *node) +{ + if (node == nullptr) { + return HierarchyType::OTHERS; + } + if (node->IsClassDeclaration()) { + return HierarchyType::CLASS; + } + if (node->IsTSInterfaceDeclaration()) { + return HierarchyType::INTERFACE; + } + return HierarchyType::OTHERS; +} + +size_t GetPosition(const ir::AstNode *node) +{ + if (node == nullptr) { + return 0; + } + if (node->IsClassDeclaration()) { + return node->AsClassDeclaration()->Definition()->Ident()->Start().index; + } + if (node->IsTSInterfaceDeclaration()) { + return node->AsTSInterfaceDeclaration()->Id()->Start().index; + } + return 0; +} + +const ir::AstNode *GetEffectiveBaseTypeNode(const ir::AstNode *node) +{ + if (node == nullptr || !node->IsClassDeclaration()) { + return nullptr; + } + auto super = node->AsClassDeclaration()->Definition()->Super(); + if (super == nullptr || !super->IsETSTypeReference()) { + return nullptr; + } + auto id = super->AsETSTypeReference()->Part()->Name(); + if (id == nullptr || !id->IsIdentifier()) { + return nullptr; + } + auto result = compiler::DeclarationFromIdentifier(id->AsIdentifier()); + if (result == nullptr || !result->IsClassDefinition()) { + return nullptr; + } + return result->Parent(); +} + +std::vector GetInterfaceExtendsHeritageElement(const ir::AstNode *node) +{ + std::vector result; + if (node == nullptr || !node->IsTSInterfaceDeclaration()) { + return result; + } + auto extends = node->AsTSInterfaceDeclaration()->Extends(); + for (auto e : extends) { + auto id = e->Expr()->AsETSTypeReference()->Part()->Name(); + result.push_back(compiler::DeclarationFromIdentifier(id->AsIdentifier())); + } + return result; +} + +void FindSuper(const ir::AstNode *node, TypeHierarchies &typeHierarchies, std::set &superLists) +{ + auto name = GetHierarchyDeclarationName(node); + if (name.empty()) { + return; + } + TypeHierarchies subOrSuper(GetHierarchyDeclarationFileName(node), name, GetHierarchyType(node), GetPosition(node)); + if (superLists.find(subOrSuper) != superLists.end()) { + return; + } + superLists.insert(subOrSuper); + GetSuperTypeHierarchies(node, subOrSuper, superLists); + typeHierarchies.subOrSuper.emplace_back(subOrSuper); +} + +std::vector GetEffectiveImplementsTypeNodes(const ir::AstNode *node) +{ + std::vector result; + if (node == nullptr || !node->IsClassDeclaration()) { + return result; + } + auto implements = node->AsClassDeclaration()->Definition()->Implements(); + for (auto imp : implements) { + result.emplace_back(compiler::DeclarationFromIdentifier( + imp->AsTSClassImplements()->Expr()->AsETSTypeReference()->Part()->Name()->AsIdentifier())); + } + return result; +} + +void GetSuperTypeHierarchies(const ir::AstNode *node, TypeHierarchies &typeHierarchies, + std::set &superLists) +{ + std::set currentList; + auto extendsNode = GetEffectiveBaseTypeNode(node); + if (extendsNode != nullptr) { + currentList = superLists; + FindSuper(extendsNode, typeHierarchies, currentList); + } + auto implementsNodes = GetEffectiveImplementsTypeNodes(node); + for (auto n : implementsNodes) { + currentList = superLists; + FindSuper(n, typeHierarchies, currentList); + } + auto extendsNodes = GetInterfaceExtendsHeritageElement(node); + for (auto n : extendsNodes) { + currentList = superLists; + FindSuper(n, typeHierarchies, currentList); + } +} + +ir::AstNode *GetCurrentClassOrInterfaceDeclaration(ir::AstNode *node) +{ + auto tmp = node; + while (tmp != nullptr) { + if (tmp->IsClassDeclaration() || tmp->IsTSInterfaceDeclaration()) { + return tmp; + } + tmp = tmp->Parent(); + } + return nullptr; +} + +ir::AstNode *GetTargetDeclarationNodeByPosition(es2panda_Context *context, size_t pos) +{ + auto node = ark::es2panda::lsp::GetTouchingToken(context, pos, false); + if (node == nullptr) { + return nullptr; + } + return GetCurrentClassOrInterfaceDeclaration(node); +} + +bool IsChildNode(const ir::AstNode *child, const ir::AstNode *parent) +{ + std::vector parentList = GetInterfaceExtendsHeritageElement(child); + auto baseNode = GetEffectiveBaseTypeNode(child); + if (baseNode != nullptr) { + parentList.emplace_back(baseNode); + } + auto parentName = GetHierarchyDeclarationName(parent); + auto parentFileName = GetHierarchyDeclarationFileName(parent); + auto parentPosition = GetPosition(parent); + auto result = std::find_if(parentList.begin(), parentList.end(), [&](const ir::AstNode *n) { + auto p = GetPosition(n); + return parentName == GetHierarchyDeclarationName(n) && parentFileName == GetHierarchyDeclarationFileName(n) && + p == parentPosition; + }); + return result != parentList.end(); +} + +std::vector GetImplementationReferenceEntries(es2panda_Context *context, const ir::AstNode *node, + std::set &subLists) +{ + std::vector result; + if (context == nullptr) { + return result; + } + auto ctx = reinterpret_cast(context); + if (ctx->parserProgram == nullptr || ctx->parserProgram->Ast() == nullptr) { + return result; + } + auto astNode = reinterpret_cast(ctx->parserProgram->Ast()); + astNode->IterateRecursively([&subLists, node, &result](ir::AstNode *child) { + if (child == nullptr || (!child->IsClassDeclaration() && !child->IsTSInterfaceDeclaration())) { + return; + } + auto name = GetHierarchyDeclarationName(child); + if (name.empty()) { + return; + } + auto fileName = GetHierarchyDeclarationFileName(child); + if (fileName.empty()) { + return; + } + TypeHierarchies childTypeHierarchies(fileName, name, GetHierarchyType(child), GetPosition(child)); + if (subLists.find(childTypeHierarchies) != subLists.end()) { + return; + } + if (!IsChildNode(child, node)) { + return; + } + result.emplace_back(child); + subLists.insert(childTypeHierarchies); + }); + return result; +} + +void GetSubTypeHierarchies(es2panda_Context *context, const ir::AstNode *node, TypeHierarchies &typeHierarchies, + std::set &subLists) +{ + if (node == nullptr || (!node->IsTSInterfaceDeclaration() && !node->IsClassDeclaration())) { + return; + } + auto name = GetHierarchyDeclarationName(node); + if (name.empty()) { + return; + } + auto childList = GetImplementationReferenceEntries(context, node, subLists); + for (auto child : childList) { + TypeHierarchies childType(GetHierarchyDeclarationFileName(child), GetHierarchyDeclarationName(child), + GetHierarchyType(child), GetPosition(child)); + std::set curList; + curList.insert(childType); + GetSubTypeHierarchies(context, child, childType, curList); + typeHierarchies.subOrSuper.emplace_back(childType); + } +} + +void InitHierarchies(TypeHierarchies &typeHierarchies, std::string &fileName, std::string &name, HierarchyType type, + size_t pos) +{ + typeHierarchies.fileName = fileName; + typeHierarchies.name = name; + typeHierarchies.type = type; + typeHierarchies.pos = pos; +} + +TypeHierarchiesInfo GetTypeHierarchiesImpl(es2panda_Context *context, size_t pos, const ir::AstNode *declaration) +{ + TypeHierarchiesInfo result; + if (context == nullptr) { + return result; + } + auto ctx = reinterpret_cast(context); + if (ctx->parserProgram == nullptr || ctx->parserProgram->Ast() == nullptr) { + return result; + } + if (declaration == nullptr) { + declaration = GetTargetDeclarationNodeByPosition(context, pos); + } + if (declaration == nullptr || (!declaration->IsTSInterfaceDeclaration() && !declaration->IsClassDeclaration())) { + return result; + } + result.fileName = GetHierarchyDeclarationFileName(declaration); + result.name = GetHierarchyDeclarationName(declaration); + result.type = GetHierarchyType(declaration); + result.pos = GetPosition(declaration); + InitHierarchies(result.superHierarchies, result.fileName, result.name, result.type, result.pos); + InitHierarchies(result.subHierarchies, result.fileName, result.name, result.type, result.pos); + std::set superLists; + superLists.insert(result.superHierarchies); + GetSuperTypeHierarchies(declaration, result.superHierarchies, superLists); + std::set subLists; + subLists.insert(result.subHierarchies); + GetSubTypeHierarchies(context, declaration, result.subHierarchies, subLists); + return result; +} + +/** + * @brief (查找当前类的父类) Retrieves the direct superclass of a given class declaration node + * @param node - AST node representing a class declaration + * @return Pointer to the direct superclass node or nullptr if not found + */ +ir::AstNode *GetClassDirectSuperClass(ir::AstNode *node) +{ + if (!node->IsClassDeclaration()) { + return nullptr; + } + auto classNode = node->AsClassDeclaration()->Definition(); + auto super = classNode->Super(); + if (super == nullptr || !super->IsETSTypeReference()) { + return nullptr; + } + auto part = super->AsETSTypeReference()->Part(); + if (part == nullptr || !part->IsETSTypeReferencePart()) { + return nullptr; + } + auto partNode = part->AsETSTypeReferencePart()->Name(); + if (partNode == nullptr || !partNode->IsIdentifier()) { + return nullptr; + } + auto superClass = compiler::DeclarationFromIdentifier(partNode->AsIdentifier()); + if (superClass->IsClassDefinition()) { + return superClass->Parent(); + } + return nullptr; +} + +/** + * @brief (1. 查找当前类的(所有)父类) Collects all ancestor classes in the inheritance hierarchy + * @param context - Compiler context (unused) + * @param node - Starting class declaration node + * @return Vector of superclass nodes in inheritance order + */ +std::vector GetClassSuperClasses([[maybe_unused]] es2panda_Context *context, ir::AstNode *node) +{ + std::vector res; + + ir::AstNode *subClass = node; + ir::AstNode *superClass = nullptr; + do { + superClass = GetClassDirectSuperClass(subClass); + if (superClass != nullptr) { + res.push_back(superClass); + } + subClass = superClass; + } while (superClass != nullptr); + + return res; +} + +/** + * @brief (查找当前类的子类) Finds immediate subclasses of a given class + * @param program - Pointer to the program AST + * @param node - Class declaration node to check + * @return Set of direct subclass nodes + */ +std::unordered_set GetClassDirectSubClasses(ark::es2panda::parser::Program *program, ir::AstNode *node) +{ + std::unordered_set res; + + if (node == nullptr) { + return res; + } + if (!node->IsClassDeclaration()) { + return res; + } + auto rootNode = program->Ast(); + if (rootNode == nullptr) { + return res; + } + auto statements = rootNode->Statements(); + for (auto statement : statements) { + if (!statement->IsClassDeclaration()) { + continue; + } + if (GetClassDirectSuperClass(statement) == node) { + res.insert(statement); + } + } + + return res; +} + +/** + * @brief (2. 查找当前类的(所有)子类) Discovers all subclasses in the inheritance hierarchy using BFS + * @param context - Compiler context containing program AST + * @param node - Root class declaration node + * @return Vector of all subclass nodes + */ +std::vector GetClassSubClasses(es2panda_Context *context, ir::AstNode *node) +{ + auto pctx = reinterpret_cast(context); + auto program = pctx->parserProgram; + std::vector result; + std::unordered_set resultSet; + std::unordered_set gottenSet; + std::unordered_set superClasses; + superClasses.insert(node); + std::unordered_set directSubClasses; + + do { + directSubClasses.clear(); + for (auto superClass : superClasses) { + auto it = gottenSet.find(superClass); + if (it == gottenSet.end()) { + auto subClasses = GetClassDirectSubClasses(program, superClass); + directSubClasses.insert(subClasses.begin(), subClasses.end()); + } + } + gottenSet.insert(superClasses.begin(), superClasses.end()); + if (!directSubClasses.empty()) { + resultSet.insert(directSubClasses.begin(), directSubClasses.end()); + superClasses.clear(); + superClasses.insert(directSubClasses.begin(), directSubClasses.end()); + } + } while (!directSubClasses.empty()); + + result.insert(result.end(), resultSet.begin(), resultSet.end()); + return result; +} + +/** + * @brief (查找当前类的父接口) Extracts directly implemented interfaces from class declaration + * @param node - Class declaration node + * @return Set of directly implemented interface nodes + */ +std::unordered_set GetClassDirectImplementedInterfaces(ir::AstNode *node) +{ + std::unordered_set res; + if (node == nullptr) { + return res; + } + if (!node->IsClassDeclaration()) { + return res; + } + auto classDefinition = node->AsClassDeclaration()->Definition(); + auto implements = classDefinition->Implements(); + for (auto implement : implements) { + auto partNode = GetIdentifierFromTSInterfaceHeritage(implement); + if (partNode == nullptr) { + continue; + } + auto interfaceDecl = compiler::DeclarationFromIdentifier(partNode->AsIdentifier()); + if (interfaceDecl->IsTSInterfaceDeclaration()) { + res.insert(interfaceDecl); + } + } + return res; +} + +/** + * @brief (查找当前接口的父接口) Gets directly extended interfaces from interface declaration + * @param node - Interface declaration node + * @return Set of directly extended interface nodes + */ +std::unordered_set GetInterfaceDirectExtendedInterfaces(ir::AstNode *node) +{ + std::unordered_set res; + if (node == nullptr) { + return res; + } + if (!node->IsTSInterfaceDeclaration()) { + return res; + } + auto childInterface = node->AsTSInterfaceDeclaration(); + auto extends = childInterface->Extends(); + for (auto extend : extends) { + auto partNode = GetIdentifierFromTSInterfaceHeritage(extend->AsTSInterfaceHeritage()); + if (partNode == nullptr || !partNode->IsIdentifier()) { + continue; + } + auto interfaceDecl = compiler::DeclarationFromIdentifier(partNode->AsIdentifier()); + if (interfaceDecl->IsTSInterfaceDeclaration()) { + res.insert(interfaceDecl); + } + } + return res; +} + +/** + * @brief (3. 查找当前类的(所有)父接口) Aggregates all implemented interfaces including inherited ones + * @param context - Compiler context (unused) + * @param node - Starting class declaration node + * @return Vector of implemented interface nodes + */ +std::vector GetClassImplementedInterfaces([[maybe_unused]] es2panda_Context *context, ir::AstNode *node) +{ + std::vector result; + std::unordered_set resultSet; + std::unordered_set subClasses {node}; + std::unordered_set subInterfaces; + std::unordered_set gottenSet; + std::unordered_set directSuperClasses; + std::unordered_set directSuperInterfaces; + do { + directSuperInterfaces.clear(); + directSuperClasses.clear(); + for (auto subClass : subClasses) { + if (gottenSet.find(subClass) != gottenSet.end()) { + continue; + } + auto superInterfaces = GetClassDirectImplementedInterfaces(subClass); + directSuperInterfaces.insert(superInterfaces.begin(), superInterfaces.end()); + auto superClass = GetClassDirectSuperClass(subClass); + if (superClass != nullptr) { + directSuperClasses.insert(superClass); + } + } + gottenSet.insert(subClasses.begin(), subClasses.end()); + for (auto subInterface : subInterfaces) { + if (gottenSet.find(subInterface) != gottenSet.end()) { + continue; + } + auto superInterfaces = GetInterfaceDirectExtendedInterfaces(subInterface); + directSuperInterfaces.insert(superInterfaces.begin(), superInterfaces.end()); + } + gottenSet.insert(subInterfaces.begin(), subInterfaces.end()); + if (!directSuperInterfaces.empty()) { + resultSet.insert(directSuperInterfaces.begin(), directSuperInterfaces.end()); + subInterfaces.clear(); + subInterfaces.insert(directSuperInterfaces.begin(), directSuperInterfaces.end()); + } + if (!directSuperClasses.empty()) { + subClasses.clear(); + subClasses.insert(directSuperClasses.begin(), directSuperClasses.end()); + } + } while (!directSuperInterfaces.empty() || !directSuperClasses.empty()); + result.insert(result.end(), resultSet.begin(), resultSet.end()); + return result; +} + +/** + * @brief (4. 查找当前接口的(所有)父接口) Collects all ancestor interfaces through extension hierarchy + * @param context - Compiler context (unused) + * @param node - Starting interface node + * @return Vector of ancestor interface nodes + */ +std::vector GetInterfaceSuperInterfaces([[maybe_unused]] es2panda_Context *context, ir::AstNode *node) +{ + std::vector superInterfaces {}; + std::unordered_set visited; + std::function findSuperInterfaces = [&](ir::AstNode *currentNode) { + if (currentNode == nullptr) { + return; + } + if (!visited.insert(currentNode).second) { + return; + } + auto extends = node->AsTSInterfaceDeclaration()->Extends(); + for (auto extend : extends) { + auto partNode = GetIdentifierFromTSInterfaceHeritage(extend); + if (partNode == nullptr) { + continue; + } + auto interfaceDecl = compiler::DeclarationFromIdentifier(partNode->AsIdentifier()); + if (interfaceDecl->IsTSInterfaceDeclaration()) { + ir::AstNode *superInterface = interfaceDecl->AsTSInterfaceDeclaration(); + superInterfaces.push_back(superInterface); + findSuperInterfaces(superInterface); + } + } + }; + findSuperInterfaces(node); + return superInterfaces; +} + +/** + * @brief Helper function to get directly implemented interfaces + * @param node - Class definition node + * @return Vector of directly implemented interface nodes + */ +std::vector GetImplements(ir::AstNode *node) +{ + std::vector result {}; + if (node == nullptr) { + return result; + } + auto classDefinition = node->AsClassDefinition(); + auto implements = classDefinition->Implements(); + for (auto implement : implements) { + auto partNode = GetIdentifierFromTSInterfaceHeritage(implement->AsTSInterfaceHeritage()); + if (partNode == nullptr || !partNode->IsIdentifier()) { + continue; + } + auto interfaceDecl = compiler::DeclarationFromIdentifier(partNode->AsIdentifier()); + if (interfaceDecl->IsTSInterfaceDeclaration()) { + result.push_back(interfaceDecl->AsTSInterfaceDeclaration()); + } + } + return result; +} + +std::vector GetInterfaceOrClasses(es2panda_Context *context, ir::AstNode *node, bool isInterfaceMode) +{ + std::vector result; + std::unordered_set parentSet; + parentSet.insert(node); + auto ctx = reinterpret_cast(context); + auto rootNode = ctx->parserProgram->Ast(); + if (rootNode == nullptr) { + return result; + } + for (auto statement : rootNode->Statements()) { + if (isInterfaceMode) { + // The current interface obtains the interface + if (!statement->IsTSInterfaceDeclaration()) { + continue; + } + auto child = statement->AsTSInterfaceDeclaration(); + auto extends = GetInterfaceDirectExtendedInterfaces(child); + bool isSubInterface = std::any_of(extends.begin(), extends.end(), + [&](ir::AstNode *base) { return parentSet.count(base) > 0; }); + if (isSubInterface) { + result.push_back(child); + GetInterfaceOrClasses(context, child, isInterfaceMode); // 递归处理子接口 + } + } else { + // The current interface gets the subclass + if (!statement->IsClassDeclaration()) { + continue; + } + auto classDef = statement->AsClassDeclaration()->Definition(); + auto implements = GetImplements(classDef); + bool isImplement = std::any_of(implements.begin(), implements.end(), + [&](ir::AstNode *base) { return parentSet.count(base) > 0; }); + if (isImplement) { + result.push_back(classDef); + } + } + } + return result; +} + +/** + * @brief (5|6、查找当前接口的(所有)子类或子接口) Finds all subclasses/sub-interfaces of the current interface node + * @param context - Compiler context with AST tree + * @param node - Target interface node to search from + * @return Vector of subclass/sub-interface nodes (includes both direct and nested) + */ +std::vector GetInterfaceImplementingClasses(es2panda_Context *context, ir::AstNode *node) +{ + std::vector implementingClasses; + auto ctx = reinterpret_cast(context); + auto rootNode = ctx->parserProgram->Ast(); + if (rootNode == nullptr) { + return implementingClasses; + } + bool findSubInterfaces = true; + implementingClasses = GetInterfaceOrClasses(context, node, findSubInterfaces); + if (!findSubInterfaces) { + std::vector subInterfaces = GetInterfaceImplementingClasses(context, node); + for (auto subInterface : subInterfaces) { + implementingClasses = GetInterfaceOrClasses(context, subInterface, false); + } + } + return implementingClasses; +} + +/** + * @brief Extracts public, non-static, non-constructor members from a class or interface node. + * @param context Unused context pointer. + * @param node AST node (TSInterfaceDeclaration or ClassDeclaration). + * @return Vector of AST nodes for class properties and filtered methods. + */ +std::vector GetMembers([[maybe_unused]] es2panda_Context *context, ir::AstNode *node) +{ + std::vector res; + std::vector body; + if (node->IsTSInterfaceDeclaration()) { + auto interfaceBody = node->AsTSInterfaceDeclaration()->Body()->Body(); + body.insert(body.end(), interfaceBody.begin(), interfaceBody.end()); + } else { + if (node->IsClassDefinition()) { + node = node->Parent(); + } + auto classBody = node->AsClassDeclaration()->Definition()->Body(); + body.insert(body.end(), classBody.begin(), classBody.end()); + } + for (auto *field : body) { + if (field->IsClassProperty()) { + res.emplace_back(field); + } else if (field->IsMethodDefinition()) { + auto *method = field->AsMethodDefinition(); + if (!method->IsPrivate() && !method->IsStatic() && !method->IsConstructor()) { + res.emplace_back(field); + } + } + } + return res; +} + +/** + * @brief Determines if two method nodes have matching signatures + * @param a - First method node + * @param b - Second method node + * @return True if methods have identical identifier names + */ +bool IsMethodMatch(ir::AstNode *a, ir::AstNode *b) +{ + if (!a->IsMethodDefinition() || !b->IsMethodDefinition()) { + return false; + } + return GetIdentifierName(a) == GetIdentifierName(b); +} + +/** + * @brief 比较成员匹配情况,记录匹配与未匹配项 + * @param currentMembers 当前类的成员列表 + * @param targetMembers 目标类的成员列表 + * @param matchedContainer 匹配成员的记录容器 + * @param unmatchedContainer 未匹配成员的记录容器 + * @param fileName 文件名,用于记录定位信息 + */ +void CompareMembersCommon(const std::vector ¤tMembers, + const std::vector &targetMembers, + std::vector &matchedContainer, + std::vector &unmatchedContainer, const std::string &fileName) +{ + for (auto *targetMember : targetMembers) { + auto kind = targetMember->IsMethodDefinition() ? ClassRelationKind::METHOD : ClassRelationKind::PROPERTY; + bool isMatch = false; + for (auto *currentMember : currentMembers) { + if (IsMethodMatch(currentMember, targetMember)) { + isMatch = true; + matchedContainer.emplace_back(fileName, currentMember->Start().index, kind); + break; + } + } + if (!isMatch) { + unmatchedContainer.emplace_back(fileName, targetMember->Start().index, kind); + } + } +} + +void CompareMembersForImplementation(const std::vector ¤tMembers, + const std::vector &interfaceMembers, ClassHierarchyItemInfo &info, + const std::string &fileName) +{ + CompareMembersCommon(currentMembers, interfaceMembers, info.implemented, info.implementing, fileName); +} + +void CompareMembersForOverride(const std::vector ¤tMembers, + const std::vector &targetMembers, ClassHierarchyItemInfo &info, + const std::string &fileName) +{ + CompareMembersCommon(currentMembers, targetMembers, info.overridden, info.overriding, fileName); +} + +struct ProcessItemsParams { + const std::vector ¤tMembers; + std::vector &result; + std::vector (*getListFunc)(es2panda_Context *, ir::AstNode *); + ClassRelationKind kind; + bool swapCompareArgs; + void (*compareFunc)(const std::vector &, const std::vector &, + ClassHierarchyItemInfo &, const std::string &); +}; + +void ProcessItems(es2panda_Context *context, ir::AstNode *node, const std::string &fileName, + const ProcessItemsParams ¶ms) +{ + auto itemList = params.getListFunc(context, node); + for (auto *item : itemList) { + std::string name = GetIdentifierName(item); + ClassHierarchyItemInfo info(name, params.kind, item->Start().index); + auto itemMembers = GetMembers(context, item); + if (params.swapCompareArgs) { + params.compareFunc(itemMembers, params.currentMembers, info, fileName); + } else { + params.compareFunc(params.currentMembers, itemMembers, info, fileName); + } + params.result.emplace_back(info); + } +} + +std::vector GetClassHierarchiesImpl(es2panda_Context *context, const std::string &fileName, + size_t pos) +{ + auto pctx = reinterpret_cast(context); + auto program = pctx->parserProgram; + std::vector result; + if (program == nullptr) { + return result; + } + auto classNode = GetTargetDeclarationNodeByPosition(context, pos); + if (classNode == nullptr) { + return result; + } + std::vector currentMembers = GetMembers(context, classNode); + if (classNode->IsClassDeclaration()) { + ProcessItems(context, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetClassSuperClasses, ClassRelationKind::CLASS, false, + CompareMembersForOverride}); + ProcessItems(context, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetClassImplementedInterfaces, + ClassRelationKind::INTERFACE, false, CompareMembersForImplementation}); + ProcessItems(context, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetClassSubClasses, ClassRelationKind::CLASS, true, + CompareMembersForOverride}); + } else if (classNode->IsTSInterfaceDeclaration()) { + ProcessItems(context, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetInterfaceSuperInterfaces, + ClassRelationKind::INTERFACE, false, CompareMembersForOverride}); + ProcessItems(context, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetInterfaceImplementingClasses, + ClassRelationKind::INTERFACE, true, CompareMembersForOverride}); + ProcessItems(context, classNode, fileName, + ProcessItemsParams {currentMembers, result, GetInterfaceImplementingClasses, + ClassRelationKind::CLASS, false, CompareMembersForImplementation}); + } + return result; +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/class_hierarchy_info.cpp b/ets2panda/lsp/src/class_hierarchy_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6534cd30d9335201bfa4f3a73712978181aae7ed --- /dev/null +++ b/ets2panda/lsp/src/class_hierarchy_info.cpp @@ -0,0 +1,296 @@ +/** + * 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 "class_hierarchy_info.h" +#include "internal_api.h" +#include "public/public.h" +#include "compiler/lowering/util.h" + +namespace ark::es2panda::lsp { +std::string GetNameFromIdentifierNode(const ir::AstNode *node) +{ + if (node == nullptr || !node->IsIdentifier()) { + return ""; + } + return std::string(node->AsIdentifier()->Name()); +} + +// Currently only considering enum scenarios. +bool IsClassLiteralDefinition(const ir::AstNode *node) +{ + return !(compiler::ClassDefinitionIsEnumTransformed(node)); +} + +ir::ClassDefinition *GetClassDefinitionFromIdentifierNode(const ir::AstNode *node) +{ + auto decl = compiler::DeclarationFromIdentifier(node->AsIdentifier()); + if (decl == nullptr) { + return nullptr; + } + if (decl->IsClassDeclaration()) { + decl = decl->AsClassDeclaration()->Definition(); + } + if (!IsClassLiteralDefinition(decl)) { + return nullptr; + } + return decl->AsClassDefinition(); +} + +std::string SpliceFunctionDetailStr(const std::string &functionName, const std::vector ¶ms, + const std::string &returnType) +{ + std::string result; + if (functionName.empty()) { + return result; + } + result.append(functionName).append("("); + auto iter = params.cbegin(); + while (iter != params.cend()) { + auto name = iter->GetParamName(); + auto kind = iter->GetParamKind(); + if (name.empty() || kind.empty()) { + ++iter; + continue; + } + result.append(name).append(": ").append(kind); + ++iter; + if (iter != params.cend()) { + result.append(", "); + } + } + result.append(")"); + if (!returnType.empty()) { + result.append(": ").append(returnType); + } + return result; +} + +std::string GetFunctionNameFromScriptFunction(const ir::ScriptFunction *function) +{ + if (function == nullptr) { + return ""; + } + return function->Id()->ToString(); +} + +std::vector GetParamListFromScriptFunction(const ir::ScriptFunction *function) +{ + std::vector params; + if (function == nullptr) { + return params; + } + auto nodeParams = function->Params(); + for (const auto &nodeParam : nodeParams) { + std::string paramName; + std::string paramKind; + if (!nodeParam->IsETSParameterExpression()) { + continue; + } + paramName = std::string(nodeParam->AsETSParameterExpression()->Name()); + nodeParam->AsETSParameterExpression()->FindChild([¶mKind](ir::AstNode *childNode) { + if (childNode->IsETSTypeReference()) { + paramKind = childNode->AsETSTypeReference()->Part()->Name()->ToString(); + } + return false; + }); + FunctionParamStyle tmp(paramName, paramKind); + params.emplace_back(std::move(tmp)); + } + return params; +} + +std::string GetReturnTypeFromScriptFunction(const ir::ScriptFunction *function) +{ + if (function == nullptr) { + return ""; + } + auto nodeReturn = function->ReturnTypeAnnotation(); + if (nodeReturn == nullptr || !nodeReturn->IsETSTypeReference()) { + return ""; + } + auto ident = nodeReturn->AsETSTypeReference()->Part()->Name(); + if (ident == nullptr || !ident->IsIdentifier()) { + return ""; + } + return std::string(ident->AsIdentifier()->Name()); +} + +SetterStyle CreateSetterStyle(ir::MethodDefinitionKind kind) +{ + SetterStyle setter = SetterStyle::METHOD; + switch (kind) { + case ir::MethodDefinitionKind::GET: + case ir::MethodDefinitionKind::EXTENSION_GET: + setter = SetterStyle::GETTER; + break; + case ir::MethodDefinitionKind::SET: + case ir::MethodDefinitionKind::EXTENSION_SET: + setter = SetterStyle::SETTER; + break; + default: + break; + } + return setter; +} + +std::shared_ptr CreateClassMethodItem(const ir::MethodDefinition *methodDefinition, + const std::string &funcName, std::string detail) +{ + if (methodDefinition == nullptr || funcName.empty() || detail.empty()) { + return nullptr; + } + + auto setter = CreateSetterStyle(methodDefinition->Kind()); + AccessModifierStyle access = AccessModifierStyle::PUBLIC; + if (methodDefinition->IsProtected()) { + access = AccessModifierStyle::PROTECTED; + } + auto item = std::make_shared(std::move(detail), setter, access); + item->SetFunctionName(funcName); + return item; +} + +std::shared_ptr ParseFunctionStyleWithCreateItem(const ir::MethodDefinition *methodDefinition, + bool isCurrentToken) +{ + if (methodDefinition == nullptr) { + return nullptr; + } + if ((isCurrentToken && methodDefinition->IsStatic()) || + (!isCurrentToken && + (methodDefinition->IsPrivate() || methodDefinition->IsStatic() || methodDefinition->IsConstructor()))) { + return nullptr; + } + auto function = methodDefinition->Function(); + auto functionName = GetFunctionNameFromScriptFunction(function); + if (functionName.empty()) { + return nullptr; + } + auto paramList = GetParamListFromScriptFunction(function); + auto returnType = GetReturnTypeFromScriptFunction(function); + auto functionDetail = SpliceFunctionDetailStr(functionName, paramList, returnType); + return CreateClassMethodItem(methodDefinition, functionName, functionDetail); +} + +ClassHierarchyInfo CreateClassHierarchyInfoFromBody(const ir::ClassDefinition *classDefinition, + const std::string &className, bool isCurrentToken) +{ + ClassHierarchyInfo result; + if (classDefinition == nullptr) { + return result; + } + result.SetClassName(className); + auto bodyNodes = classDefinition->Body(); + for (const auto &node : bodyNodes) { + if (node == nullptr || !node->IsMethodDefinition()) { + continue; + } + auto methodDefinition = node->AsMethodDefinition(); + if (methodDefinition == nullptr) { + continue; + } + auto item = ParseFunctionStyleWithCreateItem(methodDefinition, isCurrentToken); + if (item != nullptr) { + result.AddClassMethodItem(item); + } + auto overLoads = methodDefinition->Overloads(); + for (const auto *overLoadMethodDefinition : overLoads) { + auto overLoadItem = ParseFunctionStyleWithCreateItem(overLoadMethodDefinition, isCurrentToken); + if (overLoadItem != nullptr) { + result.AddClassMethodItem(overLoadItem); + } + } + } + return result; +} + +ir::AstNode *GetSuperClassNode(const ir::ClassDefinition *classDefinition) +{ + if (classDefinition == nullptr) { + return nullptr; + } + auto super = const_cast(classDefinition->Super()); + if (super == nullptr) { + return nullptr; + } + return GetIdentifierFromSuper(super); +} + +void ComputeClassHierarchyInfo(const ClassHierarchyInfo &deriveInfo, ClassHierarchyInfo &superInfo) +{ + auto deriveMethods = deriveInfo.GetMethodList(); + for (const auto &method : deriveMethods) { + superInfo.DeleteClassMethodItem(method.second); + } +} + +void ProcessClassHierarchy(const ir::AstNode *token, const ClassHierarchyInfo &baseInfo, ClassHierarchy &result) +{ + if (token == nullptr || !token->IsIdentifier()) { + return; + } + std::string className = GetNameFromIdentifierNode(token); + auto classDefinition = GetClassDefinitionFromIdentifierNode(token); + if (classDefinition == nullptr) { + return; + } + auto info = CreateClassHierarchyInfoFromBody(classDefinition, className, false); + if (!className.empty()) { + // Calculate the difference between the obtained parent class info and the current clicked node class info. + ComputeClassHierarchyInfo(baseInfo, info); + if (info.GetClassName() == className && !info.GetMethodList().empty()) { + result.emplace_back(info); + } + } + auto superClass = GetSuperClassNode(classDefinition); + if (superClass == nullptr) { + return; + } + ProcessClassHierarchy(superClass, baseInfo, result); +} + +ir::AstNode *GetTargetClassDeclarationByPosition(es2panda_Context *context, size_t position) +{ + if (context == nullptr) { + return nullptr; + } + auto token = GetTouchingToken(context, position, false); + auto tmp = token; + while (tmp != nullptr) { + if (tmp->IsClassDeclaration()) { + return tmp; + } + tmp = tmp->Parent(); + } + return nullptr; +} + +ClassHierarchy GetClassHierarchyInfoImpl(es2panda_Context *context, size_t position) +{ + ClassHierarchy result; + auto classDeclaration = GetTargetClassDeclarationByPosition(context, position); + if (classDeclaration == nullptr) { + return result; + } + auto classDefinition = classDeclaration->AsClassDeclaration()->Definition(); + auto currentInfo = CreateClassHierarchyInfoFromBody(classDefinition, "", true); + auto superClass = GetSuperClassNode(classDefinition); + if (superClass == nullptr) { + return result; + } + ProcessClassHierarchy(superClass, currentInfo, result); + return result; +} +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/code_fix_provider.cpp b/ets2panda/lsp/src/code_fix_provider.cpp new file mode 100644 index 0000000000000000000000000000000000000000..184391276794fd48e7cc179c37b4d68d515d62f7 --- /dev/null +++ b/ets2panda/lsp/src/code_fix_provider.cpp @@ -0,0 +1,234 @@ +/* + * 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/code_fix_provider.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { + +void CodeFixProvider::RegisterCodeFix(const std::string &aliasName, std::unique_ptr registration) +{ + if (aliasName.empty()) { + ASSERT("Alias name cannot be empty"); + } + auto shared = std::shared_ptr(std::move(registration)); + + for (auto error : shared->GetErrorCodes()) { + errorCodeToFixes_.emplace(std::to_string(error), shared); + } + if (!shared->GetFixIds().empty()) { + for (const auto &fixId : shared->GetFixIds()) { + fixIdToRegistration_.emplace(fixId, shared); + } + } +} + +CodeFixProvider &CodeFixProvider::Instance() +{ + static CodeFixProvider instance; + return instance; +} + +std::string CodeFixProvider::FormatWithArgs(const std::string &text) +{ + std::string result = text; + const std::string regExp = R"(\{(\d+)\})"; + std::regex pattern(regExp); + std::smatch match; + return result; +} + +std::string CodeFixProvider::DiagnosticToString(const DiagnosticAndArguments &diag) +{ + std::string message; + if (diag.arguments.empty()) { + message = diag.message.message; + } else { + message = FormatWithArgs(diag.message.message); + } + return message; +} + +CodeFixAction CodeFixProvider::CreateCodeFixActionWorker(std::string &fixName, std::string &description, + std::vector &changes, std::string &fixId, + std::string &fixAllDescription, + std::vector command = {}) +{ + CodeAction codeAction; + codeAction.description = description; + codeAction.changes = changes; + codeAction.commands = std::move(command); + return {codeAction, fixName, fixId, fixAllDescription}; +} + +CodeFixAction CodeFixProvider::CreateCodeFixActionWithoutFixAll(std::string &fixName, + std::vector &changes, + DiagnosticAndArguments &description) +{ + std::string fixId; + std::string descriptionMessage = DiagnosticToString(description); + std::string fixAllDescription; + return CreateCodeFixActionWorker(fixName, descriptionMessage, changes, fixId, fixAllDescription); +} + +CodeFixAction CodeFixProvider::CreateCodeFixAction(std::string fixName, std::vector changes, + DiagnosticAndArguments &description, std::string fixId, + DiagnosticAndArguments &fixAllDescription, + std::vector &command) +{ + std::string descriptionMessage = DiagnosticToString(description); + std::string fixAllDescriptionMessage = DiagnosticToString(fixAllDescription); + return CreateCodeFixActionWorker(fixName, descriptionMessage, changes, fixId, fixAllDescriptionMessage, + std::move(command)); +} + +std::string CodeFixProvider::GetFileName(const std::string &filePath) +{ + if (filePath.empty()) { + return ""; + } + + std::size_t pos = filePath.find_last_of('/'); + if (pos != std::string::npos) { + return filePath.substr(pos + 1); + } + + pos = filePath.find_last_of('\\'); + if (pos != std::string::npos) { + return filePath.substr(pos + 1); + } + + return filePath; +} + +std::vector CodeFixProvider::GetSupportedErrorCodes() +{ + std::vector result; + for (const auto &kv : errorCodeToFixes_) { + result.push_back(kv.first); + } + return result; +} + +DiagnosticReferences *CodeFixProvider::GetDiagnostics(const CodeFixContextBase &context) +{ + DiagnosticReferences *result = nullptr; + LSPAPI const *lspApi = GetImpl(); + Initializer initializer = Initializer(); + auto it = reinterpret_cast(context.context); + std::string fileNameStr(GetFileName(std::string(it->sourceFile->filePath))); + std::string sourceStr(it->sourceFile->source); + const auto ctx = initializer.CreateContext(fileNameStr.c_str(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + DiagnosticReferences semantic = lspApi->getSemanticDiagnostics(ctx); + DiagnosticReferences syntactic = lspApi->getSyntacticDiagnostics(ctx); + DiagnosticReferences suggestions = lspApi->getSuggestionDiagnostics(ctx); + + for (const auto &d : semantic.diagnostic) { + result->diagnostic.push_back(d); + } + for (const auto &d : syntactic.diagnostic) { + result->diagnostic.push_back(d); + } + for (const auto &d : suggestions.diagnostic) { + result->diagnostic.push_back(d); + } + initializer.DestroyContext(ctx); + return result; +} + +bool CodeFixProvider::ShouldIncludeFixAll(const CodeFixRegistration ®istration, + const std::vector &diagnostics) +{ + int maybeFixableDiagnostics = 0; + const int minFixableDiagnostics = 1; + for (size_t i = 0; i <= diagnostics.size(); i++) { + if (std::find(registration.GetErrorCodes().begin(), registration.GetErrorCodes().end(), i) != + registration.GetErrorCodes().end()) { + ++maybeFixableDiagnostics; + if (maybeFixableDiagnostics > minFixableDiagnostics) { + break; + } + } + } + return maybeFixableDiagnostics > minFixableDiagnostics; +} + +CombinedCodeActions CodeFixProvider::GetAllFixes(const CodeFixAllContext &context) +{ + auto it = fixIdToRegistration_.find(context.fixId); + if (it == fixIdToRegistration_.end() || !it->second) { + return CombinedCodeActions(); + } + const std::shared_ptr ®istration = it->second; + return registration->GetAllCodeActions(context); +} + +void CodeFixProvider::EachDiagnostic(const CodeFixAllContext &context, const std::vector &errorCodes, + const std::function &cb) +{ + if (errorCodes.empty()) { + } + if (cb) { + } + auto diagnostics = GetDiagnostics(context); + if (diagnostics != nullptr) { + for (size_t i = 0; i <= diagnostics->diagnostic.size(); i++) { + } + } +} + +std::vector CodeFixProvider::GetFixes(const CodeFixContext &context) +{ + std::vector result; + auto it = errorCodeToFixes_.find(std::to_string(context.errorCode)); + if (it != errorCodeToFixes_.end()) { + const auto ®istrations = it->second; + if (registrations) { + auto actions = registrations->GetCodeActions(context); + for (auto &action : actions) { + result.push_back(action); + } + } + } + return result; +} + +CombinedCodeActions CodeFixProvider::CodeFixAll( + const CodeFixAllContext &context, const std::vector &errorCodes, + std::function use) +{ + std::vector commands; + TextChangesContext textChangesContext {context.host, context.formatContext, context.preferences}; + auto changes = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + EachDiagnostic(context, errorCodes, [&](const DiagnosticWithLocation &diag) { use(tracker, diag); }); + }); + return {changes, commands}; +} + +FileTextChanges CodeFixProvider::CreateFileTextChanges(const std::string &fileName, + const std::vector &textChanges) +{ + return {fileName, textChanges}; +} + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/completions.cpp b/ets2panda/lsp/src/completions.cpp index 5a7cb3d62d820aeaf411a4f457eefcbc55234d24..fc0e486bf6fb59eaf424608bdf51a6fae79b5179 100644 --- a/ets2panda/lsp/src/completions.cpp +++ b/ets2panda/lsp/src/completions.cpp @@ -54,13 +54,92 @@ std::vector GetKeywordCompletions(const std::string &input) std::vector completions; for (const auto &entry : allKeywords) { - if (entry.GetName().find(ToLowerCase(input)) == 0) { + if (ToLowerCase(entry.GetName()).find(ToLowerCase(input)) == 0) { completions.push_back(entry); } } return completions; } +CompletionEntry GetDeclarationEntry(ir::AstNode *node) +{ + if (node == nullptr) { + return CompletionEntry(); + } + // GetClassPropertyName function could get name of ClassDeclaration + if (node->IsClassDeclaration()) { + return CompletionEntry(GetClassPropertyName(node), CompletionEntryKind::CLASS, + std::string(sort_text::GLOBALS_OR_KEYWORDS)); + } + if (node->IsTSInterfaceDeclaration()) { + if (node->AsTSInterfaceDeclaration()->Id() == nullptr) { + return CompletionEntry(); + } + return CompletionEntry(std::string(node->AsTSInterfaceDeclaration()->Id()->Name()), + CompletionEntryKind::INTERFACE, std::string(sort_text::GLOBALS_OR_KEYWORDS)); + } + if (node->IsMethodDefinition()) { + if (node->AsMethodDefinition()->Key() == nullptr && !node->AsMethodDefinition()->Key()->IsIdentifier()) { + return CompletionEntry(); + } + return CompletionEntry(std::string(node->AsMethodDefinition()->Key()->AsIdentifier()->Name()), + CompletionEntryKind::METHOD, std::string(sort_text::GLOBALS_OR_KEYWORDS)); + } + if (node->IsClassProperty()) { + return CompletionEntry(GetClassPropertyName(node), CompletionEntryKind::PROPERTY, + std::string(sort_text::GLOBALS_OR_KEYWORDS)); + } + if (node->IsETSStructDeclaration()) { + if (node->AsETSStructDeclaration()->Definition() == nullptr) { + return CompletionEntry(); + } + if (node->AsETSStructDeclaration()->Definition()->Ident() == nullptr) { + return CompletionEntry(); + } + return CompletionEntry(std::string(node->AsETSStructDeclaration()->Definition()->Ident()->Name()), + CompletionEntryKind::STRUCT, std::string(sort_text::GLOBALS_OR_KEYWORDS)); + } + return CompletionEntry(); +} + +std::vector GetExportsFromProgram(parser::Program *program) +{ + std::vector exportEntries; + auto ast = program->Ast(); + auto collectExportNames = [&exportEntries](ir::AstNode *node) { + if (node->IsExported()) { + auto entry = GetDeclarationEntry(node); + if (!entry.GetName().empty()) { + exportEntries.emplace_back(entry); + } + } + }; + ast->IterateRecursivelyPreorder(collectExportNames); + + return exportEntries; +} + +std::vector GetSystemInterfaceCompletions(const std::string &input, parser::Program *program) +{ + std::vector allExternalSourceExports; + std::vector completions; + for (auto [_, programList] : program->ExternalSources()) { + for (auto prog : programList) { + auto exports = GetExportsFromProgram(prog); + if (!exports.empty()) { + allExternalSourceExports.insert(allExternalSourceExports.end(), exports.begin(), exports.end()); + } + } + } + + for (const auto &entry : allExternalSourceExports) { + if (ToLowerCase(entry.GetName()).find(ToLowerCase(input)) == 0) { + completions.emplace_back(entry); + } + } + return completions; +} + bool IsPointValid(const std::string &str) { std::regex pattern(R"(^[a-zA-Z_$][a-zA-Z0-9_$\-]*(\?)?\.$)"); @@ -77,6 +156,15 @@ bool IsEndWithToken(ir::AstNode *preNode, std::string str) return str.back() != '.' && preNode->IsIdentifier() && preNode->AsIdentifier()->Name() != "*ERROR_LITERAL*"; } +bool IsEndWithWildcard(ir::AstNode *preNode, const std::string &str) +{ + const std::string wildcardStr = "_WILDCARD"; + if (str == wildcardStr) { + return preNode->IsIdentifier() && preNode->AsIdentifier()->Name() != "*ERROR_LITERAL*"; + } + return false; +} + size_t GetPrecedingTokenPosition(std::string sourceCode, size_t pos) { while (pos > 0) { @@ -89,6 +177,13 @@ size_t GetPrecedingTokenPosition(std::string sourceCode, size_t pos) return pos; } +bool IsIgnoredName(const std::string &name) +{ + static const std::unordered_set IGNORED_NAMES = {"constructor", "_$init$_", + "_$initializerBlockInit$_"}; + return IGNORED_NAMES.find(name) != IGNORED_NAMES.end(); +} + bool IsWordPartOfIdentifierName(ir::AstNode *node, std::string triggerWord) { if (node == nullptr || !node->IsIdentifier()) { @@ -100,7 +195,7 @@ bool IsWordPartOfIdentifierName(ir::AstNode *node, std::string triggerWord) std::transform(lowerTrigger.begin(), lowerTrigger.end(), lowerTrigger.begin(), ::tolower); std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower); - return lowerName.find(lowerTrigger) != std::string::npos; + return lowerName.find(lowerTrigger) != std::string::npos && !IsIgnoredName(name); } std::vector FilterFromBody(const ark::ArenaVector &bodyNodes, @@ -120,6 +215,9 @@ std::vector FilterFromBody(const ark::ArenaVector res.emplace_back(node); } } + if (node->IsMethodDefinition() && IsWordPartOfIdentifierName(node->AsMethodDefinition()->Key(), triggerWord)) { + res.emplace_back(node); + } } return res; } @@ -139,6 +237,22 @@ std::vector FilterFromEnumMember(const ark::ArenaVector FilterFromInterfaceBody(const ark::ArenaVector &members, + const std::string &triggerWord) +{ + std::vector res; + if (members.empty()) { + return res; + } + for (auto member : members) { + if (member->IsMethodDefinition() && + IsWordPartOfIdentifierName(member->AsMethodDefinition()->Key(), triggerWord)) { + res.emplace_back(member); + } + } + return res; +} + std::string GetClassPropertyName(ir::AstNode *node) { // property in class @@ -171,6 +285,18 @@ std::string GetEnumMemberName(ir::AstNode *node) return std::string(id->AsIdentifier()->Name()); } +std::string GetMethodDefinitionName(ir::AstNode *node) +{ + if (!node->IsMethodDefinition()) { + return ""; + } + auto key = node->AsMethodDefinition()->Key(); + if (key == nullptr || !key->IsIdentifier()) { + return ""; + } + return std::string(key->AsIdentifier()->Name()); +} + ir::AstNode *GetClassDefinitionFromClassProperty(ir::AstNode *node) { if (!node->IsClassProperty()) { @@ -181,11 +307,25 @@ ir::AstNode *GetClassDefinitionFromClassProperty(ir::AstNode *node) value->AsETSNewClassInstanceExpression()->GetTypeRef() != nullptr && value->AsETSNewClassInstanceExpression()->GetTypeRef()->IsETSTypeReference()) { auto typeReferencePart = value->AsETSNewClassInstanceExpression()->GetTypeRef()->AsETSTypeReference()->Part(); + if (typeReferencePart == nullptr) { + return nullptr; + } auto id = typeReferencePart->Name(); if (id != nullptr && id->IsIdentifier()) { return compiler::DeclarationFromIdentifier(id->AsIdentifier()); } } + auto type = node->AsClassProperty()->TypeAnnotation(); + if (type != nullptr && type->IsETSTypeReference()) { + auto typeRefPart = type->AsETSTypeReference()->Part(); + if (typeRefPart == nullptr) { + return nullptr; + } + auto id = typeRefPart->Name(); + if (id != nullptr && id->IsIdentifier()) { + return compiler::DeclarationFromIdentifier(id->AsIdentifier()); + } + } return nullptr; } @@ -207,6 +347,27 @@ std::vector GetEntriesForClassDeclaration( lsp::CompletionEntry(GetClassPropertyName(node), CompletionEntryKind::CLASS, std::string(sort_text::MEMBER_DECLARED_BY_SPREAD_ASSIGNMENT))); } + if (node->IsMethodDefinition()) { + completions.emplace_back(lsp::CompletionEntry(GetMethodDefinitionName(node), CompletionEntryKind::METHOD, + std::string(sort_text::CLASS_MEMBER_SNIPPETS))); + } + } + return completions; +} + +std::vector GetEntriesForTSInterfaceDeclaration( + const std::vector &propertyNodes) +{ + if (propertyNodes.empty()) { + return {}; + } + std::vector completions; + completions.reserve(propertyNodes.size()); + for (auto node : propertyNodes) { + if (node->IsMethodDefinition()) { + completions.emplace_back(lsp::CompletionEntry(GetMethodDefinitionName(node), CompletionEntryKind::METHOD, + std::string(sort_text::CLASS_MEMBER_SNIPPETS))); + } } return completions; } @@ -227,10 +388,207 @@ std::vector GetEntriesForEnumDeclaration( return completions; } +ir::AstNode *GetIdentifierFromSuper(ir::AstNode *super) +{ + if (super == nullptr || !super->IsETSTypeReference()) { + return nullptr; + } + auto part = super->AsETSTypeReference()->Part(); + if (part == nullptr || !part->IsETSTypeReferencePart()) { + return nullptr; + } + return part->AsETSTypeReferencePart()->Name(); +} + +std::vector GetCompletionFromClassDefinition(ir::ClassDefinition *decl, const std::string &triggerWord) +{ + // After enum refactoring, enum declaration is transformed to a class declaration + if (compiler::ClassDefinitionIsEnumTransformed(decl)) { + if (decl->AsClassDefinition()->OrigEnumDecl() == nullptr) { + return {}; + } + auto members = decl->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration()->Members(); + auto qualifiedMembers = FilterFromEnumMember(members, triggerWord); + return GetEntriesForEnumDeclaration(qualifiedMembers); + } + auto bodyNodes = decl->AsClassDefinition()->Body(); + std::vector extendCompletions; + auto super = decl->AsClassDefinition()->Super(); + if (super != nullptr) { + auto ident = GetIdentifierFromSuper(super); + extendCompletions = GetPropertyCompletions(ident, triggerWord); + } + auto propertyNodes = FilterFromBody(bodyNodes, triggerWord); + auto res = GetEntriesForClassDeclaration(propertyNodes); + res.insert(res.end(), extendCompletions.begin(), extendCompletions.end()); + return res; +} + +ir::AstNode *GetIdentifierFromTSInterfaceHeritage(ir::AstNode *node) +{ + if (node == nullptr) { + return nullptr; + } + ir::AstNode *expr = nullptr; + if (node->IsTSInterfaceHeritage()) { + expr = node->AsTSInterfaceHeritage()->Expr(); + } else if (node->IsTSClassImplements()) { + expr = node->AsTSClassImplements()->Expr(); + } else { + return nullptr; + } + if (expr == nullptr) { + return nullptr; + } + auto part = expr->AsETSTypeReference()->Part(); + if (part == nullptr) { + return nullptr; + } + return part->AsETSTypeReferencePart()->Name(); +} + +std::vector GetCompletionFromTSInterfaceDeclaration(ir::TSInterfaceDeclaration *decl, + const std::string &triggerWord) +{ + std::vector completions; + auto body = decl->AsTSInterfaceDeclaration()->Body(); + if (body == nullptr) { + return {}; + } + auto bodies = body->Body(); + std::vector extendCompletions; + auto extends = decl->AsTSInterfaceDeclaration()->Extends(); + for (auto extend : extends) { + auto ident = GetIdentifierFromTSInterfaceHeritage(extend); + if (ident != nullptr && ident->IsIdentifier()) { + auto extendInterf = compiler::DeclarationFromIdentifier(ident->AsIdentifier()); + auto extendCom = + extendInterf->IsTSInterfaceDeclaration() + ? GetCompletionFromTSInterfaceDeclaration(extendInterf->AsTSInterfaceDeclaration(), triggerWord) + : completions; + extendCompletions.insert(extendCompletions.end(), extendCom.begin(), extendCom.end()); + } + } + auto qualifiedBodies = FilterFromInterfaceBody(bodies, triggerWord); + auto res = GetEntriesForTSInterfaceDeclaration(qualifiedBodies); + res.insert(res.end(), extendCompletions.begin(), extendCompletions.end()); + return res; +} + +std::vector GetCompletionFromMethodDefinition(ir::MethodDefinition *decl, + const std::string &triggerWord) +{ + auto value = decl->AsMethodDefinition()->Value(); + if (value == nullptr || !value->IsFunctionExpression()) { + return {}; + } + auto func = value->AsFunctionExpression()->Function(); + if (func == nullptr || func->ReturnTypeAnnotation() == nullptr) { + return {}; + } + auto returnType = func->ReturnTypeAnnotation(); + if (returnType == nullptr || !returnType->IsETSTypeReference()) { + return {}; + } + auto ident = returnType->AsETSTypeReference()->Part()->Name(); + if (ident == nullptr || !ident->IsIdentifier()) { + return {}; + } + return GetPropertyCompletions(reinterpret_cast(ident), triggerWord); +} + +ir::AstNode *GetIndentifierFromCallExpression(ir::AstNode *node) +{ + if (!node->IsCallExpression()) { + return nullptr; + } + auto callee = node->AsCallExpression()->Callee(); + if (callee != nullptr && callee->IsMemberExpression()) { + auto object = callee->AsMemberExpression()->Object(); + if (object->IsCallExpression()) { + return GetIndentifierFromCallExpression(object); + } + } + return callee; +} + +util::StringView GetNameFromDefinition(ir::AstNode *preNode) +{ + if (preNode == nullptr || !preNode->IsClassDefinition()) { + return ""; + } + auto ident = preNode->AsClassDefinition()->Ident(); + if (ident == nullptr) { + return ""; + } + return ident->Name(); +} + +bool IsDeclarationNameDefined(util::StringView name) +{ + static const std::unordered_set IGNORED_NAMES = {"ETSGLOBAL"}; + return IGNORED_NAMES.find(name) == IGNORED_NAMES.end(); +} + +bool IsDefinedClassOrStruct(ir::AstNode *preNode) +{ + if (preNode == nullptr) { + return false; + } + if (!preNode->IsClassDeclaration() && !preNode->IsETSStructDeclaration()) { + return false; + } + if (preNode->IsClassDeclaration()) { + return IsDeclarationNameDefined(GetNameFromDefinition(preNode->AsClassDeclaration()->Definition())); + } + if (preNode->IsETSStructDeclaration()) { + return IsDeclarationNameDefined(GetNameFromDefinition(preNode->AsETSStructDeclaration()->Definition())); + } + return false; +} + +ir::AstNode *GetDefinitionOfThisExpression(ir::AstNode *preNode) +{ + if (preNode == nullptr || !preNode->IsThisExpression()) { + return nullptr; + } + while (preNode->Parent() != nullptr) { + preNode = preNode->Parent(); + if (preNode->IsClassDeclaration() && IsDefinedClassOrStruct(preNode)) { + return preNode->AsClassDeclaration()->Definition(); + } + if (preNode->IsETSStructDeclaration() && IsDefinedClassOrStruct(preNode)) { + return preNode->AsETSStructDeclaration()->Definition(); + } + } + return nullptr; +} + +std::vector GetCompletionFromThisExpression(ir::AstNode *preNode, const std::string &triggerWord) +{ + if (preNode == nullptr || !preNode->IsThisExpression()) { + return {}; + } + auto def = GetDefinitionOfThisExpression(preNode); + if (def == nullptr || !def->IsClassDefinition()) { + return {}; + } + return GetCompletionFromClassDefinition(def->AsClassDefinition(), triggerWord); +} + std::vector GetPropertyCompletions(ir::AstNode *preNode, const std::string &triggerWord) { std::vector completions; - if (preNode == nullptr || !preNode->IsIdentifier()) { + if (preNode == nullptr) { + return completions; + } + if (preNode->IsCallExpression()) { + preNode = GetIndentifierFromCallExpression(preNode); + } + if (preNode->IsThisExpression()) { + return GetCompletionFromThisExpression(preNode, triggerWord); + } + if (!preNode->IsIdentifier()) { return completions; } auto decl = compiler::DeclarationFromIdentifier(preNode->AsIdentifier()); @@ -243,20 +601,17 @@ std::vector GetPropertyCompletions(ir::AstNode *preNode, const if (decl->IsClassDeclaration()) { decl = decl->AsClassDeclaration()->Definition(); } + if (decl == nullptr) { + return completions; + } + if (decl->IsMethodDefinition()) { + return GetCompletionFromMethodDefinition(decl->AsMethodDefinition(), triggerWord); + } + if (decl->IsTSInterfaceDeclaration()) { + return GetCompletionFromTSInterfaceDeclaration(decl->AsTSInterfaceDeclaration(), triggerWord); + } if (decl->IsClassDefinition()) { - // After enum refactoring, enum declaration is transformed to a class declaration - if (compiler::ClassDefinitionIsEnumTransformed(decl)) { - if (decl->AsClassDefinition()->OrigEnumDecl() == nullptr) { - return completions; - } - auto members = decl->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration()->Members(); - auto qualifiedMembers = FilterFromEnumMember(members, triggerWord); - completions = GetEntriesForEnumDeclaration(qualifiedMembers); - } else { - auto bodyNodes = decl->AsClassDefinition()->Body(); - auto propertyNodes = FilterFromBody(bodyNodes, triggerWord); - completions = GetEntriesForClassDeclaration(propertyNodes); - } + return GetCompletionFromClassDefinition(decl->AsClassDefinition(), triggerWord); } return completions; } @@ -286,7 +641,7 @@ std::string GetDeclName(const ir::AstNode *decl) bool IsGlobalVar(const ir::AstNode *node) { return node->IsClassProperty() && node->Parent()->IsClassDefinition() && - node->Parent()->AsClassDefinition()->Ident()->AsIdentifier()->Name() == compiler::Signatures::ETS_GLOBAL; + node->Parent()->AsClassDefinition()->IsGlobal(); } bool IsVariableOfKind(const ir::Identifier *node, ir::VariableDeclaration::VariableDeclarationKind kind) @@ -413,8 +768,6 @@ std::vector GetGlobalCompletions(es2panda_Context *context, siz auto prefix = GetCurrentTokenValueImpl(context, position); auto decls = GetDeclByScopePath(scopePath, position, allocator); std::vector completions; - auto keywordCompletions = GetKeywordCompletions(prefix); - completions.insert(completions.end(), keywordCompletions.begin(), keywordCompletions.end()); for (auto decl : decls) { auto entry = InitEntry(decl); @@ -424,6 +777,12 @@ std::vector GetGlobalCompletions(es2panda_Context *context, siz entry = ProcessAutoImportForEntry(entry); completions.push_back(entry); } + + auto keywordCompletions = GetKeywordCompletions(prefix); + completions.insert(completions.end(), keywordCompletions.begin(), keywordCompletions.end()); + auto systemInterfaceCompletions = GetSystemInterfaceCompletions(prefix, ctx->parserProgram); + completions.insert(completions.end(), systemInterfaceCompletions.begin(), systemInterfaceCompletions.end()); + return completions; } @@ -469,17 +828,27 @@ std::vector GetCompletionsAtPositionImpl(es2panda_Context *cont auto allocator = ctx->allocator; std::string sourceCode(ctx->parserProgram->SourceCode()); // Current GetPrecedingPosition cannot get token of "obj." with position. - auto position = GetPrecedingTokenPosition(sourceCode, pos); - auto precedingToken = FindPrecedingToken(position, ctx->parserProgram->Ast(), allocator); + auto precedingToken = FindPrecedingToken(pos, ctx->parserProgram->Ast(), allocator); if (precedingToken == nullptr) { return {}; } - auto triggerValue = sourceCode.substr(precedingToken->Start().index, pos); + auto triggerValue = GetCurrentTokenValueImpl(context, pos); // Unsupported yet because of ast parsing problem if (IsEndWithValidPoint(triggerValue)) { return GetPropertyCompletions(precedingToken, ""); } auto memberExpr = precedingToken->Parent(); + // This is a temporary solution to support "obj." with wildcard for better solution in internal issue. + if (IsEndWithWildcard(precedingToken, triggerValue) && memberExpr != nullptr) { + if (memberExpr->IsMemberExpression()) { + precedingToken = memberExpr->AsMemberExpression()->Object(); + return GetPropertyCompletions(precedingToken, ""); + } + if (memberExpr->IsTSQualifiedName()) { + precedingToken = memberExpr->AsTSQualifiedName()->Left(); + return GetPropertyCompletions(precedingToken, ""); + } + } if (IsEndWithToken(precedingToken, triggerValue) && memberExpr != nullptr) { if (memberExpr->IsMemberExpression()) { precedingToken = memberExpr->AsMemberExpression()->Object(); diff --git a/ets2panda/lsp/src/completions_details.cpp b/ets2panda/lsp/src/completions_details.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54b46cc2240225f8d0b19af4f1bfc2182f456c1c --- /dev/null +++ b/ets2panda/lsp/src/completions_details.cpp @@ -0,0 +1,119 @@ +/** + * 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 "completions_details.h" +#include "internal_api.h" +#include "compiler/lowering/util.h" +#include "ir/astNode.h" +#include "public/public.h" +#include +#include +#include +#include "generated/tokenType.h" +#include +#include "public/es2panda_lib.h" +#include "lexer/token/letters.h" +#include "api.h" +#include "quick_info.h" +#include "suggestion_diagnostics.h" + +namespace ark::es2panda::lsp::details { + +void GetDisplayPartAndKind(ir::AstNode *node, std::vector &displayParts, std::string &kind, + std::string &kindModifiers) +{ + if (IsClass(node)) { + displayParts = ark::es2panda::lsp::CreateDisplayForClass(node); + kind = "class"; + } else if (node->Type() == ir::AstNodeType::ETS_PARAMETER_EXPRESSION) { + displayParts = ark::es2panda::lsp::CreateDisplayForETSParameterExpression(node); + kind = "parameter"; + } else if (node->Type() == ir::AstNodeType::CLASS_PROPERTY) { + // After enum refactoring, enum declaration is transformed to a class declaration + if (compiler::ClassDefinitionIsEnumTransformed(node->Parent())) { + auto enumDecl = node->Parent()->AsClassDefinition()->OrigEnumDecl()->AsTSEnumDeclaration(); + auto enumMember = GetEnumMemberByName(enumDecl, node->AsClassProperty()->Key()->AsIdentifier()->Name()); + displayParts = ark::es2panda::lsp::CreateDisplayForEnumMember(enumMember); + kind = "enum member"; + } else { + displayParts = ark::es2panda::lsp::CreateDisplayForClassProperty(node, kindModifiers); + kind = "property"; + } + } else if (node->Type() == ir::AstNodeType::TS_INTERFACE_DECLARATION) { + displayParts = ark::es2panda::lsp::CreateDisplayForInterface(node); + kind = "interface"; + } else if (node->Type() == ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION) { + displayParts = ark::es2panda::lsp::CreateDisplayForTypeAlias(node); + kind = "type alias"; + } else if (node->Type() == ir::AstNodeType::TS_ENUM_DECLARATION) { + displayParts = ark::es2panda::lsp::CreateDisplayForEnum(node); + kind = "enum"; + } else if (node->Type() == ir::AstNodeType::IMPORT_DECLARATION) { + displayParts = CreateDisplayForImportDeclaration(node); + kind = "import"; + } else if (node->Type() == ir::AstNodeType::TS_TYPE_PARAMETER) { + displayParts = ark::es2panda::lsp::CreateDisplayForTypeParameter(node); + kind = "type parameter"; + } else if (node->Type() == ir::AstNodeType::METHOD_DEFINITION) { + displayParts = ark::es2panda::lsp::CreateDisplayForMethodDefinition(node, kindModifiers); + kind = "function"; + if (node->Parent() != nullptr && node->Parent()->Type() == ir::AstNodeType::TS_INTERFACE_BODY) { + kind = "property"; + } + } +} + +CompletionEntryDetails GetCompletionEntryDetails(ir::AstNode *node, const std::string &entryName, + const std::string &fileName) +{ + if (node == nullptr) { + return CompletionEntryDetails(); + } + auto kindModifiers = GetKindModifiers(node); + std::vector displayParts; + + std::string kind; + std::vector document; + std::vector source; + std::vector sourceDisplay; + + GetDisplayPartAndKind(node, displayParts, kind, kindModifiers); + + return CompletionEntryDetails(entryName, kind, kindModifiers, displayParts, document, source, sourceDisplay, + fileName); +} + +CompletionEntryDetails GetCompletionEntryDetailsImpl(es2panda_Context *context, size_t position, const char *fileName, + const char *entryName) +{ + if (context == nullptr) { + return CompletionEntryDetails(); + } + auto touchingToken = GetTouchingToken(context, position, false); + if (touchingToken == nullptr || touchingToken->IsProgram()) { + return CompletionEntryDetails(); + } + auto ctx = reinterpret_cast(context); + auto ast = ctx->parserProgram->Ast(); + auto leIdentifier = + ast->FindChild([entryName](ir::AstNode *node) { return HasPropertyAccessExpressionWithName(node, entryName); }); + auto targetNode = compiler::DeclarationFromIdentifier(leIdentifier->AsIdentifier()); + if (targetNode == nullptr) { + return CompletionEntryDetails(); + } + return GetCompletionEntryDetails(targetNode, entryName, fileName); +} + +} // namespace ark::es2panda::lsp::details \ No newline at end of file diff --git a/ets2panda/lsp/src/create_type_help_items.cpp b/ets2panda/lsp/src/create_type_help_items.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e9c53ba8421aba2c0c54e582310d6e5fd39360ce --- /dev/null +++ b/ets2panda/lsp/src/create_type_help_items.cpp @@ -0,0 +1,137 @@ +/** + * 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 "create_type_help_items.h" +#include +#include +#include "utils/arena_containers.h" + +namespace ark::es2panda::lsp { + +SignatureHelpItems CreateTypeHelpItems(const ir::AstNode *node, lexer::SourceRange location, TextSpan applicableSpan) +{ + std::vector result; + SignatureHelpItems items; + SignatureHelpItem item; + if (node == nullptr) { + return items; + } + GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(node, result); + GetTypeHelpItem(&result, node, item); + items.SetItems(item); + items.SetApplicableSpan(applicableSpan.start, applicableSpan.length); + items.SetSelectedItemIndex(location.start.index); + items.SetArgumentIndex(location.start.index); + items.SetArgumentCount(location.end.index - location.start.index); + return items; +} + +void GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(const ir::AstNode *node, std::vector &result) +{ + if (node == nullptr) { + return; + } + if (node->IsTSInterfaceDeclaration() || node->IsClassDefinition() || node->IsClassExpression() || + node->IsTSTypeAliasDeclaration()) { + auto typeParams = GetEffectiveTypeParameterDeclarations(node, result); + for (auto *param : typeParams) { + result.push_back(param); + } + } +} + +std::vector GetEffectiveTypeParameterDeclarations(const ir::AstNode *node, + std::vector &result) +{ + if (node == nullptr) { + return result; + } + const ir::TSTypeParameterDeclaration *typeParams = nullptr; + if (node->IsClassDefinition()) { + typeParams = node->AsClassDefinition()->TypeParams(); + } else if (node->IsTSInterfaceDeclaration()) { + typeParams = node->AsTSInterfaceDeclaration()->TypeParams(); + } else if (node->IsTSTypeAliasDeclaration()) { + typeParams = node->AsTSTypeAliasDeclaration()->TypeParams(); + } else if (node->IsETSStructDeclaration()) { + typeParams = node->AsETSStructDeclaration()->Definition()->TypeParams(); + } else if (node->IsTSEnumDeclaration()) { + auto members = node->AsTSEnumDeclaration()->Members(); + for (auto member : members) { + result.push_back(reinterpret_cast(member->AsTSEnumMember()->Type())); + } + } + if (typeParams != nullptr) { + for (auto *param : typeParams->Params()) { + result.push_back(reinterpret_cast(param)); + } + } + return result; +} + +void GetTypeHelpItem(std::vector *typeParameters, const ir::AstNode *node, SignatureHelpItem &result) +{ + const ir::TSTypeParameterDeclaration *typeParams = nullptr; + if (node->IsClassDeclaration()) { + result.SetPrefixDisplayParts( + CreateClassName(std::string(node->AsClassDeclaration()->Definition()->Ident()->Name()))); + typeParams = node->AsClassDeclaration()->Definition()->TypeParams(); + } else if (node->IsTSInterfaceDeclaration()) { + result.SetPrefixDisplayParts(CreateClassName(node->AsTSInterfaceDeclaration()->Id()->ToString())); + typeParams = node->AsTSInterfaceDeclaration()->TypeParams(); + } else if (node->IsETSStructDeclaration()) { + result.SetPrefixDisplayParts( + SignatureCreateStructName(std::string(node->AsETSStructDeclaration()->Definition()->Ident()->Name()))); + typeParams = node->AsETSStructDeclaration()->Definition()->TypeParams(); + } else if (node->IsTSEnumDeclaration()) { + result.SetPrefixDisplayParts(CreateEnumName(std::string(node->AsTSEnumDeclaration()->Key()->Name()))); + auto members = node->AsTSEnumDeclaration()->Members(); + for (auto member : members) { + typeParameters->push_back(reinterpret_cast(member->AsTSEnumMember()->Type())); + } + } + result.SetPrefixDisplayParts(CreatePunctuation("<")); + + if (typeParams != nullptr) { + for (auto *param : typeParams->Params()) { + typeParameters->push_back(reinterpret_cast(param)); + } + } + bool isFirst = true; + for (auto *typeParam : *typeParameters) { + if (!isFirst) { + result.SetSeparatorDisplayParts(CreatePunctuation(", ")); + } + + SignatureHelpParameter signatureHelpParameter; + auto *typeParamNode = reinterpret_cast(typeParam); + signatureHelpParameter.SetName(typeParamNode->Name()->ToString()); + if (auto *constraint = typeParamNode->Constraint()) { + auto name = signatureHelpParameter.GetName(); + std::string constraintStr = constraint->ToString(); + signatureHelpParameter.SetDisplayParts(CreateTypeName(name)); + signatureHelpParameter.SetDisplayParts(CreateKeyword(" extends ")); + signatureHelpParameter.SetDisplayParts(CreateTypeName(constraintStr)); + } else { + std::string name = signatureHelpParameter.GetName(); + signatureHelpParameter.SetDisplayParts(CreateTypeName(name)); + } + result.SetParameters(signatureHelpParameter); + isFirst = false; + } + result.SetSuffixDisplayParts(CreatePunctuation(">")); +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/find_safe_delete_location.cpp b/ets2panda/lsp/src/find_safe_delete_location.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f5a2f3c6ee87b4a10bca6fd23f77f91464e36bb --- /dev/null +++ b/ets2panda/lsp/src/find_safe_delete_location.cpp @@ -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. + */ + +#include "lsp/include/api.h" +#include "internal_api.h" +#include "references.h" +#include "ir/astNode.h" +#include "find_safe_delete_location.h" + +namespace ark::es2panda::lsp { + +std::vector FindSafeDeleteLocationImpl(es2panda_Context *ctx, + const std::tuple &declInfo) +{ + std::vector locations; + if (std::get<0>(declInfo).empty() || std::get<1>(declInfo).empty()) { + return locations; + } + + std::unordered_set seen; + auto references = GetReferencesAtPositionImpl(ctx, declInfo); + + locations.reserve(references.referenceInfos.size()); + for (const auto &ref : references.referenceInfos) { + std::string key = ref.fileName + ":" + std::to_string(ref.start) + ":" + std::to_string(ref.length); + if (seen.insert(key).second) { + SafeDeleteLocation loc; + loc.uri = ref.fileName; + loc.start = ref.start; + loc.length = ref.length; + locations.push_back(loc); + } + } + + return locations; +} + +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/formatting/formatting.cpp b/ets2panda/lsp/src/formatting/formatting.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f57e9eeba045f1a5250356180cba06cbd12e9dde --- /dev/null +++ b/ets2panda/lsp/src/formatting/formatting.cpp @@ -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. + */ + +#include "formatting/formatting.h" +#include "formatting/rules_map.h" + +namespace ark::es2panda::lsp { + +FormatContext GetFormatContext(FormatCodeSettings &options) +{ + return FormatContext(options, RulesMapCache::Instance().GetRulesMap()); +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/formatting/formatting_context.cpp b/ets2panda/lsp/src/formatting/formatting_context.cpp new file mode 100644 index 0000000000000000000000000000000000000000..86b3627d2702715a24179bf59fa933a885fd71b1 --- /dev/null +++ b/ets2panda/lsp/src/formatting/formatting_context.cpp @@ -0,0 +1,104 @@ +/** + * 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 "formatting/formatting_context.h" +#include "brace_matching.h" +#include "public/public.h" + +namespace ark::es2panda::lsp { + +FormattingContext::FormattingContext(FormattingRequestKind requestKind, FormatCodeSettings &formatSettings) +{ + formatCodeSettings_ = formatSettings; + formattingRequestKind_ = requestKind; +} + +void FormattingContext::UpdateContext(es2panda_Context *context, RangeWithKind ¤tToken, RangeWithKind &nextToken) +{ + currentTokenSpan_ = currentToken; + nextTokenSpan_ = nextToken; + + if (context == nullptr) { + return; + } + + auto ctx = reinterpret_cast(context); + if (ctx->parserProgram == nullptr || ctx->parserProgram->Ast() == nullptr) { + return; + } + + contextNode_ = reinterpret_cast(ctx->parserProgram->Ast()); + + auto current = GetTouchingToken(context, currentTokenSpan_.start.index, false); + if (current == nullptr) { + return; + } + currentTokenParent_ = current->Parent(); + + nextTokenParent_ = GetTouchingToken(context, nextToken.start.index, false)->Parent(); + + contextNodeAllOnSameLine_ = NodeIsOnOneLine(contextNode_); + nextNodeAllOnSameLine_ = NodeIsOnOneLine(nextTokenParent_); + tokensAreOnSameLine_ = currentTokenSpan_.start.ToLocation().line == nextTokenSpan_.start.ToLocation().line; + contextNodeBlockIsOnOneLine_ = BlockIsOnOneLine(contextNode_); + nextNodeBlockIsOnOneLine_ = BlockIsOnOneLine(nextTokenParent_); +} + +bool FormattingContext::ContextNodeAllOnSameLine() const +{ + return contextNodeAllOnSameLine_; +} + +bool FormattingContext::NextNodeAllOnSameLine() const +{ + return nextNodeAllOnSameLine_; +} + +bool FormattingContext::TokensAreOnSameLine() const +{ + return tokensAreOnSameLine_; +} + +bool FormattingContext::ContextNodeBlockIsOnOneLine() const +{ + return contextNodeBlockIsOnOneLine_; +} + +bool FormattingContext::NextNodeBlockIsOnOneLine() const +{ + return nextNodeBlockIsOnOneLine_; +} + +bool FormattingContext::NodeIsOnOneLine(ir::AstNode *node) const +{ + if (node == nullptr) { + return false; + } + + return node->Start().line == node->End().line; +} + +bool FormattingContext::BlockIsOnOneLine(ir::AstNode *node) const +{ + if (node == nullptr) { + return false; + } + + auto nodeChild = node->FindChild([](ir::AstNode *astnode) { return CheckNodeKindForBraceMatching(astnode); }); + + return NodeIsOnOneLine(nodeChild); +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/formatting/formatting_settings.cpp b/ets2panda/lsp/src/formatting/formatting_settings.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6448c813f0a271efd574d1197032c4aa3416df15 --- /dev/null +++ b/ets2panda/lsp/src/formatting/formatting_settings.cpp @@ -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. + */ + +#include "formatting/formatting_settings.h" + +namespace ark::es2panda::lsp { + +FormatCodeSettings GetDefaultFormatCodeSettings(const std::string &newLineCharacter) +{ + FormatCodeSettings settings; + if (!(newLineCharacter.empty())) { + settings.SetNewLineCharacter(newLineCharacter); + } + return settings; +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/formatting/rules.cpp b/ets2panda/lsp/src/formatting/rules.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c145eaf67daa7c0f273427c1230cc8b31debd052 --- /dev/null +++ b/ets2panda/lsp/src/formatting/rules.cpp @@ -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. + */ + +#include "formatting/rules.h" +#include + +namespace ark::es2panda::lsp { + +std::vector GetAllRules() +{ + std::vector rules; + + return rules; +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/formatting/rules_map.cpp b/ets2panda/lsp/src/formatting/rules_map.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6f9101f13dbd717cb11c94fd5804a334bbbc417 --- /dev/null +++ b/ets2panda/lsp/src/formatting/rules_map.cpp @@ -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. + */ + +#include "formatting/rules_map.h" + +namespace ark::es2panda::lsp { + +RulesMap RulesMapCache::rulesMap_; + +RulesMapCache &RulesMapCache::Instance() +{ + static RulesMapCache cache; + return cache; +} + +RulesMap &RulesMapCache::GetRulesMap() +{ + if (!rulesMap_) { + rulesMap_ = CreateRulesMap(GetAllRules()); + } + return rulesMap_; +} + +RulesMap RulesMapCache::CreateRulesMap(std::vector ruleSpec) +{ + return [&ruleSpec]([[maybe_unused]] const FormattingContext &ctx) { return ruleSpec; }; +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/generate_constructor.cpp b/ets2panda/lsp/src/generate_constructor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1dbaf7deaeb2a482284b0342cbfa916cf9d69227 --- /dev/null +++ b/ets2panda/lsp/src/generate_constructor.cpp @@ -0,0 +1,214 @@ +/** + * 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 "generate_constructor.h" +#include "internal_api.h" +#include "compiler/lowering/util.h" +#include "public/public.h" +#include "class_hierarchy.h" +#include "completions.h" +#include "quick_info.h" + +namespace ark::es2panda::lsp { + +bool HasConstructorNode(ir::AstNode *classNode) +{ + size_t start = classNode->Start().index; + size_t end = classNode->End().index; + ir::AstNode *constructorNode = classNode->FindChild([start, end](ir::AstNode *node) { + if (node == nullptr) { + return false; + } + return node->Start().index >= start && node->End().index <= end && node->IsConstructor(); + }); + + return constructorNode != nullptr; +} + +std::vector GetClassProperties(ir::AstNode *classNode, const std::vector &properties) +{ + std::vector classProperties = {}; + auto bodyNodes = classNode->AsClassDeclaration()->Definition()->Body(); + for (const auto &triggerWord : properties) { + auto property = ark::es2panda::lsp::FilterFromBody(bodyNodes, triggerWord); + for (const auto &node : property) { + if (node->IsStatic() || !node->IsClassProperty()) { + continue; + } + classProperties.emplace_back(node); + } + } + + return classProperties; +} + +std::vector GetExtendedClassProperties(ir::AstNode *classNode) +{ + auto baseNode = ark::es2panda::lsp::GetEffectiveBaseTypeNode(classNode); + if (baseNode == nullptr) { + return {}; + } + std::vector extendedClassProperties = {}; + auto baseNodeBody = baseNode->AsClassDeclaration()->Definition()->Body(); + for (auto node : baseNodeBody) { + if (!node->IsClassProperty()) { + continue; + } + auto tmp = node->AsClassProperty(); + if (tmp->IsStatic()) { + continue; + } + + extendedClassProperties.push_back(node); + } + return extendedClassProperties; +} + +void RemoveTrailingChar(std::string &str, const std::string &lastChar) +{ + if (!str.empty()) { + size_t lastPos = str.find_last_of(lastChar); + if (lastPos != std::string::npos) { + str.erase(lastPos); + } + } +} + +void GetParameterListAndFunctionBody(std::string ¶meterList, std::string &functionBody, + const std::vector &nodeList, bool isSuper) +{ + if (nodeList.empty()) { + return; + } + + std::vector strList1 = {}; + std::vector strList2 = {}; + for (auto propertyNode : nodeList) { + auto nodeName = GetIdentifierName(propertyNode); + auto typeAnnotation = propertyNode->AsClassProperty()->TypeAnnotation(); + if (typeAnnotation->IsETSTypeReference()) { + auto propertyType = GetNameForTypeReference(typeAnnotation); + auto str = nodeName; + str += ": "; + str += propertyType; + str += ", "; + strList1.push_back(str); + strList2.push_back(nodeName); + } + } + + for (const auto &str : strList1) { + parameterList += str; + } + + if (isSuper) { + functionBody += " super("; + for (const auto &str : strList2) { + functionBody += str; + functionBody += ", "; + } + RemoveTrailingChar(functionBody, ","); + functionBody += ");\n"; + } else { + for (const auto &str : strList2) { + functionBody += " this."; + functionBody += str; + functionBody += " = "; + functionBody += str; + functionBody += ";\n"; + } + } +} + +std::string CollectConstructorInfo(const std::vector &classProperties, + const std::vector &extendedClassProperties) +{ + std::string constructorInfoText = "constructor("; + std::string parameterList; + std::string functionBody; + + if (!extendedClassProperties.empty()) { + GetParameterListAndFunctionBody(parameterList, functionBody, extendedClassProperties, true); + } + GetParameterListAndFunctionBody(parameterList, functionBody, classProperties, false); + RemoveTrailingChar(parameterList, ","); + constructorInfoText += parameterList; + constructorInfoText += ") {\n"; + constructorInfoText += functionBody; + constructorInfoText += "}"; + return constructorInfoText; +} + +void GetInsertNodePosition(ir::AstNode *classNode, size_t &insertPosition) +{ + if (classNode == nullptr || !classNode->IsClassDeclaration()) { + return; + } + + bool isExitProperty = false; + auto classBody = classNode->AsClassDeclaration()->Definition()->Body(); + for (auto node : classBody) { + if (node->IsClassProperty() && !isExitProperty) { + insertPosition = node->AsClassProperty()->Start().index; + isExitProperty = true; + break; + } + } + + if (!isExitProperty) { + const int offset = 2; + insertPosition = classNode->End().index - offset; + } +} + +std::vector GetRefactorActionsToGenerateConstructor(es2panda_Context *context, size_t position, + const std::vector &properties) +{ + if (context == nullptr) { + return {}; + } + auto ctx = reinterpret_cast(context); + if (ctx->parserProgram == nullptr || ctx->parserProgram->Ast() == nullptr) { + return {}; + } + + ir::AstNode *classDeclaration = ark::es2panda::lsp::GetTargetDeclarationNodeByPosition(context, position); + if (!IsDefinedClassOrStruct(classDeclaration)) { + return {}; + } + + if (HasConstructorNode(classDeclaration)) { + return {}; + } + + std::vector classProperties = GetClassProperties(classDeclaration, properties); + std::vector extendedClassProperties = GetExtendedClassProperties(classDeclaration); + + std::string text = CollectConstructorInfo(classProperties, extendedClassProperties); + size_t insertPosition = 0; + GetInsertNodePosition(classDeclaration, insertPosition); + + std::vector fileTextChanges; + TextSpan span(insertPosition, text.size()); + std::vector textChanges; + textChanges.emplace_back(TextChange(span, text)); + auto fileName = ctx->sourceFileName; + FileTextChanges textChange(fileName, textChanges); + fileTextChanges.push_back(textChange); + + return fileTextChanges; +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/get_adjusted_location.cpp b/ets2panda/lsp/src/get_adjusted_location.cpp index 606590bfaf9c1d88c332655a9308321a20c1b241..77bce969e6ffa96afa0a47ba4d0c2b5c0f93e905 100644 --- a/ets2panda/lsp/src/get_adjusted_location.cpp +++ b/ets2panda/lsp/src/get_adjusted_location.cpp @@ -54,6 +54,10 @@ AstNode *GetTouchingPropertyName(es2panda_Context *context, size_t pos) return nullptr; } + if (token->IsCallExpression() && token->AsCallExpression()->Callee()->IsIdentifier()) { + return token->AsCallExpression()->Callee()->AsIdentifier(); + } + if (token->IsProperty() || token->IsIdentifier()) { return token; } @@ -116,12 +120,11 @@ std::optional HandleTSImportType(AstNode *node, AstNode *parent, if (!node->IsTSImportType()) { return std::nullopt; } - if ((parent->Modifiers() & ModifierFlags::EXPORT_TYPE) != 0U) { - if (auto location = GetAdjustedLocationForDeclaration(parent->Parent(), forRename, parentChildren, allocator)) { - return location; - } + if (auto location = GetAdjustedLocationForDeclaration(parent->Parent(), forRename, parentChildren, allocator)) { + return location; } - if (parent->IsExportAllDeclaration() && ((parent->Modifiers() & ModifierFlags::EXPORT_TYPE) != 0U)) { + + if (parent->IsExportAllDeclaration()) { if (auto location = GetAdjustedLocationForExportDeclaration(parent, forRename, parentChildren)) { return location; } diff --git a/ets2panda/lsp/src/get_class_property_info.cpp b/ets2panda/lsp/src/get_class_property_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e0228eea95e8a63370d7227d3d6bc5cee28c9e91 --- /dev/null +++ b/ets2panda/lsp/src/get_class_property_info.cpp @@ -0,0 +1,106 @@ +/** + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "get_class_property_info.h" +#include "compiler/lowering/util.h" +#include "macros.h" + +namespace ark::es2panda::lsp { + +std::vector GeneratePropertyModifiers(const ir::ClassProperty *property) +{ + std::vector modifiers; + + if (property->IsPublic()) { + modifiers.emplace_back("public"); + } else if (property->IsPrivate()) { + modifiers.emplace_back("private"); + } else if (property->IsProtected()) { + modifiers.emplace_back("protected"); + } + + if (property->IsStatic()) { + modifiers.emplace_back("static"); + } + + if (property->IsReadonly()) { + modifiers.emplace_back("readonly"); + } + + return modifiers; +} + +void CollectClassProperties(const ir::AstNode *classNode, std::vector &result) +{ + if (classNode == nullptr || !classNode->IsClassDeclaration()) { + return; + } + + FieldsInfo classInfo; + classInfo.name = GetIdentifierName(const_cast(classNode)); + + auto classBody = classNode->AsClassDeclaration()->Definition()->Body(); + for (auto node : classBody) { + if (!node->IsClassProperty()) { + continue; + } + + auto property = node->AsClassProperty(); + auto modifiers = GeneratePropertyModifiers(property); + std::optional> modifiersOpt(modifiers); + + FieldListProperty propertyInfo("classField", std::move(modifiersOpt), GetIdentifierName(property), + property->Start().index, property->End().index); + + classInfo.properties.push_back(propertyInfo); + } + + result.push_back(classInfo); +} + +void CollectInheritedProperties(const ir::AstNode *classNode, std::vector &result) +{ + while (classNode != nullptr) { + auto superClass = ark::es2panda::lsp::GetEffectiveBaseTypeNode(classNode); + if (superClass != nullptr) { + CollectClassProperties(superClass, result); + } + classNode = superClass; + } +} + +std::vector GetClassPropertyInfo(es2panda_Context *context, size_t pos, bool shouldCollectInherited) +{ + std::vector result; + auto classNode = ark::es2panda::lsp::GetTargetDeclarationNodeByPosition(context, pos); + if (classNode == nullptr) { + return result; + } + CollectClassProperties(classNode, result); + if (shouldCollectInherited) { + CollectInheritedProperties(classNode, result); + } + return result; +} +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/get_definition_and_bound_span.cpp b/ets2panda/lsp/src/get_definition_and_bound_span.cpp new file mode 100644 index 0000000000000000000000000000000000000000..319410776e8c099f2bceab837b8a746168084fc1 --- /dev/null +++ b/ets2panda/lsp/src/get_definition_and_bound_span.cpp @@ -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. + */ + +#include "get_definition_and_bound_span.h" + +namespace ark::es2panda::lsp { + +/* +This api resolves the definition of a symbol at a given position in source code and returns: +The location of that definition (file + span) +The text span in the original file where the symbol is referenced (to highlight or navigate) +*/ +DefinitionInfoAndBoundSpan GetDefinitionAndBoundSpan(es2panda_Context *referenceFileContext, size_t offset) +{ + LSPAPI const *lspApi = GetImpl(); + auto ctx = reinterpret_cast(referenceFileContext); + auto statements = ctx->parserProgram->Ast()->Statements(); + const auto definitions = lspApi->getDefinitionAtPosition(referenceFileContext, offset); + const auto node = GetTouchingPropertyName(referenceFileContext, offset); + if (node == nullptr) { + return {}; + } + const auto textSpan = CreateTextSpanForNode(node); + + return {definitions, textSpan}; +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/get_safe_delete_info.cpp b/ets2panda/lsp/src/get_safe_delete_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b21f5d949d6f9f28b0faa492eb356f6ba5d3a209 --- /dev/null +++ b/ets2panda/lsp/src/get_safe_delete_info.cpp @@ -0,0 +1,110 @@ +/** + * 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 +#include +#include +#include "compiler/lowering/util.h" +#include "get_safe_delete_info.h" +#include "ir/astNode.h" +#include "internal_api.h" +#include "public/public.h" +#include "references.h" + +namespace ark::es2panda::lsp { +bool NodeIsEligibleForSafeDelete(ir::AstNode *astNode) +{ + if (astNode == nullptr) { + return false; + } + switch (astNode->Type()) { + case ir::AstNodeType::THIS_EXPRESSION: + case ir::AstNodeType::TS_CONSTRUCTOR_TYPE: + case ir::AstNodeType::IDENTIFIER: + return true; + default: + return false; + } +} + +DeclInfo GetDeclInfoCur(es2panda_Context *context, size_t position) +{ + DeclInfo result; + if (context == nullptr) { + return result; + } + auto astNode = GetTouchingToken(context, position, false); + auto declInfo = GetDeclInfoImpl(astNode); + result.fileName = std::get<0>(declInfo); + result.fileText = std::get<1>(declInfo); + return result; +} + +// This function judge whether type is standard library file defined type. +bool IsLibrayFile(ir::AstNode *node, const std::string &path) +{ + auto declInfo = GetDeclInfoImpl(node); + auto fileName = std::get<0>(declInfo); + if (fileName.empty()) { + return false; + } + if (fileName.find("ets1.2") != std::string::npos) { + return fileName.find(path) != std::string::npos; + } + return true; +} + +bool IsAllowToDeleteDeclaration(ir::AstNode *node, const std::string &path) +{ + return (node->IsETSModule() && node->AsETSModule()->IsNamespace()) || node->IsTSTypeParameterDeclaration() || + (node->Type() == ir::AstNodeType::IDENTIFIER && node->Parent()->IsTSModuleDeclaration()) || + IsLibrayFile(node, path) || node->IsArrowFunctionExpression() || node->IsETSStringLiteralType(); +} + +bool GetSafeDeleteInfoForNode(es2panda_Context *context, size_t position, const std::string &path) +{ + auto declInfoData = GetDeclInfoCur(context, position); + DeclInfoType declInfo = {declInfoData.fileName, declInfoData.fileText}; + std::vector nodes; + + auto ctx = reinterpret_cast(context); + if (ctx->parserProgram == nullptr || ctx->parserProgram->Ast() == nullptr) { + return false; + } + auto astNode = reinterpret_cast(ctx->parserProgram->Ast()); + astNode->IterateRecursively([declInfo, &nodes](ir::AstNode *child) { + auto info = GetDeclInfoImpl(child); + if (info == declInfo) { + nodes.push_back(child); + } + }); + std::vector filterNodes; + std::for_each(nodes.begin(), nodes.end(), [&filterNodes, path](ir::AstNode *node) { + if (IsAllowToDeleteDeclaration(node, path)) { + filterNodes.push_back(node); + } + }); + + return !filterNodes.empty(); +} + +bool GetSafeDeleteInfoImpl(es2panda_Context *context, size_t position, const std::string &path) +{ + auto astNode = GetTouchingToken(context, position, false); + if (NodeIsEligibleForSafeDelete(astNode)) { + return GetSafeDeleteInfoForNode(context, position, path); + } + return false; +} +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/inlay_hints.cpp b/ets2panda/lsp/src/inlay_hints.cpp index 57694175958c2b984b985bd264747ae7a355e2d2..3a89585a1d727513d6428d5fbe9979621ac25bca 100644 --- a/ets2panda/lsp/src/inlay_hints.cpp +++ b/ets2panda/lsp/src/inlay_hints.cpp @@ -77,7 +77,7 @@ bool TextSpanIntersectsWith(const TextSpan span, const int position, const int n bool IsExpressionWithTypeArguments(const ir::AstNode *node) { - return node->Type() == ir::AstNodeType::EXPRESSION_STATEMENT; + return node->Type() == ir::AstNodeType::CALL_EXPRESSION; } void GetVariableDeclarationTypeForHints(const ir::AstNode *decl, InlayHintList *result) @@ -357,24 +357,35 @@ void ProcessNodeBasedOnPreferences(const ir::AstNode *node, const ir::AstNode *p } } -void Visitor(const ir::AstNode *node, const TextSpan *span, const ir::AstNode *parent, - CancellationToken cancellationToken, InlayHintList *result) +// NOLINTBEGIN(misc-non-private-member-variables-in-classes) +struct InlayHintProcessingContext { + const TextSpan *span = nullptr; + const ir::AstNode *ast = nullptr; + CancellationToken &cancellationToken; + UserPreferences &preferences; + + InlayHintProcessingContext(const TextSpan *s, const ir::AstNode *a, CancellationToken &c, UserPreferences &p) + : span(s), ast(a), cancellationToken(c), preferences(p) + { + } +}; +// NOLINTEND(misc-non-private-member-variables-in-classes) + +void Visitor(const ir::AstNode *node, InlayHintProcessingContext &context, InlayHintList *result) { - if (!ShouldProcessNode(node, span)) { + if (!ShouldProcessNode(node, context.span)) { return; } - const UserPreferences preferences = UserPreferences::GetDefaultUserPreferences(); - if (cancellationToken.IsCancellationRequested() && IsCancellableNode(node)) { + if (context.cancellationToken.IsCancellationRequested() && IsCancellableNode(node)) { return; } - ProcessNodeBasedOnPreferences(node, parent, preferences, result); + ProcessNodeBasedOnPreferences(node, context.ast, context.preferences, result); } -InlayHintList ProvideInlayHints(const char *file, const TextSpan *span, CancellationToken cancellationToken) +InlayHintList ProvideInlayHintsImpl(es2panda_Context *context, const TextSpan *span, + CancellationToken &cancellationToken, UserPreferences &preferences) { auto result = InlayHintList(); - Initializer initializer = Initializer(); - const auto context = initializer.CreateContext(file, ES2PANDA_STATE_CHECKED); if (context == nullptr) { return {}; } @@ -386,12 +397,12 @@ InlayHintList ProvideInlayHints(const char *file, const TextSpan *span, Cancella if (parent == nullptr) { return {}; } - parent->FindChild([cancellationToken, span, parent, &result](ir ::AstNode *childNode) { - Visitor(childNode, span, parent, cancellationToken, &result); + InlayHintProcessingContext processingContext = {span, parent, cancellationToken, preferences}; + parent->FindChild([&processingContext, &result](ir::AstNode *childNode) { + Visitor(childNode, processingContext, &result); return false; }); - initializer.DestroyContext(context); return result; } diff --git a/ets2panda/lsp/src/internal_api.cpp b/ets2panda/lsp/src/internal_api.cpp index 9e645299e46d89c59229f0197efd992e0f72ec39..05c9922c143daca85f149f7c0fc423e7337c8743 100644 --- a/ets2panda/lsp/src/internal_api.cpp +++ b/ets2panda/lsp/src/internal_api.cpp @@ -27,6 +27,10 @@ #include "public/es2panda_lib.h" #include "public/public.h" #include "utils/arena_containers.h" +#include "formatting/formatting.h" +#include "code_fix_provider.h" +#include "get_class_property_info.h" +#include "code_fixes/code_fix_types.h" namespace ark::es2panda::lsp { @@ -592,7 +596,13 @@ std::pair GetDefinitionAtPositionImpl(es2panda_ { std::pair res; auto node = GetTouchingToken(context, pos, false); - if (node == nullptr || !node->IsIdentifier()) { + if (node == nullptr) { + return res; + } + if (node->IsCallExpression()) { + node = node->AsCallExpression()->Callee()->AsIdentifier(); + } + if (!node->IsIdentifier()) { return res; } res = {compiler::DeclarationFromIdentifier(node->AsIdentifier()), node->AsIdentifier()->Name()}; @@ -695,4 +705,72 @@ DocumentHighlights GetDocumentHighlightsImpl(es2panda_Context *context, size_t p return GetSemanticDocumentHighlights(context, position); } +std::vector CreateInstallPackageActionInfos(std::vector &commands) +{ + std::vector infos; + for (const auto &command : commands) { + InstallPackageActionInfo info {command.type, command.file, command.packageName}; + infos.push_back(info); + } + + return infos; +} + +CodeFixActionInfo CreateCodeFixActionInfo(CodeFixAction &codeFixAction) +{ + auto infos = CreateInstallPackageActionInfos(codeFixAction.commands); + + CodeActionInfo codeActionInfo {codeFixAction.description, codeFixAction.changes, infos}; + + return CodeFixActionInfo {codeActionInfo, codeFixAction.fixName, codeFixAction.fixId, + codeFixAction.fixAllDescription}; +} + +CombinedCodeActionsInfo CreateCombinedCodeActionsInfo(CombinedCodeActions &combinedCodeActions) +{ + auto infos = CreateInstallPackageActionInfos(combinedCodeActions.commands); + + return CombinedCodeActionsInfo {combinedCodeActions.changes, infos}; +} + +std::vector GetCodeFixesAtPositionImpl(es2panda_Context *context, size_t startPosition, + size_t endPosition, std::vector &errorCodes, + CodeFixOptions &codeFixOptions) +{ + TextSpan textspan = TextSpan(startPosition, endPosition); + std::vector actions; + auto formatContext = GetFormatContext(codeFixOptions.options); + + for (auto errorCode : errorCodes) { + if (codeFixOptions.token.IsCancellationRequested()) { + return actions; + } + + TextChangesContext textChangesContext {LanguageServiceHost(), formatContext, codeFixOptions.preferences}; + CodeFixContextBase codeFixContextBase {textChangesContext, context, codeFixOptions.token}; + CodeFixContext codeFixContent {codeFixContextBase, errorCode, textspan}; + + auto fixes = CodeFixProvider::Instance().GetFixes(codeFixContent); + for (auto fix : fixes) { + auto codeFixes = CreateCodeFixActionInfo(fix); + actions.push_back(codeFixes); + } + } + + return actions; +} + +CombinedCodeActionsInfo GetCombinedCodeFixImpl(es2panda_Context *context, const std::string &fixId, + CodeFixOptions &codeFixOptions) +{ + auto formatContext = GetFormatContext(codeFixOptions.options); + TextChangesContext textChangesContext {LanguageServiceHost(), formatContext, codeFixOptions.preferences}; + CodeFixContextBase codeFixContextBase {textChangesContext, context, codeFixOptions.token}; + CodeFixAllContext codeFixAllContent {codeFixContextBase, fixId}; + + auto fixes = CodeFixProvider::Instance().GetAllFixes(codeFixAllContent); + + return CreateCombinedCodeActionsInfo(fixes); +} + } // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/isolated_declaration.cpp b/ets2panda/lsp/src/isolated_declaration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..621b219c4125ce3b7a5cb26f28880366b63e10e5 --- /dev/null +++ b/ets2panda/lsp/src/isolated_declaration.cpp @@ -0,0 +1,354 @@ +/* + * 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 "checker/ETSchecker.h" +#include "checker/types/ets/etsFunctionType.h" +#include "isolated_declaration.h" +#include "compiler/lowering/util.h" +#include "ir/astNode.h" +#include "ir/base/classProperty.h" +#include "ir/base/methodDefinition.h" +#include "ir/base/scriptFunction.h" +#include "ir/ets/etsNewClassInstanceExpression.h" + +namespace ark::es2panda::lsp { +namespace { +constexpr std::array STRING_TYPE_ARRAY = {"Char", "String"}; +constexpr std::array NUMBER_TYPE_ARRAY = {"Long", "Float", "Double", "Byte", + "Short", "Int", "Number"}; + +const std::unordered_set &GetStringTypes() +{ + static const std::unordered_set STRING_TYPES(std::begin(STRING_TYPE_ARRAY), + std::end(STRING_TYPE_ARRAY)); + return STRING_TYPES; +} + +const std::unordered_set &GetNumberTypes() +{ + static const std::unordered_set NUMBER_TYPES(std::begin(NUMBER_TYPE_ARRAY), + std::end(NUMBER_TYPE_ARRAY)); + return NUMBER_TYPES; +} +} // namespace + +std::optional GenReturnTypeStr(const checker::Type *checkerType, checker::ETSChecker *checker); +std::optional GenUnionType(const checker::ETSUnionType *unionType, checker::ETSChecker *checker, + const char splitChar); + +template +std::vector FilterUnionTypes(const ArenaVector &originTypes, checker::ETSChecker *checker) +{ + if (originTypes.empty()) { + return {}; + } + bool hasNumber = false; + bool hasString = false; + std::vector filteredTypes; + for (auto originType : originTypes) { + std::string typeStr = originType->ToString(); + if constexpr (std::is_same_v) { + if (originType->IsTSThisType()) { + filteredTypes.push_back(originType); + continue; + } + typeStr = originType->GetType(checker)->ToString(); + typeStr[0] = std::toupper(typeStr[0]); + } + if (GetStringTypes().count(typeStr) != 0U) { + if (hasString) { + continue; + } + hasString = true; + } else if (GetNumberTypes().count(typeStr) != 0U) { + if (hasNumber) { + continue; + } + hasNumber = true; + } + filteredTypes.push_back(originType); + } + return filteredTypes; +} + +std::optional HandleSpecificObjectTypes(const checker::ETSObjectType *objectType, + [[maybe_unused]] checker::ETSChecker *checker) +{ + if (objectType->IsETSStringType()) { + return "string"; + } + if (objectType->IsETSBigIntType()) { + return "bigint"; + } + if (objectType->IsETSUnboxableObject()) { + return "number"; + } + return std::nullopt; +} + +std::optional GenObjectType(const checker::ETSObjectType *objectType, checker::ETSChecker *checker) +{ + if (auto specificTypeStr = HandleSpecificObjectTypes(objectType, checker); specificTypeStr.has_value()) { + return specificTypeStr.value(); + } + std::string typeStr = objectType->Name().Mutf8(); + if (typeStr == "Exception" || typeStr == "NullPointerError") { + return "Error"; + } + if (typeStr == "Array") { + const auto &typeArgs = objectType->TypeArguments(); + if (typeArgs.empty()) { + return std::nullopt; + } + if (typeArgs[0]->IsETSUnionType()) { + auto unionTypeStr = GenUnionType(typeArgs[0]->AsETSUnionType(), checker, ','); + auto tupleTypeStr = std::string("["); + if (unionTypeStr.has_value()) { + tupleTypeStr += unionTypeStr.value(); + } else { + return std::nullopt; + } + tupleTypeStr += "]"; + return tupleTypeStr; + } + + if (auto elementTypeStr = GenReturnTypeStr(typeArgs[0], checker); elementTypeStr.has_value()) { + return elementTypeStr.value() + "[]"; + } + + return std::nullopt; + } + if (size_t partialPos = typeStr.find("$partial"); partialPos != std::string::npos) { + return "Partial<" + typeStr.substr(0, partialPos) + ">"; + } + return typeStr; +} + +std::optional HandleObjectType(const checker::Type *checkerType, checker::ETSChecker *checker) +{ + std::string typeStr = checkerType->ToString(); + if (typeStr == "Boolean") { + return "boolean"; + } + if (GetStringTypes().count(typeStr) != 0U) { + return "string"; + } + if (GetNumberTypes().count(typeStr) != 0U) { + return "number"; + } + if (typeStr == "BigInt") { + return "bigint"; + } + return GenObjectType(checkerType->AsETSObjectType(), checker); +} + +std::optional GenUnionType(const checker::ETSUnionType *unionType, checker::ETSChecker *checker, + const char splitChar = '|') +{ + auto originTypes = FilterUnionTypes(unionType->ConstituentTypes(), checker); + if (originTypes.empty()) { + return std::nullopt; + } + auto unionTypeStr = std::string(); + for (size_t i = 0; i < originTypes.size(); ++i) { + auto elementTypeStr = GenReturnTypeStr(originTypes[i], checker); + if (!elementTypeStr.has_value()) { + return std::nullopt; + } + if (i == 0) { + unionTypeStr += elementTypeStr.value(); + } else { + if (splitChar == '|') { + unionTypeStr += " | " + elementTypeStr.value(); + } else if (splitChar == ',') { + unionTypeStr += ", " + elementTypeStr.value(); + } + } + } + return unionTypeStr; +} + +std::optional HandleArrayType(const checker::Type *checkerType, checker::ETSChecker *checker) +{ + auto arrayTypeStr = std::string(); + const auto *elementType = checkerType->AsETSArrayType()->ElementType(); + bool needParentheses = elementType->IsETSUnionType() || elementType->IsETSFunctionType(); + if (needParentheses) { + if (auto elementTypeStr = GenReturnTypeStr(elementType, checker); elementTypeStr.has_value()) { + arrayTypeStr += "(" + elementTypeStr.value() + ")"; + } + } else { + if (auto elementTypeStr = GenReturnTypeStr(elementType, checker); elementTypeStr.has_value()) { + arrayTypeStr += elementTypeStr.value(); + } + } + arrayTypeStr += "[]"; + return arrayTypeStr; +} + +std::optional HandleETSSpecificTypes(const checker::Type *checkerType, checker::ETSChecker *checker) +{ + switch (checker::ETSChecker::ETSType(checkerType)) { + case checker::TypeFlag::ETS_VOID: + case checker::TypeFlag::ETS_NULL: + case checker::TypeFlag::ETS_UNDEFINED: + case checker::TypeFlag::ETS_BOOLEAN: + case checker::TypeFlag::ETS_TYPE_PARAMETER: + case checker::TypeFlag::ETS_NONNULLISH: + case checker::TypeFlag::ETS_PARTIAL_TYPE_PARAMETER: + case checker::TypeFlag::ETS_NEVER: + case checker::TypeFlag::ETS_READONLY: + return checkerType->ToString(); + + case checker::TypeFlag::ETS_OBJECT: + case checker::TypeFlag::ETS_DYNAMIC_TYPE: + return HandleObjectType(checkerType, checker); + + case checker::TypeFlag::ETS_ARRAY: + return HandleArrayType(checkerType, checker); + + case checker::TypeFlag::ETS_UNION: + return GenUnionType(checkerType->AsETSUnionType(), checker); + default: + return std::nullopt; + } + return std::nullopt; +} + +std::optional HandleBasicTypes(const checker::Type *checkerType) +{ + if (checkerType->IsETSEnumType()) { + return checkerType->ToString(); + } + if (checkerType->HasTypeFlag(checker::TypeFlag::CHAR)) { + return "string"; + } + if (checkerType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + return "number"; + } + return std::nullopt; +} + +std::optional GenReturnTypeStr(const checker::Type *checkerType, checker::ETSChecker *checker) +{ + if (checkerType == nullptr) { + return std::nullopt; + } + + if (auto basicTypeStr = HandleBasicTypes(checkerType); basicTypeStr.has_value()) { + return basicTypeStr.value(); + } + + if (checkerType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + return "number"; + } + if (checkerType->IsETSStringEnumType()) { + return "string"; + } + + if (auto specificTypeStr = HandleETSSpecificTypes(checkerType, checker); specificTypeStr.has_value()) { + return specificTypeStr.value(); + } + return std::nullopt; +} + +std::string GetReturnTypeStr(const checker::Type *checkerType, checker::ETSChecker *checker) +{ + if (auto typeStr = GenReturnTypeStr(checkerType, checker); typeStr.has_value()) { + return typeStr.value(); + } + return "void"; +} + +const checker::Signature *GetFuncSignature(const checker::ETSFunctionType *etsFunctionType, + const ir::MethodDefinition *methodDef) +{ + if (etsFunctionType->IsETSArrowType()) { + return etsFunctionType->ArrowSignature(); + } + if (methodDef != nullptr) { + return methodDef->Function()->Signature(); + } + return etsFunctionType->CallSignatures()[0]; +} + +std::optional GetTextChange(ir::ScriptFunction *func, std::string &typeStr, parser::Program *program) +{ + ES2PANDA_ASSERT(func != nullptr); + + auto returnTypeAnnotation = func->ReturnTypeAnnotation(); + if (returnTypeAnnotation != nullptr) { + auto start = returnTypeAnnotation->Start().index; + auto end = returnTypeAnnotation->End().index; + return TextChange {TextSpan(start, end - start), typeStr}; + } + // try to find the position of ')' before the function body + auto bodyStart = func->Body()->Start().index; + auto sourceCode = program->SourceCode().Utf8(); + auto i = bodyStart; + for (; i >= func->Start().index; --i) { + if (i >= 1 && sourceCode[i - 1] == ')') { + break; + } + } + // set the length to 0, meaning we should insert the text instead of replacing + return TextChange {TextSpan(i, 0), ": " + typeStr}; +} + +std::optional ProcessMethodDefinition(ir::MethodDefinition *method, checker::ETSChecker *checker, + parser::Program *program) +{ + ES2PANDA_ASSERT(method != nullptr); + + auto signature = GetFuncSignature(method->TsType()->AsETSFunctionType(), method); + auto typeStr = GetReturnTypeStr(signature->ReturnType(), checker); + + auto textChange = GetTextChange(method->Function(), typeStr, program); + return textChange; +} + +std::optional ProcessArrowFunction(ir::ArrowFunctionExpression *arrowFunc, checker::ETSChecker *checker, + parser::Program *program) +{ + ES2PANDA_ASSERT(arrowFunc != nullptr); + + auto signature = arrowFunc->Function()->Signature(); + auto typeStr = GetReturnTypeStr(signature->ReturnType(), checker); + + auto textChange = GetTextChange(arrowFunc->Function(), typeStr, program); + return textChange; +} + +std::optional ProcessIdentifier(ir::Identifier *identifier, checker::ETSChecker *checker, + parser::Program *program) +{ + ES2PANDA_ASSERT(identifier != nullptr); + + auto decl = compiler::DeclarationFromIdentifier(identifier); + if (decl != nullptr && decl->IsMethodDefinition()) { + return ProcessMethodDefinition(decl->AsMethodDefinition(), checker, program); + } + if (decl != nullptr && decl->IsArrowFunctionExpression()) { + return ProcessArrowFunction(decl->AsArrowFunctionExpression(), checker, program); + } + if (decl != nullptr && decl->IsClassProperty()) { + auto propertyValue = decl->AsClassProperty()->Value(); + if (propertyValue != nullptr && propertyValue->IsArrowFunctionExpression()) { + return ProcessArrowFunction(propertyValue->AsArrowFunctionExpression(), checker, program); + } + } + return std::nullopt; +} +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/navigate_to.cpp b/ets2panda/lsp/src/navigate_to.cpp new file mode 100644 index 0000000000000000000000000000000000000000..831077d26d30a06b633105630298054bdc5ac00c --- /dev/null +++ b/ets2panda/lsp/src/navigate_to.cpp @@ -0,0 +1,163 @@ +/** + * 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 "navigate_to.h" +#include "quick_info.h" +#include "internal_api.h" +#include "lsp/include/get_adjusted_location.h" +#include "public/public.h" + +namespace ark::es2panda::lsp { + +PatternMatcher::PatternMatcher(const std::string &pattern, bool isCaseSensitive) + : pattern_(pattern), isCaseSensitive_(isCaseSensitive) +{ + try { + regexPattern_ = isCaseSensitive ? std::regex(pattern) : std::regex(pattern, std::regex_constants::icase); + } catch (const std::regex_error &) { + regexPattern_ = std::nullopt; + } +} + +bool PatternMatcher::IsPatternValid() const +{ + return regexPattern_.has_value(); +} + +bool PatternMatcher::MatchesExact(const std::string &candidate) const +{ + return regexPattern_ && std::regex_match(candidate, *regexPattern_); +} + +bool PatternMatcher::MatchesPrefix(const std::string &candidate) const +{ + if (candidate.size() < pattern_.size()) { + return false; + } + + for (size_t i = 0; i < pattern_.size(); ++i) { + char a = pattern_[i]; + char b = candidate[i]; + if (isCaseSensitive_) { + if (a != b) { + return false; + } + } else { + if (std::tolower(a) != std::tolower(b)) { + return false; + } + } + } + + return true; +} + +bool PatternMatcher::MatchesSubstring(const std::string &candidate) const +{ + return regexPattern_ && std::regex_search(candidate, *regexPattern_); +} + +MatchKind DetermineMatchKind(const std::string &candidate, const PatternMatcher &matcher) +{ + if (matcher.MatchesExact(candidate)) { + return MatchKind::EXACT; + } + if (matcher.MatchesPrefix(candidate)) { + return MatchKind::PREFIX; + } + if (matcher.MatchesSubstring(candidate)) { + return MatchKind::SUBSTRING; + } + return MatchKind::NONE; +} + +// improve get declarations correct and better +std::vector GetItemsFromNamedDeclaration(es2panda_Context *context, const SourceFile &file, + const PatternMatcher &matcher) +{ + std::vector items; + auto filePath = std::string {file.filePath}; + auto fileContent = std::string {file.source}; + auto ctx = reinterpret_cast(context); + auto ast = reinterpret_cast(ctx->parserProgram->Ast()); + + auto children = GetChildren(ast, ctx->allocator); + + for (const auto child : children) { + if (child->IsIdentifier()) { + auto name = child->AsIdentifier()->Name(); + auto matchKind = DetermineMatchKind(std::string(name), matcher); + if (matchKind != MatchKind::NONE) { + auto nodeType = child->Type(); + auto containerId = GetContainerNode(child); + auto containerName = GetIdentifierName(containerId); + auto containerType = containerId->Type(); + items.push_back({std::string(name), ToString(nodeType), matchKind, true, filePath, containerName, + ToString(containerType)}); + } + } + } + + return items; +} + +// Helper: tries to emit a single item, returns false if limit reached +static bool TryEmitItem(const NavigateToItem &item, size_t &remaining, + std::set> &seenPairs, std::vector &results) +{ + if (remaining == 0) { + return false; + } + auto key = std::make_pair(item.name, item.containerName); + if (!seenPairs.insert(key).second) { + return true; // duplicate, but still under limit + } + results.emplace_back(item); + --remaining; + return remaining > 0; +} + +std::vector GetNavigateToItems(es2panda_Context *context, const std::vector &srcFiles, + size_t maxResultCount, const std::string &searchValue, + bool isCaseSensitive) +{ + static std::unordered_map totalEmitted; + size_t &emittedSoFar = totalEmitted[searchValue]; + + std::vector results; + std::set> seenPairs; + PatternMatcher matcher(searchValue, isCaseSensitive); + + if (!matcher.IsPatternValid() || emittedSoFar >= maxResultCount) { + return results; + } + + size_t remaining = maxResultCount - emittedSoFar; + + for (const auto &file : srcFiles) { + auto items = GetItemsFromNamedDeclaration(context, file, matcher); + for (const auto &item : items) { + if (!TryEmitItem(item, remaining, seenPairs, results)) { + emittedSoFar = maxResultCount; + return results; + } + } + } + + emittedSoFar = maxResultCount - remaining; + return results; +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/organize_imports.cpp b/ets2panda/lsp/src/organize_imports.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aacf38ab477d6ec4b92d514bbd871f2915afaf18 --- /dev/null +++ b/ets2panda/lsp/src/organize_imports.cpp @@ -0,0 +1,223 @@ +/** + * 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 +#include +#include +#include + +#include "public/public.h" +#include "lsp/include/api.h" +#include "lsp/include/organize_imports.h" + +namespace ark::es2panda::lsp { + +bool IsImportUsed(es2panda_Context *ctx, const ImportSpecifier &spec) +{ + auto *context = reinterpret_cast(ctx); + auto *ast = context->parserProgram->Ast(); + bool found = false; + + ast->FindChild([&](ir::AstNode *node) { + if (node->IsETSImportDeclaration() || node->IsImportSpecifier()) { + return false; + } + + if (spec.type == ImportType::NAMESPACE) { + if (node->IsMemberExpression()) { + auto *member = node->AsMemberExpression(); + found = member->Object()->IsIdentifier() && + (std::string(member->Object()->AsIdentifier()->Name()) == spec.localName); + return found; + } + return false; + } + + if (!node->IsIdentifier() || std::string(node->AsIdentifier()->Name()) != spec.localName) { + return false; + } + + auto *parent = node->Parent(); + bool isProperty = + parent != nullptr && parent->IsMemberExpression() && (parent->AsMemberExpression()->Property() == node); + bool isImportSpecifier = parent != nullptr && parent->IsImportSpecifier(); + if (!isProperty && !isImportSpecifier) { + found = true; + return true; + } + return false; + }); + + return found; +} + +void ProcessImportSpecifier(ir::AstNode *spec, bool isTypeOnly, ImportInfo &info) +{ + if (!spec->IsImportSpecifier() && !spec->IsImportDefaultSpecifier() && !spec->IsImportNamespaceSpecifier()) { + return; + } + + ImportSpecifier specInfo {}; + ir::Identifier *local = nullptr; + if (spec->IsImportSpecifier()) { + auto *importSpec = spec->AsImportSpecifier(); + local = importSpec->Local(); + auto *imported = importSpec->Imported(); + specInfo.importedName = imported != nullptr ? std::string(imported->Name()) : std::string(local->Name()); + specInfo.type = isTypeOnly ? ImportType::TYPE_ONLY : ImportType::NORMAL; + } else if (spec->IsImportDefaultSpecifier()) { + auto *defaultSpec = spec->AsImportDefaultSpecifier(); + local = defaultSpec->Local(); + specInfo.importedName = std::string(local->Name()); + specInfo.type = ImportType::DEFAULT; + } else { + auto *nsSpec = spec->AsImportNamespaceSpecifier(); + local = nsSpec->Local(); + specInfo.importedName = std::string(local->Name()); + specInfo.type = ImportType::NAMESPACE; + } + + if (local == nullptr) { + return; + } + + specInfo.localName = std::string(local->Name()); + specInfo.start = local->Start().index; + specInfo.length = local->End().index - local->Start().index; + + info.namedImports.push_back(specInfo); +} + +void CollectImports(es2panda_Context *context, std::vector &imports) +{ + auto *ctx = reinterpret_cast(context); + if (ctx == nullptr || ctx->parserProgram == nullptr || ctx->parserProgram->Ast() == nullptr) { + return; + } + + std::vector importsNode; + ctx->parserProgram->Ast()->Iterate([&importsNode](ir::AstNode *node) { + if (node->IsETSImportDeclaration()) { + importsNode.push_back(node); + } + }); + + std::sort(importsNode.begin(), importsNode.end(), + [](ir::AstNode *a, ir::AstNode *b) { return a->Start().index < b->Start().index; }); + + for (auto *importNode : importsNode) { + auto *importDecl = importNode->AsETSImportDeclaration(); + if (importDecl == nullptr || importDecl->Source() == nullptr) { + continue; + } + + auto *declInfo = static_cast(importNode); + if (declInfo == nullptr) { + continue; + } + + ImportInfo info {}; + info.moduleName = std::string(importDecl->Source()->Str()); + + bool isTypeOnly = declInfo->IsTypeKind(); + auto &specifiers = importDecl->Specifiers(); + + for (auto *spec : specifiers) { + ProcessImportSpecifier(spec, isTypeOnly, info); + } + + info.startIndex = importDecl->Start().index; + info.endIndex = importDecl->End().index; + imports.push_back(std::move(info)); + } +} + +void RemoveUnusedImports(std::vector &imports, es2panda_Context *ctx) +{ + for (auto &import : imports) { + std::vector used; + + for (auto &namedImport : import.namedImports) { + if (IsImportUsed(ctx, namedImport)) { + used.push_back(namedImport); + } + } + + import.namedImports = used; + } +} + +std::vector GenerateTextChanges(const std::vector &imports) +{ + if (imports.empty()) { + return {}; + } + + size_t start = imports.front().startIndex; + size_t end = imports.back().endIndex; + std::ostringstream oss; + + auto generateImportBlock = [](const ImportInfo &imp, std::ostringstream &osst, const std::string &prefix) { + osst << prefix; + size_t index = 0; + for (auto &namedImport : imp.namedImports) { + const auto &spec = namedImport; + if (spec.importedName != spec.localName) { + osst << spec.importedName << " as " << spec.localName; + } else { + osst << spec.localName; + } + if (index + 1 < imp.namedImports.size()) { + osst << ", "; + } + } + osst << " } from \"" << imp.moduleName << "\";\n"; + index++; + }; + + for (const auto &imp : imports) { + if (imp.namedImports.empty()) { + continue; + } + + switch (imp.namedImports[0].type) { + case ImportType::NORMAL: + generateImportBlock(imp, oss, "import { "); + break; + case ImportType::DEFAULT: + oss << "import " << imp.namedImports[0].localName << " from \"" << imp.moduleName << "\";\n"; + break; + case ImportType::NAMESPACE: + oss << "import * as " << imp.namedImports[0].localName << " from \"" << imp.moduleName << "\";\n"; + break; + case ImportType::TYPE_ONLY: + generateImportBlock(imp, oss, "import type { "); + break; + } + } + + return {TextChange(TextSpan(start, end - start), oss.str())}; +} + +std::vector OrganizeImports::Organize(es2panda_Context *context, const std::string &fileName) +{ + std::vector imports; + + CollectImports(context, imports); + RemoveUnusedImports(imports, context); + + return {FileTextChanges(fileName, GenerateTextChanges(imports))}; +} +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/quick_info.cpp b/ets2panda/lsp/src/quick_info.cpp index 71fb0b4708a80e156ae49b5361d7c63fc900658f..1205f9ac5b2ce873ff273ec01bd485d9ce88a415 100644 --- a/ets2panda/lsp/src/quick_info.cpp +++ b/ets2panda/lsp/src/quick_info.cpp @@ -264,7 +264,6 @@ std::string ModifiersToString(ir::ModifierFlags flags) addModifier(ir::ModifierFlags::GETTER, "getter"); addModifier(ir::ModifierFlags::SETTER, "setter"); addModifier(ir::ModifierFlags::DEFAULT_EXPORT, "default_export"); - addModifier(ir::ModifierFlags::EXPORT_TYPE, "export_type"); addModifier(ir::ModifierFlags::SUPER_OWNER, "super_owner"); addModifier(ir::ModifierFlags::ANNOTATION_DECLARATION, "annotation_declaration"); addModifier(ir::ModifierFlags::ANNOTATION_USAGE, "annotation_usage"); @@ -355,86 +354,6 @@ std::string GetNodeKind(ir::AstNode *node) return ""; } -SymbolDisplayPart CreatePunctuation(std::string punc) -{ - return SymbolDisplayPart(std::move(punc), "punctuation"); -} - -SymbolDisplayPart CreateKeyword(std::string keyword) -{ - return SymbolDisplayPart(std::move(keyword), "keyword"); -} - -SymbolDisplayPart CreateSpace() -{ - return SymbolDisplayPart(" ", "space"); -} - -SymbolDisplayPart CreateText(std::string text) -{ - return SymbolDisplayPart(std::move(text), "text"); -} - -SymbolDisplayPart CreateClassName(std::string className) -{ - return SymbolDisplayPart(std::move(className), "className"); -} - -SymbolDisplayPart CreateFunctionName(std::string functionName) -{ - return SymbolDisplayPart(std::move(functionName), "functionName"); -} - -SymbolDisplayPart CreateTypeName(std::string typeName) -{ - return SymbolDisplayPart(std::move(typeName), "typeName"); -} - -SymbolDisplayPart CreateEnumName(std::string enumName) -{ - return SymbolDisplayPart(std::move(enumName), "enumName"); -} - -SymbolDisplayPart CreateEnumMember(std::string enumMember) -{ - return SymbolDisplayPart(std::move(enumMember), "enumMember"); -} - -SymbolDisplayPart CreateInterface(std::string interface) -{ - return SymbolDisplayPart(std::move(interface), "interface"); -} - -SymbolDisplayPart CreateTypeParameter(std::string typeParameter) -{ - return SymbolDisplayPart(std::move(typeParameter), "typeParameter"); -} - -SymbolDisplayPart CreateFunctionParameter(std::string functionParameter) -{ - return SymbolDisplayPart(std::move(functionParameter), "functionParameter"); -} - -SymbolDisplayPart CreateOperator(std::string oper) -{ - return SymbolDisplayPart(std::move(oper), "operator"); -} - -SymbolDisplayPart CreateReturnType(std::string returnType) -{ - return SymbolDisplayPart(std::move(returnType), "returnType"); -} - -SymbolDisplayPart CreateProperty(std::string property) -{ - return SymbolDisplayPart(std::move(property), "property"); -} - -SymbolDisplayPart CreateNamespace(std::string name) -{ - return SymbolDisplayPart(std::move(name), "namespace"); -} - std::string TransDisplayPartsToStr(const std::vector &displayParts) { std::stringstream ss; @@ -645,7 +564,11 @@ std::vector CreateDisplayForClass(ir::AstNode *node) displayParts.emplace_back(CreateClassName(GetNameFromClassDeclaration(node))); } else { // class definition - displayParts.emplace_back(CreateKeyword("class")); + if (node->AsClassDefinition()->OrigEnumDecl() != nullptr) { + displayParts.emplace_back(CreateKeyword("enum")); + } else { + displayParts.emplace_back(CreateKeyword("class")); + } displayParts.emplace_back(CreateSpace()); displayParts.emplace_back(CreateClassName(GetNameFromClassDefinition(node))); } diff --git a/ets2panda/lsp/src/refactors/convert_function.cpp b/ets2panda/lsp/src/refactors/convert_function.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5996360f3b097fb797942c414311021f49e59a3 --- /dev/null +++ b/ets2panda/lsp/src/refactors/convert_function.cpp @@ -0,0 +1,52 @@ +/** + * 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 +#include "refactors/convert_function.h" +#include "compiler/lowering/util.h" +#include "internal_api.h" + +namespace ark::es2panda::lsp { +ConvertFunctionRefactor::ConvertFunctionRefactor() +{ + AddKind(std::string(TO_ANONYMOUS_FUNCTION_ACTION.kind)); + AddKind(std::string(TO_NAMED_FUNCTION_ACTION.kind)); + AddKind(std::string(TO_ARROW_FUNCTION_ACTION.kind)); +} + +ApplicableRefactorInfo ConvertFunctionRefactor::GetAvailableActions(es2panda_Context *context, std::string kind, + size_t position) +{ + ApplicableRefactorInfo res; + if (TO_NAMED_FUNCTION_ACTION.kind.substr(0, kind.length()) != kind) { + return res; + } + auto node = GetTouchingToken(context, position, false); + if (node == nullptr || !node->IsIdentifier()) { + return res; + } + auto nodeDecl = compiler::DeclarationFromIdentifier(node->AsIdentifier()); + if (nodeDecl->IsClassProperty() && nodeDecl->AsClassProperty()->Value()->IsArrowFunctionExpression()) { + res.name = refactor_name::CONVERT_FUNCTION_REFACTOR_NAME; + res.description = refactor_description::CONVERT_FUNCTION_REFACTOR_DESC; + res.action.kind = std::string(TO_NAMED_FUNCTION_ACTION.kind); + res.action.name = std::string(TO_NAMED_FUNCTION_ACTION.name); + res.action.description = std::string(TO_NAMED_FUNCTION_ACTION.description); + return res; + } + + return res; +} +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/register_code_fix/add_missing_declare_property.cpp b/ets2panda/lsp/src/register_code_fix/add_missing_declare_property.cpp new file mode 100644 index 0000000000000000000000000000000000000000..600252a8b0a4769ae7a4b05ac7b6069c80eda1a1 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/add_missing_declare_property.cpp @@ -0,0 +1,93 @@ +/** + * 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/register_code_fix/add_missing_declare_property.h" +#include +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { + +const int G_ADD_MISSING_DECLARE_PROPERTY_CODE = 1001; // change this to the error code you want to handle + +void MakeChange(ChangeTracker changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes) +{ + const auto token = GetTouchingToken(context, pos, false); + if (token == nullptr || !token->IsIdentifier()) { + return; + } + const auto declaration = token->Parent(); + if (declaration->IsProperty()) { + fixedNodes.push_back(declaration); + changeTracker.InsertModifierBefore(context, token, declaration); + } +} + +std::vector GetCodeActionsToAddMissingDeclareOnProperty(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, 3, fixedNodes); }); + return fileTextChanges; +} + +AddMissingDeclareProperty::AddMissingDeclareProperty() +{ + const char *addMissingDeclarationPropertyId = "AddMissingDeclareProperty"; + SetErrorCodes({G_ADD_MISSING_DECLARE_PROPERTY_CODE}); + SetFixIds({addMissingDeclarationPropertyId}); +} + +std::vector AddMissingDeclareProperty::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToAddMissingDeclareOnProperty(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = "Fix"; + codeAction.description = "Fix Description"; + codeAction.changes = changes; + codeAction.fixId = "AddMissingDeclareProperty"; + codeAction.fixAllDescription = "Fix All Description"; + InstallPackageAction codeActionCommand; + codeActionCommand.file = "addMissingDeclareProperty.ets"; + codeActionCommand.packageName = "dummy-package"; + codeAction.commands.push_back(codeActionCommand); + returnedActions.push_back(codeAction); + } + return returnedActions; +} + +CombinedCodeActions AddMissingDeclareProperty::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + std::vector fixedNodes; + CodeFixProvider provider; + + const auto changes = provider.CodeFixAll(codeFixAll, GetErrorCodes(), + [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + MakeChange(tracker, codeFixAll.context, diag.start, fixedNodes); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + return combinedCodeActions; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_addMissingDeclareProperty("AddMissingDeclareProperty"); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/fix_missing_call_parantheses.cpp b/ets2panda/lsp/src/register_code_fix/fix_missing_call_parantheses.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6c414f7f7e86bbdbd5b864d4dafffd1cf14d5f1c --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_missing_call_parantheses.cpp @@ -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. + */ + +#include "lsp/include/register_code_fix/fix_missing_call_parantheses.h" +#include +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { +const int G_FIX_MISSING_CALL_PARANTHESES_CODE = 1002; // change this to the error code you want to handle + +FixMissingCallParantheses::FixMissingCallParantheses() +{ + const char *fixMissingCallParanthesesId = "FixMissingCallParantheses"; + + SetErrorCodes({G_FIX_MISSING_CALL_PARANTHESES_CODE}); // change this to the error code you want to handle + SetFixIds({fixMissingCallParanthesesId}); +} + +std::vector FixMissingCallParantheses::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + if (context.errorCode == G_FIX_MISSING_CALL_PARANTHESES_CODE) { + } + return returnedActions; +} + +CombinedCodeActions FixMissingCallParantheses::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + CombinedCodeActions combinedCodeActions; + if (codeFixAll.fixId == "FixMissingCallParantheses") { + } + + return combinedCodeActions; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_fixMissingCallParantheses("FixMissingCallParantheses"); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/fix_nan_equality.cpp b/ets2panda/lsp/src/register_code_fix/fix_nan_equality.cpp new file mode 100644 index 0000000000000000000000000000000000000000..11080e91fb7ddc088fbeef974c9bc786ae1c7abd --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/fix_nan_equality.cpp @@ -0,0 +1,125 @@ + +/** + * 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/register_code_fix/fix_nan_equality.h" +#include +#include +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { + +const int G_FIX_NAN_EQUALITY_CODE = 1003; // change this to the error code you want to handle + +void FixNaNEquality::MakeChangeForNaNEquality(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr || !token->IsBinaryExpression()) { + return; + } + + const auto *binaryExpr = token->AsBinaryExpression(); + if (binaryExpr->Left() == nullptr || binaryExpr->Right() == nullptr) { + return; + } + + auto isLeftNaN = binaryExpr->Left()->IsIdentifier() && binaryExpr->Left()->AsIdentifier()->Name() == "NaN"; + auto isRightNaN = binaryExpr->Right()->IsIdentifier() && binaryExpr->Right()->AsIdentifier()->Name() == "NaN"; + if (!isLeftNaN && !isRightNaN) { + return; + } + + auto *expr = isLeftNaN ? binaryExpr->Right() : binaryExpr->Left(); + std::string exprText = expr->ToString(); + std::string newText; + + if (binaryExpr->Type() == ir::AstNodeType::TS_IMPORT_EQUALS_DECLARATION) { + newText = "Number.isNaN(" + exprText + ")"; + } else { + return; + } + + // auto *ctx = reinterpret_cast(context); + + fixedNodes.push_back(const_cast(token)); + // ark::es2panda::ir::AstNode *bClone = token->Clone(ctx->allocator, nullptr); + + ChangeNodeOptions changeNodeOptions; + changeNodeOptions.insertNodeOptions->prefix = ""; + changeNodeOptions.insertNodeOptions->suffix = ""; + changeNodeOptions.insertNodeOptions->delta = 0; + + ark::es2panda::lsp::ChangeNodeOptions options = {}; + changeTracker.ReplaceNode(context, token, token, changeNodeOptions); +} + +std::vector FixNaNEquality::GetCodeActionsToFixNaNEquality(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + std::vector fixedNodes; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChangeForNaNEquality(tracker, context.context, context.span.start, fixedNodes); + }); + + return fileTextChanges; +} + +FixNaNEquality::FixNaNEquality() +{ + const char *fixNanEqualityId = "FixNaNEquality"; + SetErrorCodes({G_FIX_NAN_EQUALITY_CODE}); // "NaN comparison" error code + SetFixIds({fixNanEqualityId}); // "fixNaNEquality" fix ID +} + +std::vector FixNaNEquality::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToFixNaNEquality(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = "fixNaNEquality"; + codeAction.description = "Use Number.isNaN instead of comparing with NaN"; + codeAction.changes = changes; + codeAction.fixId = "FixNaNEquality"; + codeAction.fixAllDescription = "Replace all NaN equality comparisons"; + returnedActions.push_back(codeAction); + } + return returnedActions; +} + +CombinedCodeActions FixNaNEquality::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + const std::vector fixedNodes; + CodeFixProvider provider; + + const auto changes = provider.CodeFixAll( + codeFixAll, GetErrorCodes(), [&](ChangeTracker &tracker, const DiagnosticWithLocation &diag) { + Initializer initializer = Initializer(); + auto ctx = + initializer.CreateContext(diag.file.source.data(), ES2PANDA_STATE_CHECKED, diag.file.source.data()); + MakeChangeForNaNEquality(tracker, ctx, diag.start, const_cast &>(fixedNodes)); + initializer.DestroyContext(ctx); + }); + + CombinedCodeActions combinedCodeActions; + combinedCodeActions.changes = changes.changes; + combinedCodeActions.commands = changes.commands; + return combinedCodeActions; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_fixNaNEquality("FixNaNEquality"); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/forgetten_this_property_access.cpp b/ets2panda/lsp/src/register_code_fix/forgetten_this_property_access.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1bda5b238ae79e836cacf9dcebb4062e51f84b1 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/forgetten_this_property_access.cpp @@ -0,0 +1,51 @@ +/** + * 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/register_code_fix/forgetten_this_property_access.h" +#include +#include +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { + +const int G_FORGETTEN_THIS_PROPERTY_ACCESS_CODE = 1004; // change this to the error code you want to handle + +ForgettenThisPropertyAccess::ForgettenThisPropertyAccess() +{ + const char *forgottenThisPropertAccesId = "ForgettenThisPropertyAccess"; + SetErrorCodes({G_FORGETTEN_THIS_PROPERTY_ACCESS_CODE}); // change this to the error code you want to handle + SetFixIds({forgottenThisPropertAccesId}); +} + +std::vector ForgettenThisPropertyAccess::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + if (context.errorCode == G_FORGETTEN_THIS_PROPERTY_ACCESS_CODE) { + } + return returnedActions; +} + +CombinedCodeActions ForgettenThisPropertyAccess::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + CombinedCodeActions combinedCodeActions; + if (codeFixAll.fixId == "ForgettenThisPropertyAccess") { + } + + return combinedCodeActions; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_forgettenThisPropertyAccess("ForgettenThisPropertyAccess"); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/register_code_fix/import_fixes.cpp b/ets2panda/lsp/src/register_code_fix/import_fixes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..22a12042fa2593313171f5479dc08b3f3b78493a --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/import_fixes.cpp @@ -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. + */ + +#include "lsp/include/register_code_fix/import_fixes.h" +#include +#include +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/internal_api.h" + +namespace ark::es2panda::lsp { +const int G_IMPORT_FIXES_CODE = 1005; // change this to the error code you want to handle + +ImportFixes::ImportFixes() +{ + const char *importFixesId = "ImportFixes"; + SetErrorCodes({G_IMPORT_FIXES_CODE}); // change this to the error code you want to handle + SetFixIds({importFixesId}); +} + +std::vector ImportFixes::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + if (context.errorCode == G_IMPORT_FIXES_CODE) { + } + return returnedActions; +} + +CombinedCodeActions ImportFixes::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + CombinedCodeActions combinedCodeActions; + if (codeFixAll.fixId == "ImportFixes") { + } + + return combinedCodeActions; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_importFixes("ImportFixes"); +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/rename.cpp b/ets2panda/lsp/src/rename.cpp index 453703e9411882cc0e94d47c5bb8147147d6f4f8..e836fb4858a2e21712155eef08dd868bf3905e15 100644 --- a/ets2panda/lsp/src/rename.cpp +++ b/ets2panda/lsp/src/rename.cpp @@ -31,7 +31,7 @@ constexpr size_t QUOTE_START_OFFSET = 1; RenameInfoType GetRenameInfo(es2panda_Context *context, size_t pos) { auto ctx = reinterpret_cast(context); - auto checker = reinterpret_cast(ctx)->checker->AsETSChecker(); + auto checker = reinterpret_cast(ctx)->GetChecker()->AsETSChecker(); auto program = reinterpret_cast(ctx)->parserProgram; auto node = GetAdjustedLocation(GetTouchingPropertyName(context, pos), true, ctx->allocator); if (node.has_value() && NodeIsEligibleForRename(node.value())) { @@ -337,12 +337,10 @@ ir::AstNode *GetNonAssignedNameOfDeclaration(ir::AstNode *node) return node->AsIdentifier(); } if (node->Type() == ir::AstNodeType::CALL_EXPRESSION || node->Type() == ir::AstNodeType::BINARY_EXPRESSION) { - if (node->AsBinaryExpression()->IsExportedType() || node->AsBinaryExpression()->IsTSThisType() || - node->AsBinaryExpression()->IsProperty()) { + if (node->AsBinaryExpression()->IsTSThisType() || node->AsBinaryExpression()->IsProperty()) { return node->AsBinaryExpression(); } - if (node->AsCallExpression()->IsExportedType() || node->AsCallExpression()->IsTSThisType() || - node->AsCallExpression()->IsProperty()) { + if (node->AsCallExpression()->IsTSThisType() || node->AsCallExpression()->IsProperty()) { return node->AsCallExpression(); } return nullptr; diff --git a/ets2panda/lsp/src/script_element_kind.cpp b/ets2panda/lsp/src/script_element_kind.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eba06f44217d8236a01f0acb81d12f7602847a4b --- /dev/null +++ b/ets2panda/lsp/src/script_element_kind.cpp @@ -0,0 +1,312 @@ +/** + * 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 "internal_api.h" +#include "rename.h" +#include "public/public.h" +#include "script_element_kind.h" +#include "compiler/lowering/util.h" + +namespace ark::es2panda::lsp { +std::tuple GetTargetTokenKindIfETSType(ir::AstNodeType type) +{ + switch (type) { + case ir::AstNodeType::ETS_NULL_TYPE: + case ir::AstNodeType::ETS_UNDEFINED_TYPE: + case ir::AstNodeType::ETS_NEVER_TYPE: + case ir::AstNodeType::ETS_STRING_LITERAL_TYPE: + return std::make_tuple(true, CompletionEntryKind::VALUE); + case ir::AstNodeType::ETS_PRIMITIVE_TYPE: + case ir::AstNodeType::ETS_CLASS_LITERAL: + case ir::AstNodeType::ETS_UNION_TYPE: + case ir::AstNodeType::ETS_KEYOF_TYPE: + return std::make_tuple(true, CompletionEntryKind::KEYWORD); + case ir::AstNodeType::ETS_NEW_ARRAY_INSTANCE_EXPRESSION: + case ir::AstNodeType::ETS_NEW_MULTI_DIM_ARRAY_INSTANCE_EXPRESSION: + case ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION: + case ir::AstNodeType::ETS_PARAMETER_EXPRESSION: + case ir::AstNodeType::ETS_TUPLE: + return std::make_tuple(true, CompletionEntryKind::OPERATOR); + case ir::AstNodeType::ETS_FUNCTION_TYPE: + return std::make_tuple(true, CompletionEntryKind::FUNCTION); + case ir::AstNodeType::ETS_PACKAGE_DECLARATION: + case ir::AstNodeType::ETS_IMPORT_DECLARATION: + case ir::AstNodeType::ETS_MODULE: + return std::make_tuple(true, CompletionEntryKind::MODULE); + case ir::AstNodeType::ETS_TYPE_REFERENCE: + case ir::AstNodeType::ETS_TYPE_REFERENCE_PART: + return std::make_tuple(true, CompletionEntryKind::REFERENCE); + case ir::AstNodeType::ETS_WILDCARD_TYPE: + return std::make_tuple(true, CompletionEntryKind::TEXT); + default: + break; + } + return std::make_tuple(false, CompletionEntryKind::TEXT); +} + +bool IsTSParameterKind(ir::AstNodeType type) +{ + switch (type) { + case ir::AstNodeType::TS_ARRAY_TYPE: + case ir::AstNodeType::TS_UNION_TYPE: + case ir::AstNodeType::TS_INTERSECTION_TYPE: + case ir::AstNodeType::TS_LITERAL_TYPE: + case ir::AstNodeType::TS_MAPPED_TYPE: + case ir::AstNodeType::TS_THIS_TYPE: + case ir::AstNodeType::TS_TYPE_PARAMETER: + case ir::AstNodeType::TS_TYPE_PARAMETER_DECLARATION: + case ir::AstNodeType::TS_TYPE_PARAMETER_INSTANTIATION: + case ir::AstNodeType::TS_TYPE_PREDICATE: + case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: + case ir::AstNodeType::TS_TYPE_REFERENCE: + case ir::AstNodeType::TS_INDEXED_ACCESS_TYPE: + case ir::AstNodeType::TS_TUPLE_TYPE: + return true; + default: + break; + } + return false; +} + +bool IsTSMoudleKind(ir::AstNodeType type) +{ + switch (type) { + case ir::AstNodeType::TS_IMPORT_TYPE: + case ir::AstNodeType::TS_MODULE_BLOCK: + case ir::AstNodeType::TS_EXTERNAL_MODULE_REFERENCE: + case ir::AstNodeType::TS_MODULE_DECLARATION: + case ir::AstNodeType::TS_IMPORT_EQUALS_DECLARATION: + return true; + default: + break; + } + return false; +} + +std::tuple GetTargetTokenKindIfTSType(ir::AstNodeType type) +{ + auto reuslt = std::make_tuple(false, CompletionEntryKind::TEXT); + if (IsValidAncestorType(type)) { + reuslt = std::make_tuple(true, CompletionEntryKind::KEYWORD); + } else if (IsTSParameterKind(type)) { + reuslt = std::make_tuple(true, CompletionEntryKind::TYPE_PARAMETER); + } else if (IsTSMoudleKind(type)) { + reuslt = std::make_tuple(true, CompletionEntryKind::MODULE); + } + switch (type) { + case ir::AstNodeType::TS_ENUM_DECLARATION: + return std::make_tuple(true, CompletionEntryKind::ENUM); + case ir::AstNodeType::TS_ENUM_MEMBER: + return std::make_tuple(true, CompletionEntryKind::ENUM_MEMBER); + case ir::AstNodeType::TS_NON_NULL_EXPRESSION: + case ir::AstNodeType::TS_TYPE_OPERATOR: + case ir::AstNodeType::TS_AS_EXPRESSION: + return std::make_tuple(true, CompletionEntryKind::OPERATOR); + case ir::AstNodeType::TS_TYPE_LITERAL: + return std::make_tuple(true, CompletionEntryKind::VALUE); + case ir::AstNodeType::TS_PROPERTY_SIGNATURE: + return std::make_tuple(true, CompletionEntryKind::PROPERTY); + case ir::AstNodeType::TS_METHOD_SIGNATURE: + return std::make_tuple(true, CompletionEntryKind::METHOD); + case ir::AstNodeType::TS_FUNCTION_TYPE: + return std::make_tuple(true, CompletionEntryKind::FUNCTION); + case ir::AstNodeType::TS_CONSTRUCTOR_TYPE: + return std::make_tuple(true, CompletionEntryKind::CONSTRUCTOR); + case ir::AstNodeType::TS_NAMED_TUPLE_MEMBER: + return std::make_tuple(true, CompletionEntryKind::VALUE); + case ir::AstNodeType::TS_INTERFACE_DECLARATION: + case ir::AstNodeType::TS_INTERFACE_BODY: + case ir::AstNodeType::TS_INTERFACE_HERITAGE: + return std::make_tuple(true, CompletionEntryKind::INTERFACE); + case ir::AstNodeType::TS_SIGNATURE_DECLARATION: + case ir::AstNodeType::TS_PARENT_TYPE: + case ir::AstNodeType::TS_INFER_TYPE: + case ir::AstNodeType::TS_CONDITIONAL_TYPE: + case ir::AstNodeType::TS_PARAMETER_PROPERTY: + case ir::AstNodeType::TS_QUALIFIED_NAME: + case ir::AstNodeType::TS_INDEX_SIGNATURE: + case ir::AstNodeType::TS_TYPE_QUERY: + case ir::AstNodeType::TS_CLASS_IMPLEMENTS: + case ir::AstNodeType::TS_TYPE_ASSERTION: + return std::make_tuple(true, CompletionEntryKind::TEXT); + default: + break; + } + return reuslt; +} + +bool IsExpress(ir::AstNodeType type) +{ + switch (type) { + case ir::AstNodeType::ARROW_FUNCTION_EXPRESSION: + case ir::AstNodeType::AWAIT_EXPRESSION: + case ir::AstNodeType::BINARY_EXPRESSION: + case ir::AstNodeType::CALL_EXPRESSION: + case ir::AstNodeType::CHAIN_EXPRESSION: + case ir::AstNodeType::CLASS_EXPRESSION: + case ir::AstNodeType::CONDITIONAL_EXPRESSION: + case ir::AstNodeType::DIRECT_EVAL: + case ir::AstNodeType::FUNCTION_EXPRESSION: + case ir::AstNodeType::MEMBER_EXPRESSION: + case ir::AstNodeType::META_PROPERTY_EXPRESSION: + case ir::AstNodeType::NEW_EXPRESSION: + case ir::AstNodeType::OMITTED_EXPRESSION: + case ir::AstNodeType::PREFIX_ASSERTION_EXPRESSION: + case ir::AstNodeType::SEQUENCE_EXPRESSION: + case ir::AstNodeType::SUPER_EXPRESSION: + case ir::AstNodeType::TAGGED_TEMPLATE_EXPRESSION: + case ir::AstNodeType::THIS_EXPRESSION: + case ir::AstNodeType::TYPEOF_EXPRESSION: + case ir::AstNodeType::UNARY_EXPRESSION: + case ir::AstNodeType::UPDATE_EXPRESSION: + case ir::AstNodeType::YIELD_EXPRESSION: + case ir::AstNodeType::BLOCK_EXPRESSION: + return true; + default: + break; + } + return false; +} + +bool IsStatement(ir::AstNodeType type) +{ + switch (type) { + case ir::AstNodeType::ASSERT_STATEMENT: + case ir::AstNodeType::CONTINUE_STATEMENT: + case ir::AstNodeType::IF_STATEMENT: + case ir::AstNodeType::DEBUGGER_STATEMENT: + case ir::AstNodeType::DO_WHILE_STATEMENT: + case ir::AstNodeType::EMPTY_STATEMENT: + case ir::AstNodeType::EXPRESSION_STATEMENT: + case ir::AstNodeType::BLOCK_STATEMENT: + case ir::AstNodeType::BREAK_STATEMENT: + case ir::AstNodeType::CATCH_CLAUSE: + case ir::AstNodeType::FOR_IN_STATEMENT: + case ir::AstNodeType::FOR_OF_STATEMENT: + case ir::AstNodeType::FOR_UPDATE_STATEMENT: + case ir::AstNodeType::REEXPORT_STATEMENT: + case ir::AstNodeType::RETURN_STATEMENT: + case ir::AstNodeType::LABELLED_STATEMENT: + case ir::AstNodeType::SWITCH_CASE_STATEMENT: + case ir::AstNodeType::SWITCH_STATEMENT: + case ir::AstNodeType::THROW_STATEMENT: + case ir::AstNodeType::TRY_STATEMENT: + case ir::AstNodeType::WHILE_STATEMENT: + return true; + default: + break; + } + return false; +} + +bool IsLiteral(ir::AstNodeType type) +{ + switch (type) { + case ir::AstNodeType::BIGINT_LITERAL: + case ir::AstNodeType::BOOLEAN_LITERAL: + case ir::AstNodeType::CHAR_LITERAL: + case ir::AstNodeType::NULL_LITERAL: + case ir::AstNodeType::UNDEFINED_LITERAL: + case ir::AstNodeType::NUMBER_LITERAL: + case ir::AstNodeType::REGEXP_LITERAL: + case ir::AstNodeType::STRING_LITERAL: + case ir::AstNodeType::TEMPLATE_LITERAL: + return true; + default: + break; + } + return false; +} + +bool IsModule(ir::AstNodeType type) +{ + switch (type) { + case ir::AstNodeType::EXPORT_ALL_DECLARATION: + case ir::AstNodeType::EXPORT_DEFAULT_DECLARATION: + case ir::AstNodeType::EXPORT_NAMED_DECLARATION: + case ir::AstNodeType::EXPORT_SPECIFIER: + case ir::AstNodeType::IMPORT_DECLARATION: + case ir::AstNodeType::IMPORT_EXPRESSION: + case ir::AstNodeType::IMPORT_DEFAULT_SPECIFIER: + case ir::AstNodeType::IMPORT_NAMESPACE_SPECIFIER: + case ir::AstNodeType::IMPORT_SPECIFIER: + return true; + default: + break; + } + return false; +} + +CompletionEntryKind GetTargetTokenKind(const ir::AstNode *node) +{ + CompletionEntryKind normalResult = CompletionEntryKind::TEXT; + if (node == nullptr) { + return normalResult; + } + auto type = node->Type(); + if (IsExpress(type)) { + normalResult = CompletionEntryKind::OPERATOR; + } else if (IsStatement(type)) { + normalResult = CompletionEntryKind::SNIPPET; + } else if (IsLiteral(type)) { + normalResult = CompletionEntryKind::VALUE; + } else if (IsModule(type)) { + normalResult = CompletionEntryKind::MODULE; + } + switch (type) { + case ir::AstNodeType::CLASS_DEFINITION: + case ir::AstNodeType::CLASS_DECLARATION: + return CompletionEntryKind::CLASS; + case ir::AstNodeType::CLASS_PROPERTY: + case ir::AstNodeType::PROPERTY: + return CompletionEntryKind::FIELD; + case ir::AstNodeType::FUNCTION_DECLARATION: + case ir::AstNodeType::SCRIPT_FUNCTION: + return CompletionEntryKind::FUNCTION; + case ir::AstNodeType::METHOD_DEFINITION: { + auto kind = node->AsMethodDefinition()->Kind(); + return (kind == ir::MethodDefinitionKind::CONSTRUCTOR) ? CompletionEntryKind::CONSTRUCTOR + : CompletionEntryKind::METHOD; + } + case ir::AstNodeType::NAMED_TYPE: + return CompletionEntryKind::TYPE_PARAMETER; + case ir::AstNodeType::STRUCT_DECLARATION: + return CompletionEntryKind::STRUCT; + case ir::AstNodeType::VARIABLE_DECLARATION: + case ir::AstNodeType::VARIABLE_DECLARATOR: + return CompletionEntryKind::VARIABLE; + default: + auto etsResult = GetTargetTokenKindIfETSType(type); + if (std::get<0>(etsResult)) { + return std::get<1>(etsResult); + } + auto tsResult = GetTargetTokenKindIfTSType(type); + if (std::get<0>(tsResult)) { + return std::get<1>(tsResult); + } + } + return normalResult; +} + +CompletionEntryKind GetAliasScriptElementKindImpl(es2panda_Context *context, size_t position) +{ + auto touchingToken = GetTouchingToken(context, position, false); + if (touchingToken == nullptr) { + return CompletionEntryKind::TEXT; + } + auto result = GetTargetTokenKind(touchingToken); + return result; +} +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/services/text_change/change_tracker.cpp b/ets2panda/lsp/src/services/text_change/change_tracker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b4aca7e1efd28cba77837fbe1be9308434ca70f --- /dev/null +++ b/ets2panda/lsp/src/services/text_change/change_tracker.cpp @@ -0,0 +1,848 @@ +/** + * 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/services/text_change/change_tracker.h" +#include +#include +#include +#include +#include +#include "get_adjusted_location.h" + +namespace ark::es2panda::lsp { + +ConfigurableStartEnd g_useNonAdjustedPositions = {{LeadingTriviaOption::EXCLUDE}, {TrailingTriviaOption::EXCLUDE}}; + +ChangeTracker ChangeTracker::FromContext(TextChangesContext &context) +{ + return ChangeTracker(context.formatContext, context.formatContext.GetFormatCodeSettings().GetNewLineCharacter()); +} + +std::vector ChangeTracker::With(TextChangesContext &context, + const std::function &cb) +{ + auto tracker = FromContext(context); + cb(tracker); + ValidateNonFormattedText validateNonFormattedText = [](ark::es2panda::ir::AstNode *, const std::string &) {}; + return tracker.GetChanges(); +} +ir::AstNode *ChangeTracker::GetAstFromContext(const es2panda_Context *context) +{ + auto ctx = reinterpret_cast(const_cast(context)); + auto ast = reinterpret_cast(ctx->parserProgram->Ast()); + return ast; +} + +size_t ChangeTracker::GetStartPositionOfLine(size_t line, const es2panda_Context *context) +{ + auto ast = GetAstFromContext(context); + ir::AstNode *targetNode; + ast->FindChild([line, &targetNode](ark::es2panda::ir::AstNode *node) { + if (node->Start().line == line) { + targetNode = node; + } + return false; + }); + if (targetNode != nullptr) { + return targetNode->Start().index; + } + return 0; +} +bool ChangeTracker::RangeContainsPosition(TextRange r, size_t pos) +{ + return r.pos <= pos && pos <= r.end; +} + +void ChangeTracker::ReplaceRangeWithNodes(es2panda_Context *context, const TextRange range, + std::vector &newNodes, ReplaceWithMultipleNodesOptions options) +{ + auto astContext = reinterpret_cast(context); + const auto sourceFile = astContext->sourceFile; + ReplaceWithMultipleNodes replaceNodes = {sourceFile, range, ChangeKind::REPLACEWITHMULTIPLENODES, newNodes, + options}; + changes_.emplace_back(replaceNodes); +} +ir::AstNode *ChangeTracker::NextCommaToken(es2panda_Context *context, const ir::AstNode *node) +{ + auto astContext = reinterpret_cast(context); + auto *astNodes = astContext->parserProgram->Ast(); + const auto children = GetChildren(astNodes, astContext->allocator); + const auto next = FindRightToken(node->Start().index, children); + return next; +} + +void ChangeTracker::InsertNodesAt(es2panda_Context *context, const size_t pos, std::vector &newNodes, + ReplaceWithMultipleNodesOptions options) +{ + const auto posRange = CreateRange(pos); + ReplaceRangeWithNodes(context, posRange, newNodes, std::move(options)); +} + +void ChangeTracker::InsertAtTopOfFile(es2panda_Context *context, + const std::variant> &insert, + bool blankLineBetween) +{ + auto astContext = reinterpret_cast(const_cast(context)); + const auto sourceFile = astContext->sourceFile; + const auto sourceFileAst = GetAstFromContext(context); + const size_t pos = GetInsertionPositionAtSourceFileTop(sourceFileAst); + + std::string prefix = (pos == 0) ? "" : "\n"; + char currentChar = pos < sourceFile->source.size() ? sourceFile->source.at(pos) : '\0'; + std::string suffix = (IsLineBreak(currentChar) ? "" : "\n"); + if (blankLineBetween) { + suffix += "\n"; + } + if (std::holds_alternative>(insert)) { + ReplaceWithMultipleNodesOptions options; + options.suffix = suffix; + options.prefix = prefix; + auto list = std::get>(insert); + InsertNodesAt(context, pos, list, options); + } else { + InsertNodeOptions options; + options.suffix = suffix; + options.prefix = prefix; + InsertNodeAt(context, pos, std::get(insert), options); + } +} + +InsertNodeOptions ChangeTracker::GetOptionsForInsertNodeBefore(const ir::AstNode *before, const ir::AstNode *inserted, + const bool blankLineBetween) +{ + InsertNodeOptions options; + if (before->IsStatement() || before->IsClassProperty()) { + options.suffix = blankLineBetween ? "\n\n" : "\n"; + } else if (before->IsVariableDeclaration()) { + options.suffix = ", "; + } else if (before->IsTSTypeParameterDeclaration()) { + options.suffix = (inserted->IsTSTypeParameterDeclaration() ? ", " : ""); + } else if ((before->IsStringLiteral() && before->Parent()->IsImportDeclaration()) || before->IsNamedType()) { + options.suffix = ", "; + } else if (before->IsImportSpecifier()) { + options.suffix = "," + std::string(blankLineBetween ? "\n" : " "); + } + return options; // We haven't handled this kind of node yet -- add it +} + +std::vector ChangeTracker::GetMembersOrProperties(const ir::AstNode *node) +{ + std::vector membersOrProperties; + if (node->IsObjectExpression()) { + const auto &properties = node->AsObjectExpression()->Properties(); + membersOrProperties.reserve(properties.size()); + for (auto *property : properties) { + membersOrProperties.emplace_back(property->AsExpression()); + } + } else { + node->FindChild([&membersOrProperties](ir::AstNode *n) { + if (n->IsMemberExpression() || n->IsTSEnumMember()) { + membersOrProperties.emplace_back(n); + } + return false; + }); + } + return membersOrProperties; +} + +InsertNodeOptions ChangeTracker::GetInsertNodeAtStartInsertOptions(const ir::AstNode *node) +{ + // Rules: + // - Always insert leading newline. + // - For object literals: + // - Add a trailing comma if there are existing members in the node, or the source file is not a JSON file + // (because trailing commas are generally illegal in a JSON file). + // - Add a leading comma if the source file is not a JSON file, there are existing insertions, + // and the node is empty (because we didn't add a trailing comma per the previous rule). + // - Only insert a trailing newline if body is single-line and there are no other insertions for the node. + // NOTE: This is handled in `finishClassesWithNodesInsertedAtStart`. + + const auto members = GetMembersOrProperties(node); + const auto isEmpty = members.empty(); + const auto isFirstInsertion = classesWithNodesInsertedAtStart_.at(0).node == node; + const auto insertTrailingComma = node->IsObjectExpression(); + const auto insertLeadingComma = node->IsObjectExpression() && isEmpty && !isFirstInsertion; + InsertNodeOptions options; + options.prefix = (insertLeadingComma ? "," : "") + std::string("\n"); + options.suffix = insertTrailingComma ? "," : (node->IsTSInterfaceDeclaration() && isEmpty ? ";" : ""); + options.delta = 0; + return {options}; +} + +void ChangeTracker::InsertNodeAtStartWorker(es2panda_Context *context, const ir::AstNode *node, + const ir::AstNode *newElement) +{ + if (node == nullptr || newElement == nullptr) { + return; + } + if (node->IsClassDeclaration() || node->IsTSInterfaceDeclaration() || node->IsTSTypeLiteral() || + node->IsObjectExpression()) { + if (newElement->IsClassProperty() || newElement->IsSpreadElement() || newElement->IsMethodDefinition() || + newElement->IsTSPropertySignature()) { + const auto membersOrProperties = GetMembersOrProperties(node); + const auto size = membersOrProperties.size(); + InsertNodeOptions options = GetInsertNodeAtStartInsertOptions(node); + InsertNodeAt(context, membersOrProperties.at(size - 1)->End().index, newElement, options); + } + } +} + +bool ChangeTracker::NeedSemicolonBetween(const ir::AstNode *a, const ir::AstNode *b) +{ + if (a == nullptr || b == nullptr) { + return false; + } + return (a->IsTSPropertySignature() || a->IsTSParameterProperty()) && (b->IsClassProperty() || b->IsTyped()) && + (a->IsStatement() || !a->IsDeclare()) && (b->IsStatement() || !b->IsDeclare()); +} + +size_t ChangeTracker::InsertNodeAfterWorker(es2panda_Context *context, ir::AstNode *after, const ir::AstNode *newNode) +{ + if (NeedSemicolonBetween(after, newNode)) { + // check if previous statement ends with semicolon + // if not - insert semicolon to preserve the code from changing the meaning + // due to ASI + auto astContext = + reinterpret_cast(const_cast(context)); + const auto sourceFile = astContext->sourceFile; + if (sourceFile->source.at(after->End().index - 1) != ':') { + InsertNodeOptions options; + ReplaceRange(context, CreateRange(after->End().index), nullptr, + options); // newNode should get from factory.createToken(':') + } + } + + auto *ctx = reinterpret_cast(context); + + const auto endPosition = GetAdjustedLocation(after, false, ctx->allocator); + return (*endPosition)->End().index; +} + +InsertNodeOptions ChangeTracker::GetInsertNodeAfterOptionsWorker(const ir::AstNode *node) +{ + InsertNodeOptions options; + switch (node->Type()) { + case ark::es2panda::ir::AstNodeType::CLASS_DECLARATION: + case ark::es2panda::ir::AstNodeType::STRUCT_DECLARATION: + case ark::es2panda::ir::AstNodeType::TS_MODULE_DECLARATION: + options.prefix = "\n"; + options.suffix = "\n"; + return options; + case ark::es2panda::ir::AstNodeType::VARIABLE_DECLARATION: + case ark::es2panda::ir::AstNodeType::STRING_LITERAL: + case ark::es2panda::ir::AstNodeType::IDENTIFIER: + options.prefix = ", "; + return options; + case ark::es2panda::ir::AstNodeType::PROPERTY: + options.suffix = "," + std::string("\n"); + return options; + case ark::es2panda::ir::AstNodeType::EXPORT_SPECIFIER: + options.prefix = ", "; + return options; + case ark::es2panda::ir::AstNodeType::TS_TYPE_PARAMETER: + return options; + default: + // Else we haven't handled this kind of node yet -- add it + options.suffix = "\n"; + return options; + } +} +struct StartandEndOfNode { + size_t start; + size_t end; +}; + +StartandEndOfNode GetClassOrObjectBraceEnds(ir::AstNode *node) +{ + const auto open = node->Start().index; + const auto close = node->End().index; + return StartandEndOfNode {open, close}; +} + +void ChangeTracker::FinishClassesWithNodesInsertedAtStart() +{ + for (const auto mapElem : classesWithNodesInsertedAtStart_) { + StartandEndOfNode braceEnds = GetClassOrObjectBraceEnds(mapElem.second.node); + const auto isEmpty = GetMembersOrProperties(mapElem.second.node).empty(); + const auto isSingleLine = mapElem.second.node->Start().line == mapElem.second.node->End().line; + if (isEmpty && isSingleLine) { + // For `class C { }` remove the whitespace inside the braces. + DeleteRange(mapElem.second.sourceFile, CreateRange(braceEnds.start, braceEnds.end - 1)); + } + if (isSingleLine) { + InsertText(mapElem.second.sourceFile, braceEnds.end - 1, "\n"); + } + } +} + +void ChangeTracker::FinishDeleteDeclarations() +{ + // its about delete declarations + // will develop next version + // its about delete declarations +} +/* createTextrangeFromSpan did not developed. it will develop next version.it should be gotten from utılıtıes + * createTextTangeFromSpan method. pls check it from ts side*/ +void ChangeTracker::PushRaw(const SourceFile *sourceFile, const FileTextChanges &change) +{ + for (const auto &c : change.textChanges) { + ChangeText changeText { + sourceFile, {c.span.start, c.span.start + c.newText.length()}, ChangeKind::TEXT, c.newText}; + changes_.emplace_back(changeText); + } +} + +void ChangeTracker::DeleteRange(const SourceFile *sourceFile, TextRange range) +{ + RemoveNode removeNode = { + sourceFile, + range, + ChangeKind::REMOVE, + }; + changes_.emplace_back(removeNode); +} +void ChangeTracker::Delete(const SourceFile *sourceFile, + std::variant> &node) +{ + if (std::holds_alternative>(node)) { + std::vector constNodes; + auto nodes = std::get>(node); + constNodes.reserve(nodes.size()); + for (auto n : nodes) { + constNodes.emplace_back(n); + } + deletedNodes_.push_back({sourceFile, constNodes}); + } else { + deletedNodes_.push_back({sourceFile, node}); + } +} +TextRange ChangeTracker::GetAdjustedRange(es2panda_Context *context, ir::AstNode *startNode, ir::AstNode *endNode) +{ + auto *ctx = reinterpret_cast(context); + + const auto startPosition = GetAdjustedLocation(startNode, false, ctx->allocator); + const auto endPosition = GetAdjustedLocation(endNode, false, ctx->allocator); + return {(*startPosition)->Start().index, (*endPosition)->End().index}; +} + +void ChangeTracker::DeleteNode(es2panda_Context *context, const SourceFile *sourceFile, ir::AstNode *node) +{ + const auto adjustedRange = GetAdjustedRange(context, node, node); + DeleteRange(sourceFile, adjustedRange); +} + +void ChangeTracker::DeleteNodeRange(es2panda_Context *context, ir::AstNode *startNode, ir::AstNode *endNode) +{ + auto *ctx = reinterpret_cast(context); + + const auto startPosition = GetAdjustedLocation(startNode, false, ctx->allocator); + const auto endPosition = GetAdjustedLocation(endNode, false, ctx->allocator); + const auto sourceFile = ctx->sourceFile; + DeleteRange(sourceFile, {(*startPosition)->Start().index, (*endPosition)->End().index}); +} + +void ChangeTracker::DeleteModifier(es2panda_Context *context, ir::AstNode *modifier) +{ + auto astContext = reinterpret_cast(context); + const auto sourceFile = astContext->sourceFile; + DeleteRange(sourceFile, {modifier->Start().index, modifier->End().index}); // skipTrivia method will ask +} + +void ChangeTracker::DeleteNodeRangeExcludingEnd(es2panda_Context *context, ir::AstNode *startNode, + ir::AstNode *afterEndNode) +{ + auto astContext = reinterpret_cast(context); + const auto sourceFile = astContext->sourceFile; + + DeleteRange(sourceFile, GetAdjustedRange(context, startNode, afterEndNode)); +} + +void ChangeTracker::ReplaceRange(es2panda_Context *context, TextRange range, const ir::AstNode *newNode, + InsertNodeOptions &options) +{ + auto astContext = reinterpret_cast(context); + const auto sourceFile = astContext->sourceFile; + ReplaceWithSingleNode replaceNode = {sourceFile, range, ChangeKind::REPLACEWITHSINGLENODE, newNode, options}; + changes_.emplace_back(replaceNode); +} + +void ChangeTracker::ReplaceNode(es2panda_Context *context, ir::AstNode *oldNode, ir::AstNode *newNode, + ChangeNodeOptions options) +{ + const auto adjRange = GetAdjustedRange(context, oldNode, oldNode); + InsertNodeOptions insertOptions; + if (options.insertNodeOptions.has_value()) { + insertOptions = *options.insertNodeOptions; + } + ReplaceRange(context, adjRange, newNode, insertOptions); +} + +void ChangeTracker::ReplaceNodeRange(es2panda_Context *context, ir::AstNode *startNode, ir::AstNode *endNode, + ir::AstNode *newNode) +{ + const auto adjRange = GetAdjustedRange(context, startNode, endNode); + InsertNodeOptions options; + ReplaceRange(context, adjRange, newNode, options); +} + +void ChangeTracker::ReplaceNodeWithNodes(es2panda_Context *context, ir::AstNode *oldNode, + std::vector &newNodes) +{ + const auto adjRange = GetAdjustedRange(context, oldNode, oldNode); + ReplaceRangeWithNodes(context, adjRange, newNodes); +} + +void ChangeTracker::ReplaceNodeWithText(es2panda_Context *context, ir::AstNode *oldNode, const std::string &text) +{ + auto astContext = reinterpret_cast(context); + const auto sourceFile = astContext->sourceFile; + const auto adjRange = GetAdjustedRange(context, oldNode, oldNode); + ReplaceRangeWithText(sourceFile, adjRange, text); +} + +void ChangeTracker::ReplaceRangeWithText(const SourceFile *sourceFile, TextRange range, const std::string &text) +{ + ChangeText change = {sourceFile, range, ChangeKind::TEXT, text}; + changes_.emplace_back(change); +} + +void ChangeTracker::ReplaceNodeRangeWithNodes(es2panda_Context *context, ir::AstNode *startNode, ir::AstNode *endNode, + std::vector &newNodes) +{ + ReplaceRangeWithNodes(context, GetAdjustedRange(context, startNode, endNode), newNodes); +} + +TextRange ChangeTracker::CreateRange(size_t pos, size_t end) +{ + if (end == 0) { + end = pos; + } + return {pos, end}; +} + +void ChangeTracker::ReplacePropertyAssignment(es2panda_Context *context, ir::AstNode *oldNode, ir::AstNode *newNode) +{ + const auto suffix = NextCommaToken(context, oldNode) != nullptr ? "" : ("," + std::string("\n")); + InsertNodeOptions insertOptions; + insertOptions.suffix = suffix; + ChangeNodeOptions options = {g_useNonAdjustedPositions, insertOptions}; + ReplaceNode(context, oldNode, newNode, options); +} + +void ChangeTracker::ReplaceConstructorBody(es2panda_Context *context, ir::AstNode *ctr, + const std::vector &statements) +{ + if (statements.empty()) { + ChangeNodeOptions options = {}; + ReplaceNode(context, ctr, nullptr, + options); // newNode should get from factory.createBlock(statements, / *multiLine* ̇/ true) + } +} + +bool ChangeTracker::IsLineBreak(char ch) +{ + const auto lineFeed = '\n'; + const auto carriageReturn = '\r'; + return ch == lineFeed || ch == carriageReturn; +} +void ChangeTracker::InsertNodeAt(es2panda_Context *context, size_t pos, const ir::AstNode *newNode, + InsertNodeOptions &options) +{ + ReplaceRange(context, CreateRange(pos), newNode, options); +} + +size_t ChangeTracker::GetInsertionPositionAtSourceFileTop(ir::AstNode *sourceFileAst) +{ + const auto topOfFile = sourceFileAst->FindChild([](ir::AstNode *child) { return child->IsClassDeclaration(); }); + return topOfFile->Start().index; +} + +void ChangeTracker::InsertNodeAtTopOfFile(es2panda_Context *context, ir::AstNode *newNode, bool blankLineBetween) +{ + InsertAtTopOfFile(context, newNode, blankLineBetween); +} + +void ChangeTracker::InsertNodeBefore(es2panda_Context *context, ir::AstNode *before, ir::AstNode *newNode, + bool blankLineBetween) +{ + InsertNodeOptions insertOptions = GetOptionsForInsertNodeBefore(before, newNode, blankLineBetween); + auto ctx = reinterpret_cast(context); + auto startpos = GetAdjustedLocation(before, false, ctx->allocator); + InsertNodeAt(context, (*startpos)->Start().index, newNode, insertOptions); +} + +void ChangeTracker::InsertModifierAt(es2panda_Context *context, const size_t pos, const ir::AstNode *modifier, + InsertNodeOptions &options) +{ + (void)modifier; + InsertNodeAt(context, pos, nullptr, options); // newNode should get from factory.createToken(modifier) +} + +void ChangeTracker::InsertModifierBefore(es2panda_Context *context, const ir::AstNode *modifier, ir::AstNode *before) +{ + InsertNodeOptions options; + options.suffix = " "; + return InsertModifierAt(context, before->Start().index, modifier, options); +} + +void ChangeTracker::InsertText(const SourceFile *sourceFile, size_t pos, const std::string &text) +{ + ReplaceRangeWithText(sourceFile, CreateRange(pos), text); +} + +/** Prefer this over replacing a node with another that has a type annotation, + * as it avoids reformatting the other parts of the node. */ +bool ChangeTracker::TryInsertTypeAnnotation(es2panda_Context *context, ir::AstNode *node, ir::AstNode *type) +{ + InsertNodeOptions options; + options.prefix = ": "; + InsertNodeAt(context, node->End().index, type, options); + return true; +} + +void ChangeTracker::TryInsertThisTypeAnnotation(es2panda_Context *context, ir::AstNode *node, ir::AstNode *type) +{ + InsertNodeOptions options; + options.prefix = "this: "; + if (node->IsFunctionExpression()) { + options.suffix = node->AsFunctionExpression()->Function()->Params().empty() ? ", " : ""; + } + + InsertNodeAt(context, node->Start().index, type, options); +} + +void ChangeTracker::InsertTypeParameters(es2panda_Context *context, const ir::AstNode *node, + std::vector &typeParameters) +{ + size_t start; + if (node->IsFunctionDeclaration()) { + start = node->AsFunctionExpression()->Function()->Params().at(0)->End().index; + } else { + start = node->End().index; + } + ReplaceWithMultipleNodesOptions options; + options.prefix = "<"; + options.suffix = ">"; + options.joiner = ", "; + InsertNodesAt(context, start, typeParameters, options); +} + +void ChangeTracker::InsertNodeAtConstructorStart(es2panda_Context *context, ir::AstNode *ctr, + ir::Statement *newStatement) +{ + if (!ctr->IsConstructor()) { + return; + } + std::vector statements; + ir::Statement *superStatement; + + ctr->FindChild([&statements, &superStatement](ir::AstNode *n) { + if (n->IsSuperExpression()) { + superStatement = n->AsStatement(); + return true; + } + if (n->IsStatement()) { + statements.push_back(n->AsStatement()); + } + + return false; + }); + if (superStatement == nullptr && !statements.empty()) { + ReplaceConstructorBody(context, ctr, statements); + } else { + if (superStatement != nullptr) { + InsertNodeAfter(context, superStatement, newStatement->AsStatement()); + } else { + InsertNodeBefore(context, ctr, newStatement->AsStatement()); + } + } +} + +void ChangeTracker::InsertNodeAfter(es2panda_Context *context, ir::AstNode *after, ir::AstNode *newNode) +{ + const auto endPosition = InsertNodeAfterWorker(context, after, newNode); + InsertNodeOptions options = GetInsertNodeAfterOptions(after); + InsertNodeAt(context, endPosition, newNode, options); +} + +void ChangeTracker::InsertNodeAtConstructorEnd(es2panda_Context *context, ir::AstNode *ctr, ir::Statement *newStatement) +{ + if (!ctr->IsConstructor()) { + return; + } + std::vector statements; + ctr->FindChild([&statements](ir::AstNode *n) { + if (n->IsStatement()) { + statements.push_back(n->AsStatement()); + } + return false; + }); + + if (statements.empty()) { + ReplaceConstructorBody(context, ctr, statements); + } else { + InsertNodeAfter(context, statements[statements.size() - 1], newStatement); + } +} + +void ChangeTracker::InsertNodeAtEndOfScope(es2panda_Context *context, ir::AstNode *scope, ir::AstNode *newNode) +{ + InsertNodeOptions options; + options.prefix = "\n"; + options.suffix = "\n"; + InsertNodeAt(context, scope->End().index, newNode, options); +} + +void ChangeTracker::InsertMemberAtStart(es2panda_Context *context, ir::AstNode *node, ir::AstNode *newElement) +{ + if (node == nullptr || newElement == nullptr) { + return; + } + if (node->IsClassDeclaration() || node->IsTSInterfaceDeclaration() || node->IsTSTypeLiteral() || + node->IsObjectExpression()) { + if (newElement->IsClassProperty() || newElement->IsTSPropertySignature() || newElement->IsTSMethodSignature()) { + InsertNodeAtStartWorker(context, node, newElement); + } + } +} + +void ChangeTracker::InsertNodeAtObjectStart(es2panda_Context *context, ir::ObjectExpression *obj, + ir::AstNode *newElement) +{ + InsertNodeAtStartWorker(context, obj, newElement); +} + +void ChangeTracker::InsertNodeAfterComma(es2panda_Context *context, ir::AstNode *after, ir::AstNode *newNode) +{ + const auto endPosition = InsertNodeAfterWorker(context, NextCommaToken(context, after), newNode); + InsertNodeOptions options = GetInsertNodeAfterOptions(after); + InsertNodeAt(context, endPosition, newNode, options); +} + +void ChangeTracker::InsertNodeAtEndOfList(es2panda_Context *context, std::vector &list, + ir::AstNode *newNode) +{ + InsertNodeOptions options; + options.prefix = ", "; + const auto size = list.size(); + InsertNodeAt(context, size - 1, newNode, options); +} +InsertNodeOptions ChangeTracker::GetInsertNodeAfterOptions(const ir::AstNode *after) +{ + return GetInsertNodeAfterOptionsWorker(after); +} + +void ChangeTracker::InsertNodesAfter(es2panda_Context *context, ir::AstNode *after, std::vector newNodes) +{ + const auto endPosition = InsertNodeAfterWorker(context, after, newNodes.at(0)); + InsertNodeOptions insertOptions = GetInsertNodeAfterOptions(after); + ReplaceWithMultipleNodesOptions afterOptions; + afterOptions.prefix = insertOptions.prefix; + afterOptions.suffix = insertOptions.suffix; + InsertNodesAt(context, endPosition, newNodes, afterOptions); +} + +void ChangeTracker::InsertFirstParameter(es2panda_Context *context, + std::vector parameters, + ir::TSTypeParameterDeclaration newParam) +{ + if (parameters.empty()) { + InsertNodeBefore(context, parameters[0], newParam.AsTSTypeParameterDeclaration()); + } else { + InsertNodeOptions insertOptions; + InsertNodeAt(context, parameters.size(), newParam.AsTSTypeParameterDeclaration(), insertOptions); + } +} + +void ChangeTracker::InsertExportModifier(const SourceFile *sourceFile, ir::Statement *node) +{ + const std::basic_string exportModifier = "export "; + InsertText(sourceFile, node->Start().index, exportModifier); +} + +std::vector ChangeTracker::GetContainingList(ir::AstNode *node) +{ + std::vector containingList; + node->Parent()->FindChild([&containingList](ir::AstNode *child) { + if (child->IsObjectExpression() || child->IsObjectExpression()) { + for (auto *property : child->AsObjectExpression()->Properties()) { + containingList.push_back(property); + } + return true; + } + return false; + }); + return containingList; +} + +/** + * This function should be used to insert nodes in lists when nodes don't carry + * separators as the part of the node range, i.e. arguments in arguments lists, + * parameters in parameter lists etc. Note that separators are part of the node + * in statements and class elements. + */ + +void ChangeTracker::InsertNodeInListAfterMultiLine(bool multilineList, es2panda_Context *context, + const SourceFile *sourceFile, size_t end, const ir::AstNode *newNode) +{ + if (multilineList) { + InsertNodeOptions insertOptions; + ReplaceRange(context, CreateRange(end), nullptr, + insertOptions); // newNode should get from factory.createToken(separator) + const int indentation = 4; + size_t insertPos = 4; + while (insertPos != end && IsLineBreak(sourceFile->source.at(insertPos - 1))) { + insertPos--; + } + insertOptions.indentation = indentation; + insertOptions.prefix = "\n"; + ReplaceRange(context, CreateRange(insertPos), newNode, insertOptions); + } else { + InsertNodeOptions insertOptions; + insertOptions.prefix = " "; + ReplaceRange(context, CreateRange(end), newNode, insertOptions); + } +} + +void ChangeTracker::InsertNodeInListAfter(es2panda_Context *context, ir::AstNode *after, ir::AstNode *newNode, + std::vector &containingList) +{ + std::vector containingListResult = GetContainingList(after); + containingList = std::vector(containingListResult.begin(), containingListResult.end()); + if (containingList.empty()) { + return; + } + size_t index = 0; + for (size_t i = 0; i < containingList.size(); i++) { + if (containingList[i] == after) { + index = i; + break; + } + } + if (index == 0) { + return; + } + const auto end = after->End().index; + Initializer initializer = Initializer(); + auto astContext = reinterpret_cast(context); + auto sourceFile = astContext->sourceFile; + if (index != containingList.size() - 1) { + const auto nextToken = sourceFile->source.at(after->End().index); + if (nextToken != 0 && (nextToken == ',' || nextToken == ';' || nextToken == ':' || nextToken == '.')) { + const auto nextNode = containingList[index + 1]; + const auto startPos = nextNode->Start().index; + ReplaceWithMultipleNodesOptions options; + options.suffix = std::string(1, nextToken); + InsertNodesAt(context, startPos, containingList, options); + } else { + bool multilineList = false; + char separator; + if (containingList.size() == 1) { + separator = ','; + } else { + const auto tokenBeforeInsertPosition = + FindPrecedingToken(after->Start().index, after, initializer.Allocator()); + separator = ','; + const auto afterMinusOneStartLinePosition = + GetStartPositionOfLine(containingList.at(index - 1)->Start().line, context); + multilineList = containingList[index - 1]->Start().line != containingList[index]->Start().line; + (void)tokenBeforeInsertPosition; // Use tokenBeforeInsertPosition if needed + (void)afterMinusOneStartLinePosition; // Use afterMinusOneStartLinePosition if needed + } + (void)separator; // Use separator if needed + InsertNodeInListAfterMultiLine(multilineList, context, sourceFile, end, newNode); + } + } +} + +void ChangeTracker::InsertImportSpecifierAtIndex(es2panda_Context *context, ir::AstNode *importSpecifier, + std::vector &namedImports, size_t index) +{ + const auto prevSpecifier = namedImports.at(index - 1); + if (prevSpecifier != nullptr) { + InsertNodeInListAfter(context, prevSpecifier, nullptr, namedImports); + } else { + InsertNodeBefore(context, namedImports[0], importSpecifier, + namedImports[0]->Parent()->Start().index == namedImports[0]->Parent()->End().index); + } +} + +std::vector GetTextChangesFromChanges( + Change &changes, std::string &newLineCharacter, + FormattingContext &formattingContext) // ValidateNonFormattedText should add +{ + // will develop with changestoText + // Its about finishing changes processes + (void)changes; + (void)newLineCharacter; + (void)formattingContext; + + return {}; +} +std::vector ChangeTracker::GetTextChangesFromChanges(std::vector &changes, + std::string &newLineCharacter, + const FormatCodeSettings &formatCodeSettings) +{ + (void)newLineCharacter; + (void)formatCodeSettings; + + std::unordered_map fileChangesMap; + 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); + } + } + + std::vector fileTextChanges; + fileTextChanges.reserve(fileChangesMap.size()); + for (auto &pair : fileChangesMap) { + fileTextChanges.push_back(std::move(pair.second)); + } + + return fileTextChanges; +} + +/** + * Note: after calling this, the TextChanges object must be discarded! + * @param validate only for tests + * The reason we must validate as part of this method is that + * `getNonFormattedText` changes the node's positions, so we can only call this + * once and can't get the non-formatted text separately. + */ +std::vector ChangeTracker::GetChanges() // should add ValidateNonFormattedText +{ + FinishDeleteDeclarations(); + FinishClassesWithNodesInsertedAtStart(); + auto textChangesList = + GetTextChangesFromChanges(changes_, newLineCharacter_, formatContext_.GetFormatCodeSettings()); + + return textChangesList; +} + +void ChangeTracker::CreateNewFile(SourceFile *oldFile, const std::string &fileName, + std::vector &statements) +{ + NewFile newFile; + newFile.oldFile = oldFile; + newFile.fileName = fileName; + newFile.statements = statements; + newFiles_.push_back(newFile); +} +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/signature_help.cpp b/ets2panda/lsp/src/signature_help.cpp new file mode 100644 index 0000000000000000000000000000000000000000..58a726287f413e54d0020a927636592cbe8c46ac --- /dev/null +++ b/ets2panda/lsp/src/signature_help.cpp @@ -0,0 +1,380 @@ +/** + * 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 "signature_help.h" +#include "internal_api.h" +#include "utils/arena_containers.h" +#include +#include +#include +#include +#include +#include +#include "create_type_help_items.h" + +namespace ark::es2panda::lsp { + +ir::AstNode *FindTokenOnLeftOfPosition(es2panda_Context *context, size_t position) +{ + auto const tokenAtPosition = GetTouchingToken(context, position, false); + if (tokenAtPosition->Start().index < position && tokenAtPosition->End().index > position) { + return tokenAtPosition; + } + const auto ctx = reinterpret_cast(context); + return FindPrecedingToken(position, ctx->parserProgram->Ast(), ctx->allocator); +} + +TextSpan CreateTextSpanForNode(const ir::AstNode *node) +{ + TextSpan span {0, 0}; + span.start = node->Start().index; + span.length = node->End().index - node->Start().index; + return span; +} +bool IsSyntacticOwner(const ir::AstNode *node) +{ + return node->IsCallExpression() || node->IsNewExpression(); +} +checker::Signature *GetResolvedSignatureForSignatureHelp(const ir::AstNode *call, const ir::AstNode *parent, + std::vector &candidates) +{ + parent->FindChild([&call, &candidates](ir::AstNode *n) { + switch (n->Type()) { + case ir::AstNodeType::METHOD_DEFINITION: + if (call->AsCallExpression()->Callee()->ToString() == n->AsMethodDefinition()->Id()->ToString()) { + candidates.push_back(n->AsMethodDefinition()->Function()->Signature()); + } + break; + + case ir::AstNodeType::CALL_EXPRESSION: + if (call->AsCallExpression()->Callee()->ToString() == n->AsCallExpression()->Callee()->ToString()) { + candidates.push_back(n->AsCallExpression()->Signature()); + } + break; + + default: + break; + } + return false; + }); + if (call->IsCallExpression()) { + auto callExpr = call->AsCallExpression(); + return callExpr->Signature(); + } + return nullptr; +} + +std::optional GetCandidateOrTypeInfo(const std::optional info, ir::AstNode *parent, + const bool onlyUseSyntacticOwners) +{ + if (const auto *call = std::get_if(&info->GetInvocation()); + call != nullptr && call->callExpressionNode != nullptr) { + if (onlyUseSyntacticOwners && !IsSyntacticOwner(call->callExpressionNode)) { + return std::nullopt; + } + std::vector candidates; + checker::Signature *resolvedSignature = nullptr; + if (call->callExpressionNode != nullptr && call->callExpressionNode->IsCallExpression()) { + resolvedSignature = GetResolvedSignatureForSignatureHelp(call->callExpressionNode, parent, candidates); + } else { + resolvedSignature = + GetResolvedSignatureForSignatureHelp(call->callExpressionNode->Parent(), parent, candidates); + } + if (!candidates.empty()) { + const auto can = CandidateInfo {CandidateOrTypeKind::CANDIDATE, candidates, resolvedSignature}; + return std::make_optional(can); + } + } else if (const auto *typeArgs = std::get_if(&info->GetInvocation())) { + auto called = typeArgs->identifierNode; + const auto tp = CandidateOrTypeKind::TYPEENUM; + TypeInfo val = TypeInfo {tp, called}; + return std::make_optional(val); + } else if (const auto *context = std::get_if(&info->GetInvocation()); context != nullptr) { + auto node = context->node; + std::vector candidates; + if (node != nullptr && node->IsMethodDefinition()) { + auto funcSignature = node->AsMethodDefinition()->Function()->Signature(); + candidates.push_back(funcSignature); + const auto can = CandidateInfo {CandidateOrTypeKind::CANDIDATE, candidates, funcSignature}; + return std::make_optional(can); + } + } + return std::nullopt; +} + +std::string IsReasonCharacterTyped(const SignatureHelpTriggerReason &triggerReason) +{ + return std::visit( + [](const auto &reason) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return reason.GetKind(); + } + return ""; + }, + triggerReason); +} + +std::string IsManuallyInvoked(const SignatureHelpTriggerReason &triggerReason) +{ + return std::visit( + [](const auto &reason) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return reason.GetKind(); + } + return ""; + }, + triggerReason); +} + +SignatureHelpItems GetSignatureHelpItems(es2panda_Context *ctx, size_t position, + SignatureHelpTriggerReason triggeredReason, + CancellationToken cancellationToken) +{ + auto const startingToken = FindTokenOnLeftOfPosition(ctx, position); + if (startingToken == nullptr) { + return {}; + } + + auto context = reinterpret_cast(ctx); + auto astNode = reinterpret_cast(context->parserProgram->Ast()); + + const auto onlyUseSyntacticOwners = IsReasonCharacterTyped(triggeredReason) == "characterTyped"; + if (onlyUseSyntacticOwners) { + return {}; + } + const auto isManuallyInvoked = IsManuallyInvoked(triggeredReason) == "invoked"; + const auto argumentInfo = GetContainingArgumentInfo(startingToken, position, isManuallyInvoked); + if (argumentInfo == std::nullopt) { + return {}; + } + if (cancellationToken.IsCancellationRequested()) { + return {}; + } + const auto candidateInfoOpt = GetCandidateOrTypeInfo(argumentInfo, astNode, onlyUseSyntacticOwners); + if (candidateInfoOpt == std::nullopt) { + return {}; + } + + const auto &candidateInfo = *candidateInfoOpt; + + auto res = SignatureHelpItems(); + if (std::holds_alternative(candidateInfo)) { + const auto &typeInfo = std::get(candidateInfo); + res = CreateTypeHelpItems(typeInfo.GetSymbol(), typeInfo.GetSymbol()->Range(), + CreateTextSpanForNode(typeInfo.GetSymbol())); + } else if (std::holds_alternative(candidateInfo)) { + auto candidate = std::get(candidateInfo); + res = CreateSignatureHelpItems(candidate.GetSignatures(), candidate.GetResolvedSignature(), argumentInfo); + } + return res; +} +ir::AstNode *GetHighestBinary(ir::AstNode *node) +{ + return node->Parent()->IsBinaryExpression() ? GetHighestBinary(node->Parent()) : node; +} + +size_t CountBinaryExpressionParameters(ir::AstNode *node) +{ + const size_t binaryReturnParam = 2; + return node->AsBinaryExpression()->Left()->IsBinaryExpression() + ? CountBinaryExpressionParameters(node->AsBinaryExpression()->Left()) + 1 + : binaryReturnParam; +} + +std::optional GetImmediatelyContainingArgumentOrContextualParameterInfo(ir::AstNode *node, + size_t position) +{ + return TryGetParameterInfo(node).has_value() ? TryGetParameterInfo(node) + : (GetImmediatelyContainingArgumentInfo(node, position)); +} + +std::optional GetContainingArgumentInfo(ir::AstNode *node, size_t position, bool isManuallyInvoked) +{ + if (!isManuallyInvoked) { + return std::nullopt; + } + + return GetImmediatelyContainingArgumentOrContextualParameterInfo(node, position); +} + +ir::AstNode *GetChildListThatStartsWithOpenerToken(ir::AstNode *parent, ir::AstNode *openerToken) +{ + std::vector children; + parent->FindChild([&children](ir::AstNode *n) { + children.push_back(n); + return false; + }); + + auto const indexOfOpenerToken = + std::distance(children.begin(), std::find(children.begin(), children.end(), openerToken)); + if (!(indexOfOpenerToken >= 0 && (int)children.size() > indexOfOpenerToken + 1)) { + return nullptr; + } + return children.at(indexOfOpenerToken + 1); +} + +size_t GetArgumentCount(ir::AstNode *node, bool ignoreTrailingComma) +{ + int argumentCount = 0; + + node->FindChild([&argumentCount, ignoreTrailingComma](ir::AstNode *child) { + if (!ignoreTrailingComma && child->IsTSTypeParameter()) { + argumentCount++; + } else if (!ignoreTrailingComma && child->IsMemberExpression()) { + argumentCount++; + } + return false; + }); + return argumentCount; +} +std::vector GetArgumentOrParameterListAndIndex(ir::AstNode *node, std::vector &list) +{ + if (node->IsMethodDefinition()) { + const auto params = node->AsMethodDefinition()->Function()->Params(); + for (const auto param : params) { + auto argum = ArgumentListInfo(); + argum.SetInvocation(Invocation(CallInvocation {InvocationKind::CALL, param})); + argum.SetApplicableSpan(CreateTextSpanForNode(param)); + argum.SetArgumentIndex(param->Start().index); + argum.SetArgumentCount(params.size()); + list.push_back(argum); + } + } + if (node->IsCallExpression()) { + const auto params = node->AsCallExpression()->Arguments(); + for (const auto param : params) { + auto argum = ArgumentListInfo(); + argum.SetInvocation(Invocation(CallInvocation {InvocationKind::CALL, param})); + argum.SetApplicableSpan(CreateTextSpanForNode(param)); + argum.SetArgumentIndex(param->Start().index); + argum.SetArgumentCount(params.size()); + list.push_back(argum); + } + } + + return list; +} +ContextualSignatureLocationInfo GetArgumentOrParameterListInfo(ir::AstNode *node) +{ + std::vector info; + info = GetArgumentOrParameterListAndIndex(node, info); + if (info.empty()) { + return ContextualSignatureLocationInfo {}; + } + + const auto argumentCount = GetArgumentCount(node, false); + auto textSpan = CreateTextSpanForNode(node); + return {info, node->Start().index, argumentCount, textSpan}; +} + +std::optional TryGetParameterInfo(ir::AstNode *node) +{ + auto const info = GetContextualSignatureLocationInfo(node); + if (!info) { + return std::nullopt; + } + auto const index = info->GetArgumentIndex(); + auto const count = info->GetArgumentCount(); + auto const span = info->GetArgumentsSpan(); + + std::optional argumentList = ArgumentListInfo(); + if (node->IsCallExpression()) { + const ContextualInvocation invocation = + ContextualInvocation {InvocationKind::CONTEXTUAL, node->AsCallExpression()->Signature(), node}; + argumentList->SetInvocation(invocation); + } else if (node->IsMethodDefinition()) { + const ContextualInvocation invocation = ContextualInvocation { + InvocationKind::CONTEXTUAL, node->AsMethodDefinition()->Function()->Signature(), node}; + argumentList->SetInvocation(invocation); + } + argumentList->SetApplicableSpan(span); + argumentList->SetArgumentIndex(index); + argumentList->SetArgumentCount(count); + return argumentList; +} + +size_t GetArgumentIndexForTemplatePiece(size_t spanIndex, ir::AstNode *node, size_t position) +{ + const size_t spanIndexOne = 1; + const size_t spanIndexTwo = 2; + if (node->Type() == ir::AstNodeType::TEMPLATE_LITERAL) { + if (node->Start().index < position && position < node->End().index) { + return 0; + } + return spanIndex + spanIndexTwo; + } + return spanIndex + spanIndexOne; +} + +std::optional GetImmediatelyContainingArgumentInfo(ir::AstNode *node, size_t position) +{ + if (position == 0) { + return std::nullopt; + } + if (node->Parent()->Type() == ir::AstNodeType::CALL_EXPRESSION || + node->Parent()->Type() == ir::AstNodeType::NEW_EXPRESSION) { + auto const invocation = node->Parent(); + + auto const argument = GetArgumentOrParameterListInfo(node->Parent()); + const auto &list = argument.GetList(); + if (!list.empty()) { + auto const argumentIndex = argument.GetArgumentIndex(); + auto const argumentCount = GetArgumentCount(node->Parent(), false); + auto const span = CreateTextSpanForNode(node->Parent()); + ArgumentListInfo argumentList; + argumentList.SetInvocation(Invocation(CallInvocation {InvocationKind::CALL, invocation})); + argumentList.SetApplicableSpan(span); + argumentList.SetArgumentIndex(argumentIndex); + argumentList.SetArgumentCount(argumentCount); + return argumentList; + } + } else if (node->Parent()->Type() == ir::AstNodeType::METHOD_DEFINITION) { + auto const info = GetContextualSignatureLocationInfo(node->Parent()); + if (!info) { + return std::nullopt; + } + auto const index = info->GetArgumentIndex(); + auto const count = info->GetArgumentCount(); + auto const span = info->GetArgumentsSpan(); + std::optional argumentList = ArgumentListInfo(); + const ContextualInvocation invocation = ContextualInvocation { + InvocationKind::CONTEXTUAL, node->Parent()->AsMethodDefinition()->Function()->Signature(), node->Parent()}; + argumentList->SetInvocation(invocation); + argumentList->SetApplicableSpan(span); + argumentList->SetArgumentIndex(index); + argumentList->SetArgumentCount(count); + return argumentList; + } + return std::nullopt; +} + +std::optional GetContextualSignatureLocationInfo(ir::AstNode *node) +{ + ContextualSignatureLocationInfo info; + switch (node->Type()) { + case ir::AstNodeType::METHOD_DEFINITION: + case ir::AstNodeType::FUNCTION_EXPRESSION: + case ir::AstNodeType::ARROW_FUNCTION_EXPRESSION: + info = GetArgumentOrParameterListInfo(node); + return std::make_optional(info); + break; + default: + return std::nullopt; + break; + } +} +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/signature_help_items.cpp b/ets2panda/lsp/src/signature_help_items.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01f5fc651ff81fb26db7972a8094c9d683facca6 --- /dev/null +++ b/ets2panda/lsp/src/signature_help_items.cpp @@ -0,0 +1,173 @@ +/** + * 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 "signature_help_items.h" +#include +#include +#include +#include "utils/arena_containers.h" + +namespace ark::es2panda::lsp { + +SignatureHelpItems CreateSignatureHelpItems(std::vector &signatures, + checker::Signature *signature, + std::optional argumentListInfo) +{ + SignatureHelpItems items; + + size_t selectedItemIndex = -1; + size_t itemsSeen = 0; + const size_t one = 1; + + for (size_t i = itemsSeen; i < signatures.size(); i++) { + auto ¤tSignature = signatures[i]; + if (currentSignature->ToString() == signature->ToString()) { + selectedItemIndex = itemsSeen; + break; + } + itemsSeen++; + } + + ES2PANDA_ASSERT(selectedItemIndex != static_cast(-1)); + + for (const auto &helpItem : GetSignatureHelpItem(signatures)) { + items.SetItems(helpItem); + } + + items.SetApplicableSpan(argumentListInfo->GetApplicableSpan().start, argumentListInfo->GetApplicableSpan().length); + + items.SetSelectedItemIndex(selectedItemIndex); + + size_t argumentIndex = argumentListInfo->GetArgumentIndex(); + const auto selectedSignature = signatures[selectedItemIndex]; + + if (selectedSignature->HasRestParameter() && selectedSignature->ArgCount() > one) { + argumentIndex = selectedSignature->ArgCount(); + } else { + argumentIndex = std::min(argumentIndex, selectedSignature->ArgCount() - one); + } + + items.SetArgumentIndex(argumentIndex); + items.SetArgumentCount(argumentListInfo->GetArgumentCount()); + + return items; +} + +std::vector GetSignatureHelpItem(const std::vector &signatures) +{ + std::vector items; + if (signatures.empty()) { + return items; + } + for (auto *signature : signatures) { + const auto item = CreateSignatureHelpItem(*signature); + items.push_back(item); + } + + return items; +} + +SignatureHelpItem CreateSignatureHelpItem(checker::Signature &signature) +{ + const checker::SignatureInfo *signatureInfo = signature.GetSignatureInfo(); + SignatureHelpItem item; + if (!signatureInfo->typeParams.empty()) { + item.SetPrefixDisplayParts(CreatePunctuation("<")); + for (auto it = signatureInfo->typeParams.begin(); it != signatureInfo->typeParams.end(); ++it) { + std::string typeName = (*it)->ToString(); + item.SetPrefixDisplayParts(CreateTypeName(typeName)); + if (std::next(it) != signatureInfo->typeParams.end()) { + item.SetPrefixDisplayParts(CreatePunctuation(",")); + item.SetSeparatorDisplayParts(CreatePunctuation(",")); + } + } + item.SetPrefixDisplayParts(CreatePunctuation(">")); + } + item.SetPrefixDisplayParts(CreatePunctuation("(")); + + SetSignatureHelpParameter(signatureInfo, item); + + item.SetSuffixDisplayParts(CreatePunctuation(")")); + + if (signature.HasFunction() || + (signature.OwnerVar() != nullptr && signature.OwnerVar()->HasFlag(varbinder::VariableFlags::METHOD))) { + item.SetSuffixDisplayParts(CreatePunctuation(":")); + } else { + item.SetSuffixDisplayParts(CreatePunctuation("=>")); + } + + std::string returnType = signature.ReturnType()->ToString(); + item.SetSuffixDisplayParts(CreateTypeName(returnType)); + + if (signature.HasSignatureFlag(checker::SignatureFlags::THROWS)) { + item.SetSuffixDisplayParts(CreateKeyword("throws")); + } else if (signature.HasSignatureFlag(checker::SignatureFlags::RETHROWS)) { + item.SetSuffixDisplayParts(CreateKeyword("rethrows")); + } + + return item; +} + +void SetSignatureHelpParameter(const checker::SignatureInfo *signatureInfo, SignatureHelpItem &signatureHelpItem) +{ + for (auto it = signatureInfo->params.begin(); it != signatureInfo->params.end(); it++) { + SignatureHelpParameter param; + + std::string paramName = + (!(*it)->Name().StartsWith(GENSYM_CORE) ? std::string((*it)->Name().Utf8()) : std::string(DUMMY_ID)); + param.SetName(paramName); + param.SetDisplayParts(SignatureCreateParameterName(paramName)); + + if ((*it)->HasFlag(varbinder::VariableFlags::OPTIONAL)) { + param.SetDisplayParts(CreatePunctuation("?")); + } + + param.SetDisplayParts(CreatePunctuation(":")); + + std::string paramType = (*it)->TsType()->ToString(); + param.SetDisplayParts(CreateTypeName(paramType)); + + if (std::next(it) != signatureInfo->params.end()) { + param.SetDisplayParts(CreatePunctuation(",")); + } + + signatureHelpItem.SetParameters(param); + } + + if (signatureInfo->restVar == nullptr) { + return; + } + + SignatureHelpParameter param; + + if (!signatureInfo->params.empty()) { + param.SetDisplayParts(CreatePunctuation(",")); + } + param.SetDisplayParts(CreatePunctuation("...")); + + std::string paramName = + (!signatureInfo->restVar->Name().StartsWith(GENSYM_CORE) ? std::string(signatureInfo->restVar->Name().Utf8()) + : std::string(DUMMY_ID)); + param.SetDisplayParts(SignatureCreateParameterName(paramName)); + + param.SetDisplayParts(CreatePunctuation(":")); + + std::string paramType = signatureInfo->restVar->TsType()->ToString(); + param.SetDisplayParts(CreateTypeName(paramType)); + + signatureHelpItem.SetParameters(param); +} + +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/todo_comments.cpp b/ets2panda/lsp/src/todo_comments.cpp new file mode 100644 index 0000000000000000000000000000000000000000..15eba3e3cfe6771b155748273ab5a84c54ff7492 --- /dev/null +++ b/ets2panda/lsp/src/todo_comments.cpp @@ -0,0 +1,238 @@ +/** + * 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 +#include "internal_api.h" +#include "todo_comments.h" +#include "lexer/token/letters.h" +#include "public/public.h" + +namespace { +bool IsNodeModulesFile(const std::string_view &path) +{ + return path.find("/node_modules/") != std::string::npos; +} + +bool IsOHModulesFile(const std::string_view &path) +{ + return path.find("/oh_modules/") != std::string::npos; +} + +bool IsLetterOrDigit(char32_t c) +{ + return (c >= ark::es2panda::lexer::LEX_CHAR_LOWERCASE_A && c <= ark::es2panda::lexer::LEX_CHAR_LOWERCASE_Z) || + (c >= ark::es2panda::lexer::LEX_CHAR_UPPERCASE_A && c <= ark::es2panda::lexer::LEX_CHAR_UPPERCASE_Z) || + (c >= ark::es2panda::lexer::LEX_CHAR_0 && c <= ark::es2panda::lexer::LEX_CHAR_9); +} + +// Function to escape regex special characters +std::string EscapeRegExp(const std::string &str) +{ + std::string escaped; + for (char c : str) { + if (std::string("-[]/{}()*+?.\\^$|").find(c) != std::string::npos) { + escaped += '\\'; // Escape special characters + } + escaped += c; + } + return escaped; +} + +std::regex GetTodoCommentsRegExp(const std::vector &descriptors) +{ + // Single-line comments: // TO-DO or //// TO-DO + std::string singleLineCommentStart = R"((?:\/\/+\s*))"; + + // Multi-line comment start: /* TO-DO or /** TO-DO + std::string multiLineCommentStart = R"((?:\/\*+\s*))"; + + // Any number of spaces or `*` at the start of a line (for block comments) + std::string anyNumberOfSpacesAndAsterisksAtStartOfLine = R"((?:^(?:\s|\*)*))"; + + // Match any of the comment start patterns + std::string preamble = "(" + singleLineCommentStart + "|" + multiLineCommentStart + "|" + + anyNumberOfSpacesAndAsterisksAtStartOfLine + ")"; + + /* + * This comments includes commonly flagged descriptors such as "TO-DO", "FIX-ME", "NOTE", "HACK", "FIX", "WARNING". + * A regex is created to identify these patterns intentionally. + */ + std::vector literalGroups; + literalGroups.reserve(descriptors.size()); + for (const auto &d : descriptors) { + literalGroups.push_back("(" + EscapeRegExp(d.GetText()) + ")"); + } + + // Join the literal groups with '|' + std::string literals; + for (size_t i = 0; i < literalGroups.size(); ++i) { + if (i > 0) { + literals += "|"; + } + literals += literalGroups[i]; + } + literals = "(?:" + literals + ")"; + + // Match the remainder of the line (up to the end of line or block comment end `*/`) + std::string messageRemainder = R"((?:.*?))"; + std::string endOfLineOrEndOfComment = R"((?:$|\*\/))"; + + // Final regex string + std::string regExpString = preamble + "(" + literals + messageRemainder + ")" + endOfLineOrEndOfComment; + + // Return compiled regex (case insensitive only) + return std::regex(regExpString, std::regex_constants::icase); +} + +std::vector SplitLines(const std::string_view &input) +{ + std::vector lines; + size_t pos = 0; + size_t newLinePos = 0; + + while ((newLinePos = input.find('\n', pos)) != std::string_view::npos) { + lines.emplace_back(input.substr(pos, newLinePos - pos)); + pos = newLinePos + 1; + } + + // Add the last line if there's content after the last newline + if (pos < input.length()) { + lines.emplace_back(input.substr(pos)); + } + + return lines; +} + +// Helper function to find the correct descriptor +const ark::es2panda::lsp::TodoCommentDescriptor *FindMatchedDescriptor( + const std::cmatch &match, const std::vector &descriptors, + size_t &firstDescriptorCaptureIndex) +{ + for (size_t i = 0; i < descriptors.size(); i++) { + if (match[i + firstDescriptorCaptureIndex].matched) { + return &descriptors[i]; + } + } + return nullptr; +} + +std::string ExtractAndCleanMessage(const std::string &rawMessage, const std::string &preamble) +{ + std::string message = rawMessage; + + // For block comments, strip leading asterisks if present + if (message.find('*') != std::string::npos && + (preamble.find("/*") != std::string::npos || preamble.find('*') != std::string::npos)) { + // This is a block comment - clean up asterisks + size_t firstNonAsterisk = message.find_first_not_of("* \t"); + if (firstNonAsterisk != std::string::npos) { + message = message.substr(firstNonAsterisk); + } + } + + return message; +} + +bool ProcessMatchedTodo(const ark::es2panda::lsp::TodoMatchContext &ctx, const std::cmatch &match) +{ + const size_t preambleIndex = 1; + size_t firstDescriptorCaptureIndex = 3; + const size_t messageIndex = 2; + + // Find which descriptor matched + const ark::es2panda::lsp::TodoCommentDescriptor *descriptor = + FindMatchedDescriptor(match, ctx.descriptors, firstDescriptorCaptureIndex); + + if (descriptor == nullptr) { + return false; + } + + std::string preamble = match[preambleIndex].str(); + + // Calculate absolute position in the file + size_t matchPositionInLine = std::distance(ctx.line->c_str(), match[0].first); + size_t matchPosition = ctx.lineStart + matchPositionInLine; + size_t descriptorPosition = matchPosition + preamble.length(); + + // We don't want to match something like 'TODOBY' + size_t afterTodoPos = descriptorPosition + descriptor->GetText().length(); + if (afterTodoPos < ctx.fileContents.length() && IsLetterOrDigit(ctx.fileContents[afterTodoPos])) { + return false; + } + + // Verify this is in a comment + if (ark::es2panda::lsp::GetTouchingToken(ctx.context, descriptorPosition, true) != nullptr) { + return false; + } + + std::string message = ExtractAndCleanMessage(match[messageIndex].str(), preamble); + + ctx.result.emplace_back(*descriptor, message, descriptorPosition); + return true; +} +} // namespace + +namespace ark::es2panda::lsp { +std::vector GetTodoCommentsImpl( + es2panda_Context *context, std::vector &descriptors, + CancellationToken *cancellationToken) +{ + auto ctx = reinterpret_cast(context); + + if (cancellationToken->IsCancellationRequested()) { + return {}; + } + + if (descriptors.empty() || IsNodeModulesFile(ctx->sourceFile->filePath) || + IsOHModulesFile(ctx->sourceFile->filePath)) { + return {}; + } + + auto fileContents = ctx->sourceFile->source; + std::vector result; + + // Split the file content into lines to handle line-by-line processing + std::vector lines = SplitLines(fileContents); + std::regex regExp = GetTodoCommentsRegExp(descriptors); + + TodoMatchContext matchContext = {context, descriptors, 0, nullptr, fileContents, result}; + + size_t lineStart = 0; + for (const auto &line : lines) { + if (cancellationToken->IsCancellationRequested()) { + return {}; + } + + matchContext.lineStart = lineStart; + matchContext.line = &line; + + std::cmatch match; + std::string_view lineView(line); + const char *lineData = lineView.data(); + const char *lineEnd = lineData; + std::advance(lineEnd, lineView.size()); + + while (std::regex_search(lineData, lineEnd, match, regExp)) { + ProcessMatchedTodo(matchContext, match); + lineData = match.suffix().first; + } + + // Move to next line (add +1 for newline character) + lineStart += lineView.size() + 1; + } + + return result; +} +} // namespace ark::es2panda::lsp diff --git a/ets2panda/lsp/src/types.cpp b/ets2panda/lsp/src/types.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5abeead248803ea49159d96d3c2bd64bf7808c85 --- /dev/null +++ b/ets2panda/lsp/src/types.cpp @@ -0,0 +1,106 @@ +/** + * 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 "types.h" + +SymbolDisplayPart CreatePunctuation(std::string punc) +{ + return SymbolDisplayPart(std::move(punc), "punctuation"); +} + +SymbolDisplayPart CreateKeyword(std::string keyword) +{ + return SymbolDisplayPart(std::move(keyword), "keyword"); +} + +SymbolDisplayPart CreateSpace() +{ + return SymbolDisplayPart(" ", "space"); +} + +SymbolDisplayPart CreateText(std::string text) +{ + return SymbolDisplayPart(std::move(text), "text"); +} + +SymbolDisplayPart CreateClassName(std::string className) +{ + return SymbolDisplayPart(std::move(className), "className"); +} + +SymbolDisplayPart CreateFunctionName(std::string functionName) +{ + return SymbolDisplayPart(std::move(functionName), "functionName"); +} + +SymbolDisplayPart CreateTypeName(std::string typeName) +{ + return SymbolDisplayPart(std::move(typeName), "typeName"); +} + +SymbolDisplayPart CreateEnumName(std::string enumName) +{ + return SymbolDisplayPart(std::move(enumName), "enumName"); +} + +SymbolDisplayPart CreateEnumMember(std::string enumMember) +{ + return SymbolDisplayPart(std::move(enumMember), "enumMember"); +} + +SymbolDisplayPart CreateInterface(std::string interface) +{ + return SymbolDisplayPart(std::move(interface), "interface"); +} + +SymbolDisplayPart CreateTypeParameter(std::string typeParameter) +{ + return SymbolDisplayPart(std::move(typeParameter), "typeParameter"); +} + +SymbolDisplayPart CreateFunctionParameter(std::string functionParameter) +{ + return SymbolDisplayPart(std::move(functionParameter), "functionParameter"); +} + +SymbolDisplayPart CreateOperator(std::string oper) +{ + return SymbolDisplayPart(std::move(oper), "operator"); +} + +SymbolDisplayPart CreateReturnType(std::string returnType) +{ + return SymbolDisplayPart(std::move(returnType), "returnType"); +} + +SymbolDisplayPart CreateProperty(std::string property) +{ + return SymbolDisplayPart(std::move(property), "property"); +} + +SymbolDisplayPart CreateNamespace(std::string name) +{ + return SymbolDisplayPart(std::move(name), "namespace"); +} + +SymbolDisplayPart SignatureCreateStructName(const std::string &name) +{ + return SymbolDisplayPart(name, "structName"); +} + +SymbolDisplayPart SignatureCreateParameterName(std::string &type) +{ + return SymbolDisplayPart(type, "paramName"); +} \ No newline at end of file diff --git a/ets2panda/parser/ETSFormattedParser.cpp b/ets2panda/parser/ETSFormattedParser.cpp index cfefa287b75e442fbdbebf19731df0da96a14327..d0b01fdad556ca202f89738c1de968e4313372a7 100644 --- a/ets2panda/parser/ETSFormattedParser.cpp +++ b/ets2panda/parser/ETSFormattedParser.cpp @@ -112,8 +112,7 @@ ir::TypeNode *ETSParser::ParseTypeFormatPlaceholder(std::optional(*nodeFormat) || std::get<1>(*nodeFormat) != TYPE_FORMAT_NODE) { - LogError(diagnostic::INVALID_NODE_TYPE, {}, Lexer()->GetToken().Start()); - ES2PANDA_UNREACHABLE(); + return nullptr; } } @@ -200,8 +199,7 @@ ir::AstNode *ETSParser::ParseTypeParametersFormatPlaceholder() auto *const insertingNode = insertingNodes_[placeholderNumber]; if (insertingNode != nullptr && !insertingNode->IsTSTypeParameterDeclaration() && !insertingNode->IsTSTypeParameterInstantiation()) { - LogError(diagnostic::INVALID_INSERT_NODE, {}, Lexer()->GetToken().Start()); - ES2PANDA_UNREACHABLE(); + return nullptr; } Lexer()->NextToken(); @@ -333,6 +331,25 @@ ir::Statement *ETSParser::CreateFormattedStatement(std::string_view const source return statement; } +ir::TypeNode *ETSParser::CreateFormattedTypeAnnotation(std::string_view const sourceCode) +{ + util::UString source {sourceCode, Allocator()}; + auto const isp = InnerSourceParser(this); + auto const lexer = InitLexer({GetContext().FormattingFileName(), source.View().Utf8()}); + lexer->NextToken(); + TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS; + return ParseTypeAnnotation(&options); +} + +ir::TypeNode *ETSParser::CreateFormattedTypeAnnotation(std::string_view const sourceCode, + std::vector &args) +{ + insertingNodes_.swap(args); + auto typeAnnotation = CreateFormattedTypeAnnotation(sourceCode); + insertingNodes_.swap(args); + return typeAnnotation; +} + ArenaVector ETSParser::CreateStatements(std::string_view const sourceCode) { util::UString source {sourceCode, Allocator()}; @@ -357,7 +374,7 @@ ArenaVector ETSParser::CreateFormattedStatements(std::string_vi ir::AstNode *ETSParser::CreateFormattedClassFieldDefinition(std::string_view sourceCode, std::vector &insertingNodes) { - static ArenaVector const DUMMY_ARRAY {Allocator()->Adapter()}; + thread_local static ArenaVector const DUMMY_ARRAY {Allocator()->Adapter()}; insertingNodes_.swap(insertingNodes); auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE); @@ -373,7 +390,7 @@ ir::AstNode *ETSParser::CreateFormattedClassFieldDefinition(std::string_view sou ir::AstNode *ETSParser::CreateFormattedClassMethodDefinition(std::string_view sourceCode, std::vector &insertingNodes) { - static ArenaVector const DUMMY_ARRAY {Allocator()->Adapter()}; + thread_local static ArenaVector const DUMMY_ARRAY {Allocator()->Adapter()}; insertingNodes_.swap(insertingNodes); auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE); @@ -494,7 +511,7 @@ ir::MethodDefinition *ETSParser::CreateConstructorDefinition(ir::ModifierFlags m modifiers |= ir::ModifierFlags::CONSTRUCTOR; Lexer()->NextToken(); - auto *const methodDefinition = ParseClassMethodDefinition(memberName, modifiers); + auto *const methodDefinition = ParseClassMethodDefinition(memberName, modifiers, true); methodDefinition->SetStart(startLoc); return methodDefinition; diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 3325fac950ed0fbfc688740f3cad19e7256b25ce..d5b315115018b2a89246b13722bd1608fdf06a4f 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -15,6 +15,8 @@ #include "ETSparser.h" #include "ETSNolintParser.h" +#include "program/program.h" +#include "public/public.h" #include #include "util/es2pandaMacros.h" @@ -100,7 +102,9 @@ bool ETSParser::IsETSParser() const noexcept std::unique_ptr ETSParser::InitLexer(const SourceFile &sourceFile) { GetProgram()->SetSource(sourceFile); + GetContext().Status() |= ParserStatus::ALLOW_JS_DOC_START; auto lexer = std::make_unique(&GetContext(), DiagnosticEngine()); + GetContext().Status() ^= ParserStatus::ALLOW_JS_DOC_START; SetLexer(lexer.get()); return lexer; } @@ -122,16 +126,24 @@ void ETSParser::ParseProgram(ScriptKind kind) statements.emplace_back(decl); // If we found a package declaration, then add all files with the same package to the package parse list AddPackageSourcesToParseList(); + GetContext().Status() |= ParserStatus::IN_PACKAGE; } ir::ETSModule *script; if ((GetContext().Status() & parser::ParserStatus::DEPENDENCY_ANALYZER_MODE) == 0) { script = ParseETSGlobalScript(startLoc, statements); } else { - script = ParseImportsOnly(startLoc, statements); + script = ParseImportsAndReExportOnly(startLoc, statements); + } + + if ((GetContext().Status() & ParserStatus::IN_PACKAGE) != 0) { + GetContext().Status() &= ~ParserStatus::IN_PACKAGE; + } + + if (!GetOptions().IsGenerateDeclEnableIsolated()) { + AddExternalSource(ParseSources(true)); } - AddExternalSource(ParseSources(true)); GetProgram()->SetAst(script); } @@ -155,11 +167,16 @@ ir::ETSModule *ETSParser::ParseETSGlobalScript(lexer::SourcePosition startLoc, A return etsModule; } -ir::ETSModule *ETSParser::ParseImportsOnly(lexer::SourcePosition startLoc, ArenaVector &statements) +ir::ETSModule *ETSParser::ParseImportsAndReExportOnly(lexer::SourcePosition startLoc, + ArenaVector &statements) { ETSNolintParser etsnolintParser(this); etsnolintParser.CollectETSNolints(); + if (Lexer()->TryEatTokenType(lexer::TokenType::JS_DOC_START)) { + // Note: Not Support JS_DOC for Import declaration now, just go on; + ParseJsDocInfos(); + } auto imports = ParseImportDeclarations(); statements.insert(statements.end(), imports.begin(), imports.end()); etsnolintParser.ApplyETSNolintsToStatements(statements); @@ -180,8 +197,16 @@ void ETSParser::AddExternalSource(const std::vector &programs) if (extSources.count(name) == 0) { extSources.try_emplace(name, Allocator()->Adapter()); } - - extSources.at(name).emplace_back(newProg); + bool found = false; + for (auto *prog : extSources.at(name)) { + if (prog->SourceFilePath() == newProg->SourceFilePath()) { + found = true; + break; + } + } + if (!found) { + extSources.at(name).emplace_back(newProg); + } } } @@ -198,7 +223,22 @@ ArenaVector ETSParser::ParseDefaultSources(std::stri auto statements = ParseImportDeclarations(); GetContext().Status() &= ~ParserStatus::IN_DEFAULT_IMPORTS; - AddExternalSource(ParseSources()); + std::vector programs; + auto *ctx = GetProgram()->VarBinder()->GetContext(); + if (ctx->compilingState == public_lib::CompilingState::MULTI_COMPILING_FOLLOW) { + return statements; + } + + if (!Context()->compiledByCapi) { + AddExternalSource(ParseSources()); + } else { + if (Context()->globalContext != nullptr && Context()->globalContext->stdLibAstCache != nullptr) { + globalProgram_->MergeExternalSource(Context()->globalContext->stdLibAstCache); + importPathManager_->ClearParseList(); + } else { + AddExternalSource(ParseSources()); + } + } return statements; } @@ -233,34 +273,54 @@ void ETSParser::ParseParseListElement(const util::ImportPathManager::ParseInfo & } } -std::vector ETSParser::ParseSources(bool firstSource) +static bool SearchImportedExternalSources(ETSParser *parser, const std::string_view &path) { - std::vector programs; - - auto &parseList = importPathManager_->ParseList(); + auto *ctx = parser->GetGlobalProgram()->VarBinder()->GetContext(); + if (ctx->compilingState != public_lib::CompilingState::MULTI_COMPILING_FOLLOW) { + return false; + } + for (const auto &[moduleName, extPrograms] : ctx->externalSources) { + for (auto *const extProg : extPrograms) { + if (extProg->SourceFilePath() == path) { + return true; + } + } + } + return false; +} - ArenaVector directImportsFromMainSource(Allocator()->Adapter()); +bool ETSParser::TryMergeFromCache(size_t idx, ArenaVector &parseList) +{ + if (Context()->globalContext == nullptr) { + return false; + } - if (firstSource) { - for (auto pl : parseList) { - if (pl.isParsed) { - // Handle excluded files, which are already set to be parsed before parsing them - continue; - } - directImportsFromMainSource.emplace_back(pl.importData.resolvedSource); + auto &importData = parseList[idx].importData; + auto src = importData.HasSpecifiedDeclPath() ? importData.declPath : importData.resolvedSource; + const auto &absPath = std::string {util::Path {src, Allocator()}.GetAbsolutePath()}; + auto cacheExtProgs = Context()->globalContext->cachedExternalPrograms; + if (cacheExtProgs.find(absPath) != cacheExtProgs.end() && cacheExtProgs[absPath] != nullptr) { + if (globalProgram_->MergeExternalSource(cacheExtProgs[absPath])) { + importPathManager_->MarkAsParsed(parseList[idx].importData.resolvedSource); + return true; } } + return false; +} +// NOTE (mmartin): Need a more optimal solution here +// This is needed, as during a parsing of a file, programs can be re-added to the parseList, which needs to be +// re-parsed. This won't change the size of the list, so with only the 'for loop', there can be unparsed files +// remained. +// An example for this, is when a file is added as an implicit package import, but it's erroneous, so we just ignore +// the file. But when the same file is also added with an explicit import declaration, then we need to re-parse it, +// and throw the syntax error. +std::vector ETSParser::SearchForNotParsed(ArenaVector &parseList, + ArenaVector &directImportsFromMainSource) +{ + std::vector programs; auto notParsedElement = std::find_if(parseList.begin(), parseList.end(), [](const auto &parseInfo) { return !parseInfo.isParsed; }); - - // NOTE (mmartin): Need a more optimal solution here - // This is needed, as during a parsing of a file, programs can be re-added to the parseList, which needs to be - // re-parsed. This won't change the size of the list, so with only the 'for loop', there can be unparsed files - // remained. - // An example for this, is when a file is added as an implicit package import, but it's erroneous, so we just ignore - // the file. But when the same file is also added with an explicit import declaration, then we need to re-parse it, - // and throw the syntax error. while (notParsedElement != parseList.end()) { // This parse list `paths` can grow in the meantime, so keep this index-based iteration // NOLINTNEXTLINE(modernize-loop-convert) @@ -269,6 +329,11 @@ std::vector ETSParser::ParseSources(bool firstSource) if (parseList[idx].isParsed) { continue; } + + if (TryMergeFromCache(idx, parseList)) { + continue; + } + const auto &data = parseList[idx].importData; if (data.declPath.empty()) { importPathManager_->MarkAsParsed(data.resolvedSource); @@ -280,34 +345,48 @@ std::vector ETSParser::ParseSources(bool firstSource) importPathManager_->MarkAsParsed(data.resolvedSource); return programs; } - util::DiagnosticMessageParams diagParams = {std::string(parseCandidate)}; std::ifstream inputStream {std::string(parseCandidate)}; if (!inputStream) { DiagnosticEngine().LogDiagnostic(diagnostic::OPEN_FAILED, diagParams); return programs; // Error processing. } - std::stringstream ss; ss << inputStream.rdbuf(); std::string externalSource = ss.str(); - auto preservedLang = GetContext().SetLanguage(data.lang); auto extSrc = Allocator()->New(externalSource, Allocator()); importPathManager_->MarkAsParsed(data.resolvedSource); - ParseParseListElement(parseList[idx], extSrc, directImportsFromMainSource, &programs); - GetContext().SetLanguage(preservedLang); } - notParsedElement = std::find_if(parseList.begin(), parseList.end(), [](const auto &parseInfo) { return !parseInfo.isParsed; }); } - return programs; } +std::vector ETSParser::ParseSources(bool firstSource) +{ + auto &parseList = importPathManager_->ParseList(); + ArenaVector directImportsFromMainSource(Allocator()->Adapter()); + if (firstSource) { + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t idx = 0; idx < parseList.size(); idx++) { + if (parseList[idx].isParsed) { + // Handle excluded files, which are already set to be parsed before parsing them + continue; + } + if (SearchImportedExternalSources(this, parseList[idx].importData.resolvedSource)) { + parseList[idx].isParsed = true; + continue; + } + directImportsFromMainSource.emplace_back(parseList[idx].importData.resolvedSource); + } + } + return SearchForNotParsed(parseList, directImportsFromMainSource); +} + parser::Program *ETSParser::ParseSource(const SourceFile &sourceFile) { importPathManager_->MarkAsParsed(sourceFile.filePath); @@ -320,10 +399,14 @@ parser::Program *ETSParser::ParseSource(const SourceFile &sourceFile) ArenaVector statements(Allocator()->Adapter()); auto decl = ParsePackageDeclaration(); + ir::ETSModule *script = nullptr; if (decl != nullptr) { statements.emplace_back(decl); + SavedParserContext contextAfterParseDecl(this, GetContext().Status() |= ParserStatus::IN_PACKAGE); + script = ParseETSGlobalScript(startLoc, statements); + } else { + script = ParseETSGlobalScript(startLoc, statements); } - auto script = ParseETSGlobalScript(startLoc, statements); program->SetAst(script); return program; } @@ -472,7 +555,7 @@ ir::AstNode *ETSParser::ParseInnerTypeDeclaration(ir::ModifierFlags memberModifi } ir::AstNode *ETSParser::ParseInnerConstructorDeclaration(ir::ModifierFlags memberModifiers, - const lexer::SourcePosition &startLoc) + const lexer::SourcePosition &startLoc, bool isDefault) { if ((memberModifiers & (~(ir::ModifierFlags::ACCESS | ir::ModifierFlags::DECLARE | ir::ModifierFlags::NATIVE))) != 0) { @@ -481,7 +564,7 @@ ir::AstNode *ETSParser::ParseInnerConstructorDeclaration(ir::ModifierFlags membe auto *memberName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); memberModifiers |= ir::ModifierFlags::CONSTRUCTOR; Lexer()->NextToken(); - auto *classMethod = ParseClassMethodDefinition(memberName, memberModifiers); + auto *classMethod = ParseClassMethodDefinition(memberName, memberModifiers, isDefault); classMethod->SetStart(startLoc); return classMethod; @@ -501,34 +584,34 @@ bool ETSParser::CheckAccessorDeclaration(ir::ModifierFlags memberModifiers) Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_SET) { return false; } - if (Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_PAREN || Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) { - return false; - } + ir::ModifierFlags methodModifiersNotAccessorModifiers = ir::ModifierFlags::ASYNC; if ((memberModifiers & methodModifiersNotAccessorModifiers) != 0) { LogError(diagnostic::MODIFIERS_OF_GET_SET_LIMITED); } - return true; + + auto pos = Lexer()->Save(); + Lexer()->NextToken(); + if (Lexer()->TryEatTokenType(lexer::TokenType::LITERAL_IDENT) || + Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_FORMAT)) { + Lexer()->Rewind(pos); + return true; + } + Lexer()->Rewind(pos); + + return false; } ir::AstNode *ETSParser::ParseInnerRest(const ArenaVector &properties, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags memberModifiers, - const lexer::SourcePosition &startLoc) + const lexer::SourcePosition &startLoc, bool isDefault) { if (CheckAccessorDeclaration(memberModifiers)) { - return ParseClassGetterSetterMethod(properties, modifiers, memberModifiers); + return ParseClassGetterSetterMethod(properties, modifiers, memberModifiers, isDefault); } - if ((GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0) { - auto type = Lexer()->GetToken().Type(); - if (type == lexer::TokenType::KEYW_FUNCTION || type == lexer::TokenType::KEYW_LET || - type == lexer::TokenType::KEYW_CONST) { - Lexer()->NextToken(); - } - } - - auto parseClassMethod = [&memberModifiers, &startLoc, this](ir::Identifier *methodName) { - auto *classMethod = ParseClassMethodDefinition(methodName, memberModifiers); + auto parseClassMethod = [&memberModifiers, &startLoc, isDefault, this](ir::Identifier *methodName) { + auto *classMethod = ParseClassMethodDefinition(methodName, memberModifiers, isDefault); classMethod->SetStart(startLoc); return classMethod; }; @@ -555,7 +638,7 @@ ir::AstNode *ETSParser::ParseInnerRest(const ArenaVector &propert ArenaVector fieldDeclarations(Allocator()->Adapter()); auto *placeholder = AllocNode(std::move(fieldDeclarations)); - ParseClassFieldDefinition(memberName, memberModifiers, placeholder->BodyPtr()); + ParseClassFieldDefinition(memberName, memberModifiers, placeholder->BodyPtr(), isDefault); return placeholder; } @@ -631,10 +714,20 @@ ir::TSTypeAliasDeclaration *ETSParser::ParseTypeAliasDeclaration() { ES2PANDA_ASSERT(Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPE); + const auto start = Lexer()->Save(); + + auto newStatus = GetContext().Status(); + newStatus &= ~ParserStatus::ALLOW_JS_DOC_START; + SavedParserContext savedContext(this, newStatus); lexer::SourcePosition typeStart = Lexer()->GetToken().Start(); Lexer()->NextToken(); // eat type keyword - if (Lexer()->GetToken().IsReservedTypeName()) { + if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + Lexer()->Rewind(start); + return nullptr; + } + + if (Lexer()->GetToken().IsReservedTypeName() && !util::Helpers::IsStdLib(GetProgram())) { LogError(diagnostic::TYPE_ALIAS_INVALID_NAME, {TokenToString(Lexer()->GetToken().KeywordType())}); } @@ -654,6 +747,9 @@ ir::TSTypeAliasDeclaration *ETSParser::ParseTypeAliasDeclaration() TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); + if (typeAnnotation == nullptr) { + return nullptr; + } typeAliasDecl->SetTsTypeAnnotation(typeAnnotation); typeAnnotation->SetParent(typeAliasDecl); typeAliasDecl->SetRange({typeStart, Lexer()->GetToken().End()}); @@ -856,10 +952,9 @@ std::tuple ETSParser::Pars if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT) { Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); } - *options |= TypeAnnotationParsingOptions::ALLOW_WILDCARD | TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW; + *options |= TypeAnnotationParsingOptions::ALLOW_WILDCARD; typeParamInst = ParseTypeParameterInstantiation(options); - *options &= - ~(TypeAnnotationParsingOptions::ALLOW_WILDCARD | TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW); + *options &= ~(TypeAnnotationParsingOptions::ALLOW_WILDCARD); } return {typeName, typeParamInst}; @@ -953,32 +1048,47 @@ void ETSParser::ParseRightParenthesis(TypeAnnotationParsingOptions *options, ir: void ETSParser::ReportIfVarDeclaration(VariableParsingFlags flags) { if ((flags & VariableParsingFlags::VAR) != 0) { - LogUnexpectedToken(lexer::TokenType::KEYW_VAR); + LogError(diagnostic::ERROR_ARKTS_NO_VAR); } } ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::ModifierFlags modifiers) { + const size_t exportDefaultMaxSize = 1; if (!InAmbientContext() && (GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0) { LogError(diagnostic::EXPORT_IN_NAMESPACE); } - ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY || - Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE || - Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT); + [[maybe_unused]] auto tokenType = Lexer()->GetToken().Type(); + // export a constant variable anonymously, as export default new A() + if ((modifiers & ir::ModifierFlags::DEFAULT_EXPORT) != 0U && tokenType != lexer::TokenType::PUNCTUATOR_MULTIPLY && + tokenType != lexer::TokenType::PUNCTUATOR_LEFT_BRACE && tokenType != lexer::TokenType::LITERAL_IDENT) { + return ParseSingleExport(modifiers); + } + ArenaVector specifiers(Allocator()->Adapter()); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { ParseNameSpaceSpecifier(&specifiers, true); + // export * as xxx from yyy, the xxx should have export flag to pass the following check. + specifiers[0]->AddModifier(ir::ModifierFlags::EXPORT); } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { auto specs = ParseNamedSpecifiers(); if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_FROM) { - specifiers = util::Helpers::ConvertVector(specs.first); + specifiers = util::Helpers::ConvertVector(specs.result); } else { ArenaVector exports(Allocator()->Adapter()); - for (auto spec : specs.first) { + for (auto spec : specs.result) { exports.emplace_back(AllocNode(spec->Local(), spec->Imported())); } + + if (specs.resultExportDefault.size() > exportDefaultMaxSize) { + LogError(diagnostic::EXPORT_DEFAULT_WITH_MUPLTIPLE_SPECIFIER); + } + for (auto spec : specs.resultExportDefault) { + exports.emplace_back(spec); + } + auto result = AllocNode(Allocator(), static_cast(nullptr), std::move(exports)); result->AddModifier(modifiers); @@ -993,7 +1103,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()->SourceFilePath(), Allocator()); + GetProgram()->AbsoluteName(), Allocator()); reExport->AddModifier(modifiers); return reExport; } @@ -1001,6 +1111,11 @@ ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::Modifi ir::ETSPackageDeclaration *ETSParser::ParsePackageDeclaration() { auto startLoc = Lexer()->GetToken().Start(); + auto savedPos = Lexer()->Save(); + if (Lexer()->TryEatTokenType(lexer::TokenType::JS_DOC_START)) { + // Note: Not Support JS_DOC for Package declaration now, just go on; + ParseJsDocInfos(); + } if (!Lexer()->TryEatTokenType(lexer::TokenType::KEYW_PACKAGE)) { // NOTE(vpukhov): the *unnamed* modules are to be removed entirely @@ -1008,6 +1123,7 @@ ir::ETSPackageDeclaration *ETSParser::ParsePackageDeclaration() util::StringView moduleName = isUnnamed ? "" : importPathManager_->FormModuleName(GetProgram()->SourceFile(), startLoc); GetProgram()->SetPackageInfo(moduleName, util::ModuleKind::MODULE); + Lexer()->Rewind(savedPos); return nullptr; } @@ -1049,7 +1165,12 @@ ir::ETSImportDeclaration *ETSParser::ParseImportPathBuildImport(ArenaVector(pathToResolve); importPathStringLiteral->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); - auto *const importDeclaration = BuildImportDeclaration(importKind, std::move(specifiers), importPathStringLiteral); + auto importFlags = (GetContext().Status() & parser::ParserStatus::IN_DEFAULT_IMPORTS) != 0U + ? util::ImportFlags::DEFAULT_IMPORT + : util::ImportFlags::NONE; + auto *const importDeclaration = + BuildImportDeclaration(importKind, std::move(specifiers), importPathStringLiteral, + const_cast(GetContext().GetProgram()), importFlags); importDeclaration->SetRange({startLoc, importPathStringLiteral->End()}); ConsumeSemicolon(importDeclaration); return importDeclaration; @@ -1057,19 +1178,28 @@ ir::ETSImportDeclaration *ETSParser::ParseImportPathBuildImport(ArenaVector &&specifiers, - ir::StringLiteral *pathToResolve) + ir::StringLiteral *pathToResolve, parser::Program *program, + util::ImportFlags importFlag) +{ + return AllocNode( + pathToResolve, importPathManager_->GatherImportMetadata(program, importFlag, pathToResolve), + std::move(specifiers), importKind); +} + +lexer::LexerPosition ETSParser::HandleJsDocLikeComments() { - ES2PANDA_ASSERT(GetProgram() == GetContext().GetProgram()); - return AllocNode(pathToResolve, - importPathManager_->GatherImportMetadata(GetContext(), pathToResolve), - std::move(specifiers), importKind); + auto savedPos = Lexer()->Save(); + if (Lexer()->TryEatTokenType(lexer::TokenType::JS_DOC_START)) { + ParseJsDocInfos(); + } + return savedPos; } ArenaVector ETSParser::ParseImportDeclarations() { + auto savedPos = HandleJsDocLikeComments(); std::vector userPaths; ArenaVector statements(Allocator()->Adapter()); - while (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_IMPORT) { auto startLoc = Lexer()->GetToken().Start(); Lexer()->NextToken(); // eat import @@ -1087,8 +1217,8 @@ ArenaVector ETSParser::ParseImportDeclarations() ParseNameSpaceSpecifier(&specifiers); } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { auto specs = ParseNamedSpecifiers(); - specifiers = util::Helpers::ConvertVector(specs.first); - defaultSpecifiers = util::Helpers::ConvertVector(specs.second); + specifiers = util::Helpers::ConvertVector(specs.result); + defaultSpecifiers = util::Helpers::ConvertVector(specs.resultDefault); } else { ParseImportDefaultSpecifier(&specifiers); } @@ -1107,17 +1237,49 @@ ArenaVector ETSParser::ParseImportDeclarations() statements.push_back(importDeclDefault->AsETSImportDeclaration()); } } + + savedPos = HandleJsDocLikeComments(); } + Lexer()->Rewind(savedPos); std::sort(statements.begin(), statements.end(), [](const auto *s1, const auto *s2) -> bool { return s1->Specifiers()[0]->IsImportNamespaceSpecifier() && !s2->Specifiers()[0]->IsImportNamespaceSpecifier(); }); return statements; } +ir::ExportNamedDeclaration *ETSParser::ParseSingleExportForAnonymousConst(ir::ModifierFlags modifiers) +{ + ir::Expression *constantExpression = ParseExpression(); + + auto *exported = AllocNode(compiler::Signatures::EXPORT_DEFAULT_CONSTANT_ANONYMOUSLY, Allocator()); + exported->SetRange(Lexer()->GetToken().Loc()); + + ArenaVector exports(Allocator()->Adapter()); + auto *exportSpecifier = AllocNode(exported, exported->Clone(Allocator(), nullptr)); + exportSpecifier->SetConstantExpression(constantExpression); + exportSpecifier->SetDefault(); + exports.push_back(exportSpecifier); + + auto result = AllocNode(Allocator(), static_cast(nullptr), + std::move(exports)); + result->AddModifier(modifiers); + ConsumeSemicolon(result); + + return result; +} + ir::ExportNamedDeclaration *ETSParser::ParseSingleExport(ir::ModifierFlags modifiers) { lexer::Token token = Lexer()->GetToken(); + if (((modifiers & ir::ModifierFlags::DEFAULT_EXPORT) != 0) && token.Type() != lexer::TokenType::LITERAL_IDENT) { + return ParseSingleExportForAnonymousConst(modifiers); + } + + if (token.Type() != lexer::TokenType::LITERAL_IDENT) { + LogError(diagnostic::EXPORT_NON_DECLARATION, {}, token.Start()); + return nullptr; + } auto *exported = AllocNode(token.Ident(), Allocator()); exported->SetRange(Lexer()->GetToken().Loc()); @@ -1145,6 +1307,25 @@ bool ETSParser::IsDefaultImport() return false; } +bool TypedParser::IsPrimitiveType(const lexer::TokenType &tokenType) +{ + switch (tokenType) { + case lexer::TokenType::KEYW_BIGINT: + case lexer::TokenType::KEYW_BOOLEAN: + case lexer::TokenType::KEYW_BYTE: + case lexer::TokenType::KEYW_CHAR: + case lexer::TokenType::KEYW_DOUBLE: + case lexer::TokenType::KEYW_FLOAT: + case lexer::TokenType::KEYW_INT: + case lexer::TokenType::KEYW_LONG: + case lexer::TokenType::KEYW_SHORT: + case lexer::TokenType::KEYW_VOID: + return true; + default: + return false; + } +} + void ETSParser::ParseNamedSpecifiesDefaultImport(ArenaVector *resultDefault, const std::string &fileName) { @@ -1159,9 +1340,50 @@ void ETSParser::ParseNamedSpecifiesDefaultImport(ArenaVectoremplace_back(specifier); } -using ImportSpecifierVector = ArenaVector; -using ImportDefaultSpecifierVector = ArenaVector; -std::pair ETSParser::ParseNamedSpecifiers() +bool ETSParser::ParseNamedSpecifiesImport(ArenaVector *result, + ArenaVector *resultExportDefault, + const std::string &fileName) +{ + if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + ir::Expression *constantExpression = ParseUnaryOrPrefixUpdateExpression(); + auto *exported = + AllocNode(compiler::Signatures::EXPORT_DEFAULT_CONSTANT_ANONYMOUSLY, Allocator()); + exported->SetRange(Lexer()->GetToken().Loc()); + auto *exportedAnonyConst = AllocNode(exported, exported->Clone(Allocator(), nullptr)); + exportedAnonyConst->SetConstantExpression(constantExpression); + exportedAnonyConst->SetDefault(); + resultExportDefault->emplace_back(exportedAnonyConst); + return Lexer()->TryEatTokenType(lexer::TokenType::KEYW_AS) && + Lexer()->TryEatTokenType(lexer::TokenType::KEYW_DEFAULT); + } + + lexer::Token importedToken = Lexer()->GetToken(); + auto *imported = ExpectIdentifier(); + + ir::Identifier *local = nullptr; + if (CheckModuleAsModifier() && Lexer()->TryEatTokenType(lexer::TokenType::KEYW_AS)) { + if (Lexer()->TryEatTokenType(lexer::TokenType::KEYW_DEFAULT)) { + auto *exportedAnonyConst = AllocNode(imported, imported->Clone(Allocator(), nullptr)); + exportedAnonyConst->SetDefault(); + resultExportDefault->emplace_back(exportedAnonyConst); + return true; + } + local = ParseNamedImport(&Lexer()->GetToken()); + Lexer()->NextToken(); + } else { + local = ParseNamedImport(&importedToken); + } + + auto *specifier = AllocNode(imported, local); + specifier->SetRange({imported->Start(), local->End()}); + + util::Helpers::CheckImportedName(*result, specifier, fileName); + + result->emplace_back(specifier); + return true; +} + +SpecifiersInfo ETSParser::ParseNamedSpecifiers() { // NOTE(user): handle qualifiedName in file bindings: qualifiedName '.' '*' if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_LEFT_BRACE)) { @@ -1176,44 +1398,23 @@ std::pair ETSParser::ParseN ArenaVector result(Allocator()->Adapter()); ArenaVector resultDefault(Allocator()->Adapter()); + ArenaVector resultExportDefault(Allocator()->Adapter()); ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::KEYWORD_TO_IDENT, - [this, &result, &resultDefault, &fileName]() { + [this, &result, &resultDefault, &resultExportDefault, &fileName]() { if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { LogError(diagnostic::ASTERIKS_NOT_ALLOWED_IN_SELECTIVE_BINDING); } if (!IsDefaultImport()) { - if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { - // NOTE: needs to be replaced by returning invalid value from `ExpectIdentifier` - ExpectToken(lexer::TokenType::LITERAL_IDENT); - return false; - } - lexer::Token importedToken = Lexer()->GetToken(); - auto *imported = ExpectIdentifier(); - - ir::Identifier *local = nullptr; - if (CheckModuleAsModifier() && Lexer()->TryEatTokenType(lexer::TokenType::KEYW_AS)) { - local = ParseNamedImport(&Lexer()->GetToken()); - Lexer()->NextToken(); - } else { - local = ParseNamedImport(&importedToken); - } - - auto *specifier = AllocNode(imported, local); - specifier->SetRange({imported->Start(), local->End()}); - - util::Helpers::CheckImportedName(result, specifier, fileName); - - result.emplace_back(specifier); - } else { - ParseNamedSpecifiesDefaultImport(&resultDefault, fileName); + return ParseNamedSpecifiesImport(&result, &resultExportDefault, fileName); } + ParseNamedSpecifiesDefaultImport(&resultDefault, fileName); return true; }, nullptr, true); - return {result, resultDefault}; + return {result, resultDefault, resultExportDefault}; } void ETSParser::ParseNameSpaceSpecifier(ArenaVector *specifiers, bool isReExport) @@ -1229,12 +1430,12 @@ void ETSParser::ParseNameSpaceSpecifier(ArenaVector *specifiers, // should be handled at some point. if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_FROM && !isReExport && (GetContext().Status() & ParserStatus::IN_DEFAULT_IMPORTS) == 0) { - LogExpectedToken(lexer::TokenType::KEYW_AS); // invalid_namespce_import.ets + LogExpectedToken(lexer::TokenType::KEYW_AS); // invalid_namespace_import.ets } auto *local = AllocNode(util::StringView(""), Allocator()); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA || - Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_FROM || isReExport) { + Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_FROM) { auto *specifier = AllocNode(local); specifier->SetRange({namespaceStart, Lexer()->GetToken().End()}); specifiers->push_back(specifier); @@ -1261,6 +1462,19 @@ ir::AstNode *ETSParser::ParseImportDefaultSpecifier(ArenaVector * imported->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // Eat import specifier. + // Support is needed at present. + // 1.import defaultExport,allBinding from importPath + // 2.import defaultExport,selectiveBindings from importPath + if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COMMA)) { + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { + ParseNameSpaceSpecifier(specifiers); + } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + auto specs = ParseNamedSpecifiers(); + auto importSpecifiers = util::Helpers::ConvertVector(specs.result); + specifiers->insert(specifiers->end(), importSpecifiers.begin(), importSpecifiers.end()); + } + } + if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_FROM) { LogExpectedToken(lexer::TokenType::KEYW_FROM); Lexer()->NextToken(); // eat 'from' @@ -1419,10 +1633,6 @@ ir::Expression *ETSParser::ParseFunctionParameter() // 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 SkipInvalidType(); - } else if (paramIdent->IsRestElement() && !typeAnnotation->IsTSArrayType() && - !IsFixedArrayTypeNode(typeAnnotation)) { - // NOTE (mmartin): implement tuple types for rest parameters - LogError(diagnostic::ONLY_ARRAY_FOR_REST); } typeAnnotation->SetParent(paramIdent); paramIdent->SetTsTypeAnnotation(typeAnnotation); @@ -1591,7 +1801,7 @@ ir::Statement *ETSParser::ParseImportDeclaration([[maybe_unused]] StatementParsi ir::Statement *ETSParser::ParseExportDeclaration([[maybe_unused]] StatementParsingFlags flags) { LogUnexpectedToken(lexer::TokenType::KEYW_EXPORT); - return nullptr; + return AllocBrokenStatement(Lexer()->GetToken().Loc()); } ir::Expression *ETSParser::ParseExpressionOrTypeAnnotation(lexer::TokenType type, @@ -1780,7 +1990,7 @@ ir::TSTypeParameter *ETSParser::ParseTypeParameter([[maybe_unused]] TypeAnnotati } } auto saveLoc = Lexer()->GetToken().Start(); - auto *paramIdent = ExpectIdentifier(); + auto *paramIdent = ExpectIdentifier(false, false, *options); ir::TypeNode *constraint = nullptr; if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS) { @@ -1847,6 +2057,7 @@ void ETSParser::CheckDeclare() case lexer::TokenType::KEYW_ABSTRACT: case lexer::TokenType::KEYW_FINAL: case lexer::TokenType::KEYW_INTERFACE: + case lexer::TokenType::KEYW_TYPE: case lexer::TokenType::KEYW_ASYNC: { return; } @@ -1865,7 +2076,7 @@ ir::FunctionDeclaration *ETSParser::ParseFunctionDeclaration(bool canBeAnonymous ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::KEYW_FUNCTION); Lexer()->NextToken(); - auto newStatus = ParserStatus::NEED_RETURN_TYPE | ParserStatus::ALLOW_SUPER; + auto newStatus = ParserStatus::NEED_RETURN_TYPE | ParserStatus::ALLOW_SUPER | ParserStatus::ALLOW_JS_DOC_START; if ((modifiers & ir::ModifierFlags::ASYNC) != 0) { newStatus |= ParserStatus::ASYNC_FUNCTION; @@ -1952,11 +2163,11 @@ ir::FunctionDeclaration *ETSParser::ParseAccessorWithReceiver(ir::ModifierFlags void ETSParser::AddPackageSourcesToParseList() { - importPathManager_->AddImplicitPackageImportToParseList(GetProgram()->SourceFileFolder(), + importPathManager_->AddImplicitPackageImportToParseList(GetProgram()->SourceFile().GetAbsoluteParentFolder(), Lexer()->GetToken().Start()); // Global program file is always in the same folder that we scanned, but we don't need to parse it twice - importPathManager_->MarkAsParsed(globalProgram_->SourceFilePath()); + importPathManager_->MarkAsParsed(globalProgram_->AbsoluteName()); } //================================================================================================// diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 9632039455bad820374bb50c506c03e071e0820f..6ca2d6d6c8c09d7b66be307381d10bbf303eb358 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -18,6 +18,7 @@ #include "util/arktsconfig.h" #include "util/importPathManager.h" +#include "util/recursiveGuard.h" #include "innerSourceParser.h" #include "TypedParser.h" #include "ir/base/classDefinition.h" @@ -32,6 +33,12 @@ enum class PrimitiveType; namespace ark::es2panda::parser { +struct SpecifiersInfo { + ArenaVector result; + ArenaVector resultDefault; + ArenaVector resultExportDefault; +}; + class ETSParser final : public TypedParser { public: ETSParser(Program *program, const util::Options &options, util::DiagnosticEngine &diagnosticEngine, @@ -54,11 +61,17 @@ public: return globalProgram_->AbsoluteName(); } + Program *GetGlobalProgram() + { + return globalProgram_; + } + [[nodiscard]] bool IsETSParser() const noexcept override; void AddDirectImportsToDirectExternalSources(const ArenaVector &directImportsFromMainSource, parser::Program *newProg) const; ArenaVector ParseDefaultSources(std::string_view srcFile, std::string_view importSrc); + lexer::LexerPosition HandleJsDocLikeComments(); public: //============================================================================================// @@ -74,156 +87,34 @@ public: return GetContext().FormattingFileName(); } - template - void SetFormattingFileName(T &&fileName) - { - GetContext().SetFormattingFileName(std::forward(fileName)); - } + ir::TypeNode *CreateFormattedTypeAnnotation(std::string_view const sourceCode); + ir::TypeNode *CreateFormattedTypeAnnotation(std::string_view sourceCode, std::vector &args); - template - void ProcessFormattedArg(std::vector &nodes, T &&arg) - { - if constexpr (std::is_convertible_v, ir::AstNode *>) { - nodes.emplace_back(std::forward(arg)); - } else if constexpr (std::is_same_v, util::StringView>) { - nodes.emplace_back(AllocNode(std::forward(arg), Allocator())); - } else if constexpr (std::is_same_v, util::UString>) { - nodes.emplace_back(AllocNode(arg.View(), Allocator())); - } else if constexpr (std::is_same_v, std::string>) { - nodes.emplace_back( - AllocNode(util::UString(std::forward(arg), Allocator()).View(), Allocator())); - } else if constexpr (std::is_constructible_v>) { - nodes.emplace_back(AllocNode( - util::UString(std::string {std::forward(arg)}, Allocator()).View(), Allocator())); - } else if constexpr (std::is_convertible_v, checker::Type *>) { - nodes.emplace_back(AllocNode(std::forward(arg), Allocator())); - } else if constexpr (std::is_same_v, ArenaVector>) { - nodes.emplace_back(AllocNode(std::forward(arg))); - } else if constexpr (std::is_same_v, ArenaVector>) { - nodes.emplace_back(AllocNode(std::forward(arg))); - } else if constexpr (std::is_same_v, ArenaVector>) { - nodes.emplace_back(AllocNode(std::forward(arg))); - } else if constexpr (std::is_same_v, ArenaVector>) { - for (auto *type : arg) { - nodes.emplace_back(AllocNode(type, Allocator())); - } - } else { - static_assert(STATIC_FALSE, "Format argument has invalid type."); - } - } +#include "parser/ETSparserTemplates.h" ir::Expression *CreateExpression(std::string_view sourceCode, ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS); - ir::Expression *CreateFormattedExpression(std::string_view sourceCode, std::vector &insertingNodes); - template - ir::Expression *CreateFormattedExpression(std::string_view const sourceCode, Args &&...args) - { - std::vector insertingNodes {}; - insertingNodes.reserve(sizeof...(Args)); - (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); - return CreateFormattedExpression(sourceCode, insertingNodes); - } - ir::Expression *CreateFormattedExpression(std::string_view const sourceCode, ArenaVector &args); - ir::Statement *CreateFormattedStatement(std::string_view sourceCode, std::vector &insertingNodes); - - template - ir::Statement *CreateFormattedStatement(std::string_view const sourceCode, Args &&...args) - { - std::vector insertingNodes {}; - insertingNodes.reserve(sizeof...(Args)); - (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); - return CreateFormattedStatement(sourceCode, insertingNodes); - } - ArenaVector CreateStatements(std::string_view sourceCode); - ArenaVector CreateFormattedStatements(std::string_view sourceCode, std::vector &insertingNodes); - - template - ArenaVector CreateFormattedStatements(std::string_view const sourceCode, Args &&...args) - { - std::vector insertingNodes {}; - insertingNodes.reserve(sizeof...(Args)); - (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); - return CreateFormattedStatements(sourceCode, insertingNodes); - } ir::Statement *ParseTopLevelAnnotation(ir::ModifierFlags memberModifiers); ArenaVector ParseAnnotations(bool isTopLevelSt); ir::Statement *CreateFormattedClassDeclaration(std::string_view sourceCode, std::vector &insertingNodes, bool allowStatic = false); - - template - ir::Statement *CreateFormattedClassDeclaration(std::string_view sourceCode, bool allowStatic, Args &&...args) - { - std::vector insertingNodes {}; - insertingNodes.reserve(sizeof...(Args)); - (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); - return CreateFormattedClassDeclaration(sourceCode, insertingNodes, allowStatic); - } - ir::AstNode *CreateFormattedClassElement(std::string_view sourceCode, std::vector &insertingNodes, const ArenaVector &properties, ir::ClassDefinitionModifiers modifiers); - - template - ir::AstNode *CreateFormattedClassElement(std::string_view sourceCode, const ArenaVector &properties, - ir::ClassDefinitionModifiers modifiers, Args &&...args) - { - std::vector insertingNodes {}; - insertingNodes.reserve(sizeof...(Args)); - (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); - return CreateFormattedClassElement(sourceCode, insertingNodes, properties, modifiers); - } - - template - ir::AstNode *CreateFormattedClassElement(std::string_view sourceCode, ir::ClassDefinition *classDefinition, - Args &&...args) - { - return CreateFormattedClassElement(sourceCode, classDefinition->Body(), classDefinition->Modifiers(), - std::forward(args...)); - } - ir::AstNode *CreateFormattedClassFieldDefinition(std::string_view sourceCode, std::vector &insertingNodes); - - template - ir::AstNode *CreateFormattedClassFieldDefinition(std::string_view const sourceCode, Args &&...args) - { - std::vector insertingNodes {}; - insertingNodes.reserve(sizeof...(Args)); - (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); - return CreateFormattedClassFieldDefinition(sourceCode, insertingNodes); - } - ir::AstNode *CreateFormattedClassMethodDefinition(std::string_view sourceCode, std::vector &insertingNodes); - - template - ir::AstNode *CreateFormattedClassMethodDefinition(std::string_view const sourceCode, Args &&...args) - { - std::vector insertingNodes {}; - insertingNodes.reserve(sizeof...(Args)); - (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); - return CreateFormattedClassMethodDefinition(sourceCode, insertingNodes); - } - ir::Statement *CreateFormattedTopLevelStatement(std::string_view sourceCode, std::vector &insertingNodes); - - template - ir::Statement *CreateFormattedTopLevelStatement(std::string_view sourceCode, Args &&...args) - { - std::vector insertingNodes {}; - insertingNodes.reserve(sizeof...(Args)); - (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); - return CreateFormattedTopLevelStatement(sourceCode, insertingNodes); - } void ApplyAnnotationsToNode(ir::AstNode *node, ArenaVector &&annotations, lexer::SourcePosition pos, TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::NO_OPTS); @@ -244,21 +135,22 @@ public: namespaceNestedRank_--; } - ir::ETSImportDeclaration *BuildImportDeclaration(ir::ImportKinds importKinds, + ir::ETSImportDeclaration *BuildImportDeclaration(ir::ImportKinds importKind, ArenaVector &&specifiers, - ir::StringLiteral *pathToResolve); + ir::StringLiteral *pathToResolve, parser::Program *program, + util::ImportFlags importFlag); void AddExternalSource(const std::vector &programs); std::vector ParseSources(bool firstSource = false); private: NodeFormatType GetFormatPlaceholderType(); - ir::Statement *ParseStatementFormatPlaceholder() override; ir::Expression *ParseExpressionFormatPlaceholder(); ir::Identifier *ParseIdentifierFormatPlaceholder(std::optional nodeFormat) override; ir::TypeNode *ParseTypeFormatPlaceholder(std::optional nodeFormat = std::nullopt); ir::AstNode *ParseTypeParametersFormatPlaceholder() override; + void ApplyJsDocInfoToSpecificNodeType(ir::AstNode *node, ArenaVector &&jsDocInformation); void ApplyAnnotationsToArrayType(ir::AstNode *node, ArenaVector &&annotations, lexer::SourcePosition pos); void ApplyAnnotationsToSpecificNodeType(ir::AstNode *node, ArenaVector &&annotations, @@ -266,15 +158,11 @@ private: ArenaVector &ParseAstNodesArrayFormatPlaceholder() override; ArenaVector &ParseStatementsArrayFormatPlaceholder() override; ArenaVector &ParseExpressionsArrayFormatPlaceholder() override; - ir::Statement *CreateStatement(std::string_view sourceCode); - ir::MethodDefinition *CreateConstructorDefinition(ir::ModifierFlags modifiers, std::string_view sourceCode); - ir::Statement *CreateClassDeclaration(std::string_view sourceCode, bool allowStatic = false); ir::AstNode *CreateClassElement(std::string_view sourceCode, const ArenaVector &properties, ir::ClassDefinitionModifiers modifiers); - ir::TypeNode *CreateTypeAnnotation(TypeAnnotationParsingOptions *options, std::string_view sourceCode); ir::Statement *CreateTopLevelStatement(std::string_view const sourceCode); @@ -288,7 +176,6 @@ private: ir::ETSPackageDeclaration *ParsePackageDeclaration(); void AddPackageSourcesToParseList(); ArenaVector ParseTopLevelStatements(); - ir::AstNode *HandleAmbientDeclaration(ir::ModifierFlags &memberModifiers, const std::function &parseClassMethod); static bool IsClassMethodModifier(lexer::TokenType type) noexcept; @@ -307,21 +194,29 @@ private: bool IsDefaultImport(); void ParseNamedSpecifiesDefaultImport(ArenaVector *resultDefault, const std::string &fileName); - std::pair, ArenaVector> ParseNamedSpecifiers(); + bool ParseNamedSpecifiesImport(ArenaVector *result, + ArenaVector *resultExportDefault, + const std::string &fileName); + SpecifiersInfo ParseNamedSpecifiers(); ir::ExportNamedDeclaration *ParseSingleExport(ir::ModifierFlags modifiers); + ir::ExportNamedDeclaration *ParseSingleExportForAnonymousConst(ir::ModifierFlags modifiers); ArenaVector ParseImportDeclarations(); ir::Statement *ParseImportDeclarationHelper(lexer::SourcePosition startLoc, ArenaVector &specifiers, ir::ImportKinds importKind); + bool TryMergeFromCache(size_t idx, ArenaVector &parseList); + std::vector SearchForNotParsed(ArenaVector &parseList, + ArenaVector &directImportsFromMainSource); parser::Program *ParseSource(const SourceFile &sourceFile); ir::ETSModule *ParseETSGlobalScript(lexer::SourcePosition startLoc, ArenaVector &statements); - ir::ETSModule *ParseImportsOnly(lexer::SourcePosition startLoc, ArenaVector &statements); + ir::ETSModule *ParseImportsAndReExportOnly(lexer::SourcePosition startLoc, + ArenaVector &statements); ir::AstNode *ParseImportDefaultSpecifier(ArenaVector *specifiers) override; - void *ApplyAnnotationsToClassElement(ir::AstNode *property, ArenaVector &&annotations, lexer::SourcePosition pos); + void ApplyJsDocInfoToClassElement(ir::AstNode *property, ArenaVector &&jsDocInformation); ir::MethodDefinition *ParseClassGetterSetterMethod(const ArenaVector &properties, ir::ClassDefinitionModifiers modifiers, - ir::ModifierFlags memberModifiers); + ir::ModifierFlags memberModifiers, bool isDefault); ir::MethodDefinition *ParseInterfaceGetterSetterMethod(const ir::ModifierFlags modifiers); ir::Statement *ParseIdentKeyword(); ir::Statement *ParseTypeDeclaration(bool allowStatic = false); @@ -329,13 +224,16 @@ private: ir::ModifierFlags ParseClassModifiers(); ir::ModifierFlags ParseInterfaceMethodModifiers(); ir::AstNode *ParseInterfaceField(); + ir::TypeNode *ParseInterfaceTypeAnnotation(ir::Identifier *name); + void ParseInterfaceModifiers(ir::ModifierFlags &fieldModifiers, bool &optionalField); ir::MethodDefinition *ParseInterfaceMethod(ir::ModifierFlags flags, ir::MethodDefinitionKind methodKind); void ReportAccessModifierError(const lexer::Token &token); - std::tuple ParseClassMemberAccessModifiers(); + std::tuple ParseClassMemberAccessModifiers(); ir::ModifierFlags ParseClassFieldModifiers(bool seenStatic); ir::ModifierFlags ParseClassMethodModifierFlag(); ir::ModifierFlags ParseClassMethodModifiers(bool seenStatic); - ir::MethodDefinition *ParseClassMethodDefinition(ir::Identifier *methodName, ir::ModifierFlags modifiers); + ir::MethodDefinition *ParseClassMethodDefinition(ir::Identifier *methodName, ir::ModifierFlags modifiers, + bool isDefault); ir::ScriptFunction *ParseFunction(ParserStatus newStatus); ir::MethodDefinition *ParseClassMethod(ClassElementDescriptor *desc, const ArenaVector &properties, ir::Expression *propName, lexer::SourcePosition *propEnd) override; @@ -345,9 +243,11 @@ private: ir::ScriptFunctionFlags ParseFunctionThrowMarker(bool isRethrowsAllowed) override; ir::Expression *CreateParameterThis(ir::TypeNode *typeAnnotation) override; ir::TypeNode *ConvertToOptionalUnionType(ir::TypeNode *typeAnno); + void ValidateFieldModifiers(ir::ModifierFlags modifiers, bool optionalField, ir::Expression *initializer, + lexer::SourcePosition pos); // NOLINTNEXTLINE(google-default-arguments) void ParseClassFieldDefinition(ir::Identifier *fieldName, ir::ModifierFlags modifiers, - ArenaVector *declarations); + ArenaVector *declarations, bool isDefault); std::tuple ParseTypeReferencePart( TypeAnnotationParsingOptions *options); ir::TypeNode *ParseTypeReference(TypeAnnotationParsingOptions *options); @@ -367,9 +267,7 @@ private: ir::TSInterfaceDeclaration *ParseInterfaceBody(ir::Identifier *name, bool isStatic); bool IsArrowFunctionExpressionStart(); ir::ArrowFunctionExpression *ParseArrowFunctionExpression(); - void ReportIfVarDeclaration(VariableParsingFlags flags) override; - ir::TypeNode *ParsePotentialFunctionalType(TypeAnnotationParsingOptions *options); std::pair GetTypeAnnotationFromToken(TypeAnnotationParsingOptions *options); std::pair GetTypeAnnotationFromParentheses(TypeAnnotationParsingOptions *options); @@ -381,10 +279,8 @@ private: bool ParseReadonlyInTypeAnnotation(); ir::TypeNode *ParseMultilineString(); ir::TSTypeAliasDeclaration *ParseTypeAliasDeclaration() override; - bool ValidateForInStatement() override; bool ValidAnnotationValue(ir::Expression *initializer); - // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParseCoverParenthesizedExpressionAndArrowParameterList( ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; @@ -399,7 +295,9 @@ private: VariableParsingFlags flags) override; ir::VariableDeclarator *ParseVariableDeclaratorInitializer(ir::Expression *init, VariableParsingFlags flags, const lexer::SourcePosition &startLoc) override; + bool IsFieldStartToken(lexer::TokenType t); ir::AstNode *ParseTypeLiteralOrInterfaceMember() override; + ir::AstNode *ParseJsDocInfoInInterfaceBody(); ir::AstNode *ParseAnnotationsInInterfaceBody(); void ParseNameSpaceSpecifier(ArenaVector *specifiers, bool isReExport = false); bool CheckModuleAsModifier(); @@ -412,6 +310,8 @@ private: ir::Expression *ParseFunctionReceiver(); ir::AnnotatedExpression *GetAnnotatedExpressionFromParam(); ir::Expression *ResolveArgumentUnaryExpr(ExpressionParseFlags flags); + ir::Expression *CreateUnaryExpressionFromArgument(ir::Expression *argument, lexer::TokenType operatorType, + char32_t beginningChar); // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParseUnaryOrPrefixUpdateExpression( ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; @@ -436,10 +336,13 @@ private: // NOLINTNEXTLINE(google-default-arguments) ir::Statement *ParseStructStatement(StatementParsingFlags flags, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags = ir::ModifierFlags::NONE) override; + ir::AstNode *ParseClassElementHelper( + const ArenaVector &properties, + std::tuple modifierInfo, + std::tuple elementFlag, std::tuple posInfo); ir::AstNode *ParseClassElement(const ArenaVector &properties, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags flags) override; - std::pair HandleClassElementModifiers(ArenaVector &annotations, - ir::ModifierFlags &memberModifiers); + std::tuple HandleClassElementModifiers(ir::ModifierFlags &memberModifiers); void UpdateMemberModifiers(ir::ModifierFlags &memberModifiers, bool &seenStatic); ir::ModifierFlags ParseMemberAccessModifiers(); template @@ -457,30 +360,25 @@ private: ir::AstNode *ParseInnerTypeDeclaration(ir::ModifierFlags memberModifiers, lexer::LexerPosition savedPos, bool isStepToken, bool seenStatic); ir::AstNode *ParseInnerConstructorDeclaration(ir::ModifierFlags memberModifiers, - const lexer::SourcePosition &startLoc); + const lexer::SourcePosition &startLoc, bool isDefault); ir::AstNode *ParseInnerRest(const ArenaVector &properties, ir::ClassDefinitionModifiers modifiers, - ir::ModifierFlags memberModifiers, const lexer::SourcePosition &startLoc); + ir::ModifierFlags memberModifiers, const lexer::SourcePosition &startLoc, + bool isDefault); bool CheckAccessorDeclaration(ir::ModifierFlags memberModifiers); - ir::AstNode *ParseAmbientSignature(const lexer::SourcePosition &startPosAmbient); - void ParseArgumentsNewExpression(ArenaVector &arguments, ir::TypeNode *typeReference); ir::Identifier *CreateInvokeIdentifier(); - ir::Expression *ParseNewExpression() override; ir::Expression *ParseAsyncExpression(); ir::Expression *ParseAwaitExpression(); ir::ArrayExpression *ParseArrayExpression(ExpressionParseFlags flags) override; ir::TSTypeParameter *ParseTypeParameter(TypeAnnotationParsingOptions *options) override; - bool IsStringEnum(); ir::TSEnumDeclaration *ParseEnumMembers(ir::Identifier *key, const lexer::SourcePosition &enumStart, bool isConst, bool isStatic) override; - ir::Expression *ParseEnumExpression(); bool ParseNumberEnumHelper(); lexer::SourcePosition ParseEnumMember(ArenaVector &members); - ir::Statement *ParseInterfaceDeclaration(bool isStatic) override; ir::TypeNode *ParseThisType(TypeAnnotationParsingOptions *options); ir::Statement *ParseFunctionStatement(StatementParsingFlags flags) override; @@ -501,13 +399,11 @@ private: // NOLINTNEXTLINE(google-default-arguments) ir::Statement *ParseEnumDeclaration(bool isConst = false, bool isStatic = false) override; ir::Statement *ParsePotentialConstEnum(VariableParsingFlags flags) override; - ir::Expression *ParseLaunchExpression(ExpressionParseFlags flags); void ValidateInstanceOfExpression(ir::Expression *expr); void ValidateRestParameter(ir::Expression *param) override; bool ValidateBreakLabel(util::StringView label) override; bool ValidateContinueLabel(util::StringView label) override; void CheckPredefinedMethods(ir::ScriptFunction const *function, const lexer::SourcePosition &position); - bool CheckClassElement(ir::AstNode *property, ir::MethodDefinition *&ctor, ArenaVector &properties) override; void CreateImplicitConstructor(ir::MethodDefinition *&ctor, ArenaVector &properties, @@ -516,11 +412,8 @@ private: bool ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir::Expression **returnExpression, const lexer::SourcePosition &startLoc, bool ignoreCallExpression) override; bool ParsePotentialNonNullExpression(ir::Expression **expression, lexer::SourcePosition startLoc) override; - std::pair ParseMemberModifiers(); - void SkipInvalidType() const; - bool IsStructKeyword() const; bool IsExternal() const override @@ -530,23 +423,24 @@ private: // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ParseExpression(ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; - ir::Expression *ParseExpressionOrTypeAnnotation(lexer::TokenType type, ExpressionParseFlags flags) override; - ir::Expression *ParsePotentialExpressionSequence(ir::Expression *expr, ExpressionParseFlags flags) override; - ir::ModifierFlags ParseTypeVarianceModifier(TypeAnnotationParsingOptions *const options); - bool IsExportedDeclaration(ir::ModifierFlags memberModifiers); ir::Statement *ParseTopLevelDeclStatement(StatementParsingFlags flags); ir::Statement *ParseTopLevelStatement(); - void ParseTrailingBlock([[maybe_unused]] ir::CallExpression *callExpr) override; - void CheckDeclare(); + void ExcludeInvalidStart(); + std::tuple ParseJsDocInfoItemValue(); + std::string ParseJsDocInfoItemParam(); + ir::JsDocInfo ParseJsDocInfo(); + ArenaVector ParseJsDocInfos(); + friend class ExternalSourceParser; friend class InnerSourceParser; + friend ir::Expression *HandleLeftParanthesis(ETSParser *parser, ExpressionParseFlags flags); private: uint32_t namespaceNestedRank_; @@ -556,6 +450,7 @@ private: parser::Program *globalProgram_; std::vector insertingNodes_ {}; std::unique_ptr importPathManager_ {nullptr}; + RecursiveContext recursiveCtx_; }; class ExternalSourceParser { @@ -596,6 +491,5 @@ private: ETSParser *parser_; std::string_view savedFname_; }; - } // namespace ark::es2panda::parser #endif diff --git a/ets2panda/parser/ETSparserAnnotations.cpp b/ets2panda/parser/ETSparserAnnotations.cpp index 511953a3c3894b6a6e3eb329e1f0bce21caef93a..25c6ec13c3afa43bcb08aafbe371f0a326fe044b 100644 --- a/ets2panda/parser/ETSparserAnnotations.cpp +++ b/ets2panda/parser/ETSparserAnnotations.cpp @@ -273,12 +273,6 @@ void ETSParser::ApplyAnnotationsToNode(ir::AstNode *node, ArenaVectorIsAnnotationDeclaration() && node->IsAbstract()) || - (node->IsClassDeclaration() && node->AsClassDeclaration()->Definition()->IsAbstract())) { - LogError(diagnostic::ANNOTATION_ABSTRACT, {}, pos); - return; - } - if (node->IsExpressionStatement()) { ApplyAnnotationsToNode(node->AsExpressionStatement()->GetExpression(), std::move(annotations), pos); return; @@ -287,16 +281,6 @@ void ETSParser::ApplyAnnotationsToNode(ir::AstNode *node, ArenaVector &&annotations, - lexer::SourcePosition pos) -{ - const auto *elementType = node->AsTSArrayType()->ElementType(); - while (elementType->IsTSArrayType()) { - elementType = elementType->AsTSArrayType()->ElementType(); - } - ApplyAnnotationsToNode(const_cast(elementType), std::move(annotations), pos); -} - // CC-OFFNXT(huge_method,huge_cyclomatic_complexity,G.FUN.01-CPP) big switch-case, solid logic void ETSParser::ApplyAnnotationsToSpecificNodeType(ir::AstNode *node, ArenaVector &&annotations, lexer::SourcePosition pos) @@ -339,7 +323,7 @@ void ETSParser::ApplyAnnotationsToSpecificNodeType(ir::AstNode *node, ArenaVecto node->AsETSTypeReference()->SetAnnotations(std::move(annotations)); break; case ir::AstNodeType::TS_ARRAY_TYPE: - ApplyAnnotationsToArrayType(node, std::move(annotations), pos); + node->AsTSArrayType()->SetAnnotations(std::move(annotations)); break; case ir::AstNodeType::ETS_TUPLE: node->AsETSTuple()->SetAnnotations(std::move(annotations)); diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index 70d5bcc5c8f54879284e2df537fa199d0e002d2a..ec767160aed54915ca2011b382eab6877726c6f1 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -16,6 +16,7 @@ #include "ETSparser.h" #include "ETSNolintParser.h" #include +#include #include "util/es2pandaMacros.h" #include "parser/parserFlags.h" #include "parser/parserStatusContext.h" @@ -54,7 +55,6 @@ #include "ir/statements/doWhileStatement.h" #include "ir/statements/breakStatement.h" #include "ir/statements/debuggerStatement.h" -#include "ir/ets/etsLaunchExpression.h" #include "ir/ets/etsClassLiteral.h" #include "ir/ets/etsPrimitiveType.h" #include "ir/ets/etsPackageDeclaration.h" @@ -190,15 +190,15 @@ void ETSParser::ReportAccessModifierError(const lexer::Token &token) } } -std::tuple ETSParser::ParseClassMemberAccessModifiers() +std::tuple ETSParser::ParseClassMemberAccessModifiers() { if (!IsClassMemberAccessModifier(Lexer()->GetToken().Type())) { - return {ir::ModifierFlags::PUBLIC, false}; + return {ir::ModifierFlags::PUBLIC, false, true}; } char32_t nextCp = Lexer()->Lookahead(); if (nextCp == lexer::LEX_CHAR_EQUALS || nextCp == lexer::LEX_CHAR_COLON || nextCp == lexer::LEX_CHAR_LEFT_PAREN) { - return {ir::ModifierFlags::NONE, false}; + return {ir::ModifierFlags::NONE, false, false}; } lexer::TokenFlags tokenFlags = Lexer()->GetToken().Flags(); @@ -227,7 +227,7 @@ std::tuple ETSParser::ParseClassMemberAccessModifiers() Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); if (Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_PROTECTED) { ReportAccessModifierError(token); - return {ir::ModifierFlags::INTERNAL, true}; + return {ir::ModifierFlags::INTERNAL, true, false}; } accessFlag = ir::ModifierFlags::INTERNAL_PROTECTED; break; @@ -246,7 +246,7 @@ std::tuple ETSParser::ParseClassMemberAccessModifiers() } Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); - return {accessFlag, true}; + return {accessFlag, true, false}; } static bool IsClassFieldModifier(lexer::TokenType type) @@ -429,6 +429,10 @@ ir::ModifierFlags ETSParser::ParseClassMethodModifiers(bool seenStatic) ir::TypeNode *ETSParser::ConvertToOptionalUnionType(ir::TypeNode *typeAnno) { + if (typeAnno == nullptr) { + return nullptr; + } + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) if (!typeAnno->IsETSUnionType()) { ArenaVector types(Allocator()->Adapter()); @@ -455,20 +459,57 @@ ir::TypeNode *ETSParser::ConvertToOptionalUnionType(ir::TypeNode *typeAnno) return newTypeAnno; } +void ETSParser::ValidateFieldModifiers(ir::ModifierFlags modifiers, bool optionalField, ir::Expression *initializer, + lexer::SourcePosition pos) +{ + const bool isDeclare = (modifiers & ir::ModifierFlags::DECLARE) != 0; + const bool isDefinite = (modifiers & ir::ModifierFlags::DEFINITE) != 0; + const bool isStatic = (modifiers & ir::ModifierFlags::STATIC) != 0; + + if (isDeclare && initializer != nullptr) { + LogError(diagnostic::INITIALIZERS_IN_AMBIENT_CONTEXTS); + return; + } + + if (isDefinite) { + if (isStatic) { + LogError(diagnostic::STATIC_LATE_INITIALIZATION_FIELD_INVALID_MODIFIER, {}, pos); + } + if (initializer != nullptr) { + LogError(diagnostic::LATE_INITIALIZATION_FIELD_HAS_DEFAULT_VALUE, {}, pos); + } + if (optionalField) { + LogError(diagnostic::CONFLICTING_FIELD_MODIFIERS, {}, pos); + } + } +} + // NOLINTNEXTLINE(google-default-arguments) void ETSParser::ParseClassFieldDefinition(ir::Identifier *fieldName, ir::ModifierFlags modifiers, - ArenaVector *declarations) + ArenaVector *declarations, bool isDefault) { lexer::SourcePosition endLoc = fieldName->End(); ir::TypeNode *typeAnnotation = nullptr; TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; bool optionalField = false; + auto start = Lexer()->GetToken().Start(); + if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK)) { + modifiers |= ir::ModifierFlags::DEFINITE; + } if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_QUESTION_MARK)) { optionalField = true; } + if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK)) { + modifiers |= ir::ModifierFlags::DEFINITE; + } if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON)) { typeAnnotation = ParseTypeAnnotation(&options); + if (typeAnnotation == nullptr) { + LogError(diagnostic::ID_EXPECTED); + return; + } + endLoc = typeAnnotation->End(); } @@ -481,19 +522,20 @@ void ETSParser::ParseClassFieldDefinition(ir::Identifier *fieldName, ir::Modifie LogError(diagnostic::FIELD_TPYE_ANNOTATION_MISSING); } - bool isDeclare = (modifiers & ir::ModifierFlags::DECLARE) != 0; - - if (isDeclare && initializer != nullptr) { - LogError(diagnostic::INITIALIZERS_IN_AMBIENT_CONTEXTS); - } + ValidateFieldModifiers(modifiers, optionalField, initializer, start); auto *field = AllocNode(fieldName, initializer, typeAnnotation, modifiers, Allocator(), false); + field->SetDefaultAccessModifier(isDefault); + if (optionalField) { + field->AddModifier(ir::ModifierFlags::OPTIONAL); + } field->SetRange({fieldName->Start(), initializer != nullptr ? initializer->End() : endLoc}); declarations->push_back(field); } -ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *methodName, ir::ModifierFlags modifiers) +ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *methodName, ir::ModifierFlags modifiers, + bool isDefault) { auto newStatus = ParserStatus::NEED_RETURN_TYPE | ParserStatus::ALLOW_SUPER; auto methodKind = ir::MethodDefinitionKind::METHOD; @@ -519,6 +561,7 @@ ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *meth auto *method = AllocNode(methodKind, methodName->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, modifiers, Allocator(), false); + method->SetDefaultAccessModifier(isDefault); method->SetRange(funcExpr->Range()); return method; } @@ -580,45 +623,27 @@ void ETSParser::UpdateMemberModifiers(ir::ModifierFlags &memberModifiers, bool & } } -std::pair ETSParser::HandleClassElementModifiers(ArenaVector &annotations, - ir::ModifierFlags &memberModifiers) +std::tuple ETSParser::HandleClassElementModifiers(ir::ModifierFlags &memberModifiers) { - auto [modifierFlags, isStepToken] = ParseClassMemberAccessModifiers(); + auto [modifierFlags, isStepToken, isDefault] = ParseClassMemberAccessModifiers(); memberModifiers |= modifierFlags; bool seenStatic = false; UpdateMemberModifiers(memberModifiers, seenStatic); - if (!annotations.empty() && (memberModifiers & ir::ModifierFlags::ABSTRACT) != 0) { - LogError(diagnostic::ANNOTATION_ABSTRACT, {}, Lexer()->GetToken().Start()); - } - - return {seenStatic, isStepToken}; + return {seenStatic, isStepToken, isDefault}; } -ir::AstNode *ETSParser::ParseClassElement(const ArenaVector &properties, - ir::ClassDefinitionModifiers modifiers, - [[maybe_unused]] ir::ModifierFlags flags) +ir::AstNode *ETSParser::ParseClassElementHelper( + const ArenaVector &properties, + std::tuple modifierInfo, + std::tuple elementFlag, std::tuple posInfo) { - auto startLoc = Lexer()->GetToken().Start(); - - ArenaVector annotations(Allocator()->Adapter()); - if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_AT)) { - annotations = ParseAnnotations(false); - } - - ir::ModifierFlags memberModifiers = ir::ModifierFlags::NONE; - auto savedPos = Lexer()->Save(); // NOLINT(clang-analyzer-deadcode.DeadStores) - - if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_STATIC && - Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_BRACE) { - return ParseClassStaticBlock(); - } - - auto [seenStatic, isStepToken] = HandleClassElementModifiers(annotations, memberModifiers); - - ir::AstNode *result = nullptr; + auto [seenStatic, isStepToken, isDefault] = elementFlag; + auto [startLoc, savedPos] = posInfo; + auto [modifiers, memberModifiers, flags] = modifierInfo; auto delcStartLoc = Lexer()->GetToken().Start(); + ir::AstNode *result = nullptr; switch (Lexer()->GetToken().Type()) { case lexer::TokenType::KEYW_INTERFACE: case lexer::TokenType::KEYW_CLASS: @@ -631,12 +656,12 @@ ir::AstNode *ETSParser::ParseClassElement(const ArenaVector &prop } else if (IsNamespaceDecl()) { result = ParseNamespace(flags); } else { - result = ParseInnerRest(properties, modifiers, memberModifiers, startLoc); + result = ParseInnerRest(properties, modifiers, memberModifiers, startLoc, isDefault); } break; } case lexer::TokenType::KEYW_CONSTRUCTOR: - result = ParseInnerConstructorDeclaration(memberModifiers, startLoc); + result = ParseInnerConstructorDeclaration(memberModifiers, startLoc, isDefault); break; case lexer::TokenType::KEYW_PUBLIC: case lexer::TokenType::KEYW_PRIVATE: @@ -646,10 +671,46 @@ ir::AstNode *ETSParser::ParseClassElement(const ArenaVector &prop return AllocBrokenStatement(delcStartLoc); } default: { - result = ParseInnerRest(properties, modifiers, memberModifiers, startLoc); - break; + result = ParseInnerRest(properties, modifiers, memberModifiers, startLoc, isDefault); } } + return result; +} + +ir::AstNode *ETSParser::ParseClassElement(const ArenaVector &properties, + ir::ClassDefinitionModifiers modifiers, + [[maybe_unused]] ir::ModifierFlags flags) +{ + ArenaVector jsDocInformation(Allocator()->Adapter()); + if (Lexer()->TryEatTokenType(lexer::TokenType::JS_DOC_START)) { + jsDocInformation = ParseJsDocInfos(); + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE || + Lexer()->GetToken().Type() == lexer::TokenType::EOS) { + return nullptr; + } + } + + auto startLoc = Lexer()->GetToken().Start(); + + ArenaVector annotations(Allocator()->Adapter()); + if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_AT)) { + annotations = ParseAnnotations(false); + } + + ir::ModifierFlags memberModifiers = ir::ModifierFlags::NONE; + auto savedPos = Lexer()->Save(); // NOLINT(clang-analyzer-deadcode.DeadStores) + + if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_STATIC && + Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_BRACE) { + return ParseClassStaticBlock(); + } + + auto [seenStatic, isStepToken, isDefault] = HandleClassElementModifiers(memberModifiers); + auto delcStartLoc = Lexer()->GetToken().Start(); + ir::AstNode *result = ParseClassElementHelper(properties, std::make_tuple(modifiers, memberModifiers, flags), + std::make_tuple(seenStatic, isStepToken, isDefault), + std::make_tuple(startLoc, savedPos)); + ApplyJsDocInfoToClassElement(result, std::move(jsDocInformation)); ApplyAnnotationsToClassElement(result, std::move(annotations), delcStartLoc); return result; } @@ -680,9 +741,44 @@ void *ETSParser::ApplyAnnotationsToClassElement(ir::AstNode *property, ArenaVect return property; } +static ir::JsDocInfo CloneJsDocInfo(ArenaAllocator *const allocator, const ir::JsDocInfo &src) +{ + ir::JsDocInfo res(allocator->Adapter()); + for (const auto &entry : src) { + const util::StringView &key = entry.first; + const ir::JsDocRecord &record = entry.second; + + util::UString copiedKey {key, allocator}; + util::UString copiedParam {record.param, allocator}; + util::UString copiedComment {record.comment, allocator}; + res.emplace(copiedKey.View(), ir::JsDocRecord(copiedKey.View(), copiedParam.View(), copiedComment.View())); + } + return res; +} + +void ETSParser::ApplyJsDocInfoToClassElement(ir::AstNode *property, ArenaVector &&jsDocInformation) +{ + if (property == nullptr || jsDocInformation.empty()) { + return; + } + + if (!property->IsTSInterfaceBody()) { + ApplyJsDocInfoToSpecificNodeType(property, std::move(jsDocInformation)); + return; + } + + for (auto *node : property->AsTSInterfaceBody()->Body()) { + ArenaVector clonedJsDocInformation(Allocator()->Adapter()); + for (auto const &jsdocInfo : jsDocInformation) { + clonedJsDocInformation.emplace_back(CloneJsDocInfo(Allocator(), jsdocInfo)); + } + ApplyJsDocInfoToSpecificNodeType(node, std::move(clonedJsDocInformation)); + } +} + ir::MethodDefinition *ETSParser::ParseClassGetterSetterMethod(const ArenaVector &properties, const ir::ClassDefinitionModifiers modifiers, - const ir::ModifierFlags memberModifiers) + const ir::ModifierFlags memberModifiers, bool isDefault) { ClassElementDescriptor desc(Allocator()); desc.methodKind = Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GET ? ir::MethodDefinitionKind::GET @@ -702,6 +798,7 @@ ir::MethodDefinition *ETSParser::ParseClassGetterSetterMethod(const ArenaVector< lexer::SourcePosition propEnd = methodName->End(); ir::MethodDefinition *method = ParseClassMethod(&desc, properties, methodName, &propEnd); + method->SetDefaultAccessModifier(isDefault); method->Function()->AddModifier(desc.modifiers); method->SetRange({desc.propStart, propEnd}); if (desc.methodKind == ir::MethodDefinitionKind::GET) { @@ -724,7 +821,6 @@ ir::MethodDefinition *ETSParser::ParseInterfaceGetterSetterMethod(const ir::Modi return nullptr; } method->AddModifier(ir::ModifierFlags::PUBLIC); - method->SetRange({Lexer()->GetToken().Start(), method->Id()->End()}); if (methodKind == ir::MethodDefinitionKind::GET) { method->Id()->SetAccessor(); method->Function()->AddFlag(ir::ScriptFunctionFlags::GETTER); @@ -876,6 +972,47 @@ ir::ModifierFlags ETSParser::ParseInterfaceMethodModifiers() return ir::ModifierFlags::PRIVATE; } +ir::TypeNode *ETSParser::ParseInterfaceTypeAnnotation(ir::Identifier *name) +{ + if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON) && + Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + LogError(diagnostic::INTERFACE_FIELDS_TYPE_ANNOTATION); + Lexer()->GetToken().SetTokenType(lexer::TokenType::PUNCTUATOR_COLON); + Lexer()->NextToken(); + } + + TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; + auto *type = ParseTypeAnnotation(&options); + name->SetTsTypeAnnotation(type); + type->SetParent(name); + return type; +} + +void ETSParser::ParseInterfaceModifiers(ir::ModifierFlags &fieldModifiers, bool &optionalField) +{ + auto processDefinite = [this, &fieldModifiers]() { + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) { + Lexer()->NextToken(); + fieldModifiers |= ir::ModifierFlags::DEFINITE; + return true; + } + return false; + }; + auto start = Lexer()->GetToken().Start(); + processDefinite(); + + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { + Lexer()->NextToken(); + optionalField = true; + } + + processDefinite(); + + if ((fieldModifiers & ir::ModifierFlags::DEFINITE) != 0 && optionalField) { + LogError(diagnostic::CONFLICTING_FIELD_MODIFIERS, {}, start); + } +} + ir::AstNode *ETSParser::ParseInterfaceField() { ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || @@ -887,7 +1024,7 @@ ir::AstNode *ETSParser::ParseInterfaceField() auto *name = AllocNode(Lexer()->GetToken().Ident(), Allocator()); auto parseClassMethod = [&fieldModifiers, &startLoc, this](ir::Identifier *methodName) { - auto *classMethod = ParseClassMethodDefinition(methodName, fieldModifiers); + auto *classMethod = ParseClassMethodDefinition(methodName, fieldModifiers, false); classMethod->SetStart(startLoc); return classMethod; }; @@ -903,24 +1040,8 @@ ir::AstNode *ETSParser::ParseInterfaceField() Lexer()->NextToken(); bool optionalField = false; - if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { - Lexer()->NextToken(); // eat '?' - optionalField = true; - } - - ir::TypeNode *typeAnnotation = nullptr; - if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON) && - Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { - // interfaces3.ets - LogError(diagnostic::INTERFACE_FIELDS_TYPE_ANNOTATION); - - Lexer()->GetToken().SetTokenType(lexer::TokenType::PUNCTUATOR_COLON); - Lexer()->NextToken(); // additional check - } - TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; - typeAnnotation = ParseTypeAnnotation(&options); - name->SetTsTypeAnnotation(typeAnnotation); - typeAnnotation->SetParent(name); + ParseInterfaceModifiers(fieldModifiers, optionalField); + auto *typeAnnotation = ParseInterfaceTypeAnnotation(name); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EQUAL && Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { LogError(diagnostic::INITIALIZERS_INTERFACE_PROPS); @@ -1018,6 +1139,23 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i return method; } +ir::AstNode *ETSParser::ParseJsDocInfoInInterfaceBody() +{ + Lexer()->NextToken(); // eat '/**' + + auto jsDocInformation = ParseJsDocInfos(); + if (Lexer()->GetToken().Type() == lexer::TokenType::EOS || + Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { + return nullptr; + } + + ir::AstNode *result = ParseTypeLiteralOrInterfaceMember(); + if (result != nullptr) { + ApplyJsDocInfoToSpecificNodeType(result, std::move(jsDocInformation)); + } + return result; +} + ir::AstNode *ETSParser::ParseAnnotationsInInterfaceBody() { Lexer()->NextToken(); // eat '@' @@ -1031,53 +1169,56 @@ ir::AstNode *ETSParser::ParseAnnotationsInInterfaceBody() return result; } +bool ETSParser::IsFieldStartToken(lexer::TokenType tokenType) +{ + return tokenType == lexer::TokenType::LITERAL_IDENT || + tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET || + tokenType == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS; +} + ir::AstNode *ETSParser::ParseTypeLiteralOrInterfaceMember() { + if (Lexer()->GetToken().Type() == lexer::TokenType::JS_DOC_START) { + return ParseJsDocInfoInInterfaceBody(); + } + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_AT) { return ParseAnnotationsInInterfaceBody(); } - auto startLoc = Lexer()->GetToken().Start(); - if (Lexer()->Lookahead() != lexer::LEX_CHAR_LEFT_PAREN && Lexer()->Lookahead() != lexer::LEX_CHAR_LESS_THAN && (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GET || Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_SET)) { return ParseInterfaceGetterSetterMethod(ir::ModifierFlags::PUBLIC); } - if (Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_READONLY)) { - char32_t nextCp = Lexer()->Lookahead(); - if (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN) { + ir::ModifierFlags modifiers = ParseInterfaceMethodModifiers(); + char32_t nextCp = Lexer()->Lookahead(); + auto startLoc = Lexer()->GetToken().Start(); + auto readonlyTok = Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_READONLY); + bool isReadonly = readonlyTok.has_value(); + + if (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN) { + if (isReadonly) { LogError(diagnostic::READONLY_INTERFACE_METHOD, {}, startLoc); - ir::ModifierFlags modfiers = ParseInterfaceMethodModifiers(); - auto *method = ParseInterfaceMethod(modfiers, ir::MethodDefinitionKind::METHOD); - method->SetStart(startLoc); - return method; } - auto *field = ParseInterfaceField(); - field->SetStart(startLoc); - field->AddModifier(ir::ModifierFlags::READONLY); - return field; + auto *method = ParseInterfaceMethod(modifiers, ir::MethodDefinitionKind::METHOD); + method->SetStart(startLoc); + return method; } - ir::ModifierFlags modfiers = ParseInterfaceMethodModifiers(); - if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT && - Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET && - Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { - LogError(diagnostic::ID_EXPECTED); + auto tok = Lexer()->GetToken().Type(); + if (!IsFieldStartToken(tok)) { + LogError(diagnostic::ID_EXPECTED, {}, startLoc); return AllocBrokenExpression(Lexer()->GetToken().Loc()); } - char32_t nextCp = Lexer()->Lookahead(); - if (nextCp == lexer::LEX_CHAR_LEFT_PAREN || nextCp == lexer::LEX_CHAR_LESS_THAN) { - auto *method = ParseInterfaceMethod(modfiers, ir::MethodDefinitionKind::METHOD); - method->SetStart(startLoc); - return method; - } - auto *field = ParseInterfaceField(); if (field != nullptr) { field->SetStart(startLoc); + if (isReadonly) { + field->AddModifier(ir::ModifierFlags::READONLY); + } return field; } @@ -1195,7 +1336,7 @@ std::pair ETSParser::ParseMemberModifi if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { Lexer()->Rewind(savedPos); } - memberModifiers |= ir::ModifierFlags::EXPORT_TYPE; + memberModifiers |= ir::ModifierFlags::EXPORT; } else { memberModifiers |= ir::ModifierFlags::EXPORT; } diff --git a/ets2panda/parser/ETSparserEnums.cpp b/ets2panda/parser/ETSparserEnums.cpp index 28614b5066fafad380f62c9c5dbac67a52fd94df..b38077398cc5b70edba573d32ea6928b9ff8dbd3 100644 --- a/ets2panda/parser/ETSparserEnums.cpp +++ b/ets2panda/parser/ETSparserEnums.cpp @@ -73,7 +73,6 @@ #include "ir/statements/doWhileStatement.h" #include "ir/statements/breakStatement.h" #include "ir/statements/debuggerStatement.h" -#include "ir/ets/etsLaunchExpression.h" #include "ir/ets/etsClassLiteral.h" #include "ir/ets/etsPrimitiveType.h" #include "ir/ets/etsPackageDeclaration.h" @@ -161,11 +160,6 @@ ir::TSEnumDeclaration *ETSParser::ParseEnumMembers(ir::Identifier *const key, co Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); // eat '{' - if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { - LogError(diagnostic::ENUM_MUST_HAVE_ONE_CONST); - return nullptr; // Error processing. - } - ArenaVector members(Allocator()->Adapter()); lexer::SourcePosition enumEnd = ParseEnumMember(members); @@ -220,6 +214,7 @@ lexer::SourcePosition ETSParser::ParseEnumMember(ArenaVector &mem // Lambda to parse enum member (maybe with initializer) auto const parseMember = [this, &members, ¤tNumberExpr]() { + HandleJsDocLikeComments(); auto *const ident = ExpectIdentifier(false, true); ir::Expression *ordinal; diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 53117acfb4847c7612f75ba5ea2032a589ea9fb5..7c0bd342e97a317106119b561437caf824eb9ed6 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -15,43 +15,30 @@ #include "ETSparser.h" +#include "generated/tokenType.h" #include "lexer/lexer.h" #include "ir/expressions/literals/undefinedLiteral.h" #include "ir/ets/etsTuple.h" +#include "macros.h" +#include "parserFlags.h" #include "util/errorRecovery.h" #include "generated/diagnostic.h" +#include "parserImpl.h" +#include "util/recursiveGuard.h" namespace ark::es2panda::parser { class FunctionContext; using namespace std::literals::string_literals; -ir::Expression *ETSParser::ParseLaunchExpression(ExpressionParseFlags flags) -{ - lexer::SourcePosition start = Lexer()->GetToken().Start(); - Lexer()->NextToken(); // eat launch - - lexer::SourcePosition exprStart = Lexer()->GetToken().Start(); - ir::Expression *expr = ParseLeftHandSideExpression(flags); - if (!expr->IsCallExpression()) { - LogError(diagnostic::ONLY_CALL_AFTER_LAUNCH, {}, exprStart); - return AllocBrokenExpression(exprStart); - } - auto call = expr->AsCallExpression(); - auto *launchExpression = AllocNode(call); - launchExpression->SetRange({start, call->End()}); - - return launchExpression; -} - static std::string GetArgumentsSourceView(lexer::Lexer *lexer, const util::StringView::Iterator &lexerPos) { std::string value = lexer->SourceView(lexerPos.Index(), lexer->Save().Iterator().Index()).Mutf8(); - while (value.back() == ' ') { + while (!value.empty() && value.back() == ' ') { value.pop_back(); } - if (value.back() == ')' || value.back() == ',') { + if (!value.empty() && (value.back() == ')' || value.back() == ',')) { value.pop_back(); } @@ -120,11 +107,33 @@ ir::Expression *ETSParser::ResolveArgumentUnaryExpr(ExpressionParseFlags flags) } } +ir::Expression *ETSParser::CreateUnaryExpressionFromArgument(ir::Expression *argument, lexer::TokenType operatorType, + char32_t beginningChar) +{ + ir::Expression *returnExpr = nullptr; + if (lexer::Token::IsUpdateToken(operatorType)) { + returnExpr = AllocNode(argument, operatorType, true); + } else if (operatorType == lexer::TokenType::KEYW_TYPEOF) { + returnExpr = AllocNode(argument); + } else if (operatorType == lexer::TokenType::PUNCTUATOR_MINUS && argument->IsNumberLiteral()) { + bool argBeginWithDigitOrDot = (beginningChar >= '0' && beginningChar <= '9') || (beginningChar == '.'); + returnExpr = argBeginWithDigitOrDot ? argument : AllocNode(argument, operatorType); + } else { + returnExpr = AllocNode(argument, operatorType); + } + + return returnExpr; +} + // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFlags flags) { auto tokenFlags = lexer::NextTokenFlags::NONE; lexer::TokenType operatorType = Lexer()->GetToken().Type(); + if (operatorType == lexer::TokenType::LITERAL_IDENT && + Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPEOF) { + operatorType = lexer::TokenType::KEYW_TYPEOF; + } switch (operatorType) { case lexer::TokenType::PUNCTUATOR_MINUS: @@ -135,21 +144,25 @@ ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFla case lexer::TokenType::PUNCTUATOR_PLUS: case lexer::TokenType::PUNCTUATOR_TILDE: case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: - case lexer::TokenType::KEYW_TYPEOF: { + case lexer::TokenType::KEYW_TYPEOF: + case lexer::TokenType::KEYW_AWAIT: { break; } - case lexer::TokenType::KEYW_LAUNCH: { - return ParseLaunchExpression(flags); - } default: { return ParseLeftHandSideExpression(flags); } } + char32_t beginningChar = Lexer()->Lookahead(); auto start = Lexer()->GetToken().Start(); Lexer()->NextToken(tokenFlags); ir::Expression *argument = ResolveArgumentUnaryExpr(flags); + if (operatorType == lexer::TokenType::KEYW_AWAIT) { + auto *awaitExpr = AllocNode(argument); + awaitExpr->SetRange({start, argument->End()}); + return awaitExpr; + } if (argument == nullptr) { return nullptr; @@ -161,21 +174,8 @@ ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFla } } - lexer::SourcePosition end = argument->End(); - - ir::Expression *returnExpr = nullptr; - if (lexer::Token::IsUpdateToken(operatorType)) { - returnExpr = AllocNode(argument, operatorType, true); - } else if (operatorType == lexer::TokenType::KEYW_TYPEOF) { - returnExpr = AllocNode(argument); - } else if (operatorType == lexer::TokenType::PUNCTUATOR_MINUS) { - returnExpr = !argument->IsNumberLiteral() ? AllocNode(argument, operatorType) : argument; - } else { - returnExpr = AllocNode(argument, operatorType); - } - - returnExpr->SetRange({start, end}); - + ir::Expression *returnExpr = CreateUnaryExpressionFromArgument(argument, operatorType, beginningChar); + returnExpr->SetRange({start, argument->End()}); return returnExpr; } @@ -220,6 +220,16 @@ ir::Expression *ETSParser::ParsePropertyDefinition(ExpressionParseFlags flags) return returnProperty; } +bool CheckNextTokenOfTypeof(const lexer::Token &token) +{ + bool pretendTypeof = token.KeywordType() == lexer::TokenType::KEYW_TYPEOF; + bool pretendIdent = token.IsLiteral(); + bool pretendOperator = token.IsUpdate(); + bool pretendUnary = token.IsUnary(); + bool pretendPuctuator = token.IsTsParamToken(token.Type()); + return (pretendTypeof || pretendIdent || pretendOperator || pretendUnary || pretendPuctuator); +} + // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags flags) { @@ -251,8 +261,13 @@ ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags fl Lexer()->NextToken(); bool pretendArrow = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_ARROW; + bool checkNextTokenOfTypeof = CheckNextTokenOfTypeof(Lexer()->GetToken()); Lexer()->Rewind(savedPos); + if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_TYPEOF && checkNextTokenOfTypeof) { + return ParseUnaryOrPrefixUpdateExpression(); + } + if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { if (pretendArrow) { return ParseArrowFunctionExpression(); @@ -260,8 +275,9 @@ ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags fl return ParsePrimaryExpressionIdent(flags); } - const auto &tokenNow = Lexer()->GetToken(); + const auto tokenNow = Lexer()->GetToken(); LogUnexpectedToken(tokenNow); + Lexer()->NextToken(); // eat an unexpected token return AllocBrokenExpression(tokenNow.Loc()); } @@ -293,12 +309,26 @@ ir::Expression *ETSParser::ParsePrimaryExpressionWithLiterals(ExpressionParseFla } } +// This function is used to handle the left parenthesis in the expression parsing. +ir::Expression *HandleLeftParanthesis(ETSParser *parser, ExpressionParseFlags flags) +{ + TrackRecursive trackRecursive(parser->recursiveCtx_); + if (!trackRecursive) { + parser->LogError(diagnostic::DEEP_NESTING); + while (parser->Lexer()->GetToken().Type() != lexer::TokenType::EOS) { + parser->Lexer()->NextToken(); + } + return parser->AllocBrokenExpression(parser->Lexer()->GetToken().Loc()); + } + return parser->ParseCoverParenthesizedExpressionAndArrowParameterList(flags); +} + // NOLINTNEXTLINE(google-default-arguments) ir::Expression *ETSParser::ParsePrimaryExpression(ExpressionParseFlags flags) { switch (Lexer()->GetToken().Type()) { case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { - return ParseCoverParenthesizedExpressionAndArrowParameterList(flags); + return HandleLeftParanthesis(this, flags); } case lexer::TokenType::KEYW_THIS: { return ParseThisExpression(); @@ -361,13 +391,13 @@ bool IsPunctuartorSpecialCharacter(lexer::TokenType tokenType) } // This function was created to reduce the size of `EatArrowFunctionParams`. -static bool IsValidTokenTypeOfArrowFunctionStart(lexer::TokenType tokenType) +bool TypedParser::IsValidTokenTypeOfArrowFunctionStart(lexer::TokenType tokenType) { - return (tokenType == lexer::TokenType::LITERAL_IDENT || + return (tokenType == lexer::TokenType::LITERAL_IDENT || IsPrimitiveType(tokenType) || tokenType == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD || tokenType == lexer::TokenType::KEYW_THIS); } -static bool EatArrowFunctionParams(lexer::Lexer *lexer) +bool TypedParser::EatArrowFunctionParams(lexer::Lexer *lexer) { ES2PANDA_ASSERT(lexer->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); lexer->NextToken(); diff --git a/ets2panda/parser/ETSparserJsDocInfo.cpp b/ets2panda/parser/ETSparserJsDocInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ddf1be0207fd411a7219e3f653c7d40ffa1bed0 --- /dev/null +++ b/ets2panda/parser/ETSparserJsDocInfo.cpp @@ -0,0 +1,274 @@ +/** + * 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. + */ + +#include "ETSparser.h" +#include "lexer/lexer.h" +#include "lexer/keywordsUtil.h" +#include "ir/astNode.h" +#include "ir/base/methodDefinition.h" +#include "ir/ets/etsStructDeclaration.h" +#include "ir/statements/classDeclaration.h" +#include +#include +#include +#include +#include +#include +#include + +namespace ark::es2panda::parser { +void ETSParser::ExcludeInvalidStart() +{ + auto cp = Lexer()->Lookahead(); + while (!lexer::KeywordsUtil::IsIdentifierStart(cp) && cp != util::StringView::Iterator::INVALID_CP && + cp != lexer::LEX_CHAR_LEFT_BRACE && cp != lexer::LEX_CHAR_ASTERISK) { + Lexer()->ForwardToken(Lexer()->GetToken().Type()); + cp = Lexer()->Lookahead(); + } +} + +std::string ETSParser::ParseJsDocInfoItemParam() +{ + ExcludeInvalidStart(); + Lexer()->NextToken(); + auto token = Lexer()->GetToken(); + std::string jsDocInfoParamStr {}; + bool needAppendToken = token.Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE; + bool needBackwardBlank = lexer::KeywordsUtil::IsIdentifierStart(Lexer()->Lookahead()); + size_t leftBraceCount = 1; + while (token.Type() != lexer::TokenType::EOS && token.Type() != lexer::TokenType::JS_DOC_END) { + if (needAppendToken) { + jsDocInfoParamStr += token.ToString(); + } + + if (needBackwardBlank) { + jsDocInfoParamStr += " "; + } + + auto cp = Lexer()->Lookahead(); + if (lexer::KeywordsUtil::IsIdentifierStart(cp) || cp == lexer::LEX_CHAR_ASTERISK) { + Lexer()->NextToken(); + token = Lexer()->GetToken(); + needAppendToken = lexer::KeywordsUtil::IsIdentifierStart(cp); + needBackwardBlank = lexer::KeywordsUtil::IsIdentifierStart(Lexer()->Lookahead()); + continue; + } + + if (cp == lexer::LEX_CHAR_RIGHT_BRACE) { + --leftBraceCount; + if (leftBraceCount == 0) { + Lexer()->NextToken(); + break; + } + } + + if (cp == lexer::LEX_CHAR_LEFT_BRACE) { + ++leftBraceCount; + } + + if (cp == util::StringView::Iterator::INVALID_CP) { + break; + } + + jsDocInfoParamStr += std::string(1, cp); + needAppendToken = false; + needBackwardBlank = false; + Lexer()->ForwardToken(token.Type()); + } + + return jsDocInfoParamStr; +} + +static void RegularCommentStr(std::string &str) +{ + if (str.empty()) { + return; + } + + auto backChar = static_cast(static_cast(str.back())); + while (backChar == lexer::LEX_CHAR_CR || backChar == lexer::LEX_CHAR_LF || backChar == lexer::LEX_CHAR_ASTERISK || + backChar == lexer::LEX_CHAR_NBSP || backChar == lexer::LEX_CHAR_SP) { + str.pop_back(); + if (str.empty()) { + return; + } + backChar = static_cast(static_cast(str.back())); + } +} + +std::tuple ETSParser::ParseJsDocInfoItemValue() +{ + ExcludeInvalidStart(); + util::UString jsDocInfoItemCommentStr(Allocator()); + std::string jsDocInfoParamStr {}; + if (Lexer()->GetToken().Type() == lexer::TokenType::JS_DOC_END) { + util::UString jsDocInfoItemParam {jsDocInfoParamStr, Allocator()}; + return std::make_tuple(jsDocInfoItemParam.View(), jsDocInfoItemCommentStr.View()); + } + + const auto startIdx = Lexer()->GetIndex(); + auto escapeEnd = startIdx; + do { + const char32_t cp = Lexer()->Lookahead(); + switch (cp) { + case lexer::LEX_CHAR_LEFT_BRACE: { + jsDocInfoParamStr = ParseJsDocInfoItemParam(); + continue; + } + case util::StringView::Iterator::INVALID_CP: { + break; + } + case lexer::LEX_CHAR_CR: + case lexer::LEX_CHAR_LF: { + Lexer()->HandleNewlineHelper(&jsDocInfoItemCommentStr, &escapeEnd); + continue; + } + case lexer::LEX_CHAR_AT: + case lexer::LEX_CHAR_ASTERISK: { + auto saved = Lexer()->Save(); + Lexer()->NextToken(); + auto nextType = Lexer()->GetToken().Type(); + Lexer()->Rewind(saved); + if (nextType == lexer::TokenType::JS_DOC_END || nextType == lexer::TokenType::PUNCTUATOR_AT) { + break; + } + [[fallthrough]]; + } + default: { + Lexer()->SkipCp(); + continue; + } + } + Lexer()->FinalizeJsDocInfoHelper(&jsDocInfoItemCommentStr, startIdx, escapeEnd); + break; + } while (true); + + std::string commentStr = std::string(jsDocInfoItemCommentStr.View()); + RegularCommentStr(commentStr); + util::UString jsDocInfoItemParam {jsDocInfoParamStr, Allocator()}; + util::UString jsDocInfoCommentStr {commentStr, Allocator()}; + return std::make_tuple(jsDocInfoItemParam.View(), jsDocInfoCommentStr.View()); +} + +ir::JsDocInfo ETSParser::ParseJsDocInfo() +{ + ir::JsDocInfo jsDocInfo(Allocator()->Adapter()); + auto tokenType = Lexer()->GetToken().Type(); + while (tokenType != lexer::TokenType::EOS && tokenType != lexer::TokenType::JS_DOC_END) { + if (tokenType != lexer::TokenType::PUNCTUATOR_AT) { + auto cp = Lexer()->Lookahead(); + if (cp == lexer::LEX_CHAR_ASTERISK || cp == lexer::LEX_CHAR_AT) { + Lexer()->NextToken(); + tokenType = Lexer()->GetToken().Type(); + continue; + } + + if (Lexer()->Lookahead() == util::StringView::Iterator::INVALID_CP) { + break; + } + + Lexer()->ForwardToken(tokenType, 1); + continue; + } + Lexer()->NextToken(); + auto const &token = Lexer()->GetToken(); + util::UString jsDocInfoItemKey {token.Ident(), Allocator()}; + auto [jsDocInfoItemParam, jsDocInfoItemComment] = ParseJsDocInfoItemValue(); + jsDocInfo.emplace(jsDocInfoItemKey.View(), + ir::JsDocRecord(jsDocInfoItemKey.View(), jsDocInfoItemParam, jsDocInfoItemComment)); + tokenType = Lexer()->GetToken().Type(); + } + + Lexer()->NextToken(); + return jsDocInfo; +} + +ArenaVector ETSParser::ParseJsDocInfos() +{ + ArenaVector result(Allocator()->Adapter()); + bool hasMoreJsDocInfos = true; + while (hasMoreJsDocInfos) { + auto jsDocInfo = ParseJsDocInfo(); + if (!jsDocInfo.empty()) { + result.emplace_back(jsDocInfo); + } + + if (Lexer()->GetToken().Type() != lexer::TokenType::JS_DOC_START) { + hasMoreJsDocInfos = false; + } + } + return result; +} + +static bool ApplyJsDocInfoToNamespace(ir::ETSModule *ns, ArenaVector &jsDocInformation) +{ + if (ns->IsNamespaceChainLastNode()) { + ns->SetJsDocInformation(std::move(jsDocInformation)); + return true; + } + + for (auto *node : ns->Statements()) { + if (node->IsETSModule()) { + if (ApplyJsDocInfoToNamespace(node->AsETSModule(), jsDocInformation)) { + return true; + } + } + } + return false; +} + +// CC-OFFNXT(huge_method,huge_cyclomatic_complexity,G.FUN.01-CPP) big switch-case, solid logic +void ETSParser::ApplyJsDocInfoToSpecificNodeType(ir::AstNode *node, ArenaVector &&jsDocInformation) +{ + if (jsDocInformation.empty()) { + return; + } + + switch (node->Type()) { + case ir::AstNodeType::METHOD_DEFINITION: + node->AsMethodDefinition()->Function()->SetJsDocInformation(std::move(jsDocInformation)); + break; + case ir::AstNodeType::CLASS_DECLARATION: + node->AsClassDeclaration()->Definition()->SetJsDocInformation(std::move(jsDocInformation)); + break; + case ir::AstNodeType::STRUCT_DECLARATION: + node->AsETSStructDeclaration()->Definition()->SetJsDocInformation(std::move(jsDocInformation)); + break; + case ir::AstNodeType::FUNCTION_DECLARATION: + node->AsFunctionDeclaration()->SetJsDocInformation(std::move(jsDocInformation)); + break; + case ir::AstNodeType::TS_INTERFACE_DECLARATION: + node->AsTSInterfaceDeclaration()->SetJsDocInformation(std::move(jsDocInformation)); + break; + case ir::AstNodeType::CLASS_PROPERTY: + node->AsClassProperty()->SetJsDocInformation(std::move(jsDocInformation)); + break; + case ir::AstNodeType::VARIABLE_DECLARATION: + node->AsVariableDeclaration()->SetJsDocInformation(std::move(jsDocInformation)); + break; + case ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION: + node->AsTSTypeAliasDeclaration()->SetJsDocInformation(std::move(jsDocInformation)); + break; + case ir::AstNodeType::ARROW_FUNCTION_EXPRESSION: + node->AsArrowFunctionExpression()->SetJsDocInformation(std::move(jsDocInformation)); + break; + case ir::AstNodeType::ETS_MODULE: + ApplyJsDocInfoToNamespace(node->AsETSModule(), jsDocInformation); + break; + default: { + } + } +} +} // namespace ark::es2panda::parser diff --git a/ets2panda/parser/ETSparserNamespaces.cpp b/ets2panda/parser/ETSparserNamespaces.cpp index af0e4d10459d086c4a20056e42f4453c4506a354..50240599974741629a8b0ec7b6ceb6b993125256 100644 --- a/ets2panda/parser/ETSparserNamespaces.cpp +++ b/ets2panda/parser/ETSparserNamespaces.cpp @@ -82,7 +82,7 @@ ir::ETSModule *ETSParser::ParseNamespaceImp(ir::ModifierFlags flags) if ((flags & ir::ModifierFlags::DECLARE) != 0) { child->AddModifier(ir::ModifierFlags::DECLARE); } - parent->Statements().emplace_back(child); + parent->AddStatement(child); parent = child; } ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE); @@ -97,7 +97,9 @@ ir::ETSModule *ETSParser::ParseNamespaceImp(ir::ModifierFlags flags) continue; } auto st = ParseTopLevelStatement(); - statements.emplace_back(st); + if (st != nullptr) { + statements.emplace_back(st); + } } Lexer()->NextToken(); if (child != nullptr) { diff --git a/ets2panda/parser/ETSparserStatements.cpp b/ets2panda/parser/ETSparserStatements.cpp index 1638ca80d6a5b170c3e95a4d2258e86e2741d9a8..3a3bcf9294d53d5659622ed6731eaba11bc2beb7 100644 --- a/ets2panda/parser/ETSparserStatements.cpp +++ b/ets2panda/parser/ETSparserStatements.cpp @@ -72,7 +72,6 @@ #include "ir/statements/doWhileStatement.h" #include "ir/statements/breakStatement.h" #include "ir/statements/debuggerStatement.h" -#include "ir/ets/etsLaunchExpression.h" #include "ir/ets/etsClassLiteral.h" #include "ir/ets/etsPrimitiveType.h" #include "ir/ets/etsPackageDeclaration.h" @@ -145,10 +144,6 @@ static ir::Statement *ValidateExportableStatement(ETSParser *parser, ir::Stateme if (stmt->IsETSModule()) { return stmt; } - if ((memberModifiers & ir::ModifierFlags::EXPORT_TYPE) != 0U && - !(stmt->IsClassDeclaration() || stmt->IsTSInterfaceDeclaration() || stmt->IsTSTypeAliasDeclaration())) { - parser->LogError(diagnostic::ONLY_EXPORT_CLASS_OR_INTERFACE, {}, stmt->Start()); - } if (stmt->IsAnnotationDeclaration()) { if ((memberModifiers & ir::ModifierFlags::DEFAULT_EXPORT) != 0U) { parser->LogError(diagnostic::INVALID_EXPORT_DEFAULT, {}, stmt->Start()); @@ -156,8 +151,7 @@ static ir::Statement *ValidateExportableStatement(ETSParser *parser, ir::Stateme } stmt->AddModifier(memberModifiers); } else { - if ((memberModifiers & - (ir::ModifierFlags::EXPORT | ir::ModifierFlags::DEFAULT_EXPORT | ir::ModifierFlags::EXPORT_TYPE)) != 0U) { + if ((memberModifiers & (ir::ModifierFlags::EXPORT | ir::ModifierFlags::DEFAULT_EXPORT)) != 0U) { parser->LogError(diagnostic::EXPORT_NON_DECLARATION, {}, pos); } } @@ -166,9 +160,7 @@ static ir::Statement *ValidateExportableStatement(ETSParser *parser, ir::Stateme } bool ETSParser::IsExportedDeclaration(ir::ModifierFlags memberModifiers) { - return (memberModifiers & ir::ModifierFlags::EXPORTED) != 0U && - (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY || - Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE); + return (memberModifiers & ir::ModifierFlags::EXPORTED) != 0U; } bool ETSParser::IsInitializerBlockStart() const @@ -180,7 +172,8 @@ bool ETSParser::IsInitializerBlockStart() const auto savedPos = Lexer()->Save(); Lexer()->NextToken(); const bool validStart = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE && - (GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0; + ((GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0 || + (GetContext().Status() & ParserStatus::IN_PACKAGE) != 0); Lexer()->Rewind(savedPos); return validStart; } @@ -188,12 +181,8 @@ bool ETSParser::IsInitializerBlockStart() const ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags) { auto [memberModifiers, startLoc] = ParseMemberModifiers(); - if (IsExportedDeclaration(memberModifiers)) { - return ParseExport(startLoc, memberModifiers); - } - if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_GET || - Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_SET) { + if (CheckAccessorDeclaration(memberModifiers)) { return ParseAccessorWithReceiver(memberModifiers); } @@ -223,7 +212,7 @@ ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags result = ParseTopLevelAnnotation(memberModifiers); break; case lexer::TokenType::LITERAL_IDENT: { - if (((memberModifiers & ir::ModifierFlags::DECLARE) != 0U) || IsNamespaceDecl()) { + if (IsNamespaceDecl()) { return ParseNamespaceStatement(memberModifiers); } result = ParseIdentKeyword(); @@ -236,14 +225,33 @@ ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags } } + if (result == nullptr && IsExportedDeclaration(memberModifiers)) { + return ParseExport(startLoc, memberModifiers); + } + return ValidateExportableStatement(this, result, memberModifiers, startLoc); } ir::Statement *ETSParser::ParseTopLevelStatement() { const auto flags = StatementParsingFlags::ALLOW_LEXICAL; + ArenaVector jsDocInformation(Allocator()->Adapter()); + if (Lexer()->TryEatTokenType(lexer::TokenType::JS_DOC_START)) { + jsDocInformation = ParseJsDocInfos(); + } + if (Lexer()->GetToken().Type() == lexer::TokenType::EOS || + ((GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0 && + Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE)) { + return nullptr; + } + GetContext().Status() |= ParserStatus::ALLOW_JS_DOC_START; auto result = ParseTopLevelDeclStatement(flags); + GetContext().Status() ^= ParserStatus::ALLOW_JS_DOC_START; + if (result != nullptr) { + ApplyJsDocInfoToSpecificNodeType(result, std::move(jsDocInformation)); + } + if (result == nullptr) { result = ParseStatement(flags); } @@ -289,7 +297,7 @@ bool ETSParser::ValidateForInStatement() ir::Statement *ETSParser::ParseDebuggerStatement() { - LogUnexpectedToken(lexer::TokenType::KEYW_DEBUGGER); + LogError(diagnostic::ERROR_ARKTS_NO_DEBUGGER_STATEMENT); return AllocBrokenStatement(Lexer()->GetToken().Loc()); } diff --git a/ets2panda/parser/ETSparserTemplates.h b/ets2panda/parser/ETSparserTemplates.h new file mode 100644 index 0000000000000000000000000000000000000000..624588a23aa08814bb11e34b86a6b718e6e2c194 --- /dev/null +++ b/ets2panda/parser/ETSparserTemplates.h @@ -0,0 +1,147 @@ +/** + * 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. + */ + +#ifndef ES2PANDA_PARSER_CORE_ETS_PARSER_TEMPLATES_H +#define ES2PANDA_PARSER_CORE_ETS_PARSER_TEMPLATES_H + +template +void SetFormattingFileName(T &&fileName) +{ + GetContext().SetFormattingFileName(std::forward(fileName)); +} + +template +void ProcessFormattedArg(std::vector &nodes, T &&arg) +{ + if constexpr (std::is_convertible_v, ir::AstNode *>) { + nodes.emplace_back(std::forward(arg)); + } else if constexpr (std::is_same_v, util::StringView>) { + nodes.emplace_back(AllocNode(std::forward(arg), Allocator())); + } else if constexpr (std::is_same_v, util::UString>) { + nodes.emplace_back(AllocNode(arg.View(), Allocator())); + } else if constexpr (std::is_same_v, std::string>) { + nodes.emplace_back( + AllocNode(util::UString(std::forward(arg), Allocator()).View(), Allocator())); + } else if constexpr (std::is_constructible_v>) { + nodes.emplace_back(AllocNode( + util::UString(std::string {std::forward(arg)}, Allocator()).View(), Allocator())); + } else if constexpr (std::is_convertible_v, checker::Type *>) { + nodes.emplace_back(AllocNode(std::forward(arg), Allocator())); + } else if constexpr (std::is_same_v, ArenaVector>) { + nodes.emplace_back(AllocNode(std::forward(arg))); + } else if constexpr (std::is_same_v, ArenaVector>) { + nodes.emplace_back(AllocNode(std::forward(arg))); + } else if constexpr (std::is_same_v, ArenaVector>) { + nodes.emplace_back(AllocNode(std::forward(arg))); + } else if constexpr (std::is_same_v, ArenaVector>) { + for (auto *type : arg) { + nodes.emplace_back(AllocNode(type, Allocator())); + } + } else { + static_assert(STATIC_FALSE, "Format argument has invalid type."); + } +} + +template +ir::Expression *CreateFormattedExpression(std::string_view const sourceCode, Args &&...args) +{ + std::vector insertingNodes {}; + insertingNodes.reserve(sizeof...(Args)); + (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); + return CreateFormattedExpression(sourceCode, insertingNodes); +} + +template +ArenaVector CreateFormattedStatements(std::string_view const sourceCode, Args &&...args) +{ + std::vector insertingNodes {}; + insertingNodes.reserve(sizeof...(Args)); + (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); + return CreateFormattedStatements(sourceCode, insertingNodes); +} + +template +ir::Statement *CreateFormattedClassDeclaration(std::string_view sourceCode, bool allowStatic, Args &&...args) +{ + std::vector insertingNodes {}; + insertingNodes.reserve(sizeof...(Args)); + (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); + return CreateFormattedClassDeclaration(sourceCode, insertingNodes, allowStatic); +} + +template +ir::AstNode *CreateFormattedClassElement(std::string_view sourceCode, ir::ClassDefinition *classDefinition, + Args &&...args) +{ + return CreateFormattedClassElement(sourceCode, classDefinition->Body(), classDefinition->Modifiers(), + std::forward(args...)); +} + +template +ir::AstNode *CreateFormattedClassFieldDefinition(std::string_view const sourceCode, Args &&...args) +{ + std::vector insertingNodes {}; + insertingNodes.reserve(sizeof...(Args)); + (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); + return CreateFormattedClassFieldDefinition(sourceCode, insertingNodes); +} + +template +ir::AstNode *CreateFormattedClassElement(std::string_view sourceCode, const ArenaVector &properties, + ir::ClassDefinitionModifiers modifiers, Args &&...args) +{ + std::vector insertingNodes {}; + insertingNodes.reserve(sizeof...(Args)); + (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); + return CreateFormattedClassElement(sourceCode, insertingNodes, properties, modifiers); +} + +template +ir::AstNode *CreateFormattedClassMethodDefinition(std::string_view const sourceCode, Args &&...args) +{ + std::vector insertingNodes {}; + insertingNodes.reserve(sizeof...(Args)); + (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); + return CreateFormattedClassMethodDefinition(sourceCode, insertingNodes); +} + +template +ir::Statement *CreateFormattedTopLevelStatement(std::string_view sourceCode, Args &&...args) +{ + std::vector insertingNodes {}; + insertingNodes.reserve(sizeof...(Args)); + (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); + return CreateFormattedTopLevelStatement(sourceCode, insertingNodes); +} + +template +ir::TypeNode *CreateFormattedTypeAnnotation(std::string_view const sourceCode, Args &&...args) +{ + std::vector insertingNodes {}; + insertingNodes.reserve(sizeof...(Args)); + (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); + return CreateFormattedTypeAnnotation(sourceCode, insertingNodes); +} + +template +ir::Statement *CreateFormattedStatement(std::string_view const sourceCode, Args &&...args) +{ + std::vector insertingNodes {}; + insertingNodes.reserve(sizeof...(Args)); + (ProcessFormattedArg(insertingNodes, std::forward(args)), ...); + return CreateFormattedStatement(sourceCode, insertingNodes); +} + +#endif diff --git a/ets2panda/parser/ETSparserTypes.cpp b/ets2panda/parser/ETSparserTypes.cpp index 98a1a79cd7c196b069d520e57bba7dcaa55a04e3..1ee35142fd8a792cb1383957cba1115dde960053 100644 --- a/ets2panda/parser/ETSparserTypes.cpp +++ b/ets2panda/parser/ETSparserTypes.cpp @@ -16,7 +16,6 @@ #include "ETSparser.h" #include "ETSNolintParser.h" #include - #include "util/es2pandaMacros.h" #include "parser/parserFlags.h" #include "parser/parserStatusContext.h" @@ -190,7 +189,8 @@ ir::TypeNode *ETSParser::ParseFunctionType(TypeAnnotationParsingOptions *options { auto startLoc = Lexer()->GetToken().Start(); auto params = ParseFunctionParams(); - bool hasReceiver = !params.empty() && params[0]->AsETSParameterExpression()->Ident()->IsReceiver(); + bool hasReceiver = !params.empty() && params[0]->IsETSParameterExpression() && + params[0]->AsETSParameterExpression()->Ident()->IsReceiver(); if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_ARROW)) { if (((*options) & TypeAnnotationParsingOptions::REPORT_ERROR) != 0) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_ARROW); @@ -309,15 +309,17 @@ ir::TypeNode *ETSParser::ParsePotentialFunctionalType(TypeAnnotationParsingOptio // Just to reduce the size of ParseTypeAnnotation(...) method std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnotationParsingOptions *options) { - switch (Lexer()->GetToken().Type()) { - case lexer::TokenType::LITERAL_IDENT: { - auto typeAnnotation = ParseLiteralIdent(options); - if (((*options) & TypeAnnotationParsingOptions::POTENTIAL_CLASS_LITERAL) != 0 && - (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword())) { - return std::make_pair(typeAnnotation, false); - } - return std::make_pair(typeAnnotation, true); + auto tokenType = Lexer()->GetToken().Type(); + if (IsPrimitiveType(Lexer()->GetToken().KeywordType()) || tokenType == lexer::TokenType::LITERAL_IDENT) { + auto typeAnnotation = ParseLiteralIdent(options); + if (((*options) & TypeAnnotationParsingOptions::POTENTIAL_CLASS_LITERAL) != 0 && + (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword())) { + return std::make_pair(typeAnnotation, false); } + return std::make_pair(typeAnnotation, true); + } + + switch (tokenType) { case lexer::TokenType::LITERAL_NULL: { auto typeAnnotation = AllocNode(Allocator()); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); @@ -388,7 +390,7 @@ std::pair ETSParser::GetTypeAnnotationFromParentheses(Type return std::make_pair(typeAnnotation, true); } -static bool IsSimpleReturnThis(lexer::Token const &tokenAfterThis) +bool IsSimpleReturnThis(lexer::Token const &tokenAfterThis) { return (tokenAfterThis.Type() == lexer::TokenType::PUNCTUATOR_ARROW) || (tokenAfterThis.Type() == lexer::TokenType::PUNCTUATOR_COMMA) || @@ -445,6 +447,7 @@ ir::TypeNode *ETSParser::ParseTsArrayType(ir::TypeNode *typeNode, TypeAnnotation if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { if ((*options & TypeAnnotationParsingOptions::REPORT_ERROR) != 0) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET); + return AllocBrokenType({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); } return nullptr; } @@ -469,12 +472,16 @@ ir::TypeNode *ETSParser::ParseTypeAnnotationNoPreferParam(TypeAnnotationParsingO if (typeAnnotation == nullptr) { if (reportError) { LogError(diagnostic::INVALID_TYPE); - auto typeNode = AllocBrokenType({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); - return typeNode; + return AllocBrokenType({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); } return nullptr; } + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) { + typeAnnotation = AllocNode(typeAnnotation, Allocator()); + Lexer()->NextToken(); + } + if (!needFurtherProcessing) { return typeAnnotation; } @@ -506,25 +513,28 @@ bool ETSParser::ParseReadonlyInTypeAnnotation() ir::TypeNode *ETSParser::ParseTypeAnnotation(TypeAnnotationParsingOptions *options) { - ir::TypeNode *typeAnnotation = nullptr; - auto startPos = Lexer()->GetToken().Start(); + const auto startPos = Lexer()->GetToken().Start(); // if there is prefix readonly parameter type, change the return result to ETSTypeReference, like Readonly<> - if (Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_READONLY)) { - typeAnnotation = ParseTypeAnnotationNoPreferParam(options); - if (!typeAnnotation->IsTSArrayType() && !typeAnnotation->IsETSTuple() && - !(typeAnnotation->IsETSTypeReference() && - typeAnnotation->AsETSTypeReference()->BaseName()->Name() == compiler::Signatures::ARRAY)) { - if (!ParseReadonlyInTypeAnnotation()) { - LogError(diagnostic::READONLY_ONLY_ON_ARRAY_OR_TUPLE); - } else { - LogError(diagnostic::READONLY_TYPE_EXPECTED); - } + if (!Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_READONLY)) { + return ParseTypeAnnotationNoPreferParam(options); + } + const auto beforeTypeAnnotation = Lexer()->GetToken().Loc(); + auto typeAnnotation = ParseTypeAnnotationNoPreferParam(options); + if (typeAnnotation == nullptr) { + LogError(diagnostic::INVALID_TYPE); + return AllocBrokenType(beforeTypeAnnotation); + } + if (!typeAnnotation->IsTSArrayType() && !typeAnnotation->IsETSTuple() && + !(typeAnnotation->IsETSTypeReference() && + typeAnnotation->AsETSTypeReference()->BaseName()->Name() == compiler::Signatures::ARRAY)) { + if (!ParseReadonlyInTypeAnnotation()) { + LogError(diagnostic::READONLY_ONLY_ON_ARRAY_OR_TUPLE); + } else { + LogError(diagnostic::READONLY_TYPE_EXPECTED); } - typeAnnotation->SetStart(startPos); - typeAnnotation->AddModifier(ir::ModifierFlags::READONLY_PARAMETER); - } else { - typeAnnotation = ParseTypeAnnotationNoPreferParam(options); } + typeAnnotation->SetStart(startPos); + typeAnnotation->AddModifier(ir::ModifierFlags::READONLY_PARAMETER); return typeAnnotation; } diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index e66067b2874846ff249d94f453426bd547d604a3..f826f534992b2412222b1473bd0842db07f04561 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -141,7 +141,11 @@ ir::Statement *TypedParser::ParsePotentialExpressionStatement(StatementParsingFl switch (Lexer()->GetToken().KeywordType()) { case lexer::TokenType::KEYW_TYPE: { - return ParseTypeAliasDeclaration(); + const auto maybeAlias = ParseTypeAliasDeclaration(); + if (maybeAlias != nullptr) { + return maybeAlias; + } + break; } case lexer::TokenType::KEYW_ABSTRACT: { Lexer()->NextToken(); // eat abstract keyword @@ -164,6 +168,7 @@ ir::Statement *TypedParser::ParsePotentialExpressionStatement(StatementParsingFl if (((GetContext().Status() & ParserStatus::IN_AMBIENT_CONTEXT) != 0U) || IsNamespaceDecl()) { return ParseModuleDeclaration(); } + [[fallthrough]]; } default: { break; @@ -553,6 +558,10 @@ ArenaVector TypedParser::ParseTypeLiteralOrInterfaceBody() util::ErrorRecursionGuard infiniteLoopBlocker(Lexer()); ir::AstNode *member = ParseTypeLiteralOrInterfaceMember(); + if (member == nullptr) { + break; + } + if (member->IsMethodDefinition() && member->AsMethodDefinition()->Function() != nullptr && member->AsMethodDefinition()->Function()->IsOverload() && member->AsMethodDefinition()->Function()->Body() != nullptr) { @@ -571,6 +580,10 @@ ArenaVector TypedParser::ParseTypeLiteralOrInterfaceBody() break; } + if (Lexer()->GetToken().Type() == lexer::TokenType::JS_DOC_START) { + continue; + } + if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COMMA && Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SEMI_COLON) { if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { @@ -1274,14 +1287,20 @@ ir::AstNode *TypedParser::ParseTypeParameterInstantiationImpl(TypeAnnotationPars Lexer()->NextToken(); continue; } + case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: { Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN, 1); break; } + case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL: case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: { Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN, 2U); break; } + case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL: { + Lexer()->BackwardToken(lexer::TokenType::PUNCTUATOR_GREATER_THAN, 3U); + break; + } case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { break; } diff --git a/ets2panda/parser/TypedParser.h b/ets2panda/parser/TypedParser.h index d9caee03b60e428f30f95b4e69cca452a142ae0f..8101ab712324f90a8655a990b4220811eb90ba0a 100644 --- a/ets2panda/parser/TypedParser.h +++ b/ets2panda/parser/TypedParser.h @@ -73,6 +73,9 @@ protected: bool CheckClassElement(ir::AstNode *property, ir::MethodDefinition *&ctor, ArenaVector &properties) override; bool IsNamespaceDecl(); + bool IsPrimitiveType(const lexer::TokenType &tokenType); + bool IsValidTokenTypeOfArrowFunctionStart(lexer::TokenType tokenType); + bool EatArrowFunctionParams(lexer::Lexer *lexer); ir::ModifierFlags ParseModifiers() override; ParserStatus ValidateArrowParameter(ir::Expression *expr, bool *seenOptional) override; diff --git a/ets2panda/parser/context/parserContext.cpp b/ets2panda/parser/context/parserContext.cpp index f475a3578e837623bc8c5667ea058b97a5d1cb81..2fa2490a991db3cf411a497e3798519831c9e32b 100644 --- a/ets2panda/parser/context/parserContext.cpp +++ b/ets2panda/parser/context/parserContext.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 @@ -23,6 +23,11 @@ ParserContext::ParserContext(const Program *program, ParserStatus status) { } +ParserContext::ParserContext(const Program *program, ParserStatus status, bool isEnableJsdoc) + : program_(program), status_(status), lang_(ToLanguage(program->Extension())), isEnableJsdoc_(isEnableJsdoc) +{ +} + const ParserContext *ParserContext::FindLabel(const util::StringView &label) const { const auto *iter = this; diff --git a/ets2panda/parser/context/parserContext.h b/ets2panda/parser/context/parserContext.h index 29130fe409ecc597f42a89018045d5aa88ed0858..80620c2c64470287090c67db64fe6ee7f2a2b237 100644 --- a/ets2panda/parser/context/parserContext.h +++ b/ets2panda/parser/context/parserContext.h @@ -73,7 +73,9 @@ enum class ParserStatus : uint64_t { DEPENDENCY_ANALYZER_MODE = 1ULL << 39ULL, - STATIC_BLOCK = 1ULL << 40ULL + STATIC_BLOCK = 1ULL << 40ULL, + ALLOW_JS_DOC_START = 1ULL << 41ULL, + IN_PACKAGE = 1ULL << 42ULL, }; } // namespace ark::es2panda::parser @@ -91,6 +93,8 @@ public: explicit ParserContext(const Program *program, ParserStatus status); + explicit ParserContext(const Program *program, ParserStatus status, bool isEnableJsdoc); + explicit ParserContext(ParserContext *current, ParserStatus newStatus, util::StringView label = "") : program_(current->program_), prev_(current), label_(label), lang_(current->lang_) { @@ -99,6 +103,7 @@ public: ParserStatus::ALLOW_THIS_TYPE | ParserStatus::IN_CLASS_BODY | ParserStatus::FUNCTION | ParserStatus::IN_AMBIENT_CONTEXT); status_ = currentStatus | newStatus; + isEnableJsdoc_ = prev_->isEnableJsdoc_; } DEFAULT_COPY_SEMANTIC(ParserContext); @@ -185,6 +190,11 @@ public: return formattingFileName_; } + [[nodiscard]] bool IsEnableJsdocParse() const noexcept + { + return isEnableJsdoc_; + } + template void SetFormattingFileName(T &&fileName) { @@ -198,6 +208,7 @@ private: util::StringView label_ {}; std::string_view formattingFileName_ {DEFAULT_SOURCE_FILE}; Language lang_; + bool isEnableJsdoc_ {false}; }; } // namespace ark::es2panda::parser diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 4e33145164b5577aefed1149bdb7bf393a55f50f..37c03683eb146388e86bb149022ca0294731df53 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -592,12 +592,13 @@ ir::Expression *ParserImpl::ParseAssignmentExpression(ir::Expression *lhsExpress conditionalExpr->SetRange({lhsExpression->Start(), alternate->End()}); return conditionalExpr; } - case lexer::TokenType::PUNCTUATOR_ARROW: + case lexer::TokenType::PUNCTUATOR_ARROW: { if (lexer_->GetToken().NewLine()) { LogError(diagnostic::EXPECTED_EXPRESSION_GOT_ARROW); } return ParseArrowFunctionExpression(lhsExpression, nullptr, nullptr, false); + } case lexer::TokenType::PUNCTUATOR_SUBSTITUTION: { ValidateAssignmentTarget(flags, lhsExpression); @@ -605,12 +606,17 @@ ir::Expression *ParserImpl::ParseAssignmentExpression(ir::Expression *lhsExpress ir::Expression *assignmentExpression = ParseExpression(CarryPatternFlags(flags)); return CreateBinaryAssignmentExpression(assignmentExpression, lhsExpression, tokenType); } - case lexer::TokenType::KEYW_AS: + case lexer::TokenType::KEYW_AS: { if (auto asExpression = ParsePotentialAsExpression(lhsExpression); asExpression != nullptr) { return ParseAssignmentExpression(asExpression); } break; + } default: { + if (tokenType == lexer::TokenType::LITERAL_IDENT && + lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_INSTANCEOF) { + tokenType = lexer::TokenType::KEYW_INSTANCEOF; + } auto expression = ParseAssignmentBinaryExpression(tokenType, lhsExpression, flags); if (expression == nullptr) { expression = ParseAssignmentEqualExpression(tokenType, lhsExpression, flags); @@ -663,7 +669,7 @@ ir::Expression *ParserImpl::ParseAssignmentBinaryExpression(const lexer::TokenTy case lexer::TokenType::PUNCTUATOR_MOD: case lexer::TokenType::KEYW_INSTANCEOF: case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: { - return ParseAssignmentExpression(ParseBinaryExpression(lhsExpression)); + return ParseAssignmentExpression(ParseBinaryExpression(lhsExpression, tokenType)); } default: break; @@ -706,6 +712,7 @@ ir::Expression *ParserImpl::ParseAssignmentEqualExpression(const lexer::TokenTyp LogUnexpectedToken(tokenType); lexer_->NextToken(); // eat token ParseExpression(); // Try to parse expression, but skip the result. + [[fallthrough]]; } default: break; @@ -1295,9 +1302,8 @@ static ir::Expression *FindAndAmendChildExpression(ir::Expression *expression, c return shouldBeAmended ? expression : parentExpression; } -ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, ExpressionParseFlags flags) +ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, const lexer::TokenType operatorType) { - lexer::TokenType operatorType = lexer_->GetToken().Type(); ES2PANDA_ASSERT(lexer::Token::IsBinaryToken(operatorType)); if (operatorType == lexer::TokenType::PUNCTUATOR_EXPONENTIATION) { @@ -1308,11 +1314,6 @@ ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, Expressi lexer_->NextToken(); - ExpressionParseFlags newFlags = ExpressionParseFlags::DISALLOW_YIELD; - if ((operatorType == lexer::TokenType::KEYW_INSTANCEOF) || ((flags & ExpressionParseFlags::INSTANCEOF) != 0)) { - newFlags |= ExpressionParseFlags::INSTANCEOF; - } - ir::Expression *rightExpr = ParseExpressionOrTypeAnnotation(operatorType, ExpressionParseFlags::DISALLOW_YIELD); ir::ConditionalExpression *conditionalExpr = nullptr; if (rightExpr->IsConditionalExpression() && !rightExpr->IsGrouped()) { diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index 60c777ff060609671b6b38aace63279e9c6ef6ef..ade0b8337b5d866c72581b70a5723e2543e37930 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -44,7 +44,10 @@ using namespace std::literals::string_literals; namespace ark::es2panda::parser { ParserImpl::ParserImpl(Program *program, const util::Options *options, util::DiagnosticEngine &diagnosticEngine, ParserStatus status) - : program_(program), context_(program_, status), options_(options), diagnosticEngine_(diagnosticEngine) + : program_(program), + context_(program_, status, options == nullptr ? false : options->IsEnableJsdocParse()), + options_(options), + diagnosticEngine_(diagnosticEngine) { } @@ -823,6 +826,10 @@ ParserImpl::ClassBody ParserImpl::ParseClassBody(ir::ClassDefinitionModifiers mo util::ErrorRecursionGuard infiniteLoopBlocker(Lexer()); ir::AstNode *property = ParseClassElement(properties, modifiers, flags); + if (property == nullptr) { + continue; + } + if (property->IsBrokenStatement()) { // Error processing. continue; } @@ -880,6 +887,19 @@ ArenaVector ParserImpl::ParseFunctionParams() if (parameter == nullptr) { return false; } + bool seenOptional = false; + for (auto const param : params) { + if (param->IsETSParameterExpression() && param->AsETSParameterExpression()->IsOptional()) { + seenOptional = true; + break; + } + } + + if (seenOptional && !(parameter->IsETSParameterExpression() && + (parameter->AsETSParameterExpression()->IsOptional() || + parameter->AsETSParameterExpression()->RestParameter() != nullptr))) { + LogError(diagnostic::REQUIRED_PARAM_AFTER_OPTIONAL, {}, parameter->Start()); + } if (parameter->IsETSParameterExpression() && parameter->AsETSParameterExpression()->Ident()->IsReceiver() && !params.empty()) { @@ -1222,11 +1242,18 @@ ir::Identifier *ParserImpl::ExpectIdentifier([[maybe_unused]] bool isReference, } } + auto const &tokenStart = token.Start(); + if (token.IsPredefinedType() && !util::Helpers::IsStdLib(program_) && + ((options & TypeAnnotationParsingOptions::ADD_TYPE_PARAMETER_BINDING) == 0)) { + LogError(diagnostic::PREDEFINED_TYPE_AS_IDENTIFIER, {token.Ident()}, tokenStart); + lexer_->NextToken(); + return AllocBrokenExpression(tokenStart); + } + if (token.IsDefinableTypeName() && isUserDefinedType) { LogError(diagnostic::NOT_ALLOWED_USER_DEFINED_TYPE); } - auto const &tokenStart = token.Start(); util::StringView tokenName {}; if (tokenType == lexer::TokenType::LITERAL_IDENT) { diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index 6ff5404d23293ce0cab4b929cfe3c3b6c2d62248..c71ad06628d3c17756b408eace5e79973cf7e316 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -37,6 +37,10 @@ class Options; class SourcePositionHelper; } // namespace ark::es2panda::util +namespace ark::es2panda::public_lib { +struct Context; +} // namespace ark::es2panda::public_lib + namespace ark::es2panda::parser { using ENUMBITOPS_OPERATORS; @@ -101,6 +105,16 @@ public: lexer::SourcePosition GetPositionForDiagnostic() const; + void SetContext(public_lib::Context *ctx) + { + ctx_ = ctx; + } + + public_lib::Context *Context() + { + return ctx_; + } + protected: virtual void ParseProgram(ScriptKind kind); static ExpressionParseFlags CarryExpressionParserFlag(ExpressionParseFlags origin, ExpressionParseFlags carry); @@ -126,8 +140,7 @@ protected: // ExpressionParser.Cpp ir::Expression *ParseKeywordExpression(); - ir::Expression *ParseBinaryExpression(ir::Expression *left, - ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS); + ir::Expression *ParseBinaryExpression(ir::Expression *left, const lexer::TokenType operatorType); void ValidateUpdateExpression(ir::Expression *returnExpression, bool isChainExpression); ir::Expression *ParseMemberExpression(bool ignoreCallExpression = false, ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS); @@ -570,6 +583,7 @@ private: lexer::Lexer *lexer_ {}; const util::Options *options_; util::DiagnosticEngine &diagnosticEngine_; + public_lib::Context *ctx_ {nullptr}; }; } // namespace ark::es2panda::parser diff --git a/ets2panda/parser/program/program.cpp b/ets2panda/parser/program/program.cpp index cd4ef559335f29546def94def9687fae01b755d2..572ce976dc019b2b7e56d904c9303874ed1e8ce9 100644 --- a/ets2panda/parser/program/program.cpp +++ b/ets2panda/parser/program/program.cpp @@ -14,6 +14,8 @@ */ #include "program.h" +#include "macros.h" +#include "public/public.h" #include "compiler/core/CFG.h" #include "generated/signatures.h" @@ -23,17 +25,52 @@ #include "ir/base/classDefinition.h" #include "ir/statements/blockStatement.h" +#include + namespace ark::es2panda::parser { Program::Program(ArenaAllocator *allocator, varbinder::VarBinder *varbinder) : allocator_(allocator), - varbinder_(varbinder), externalSources_(allocator_->Adapter()), directExternalSources_(allocator_->Adapter()), extension_(varbinder->Extension()), etsnolintCollection_(allocator_->Adapter()), - cfg_(allocator_->New(allocator_)) + cfg_(allocator_->New(allocator_)), + functionScopes_(allocator_->Adapter()), + varbinders_(allocator_->Adapter()), + checkers_(allocator_->Adapter()) +{ + PushVarBinder(varbinder); +} + +void Program::PushVarBinder(varbinder::VarBinder *varbinder) +{ + varbinders_.insert({compiler::GetPhaseManager()->GetCurrentMajor(), varbinder}); +} + +const varbinder::VarBinder *Program::VarBinder() const +{ + return varbinders_.at(compiler::GetPhaseManager()->GetCurrentMajor()); +} + +varbinder::VarBinder *Program::VarBinder() +{ + return varbinders_.at(compiler::GetPhaseManager()->GetCurrentMajor()); +} + +checker::Checker *Program::Checker() { + return checkers_.at(compiler::GetPhaseManager()->GetCurrentMajor()); +} + +void Program::PushChecker(checker::Checker *checker) +{ + checkers_.push_back(checker); +} + +const checker::Checker *Program::Checker() const +{ + return checkers_.at(compiler::GetPhaseManager()->GetCurrentMajor()); } std::string Program::Dump() const @@ -50,12 +87,16 @@ void Program::DumpSilent() const varbinder::ClassScope *Program::GlobalClassScope() { - return globalClass_->Scope()->AsClassScope(); + ES2PANDA_ASSERT(GlobalClass() != nullptr); + ES2PANDA_ASSERT(GlobalClass()->Scope() != nullptr); + return GlobalClass()->Scope()->AsClassScope(); } const varbinder::ClassScope *Program::GlobalClassScope() const { - return globalClass_->Scope()->AsClassScope(); + ES2PANDA_ASSERT(GlobalClass() != nullptr); + ES2PANDA_ASSERT(GlobalClass()->Scope() != nullptr); + return GlobalClass()->Scope()->AsClassScope(); } varbinder::GlobalScope *Program::GlobalScope() @@ -112,6 +153,32 @@ bool Program::NodeContainsETSNolint(const ir::AstNode *node, ETSWarnings warning return nodeEtsnolints->second.find(warning) != nodeEtsnolints->second.end(); } +void Program::SetFlag(ProgramFlags flag) +{ + ES2PANDA_ASSERT(VarBinder() != nullptr && VarBinder()->GetContext() != nullptr); + auto compilingState = VarBinder()->GetContext()->compilingState; + if (compilingState == public_lib::CompilingState::MULTI_COMPILING_INIT || + compilingState == public_lib::CompilingState::MULTI_COMPILING_FOLLOW) { + programFlags_ |= flag; + } +} + +bool Program::GetFlag(ProgramFlags flag) const +{ + return (programFlags_ & flag) != 0U; +} + +void Program::SetASTChecked() +{ + programFlags_ |= ProgramFlags::AST_CHECKED; +} + +bool Program::IsASTChecked() +{ + return ((programFlags_ & ProgramFlags::AST_CHECKED) != 0U) || + ((programFlags_ & ProgramFlags::AST_CHECK_PROCESSED) != 0U); +} + Program::~Program() // NOLINT(modernize-use-equals-default) { #ifndef NDEBUG @@ -124,9 +191,40 @@ compiler::CFG *Program::GetCFG() return cfg_; } +ir::ClassDefinition *Program::GlobalClass() +{ + return ast_->AsETSModule()->GlobalClass(); +} + +const ir::ClassDefinition *Program::GlobalClass() const +{ + return ast_->AsETSModule()->GlobalClass(); +} + +void Program::SetGlobalClass(ir::ClassDefinition *globalClass) +{ + ast_->AsETSModule()->SetGlobalClass(globalClass); +} + const compiler::CFG *Program::GetCFG() const { return cfg_; } +bool Program::MergeExternalSource(const ExternalSource *externalSource) +{ + // prevent using cache for cycle import + for (const auto &[moduleName, _] : *externalSource) { + if (ModuleName() == moduleName) { + return false; + } + } + + for (const auto &[moduleName, extProgs] : *externalSource) { + externalSources_.emplace(moduleName, extProgs); + } + + return true; +} + } // namespace ark::es2panda::parser diff --git a/ets2panda/parser/program/program.h b/ets2panda/parser/program/program.h index 7820ed68132b23ce73627d5e24e472fe36e8fd5b..c29543942cadcf88358a2ac9db0e08e8f34a4169 100644 --- a/ets2panda/parser/program/program.h +++ b/ets2panda/parser/program/program.h @@ -24,8 +24,10 @@ #include "util/importPathManager.h" #include "varbinder/varbinder.h" #include +#include "util/enumbitops.h" #include +#include namespace ark::es2panda::ir { class BlockStatement; @@ -33,16 +35,40 @@ class BlockStatement; namespace ark::es2panda::varbinder { class VarBinder; +class FunctionScope; } // namespace ark::es2panda::varbinder namespace ark::es2panda::compiler { class CFG; } // namespace ark::es2panda::compiler +namespace ark::es2panda::checker { +class Checker; +} // namespace ark::es2panda::checker + namespace ark::es2panda::parser { enum class ScriptKind { SCRIPT, MODULE, STDLIB }; enum EntityType { CLASS_PROPERTY = 0, METHOD_DEFINITION = 1, CLASS_DEFINITION = 2, TS_INTERFACE_DECLARATION = 3 }; +#ifndef NDEBUG +constexpr uint32_t POISON_VALUE {0x12346789}; +#endif + +using ENUMBITOPS_OPERATORS; + +enum class ProgramFlags : uint32_t { + NONE = 0U, + AST_CHECKED = 1U << 0U, + AST_CHECK_PROCESSED = 1U << 1U, + AST_ENUM_LOWERED = 1U << 2U, + AST_BOXED_TYPE_LOWERED = 1U << 3U, + AST_CONSTANT_EXPRESSION_LOWERED = 1U << 5U, + AST_STRING_CONSTANT_LOWERED = 1U << 6U, + AST_IDENTIFIER_ANALYZED = 1U << 7U, + AST_HAS_SCOPES_INITIALIZED = 1U << 8U, + AST_HAS_OPTIONAL_PARAMETER_ANNOTATION = 1U << 9U, +}; + class Program { public: using ExternalSource = ArenaUnorderedMap>; @@ -51,10 +77,13 @@ public: using ETSNolintsCollectionMap = ArenaUnorderedMap>; template - static Program NewProgram(ArenaAllocator *allocator) + static Program NewProgram(ArenaAllocator *allocator, varbinder::VarBinder *varBinder = nullptr) { - auto *varbinder = allocator->New(allocator); - return Program(allocator, varbinder); + if (varBinder == nullptr) { + auto *vb = allocator->New(allocator); + return Program(allocator, vb); + } + return Program(allocator, varBinder); } Program(ArenaAllocator *allocator, varbinder::VarBinder *varbinder); @@ -74,15 +103,16 @@ public: return allocator_; } - const varbinder::VarBinder *VarBinder() const - { - return varbinder_; - } + void PushVarBinder(varbinder::VarBinder *varbinder); - varbinder::VarBinder *VarBinder() - { - return varbinder_; - } + const varbinder::VarBinder *VarBinder() const; + + varbinder::VarBinder *VarBinder(); + + checker::Checker *Checker(); + const checker::Checker *Checker() const; + + void PushChecker(checker::Checker *checker); ScriptExtension Extension() const { @@ -161,20 +191,11 @@ public: MaybeTransformToDeclarationModule(); } - ir::ClassDefinition *GlobalClass() - { - return globalClass_; - } + ir::ClassDefinition *GlobalClass(); - const ir::ClassDefinition *GlobalClass() const - { - return globalClass_; - } + const ir::ClassDefinition *GlobalClass() const; - void SetGlobalClass(ir::ClassDefinition *globalClass) - { - globalClass_ = globalClass; - } + void SetGlobalClass(ir::ClassDefinition *globalClass); ExternalSource &ExternalSources() { @@ -255,14 +276,19 @@ public: return moduleInfo_.kind == util::ModuleKind::PACKAGE; } - void MarkASTAsChecked() + void SetFlag(ProgramFlags flag); + bool GetFlag(ProgramFlags flag) const; + void SetASTChecked(); + bool IsASTChecked(); + + void MarkASTAsLowered() { - isASTchecked_ = true; + isASTlowered_ = true; } - bool IsASTChecked() const + bool IsASTLowered() const { - return isASTchecked_; + return isASTlowered_; } bool IsStdLib() const @@ -291,6 +317,8 @@ public: return declGenExportNodes_; } + bool MergeExternalSource(const ExternalSource *externalSource); + void AddDeclGenExportNode(const std::string &declGenExportStr, ir::AstNode *node) { declGenExportNodes_.emplace_back(declGenExportStr, node); @@ -312,13 +340,40 @@ public: compiler::CFG *GetCFG(); const compiler::CFG *GetCFG() const; + [[nodiscard]] const ArenaVector &Functions() const noexcept + { + return functionScopes_; + } + + [[nodiscard]] ArenaVector &Functions() noexcept + { + return functionScopes_; + } + + void AddToFunctionScopes(varbinder::FunctionScope *funcScope) + { + functionScopes_.push_back(funcScope); + } + + std::unordered_map> &GetFileDependencies() + { + return fileDependencies_; + } + + void AddFileDependencies(const std::string &file, const std::string &depFile) + { + if (fileDependencies_.count(file) == 0U) { + fileDependencies_[file] = std::unordered_set(); + } + fileDependencies_[file].insert(depFile); + } + private: void MaybeTransformToDeclarationModule(); +private: ArenaAllocator *allocator_ {}; - varbinder::VarBinder *varbinder_ {}; ir::BlockStatement *ast_ {}; - ir::ClassDefinition *globalClass_ {}; util::StringView sourceCode_ {}; util::Path sourceFile_ {}; util::StringView sourceFileFolder_ {}; @@ -330,16 +385,29 @@ private: ScriptExtension extension_ {}; ETSNolintsCollectionMap etsnolintCollection_; util::ModuleInfo moduleInfo_; - bool isASTchecked_ {}; + bool isASTlowered_ {}; lexer::SourcePosition packageStartPosition_ {}; compiler::CFG *cfg_; std::vector> declGenExportNodes_; + ArenaVector functionScopes_; + std::unordered_map> fileDependencies_; +private: + ArenaMap varbinders_; + ArenaVector checkers_; #ifndef NDEBUG - const static uint32_t POISON_VALUE {0x12346789}; uint32_t poisonValue_ {POISON_VALUE}; #endif + ProgramFlags programFlags_ {}; }; } // namespace ark::es2panda::parser +namespace enumbitops { + +template <> +struct IsAllowedType : std::true_type { +}; + +} // namespace enumbitops + #endif diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index dc9ad8cce57ba5929ab9662064ea8ada099f96c0..ff4089f8bd874d5c536ccd7f94733429ee1b289c 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "ETSparser.h" #include "parser/parserFlags.h" #include "parser/parserStatusContext.h" #include "util/errorRecovery.h" @@ -137,6 +138,10 @@ ir::Statement *ParserImpl::ParseStatementControlFlowTokenHelper(StatementParsing // NOLINTNEXTLINE(google-default-arguments) ir::Statement *ParserImpl::ParseStatement(StatementParsingFlags flags) { + if (IsETSParser()) { + AsETSParser()->HandleJsDocLikeComments(); + } + const auto tokenType = lexer_->GetToken().Type(); bool isPunctuatorToken = tokenType == lexer::TokenType::PUNCTUATOR_LEFT_BRACE || tokenType == lexer::TokenType::PUNCTUATOR_SEMI_COLON || @@ -179,6 +184,9 @@ ir::Statement *ParserImpl::ParseStatementBasedOnTokenType(StatementParsingFlags case lexer::TokenType::KEYW_DEBUGGER: return ParseDebuggerStatement(); case lexer::TokenType::LITERAL_IDENT: + if (lexer_->GetToken().KeywordType() == lexer::TokenType::KEYW_VAR) { + return ParseVarStatement(); + } return ParseStatementLiteralIdentHelper(flags); case lexer::TokenType::KEYW_WITH: LogError(diagnostic::WITH_DEPRECATED); @@ -571,8 +579,11 @@ ir::Statement *ParserImpl::ParseDoWhileStatement() lexer::SourcePosition startLoc = lexer_->GetToken().Start(); lexer_->NextToken(); + ir::Statement *body = ParseStatement(); - ES2PANDA_ASSERT(body != nullptr); + if (IsBrokenStatement(body)) { + LogError(diagnostic::MISSING_LOOP_BODY, {"do while"}); + } if (lexer_->GetToken().Type() != lexer::TokenType::KEYW_WHILE) { if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { @@ -593,12 +604,15 @@ ir::Statement *ParserImpl::ParseDoWhileStatement() lexer_->NextToken(); - ir::Expression *test = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); + ir::Expression *condition = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); + if (condition->IsBrokenExpression()) { + LogError(diagnostic::MISSING_LOOP_CONDITION, {"do while"}); + } auto endLoc = lexer_->GetToken().End(); ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); - auto *doWhileStatement = AllocNode(body, test); + auto *doWhileStatement = AllocNode(body, condition); doWhileStatement->SetRange({startLoc, endLoc}); if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -1021,6 +1035,10 @@ ir::Statement *ParserImpl::ParseForStatement() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); ir::Statement *bodyNode = ParseStatement(); + if (bodyNode == nullptr) { + return AllocBrokenStatement(Lexer()->GetToken().Loc()); + } + return CreateForStatement({initNode, rightNode, updateNode, bodyNode}, forKind, startLoc, isAwait); } @@ -1510,17 +1528,22 @@ ir::Statement *ParserImpl::ParseWhileStatement() lexer_->NextToken(); ExpectToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); - ir::Expression *test = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); + ir::Expression *condition = ParseExpression(ExpressionParseFlags::ACCEPT_COMMA); ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); IterationContext iterCtx(&context_); ir::Statement *body = ParseStatement(); - ES2PANDA_ASSERT(body != nullptr); - ES2PANDA_ASSERT(test != nullptr); + if (IsBrokenStatement(body)) { + LogError(diagnostic::MISSING_LOOP_BODY, {"while"}); + } + + if (condition->IsBrokenExpression()) { + LogError(diagnostic::MISSING_LOOP_CONDITION, {"while"}); + } lexer::SourcePosition endLoc = body->End(); - auto *whileStatement = AllocNode(test, body); + auto *whileStatement = AllocNode(condition, body); whileStatement->SetRange({startLoc, endLoc}); return whileStatement; @@ -1937,14 +1960,17 @@ ir::Statement *ParserImpl::AllocBrokenStatement(const lexer::SourcePosition &pos ir::Statement *ParserImpl::AllocBrokenStatement(const lexer::SourceRange &range) { - auto *node = AllocEmptyStatement(); - node->SetRange(range); - return node; + auto *broken = AllocNode(true); + broken->SetRange(range); + return broken; } bool ParserImpl::IsBrokenStatement(ir::Statement *st) { - return st->IsEmptyStatement(); + if (st->IsEmptyStatement()) { + return st->AsEmptyStatement()->IsBrokenStatement(); + } + return false; } ir::Statement *ParserImpl::AllocEmptyStatement() diff --git a/ets2panda/public/CMakeLists.txt b/ets2panda/public/CMakeLists.txt index a399f4b2516e8e481541a17fd08041520f633736..12227ac6fe50d2e2f004809ff2fde43d91df7ca7 100644 --- a/ets2panda/public/CMakeLists.txt +++ b/ets2panda/public/CMakeLists.txt @@ -27,6 +27,7 @@ set(ES2PANDA_API set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/varbinder/variableFlags.h ${GENERATED_DIR}/options.h + ${ES2PANDA_ROOT}/util/options.h ${ES2PANDA_ROOT}/lexer/regexp/regexp.h ${ES2PANDA_ROOT}/util/language.h ${GENERATED_DIR}/tokenType.h @@ -130,8 +131,8 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/checker/types/ts/typeReference.h ${ES2PANDA_ROOT}/ir/expressions/memberExpression.h ${ES2PANDA_ROOT}/checker/types/ets/etsExtensionFuncHelperType.h + ${ES2PANDA_ROOT}/ir/ets/etsNonNullishTypeNode.h ${ES2PANDA_ROOT}/ir/ets/etsNullishTypes.h - ${ES2PANDA_ROOT}/ir/ets/etsLaunchExpression.h ${ES2PANDA_ROOT}/ir/expressions/awaitExpression.h ${ES2PANDA_ROOT}/ir/ets/etsFunctionType.h ${ES2PANDA_ROOT}/checker/types/ets/etsArrayType.h @@ -266,6 +267,7 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/ir/statements/annotationDeclaration.h ${ES2PANDA_ROOT}/ir/statements/annotationUsage.h ${ES2PANDA_ROOT}/ir/annotationAllowed.h + ${ES2PANDA_ROOT}/ir/jsDocAllowed.h ${ES2PANDA_ROOT}/ir/base/scriptFunctionSignature.h ${ES2PANDA_ROOT}/ir/expressions/yieldExpression.h ${ES2PANDA_ROOT}/ir/ets/etsNewMultiDimArrayInstanceExpression.h @@ -288,17 +290,20 @@ set (HEADERS_TO_BE_PARSED ${ES2PANDA_ROOT}/parser/program/program.h ${ES2PANDA_ROOT}/es2panda.h ${ES2PANDA_ROOT}/ast_verifier/ASTVerifier.h - ${ES2PANDA_ROOT}/ast_verifier/checkContext.h ${ES2PANDA_ROOT}/util/importPathManager.h + ${ES2PANDA_ROOT}/util/path.h + ${ES2PANDA_ROOT}/util/arktsconfig.h ) set (ES2PANDA_API_GENERATED ${LIBGEN_DIR}/gen/headers/checker/types/typeMapping.yaml ${LIBGEN_DIR}/gen/headers/options.yaml + ${LIBGEN_DIR}/gen/headers/util/options.yaml ${LIBGEN_DIR}/gen/headers/ir/astNodeMapping.yaml ${LIBGEN_DIR}/gen/headers/varbinder/variableFlags.yaml ${LIBGEN_DIR}/gen/headers/ir/typed.yaml ${LIBGEN_DIR}/gen/headers/ir/annotationAllowed.yaml + ${LIBGEN_DIR}/gen/headers/ir/jsDocAllowed.yaml ${LIBGEN_DIR}/gen/headers/es2panda.yaml ${LIBGEN_DIR}/gen/headers/ir/statements/labelledStatement.yaml ${LIBGEN_DIR}/gen/headers/checker/types/ts/unknownType.yaml @@ -432,7 +437,6 @@ set (ES2PANDA_API_GENERATED ${LIBGEN_DIR}/gen/headers/ir/statements/annotationDeclaration.yaml ${LIBGEN_DIR}/gen/headers/ir/statements/annotationUsage.yaml ${LIBGEN_DIR}/gen/headers/ir/statements/emptyStatement.yaml - ${LIBGEN_DIR}/gen/headers/ir/ets/etsLaunchExpression.yaml ${LIBGEN_DIR}/gen/headers/ir/statements/whileStatement.yaml ${LIBGEN_DIR}/gen/headers/ir/base/scriptFunctionSignature.yaml ${LIBGEN_DIR}/gen/headers/checker/types/ts/numberLiteralType.yaml @@ -556,8 +560,9 @@ set (ES2PANDA_API_GENERATED ${LIBGEN_DIR}/gen/headers/parser/ETSparser.yaml ${LIBGEN_DIR}/gen/headers/parser/program/program.yaml ${LIBGEN_DIR}/gen/headers/ast_verifier/ASTVerifier.yaml - ${LIBGEN_DIR}/gen/headers/ast_verifier/checkContext.yaml ${LIBGEN_DIR}/gen/headers/util/importPathManager.yaml + ${LIBGEN_DIR}/gen/headers/util/path.yaml + ${LIBGEN_DIR}/gen/headers/util/arktsconfig.yaml ) diff --git a/ets2panda/public/cppToCTypes.yaml b/ets2panda/public/cppToCTypes.yaml index abc68ed739387699e9a7429d12c599e89f647933..10e1650666a4751492058c9f438720b80251668d 100644 --- a/ets2panda/public/cppToCTypes.yaml +++ b/ets2panda/public/cppToCTypes.yaml @@ -282,7 +282,7 @@ change_types: \tsize_t i = 0;\n \tfor (auto elem : resultSet) {\n \t\tauto toPush = |reverse_template_nested_expression_1_start|(elem)|reverse_template_nested_expression_1_end|;\n - \t\tapiRes[i] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n + \t\tapiRes[i++] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n \t}" - es2panda_arg: @@ -328,7 +328,7 @@ change_types: \tsize_t i = 0;\n \tfor (auto elem : resultSet) {\n \t\tauto toPush = |reverse_template_nested_expression_1_start|(elem)|reverse_template_nested_expression_1_end|;\n - \t\tapiRes[i] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n + \t\tapiRes[i++] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n \t}" - es2panda_arg: @@ -374,7 +374,7 @@ change_types: \tsize_t i = 0;\n \tfor (auto elem : resultSet) {\n \t\tauto toPush = |reverse_template_nested_expression_1_start|(elem)|reverse_template_nested_expression_1_end|;\n - \t\tapiRes[i] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n + \t\tapiRes[i++] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n \t}" - es2panda_arg: @@ -416,11 +416,11 @@ change_types: \tauto resultSet = " end: ";\n \t*|return_args.0.name| = resultSet|accessor|size();\n - \tauto res = ctxAllocator->New<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|[]>(*|return_args.0.name|);\n + \tauto apiRes = ctxAllocator->New<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|[]>(*|return_args.0.name|);\n \tsize_t i = 0;\n \tfor (auto elem : resultSet) {\n \t\tauto toPush = |reverse_template_nested_expression_1_start|(elem)|reverse_template_nested_expression_1_end|;\n - \t\tres[i] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n + \t\tapiRes[i++] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n \t}" - es2panda_arg: @@ -462,11 +462,11 @@ change_types: \tauto resultSet = " end: ";\n \t*|return_args.0.name| = resultSet|accessor|size();\n - \tauto res = ctxAllocator->New<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|[]>(*|return_args.0.name|);\n + \tauto apiRes = ctxAllocator->New<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|[]>(*|return_args.0.name|);\n \tsize_t i = 0;\n \tfor (auto elem : resultSet) {\n \t\tauto toPush = |reverse_template_nested_expression_1_start|(elem)|reverse_template_nested_expression_1_end|;\n - \t\tres[i] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n + \t\tapiRes[i++] = reinterpret_cast<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|>(toPush);\n \t}" - es2panda_arg: @@ -634,11 +634,11 @@ change_types: \tauto resultMap = " end: ";\n \t*|return_args.1.name| = resultMap|accessor|size();\n - \tauto res = ctxAllocator->New<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|[]>(*|return_args.1.name|);\n + \tauto apiRes = ctxAllocator->New<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|[]>(*|return_args.1.name|);\n \t*|return_args.0.name| = ctxAllocator->New<|new_args.1.type.const| |new_args.1.type.name| |new_args.1.type.ptr_depth - 1||new_args.1.type.ref_depth|[]>(*|return_args.1.name|);\n \tsize_t i = 0;\n \tfor (auto [key, value] : resultMap) {\n - \t\tres[i] = |reverse_template_nested_expression_1_start|(key)|reverse_template_nested_expression_1_end|;\n + \t\tapiRes[i] = |reverse_template_nested_expression_1_start|(key)|reverse_template_nested_expression_1_end|;\n \t\t(*|return_args.0.name|)[i] = |reverse_template_nested_expression_2_start|(value)|reverse_template_nested_expression_2_end|;\n \t\t++i;\n \t}" @@ -694,11 +694,11 @@ change_types: \tauto resultMap = " end: ";\n \t*|return_args.1.name| = resultMap|accessor|size();\n - \tauto res = ctxAllocator->New<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|[]>(*|return_args.1.name|);\n + \tauto apiRes = ctxAllocator->New<|new_args.0.type.const| |new_args.0.type.name| |new_args.0.type.ptr_depth - 1||new_args.0.type.ref_depth|[]>(*|return_args.1.name|);\n \t*|return_args.0.name| = ctxAllocator->New<|new_args.1.type.const| |new_args.1.type.name| |new_args.1.type.ptr_depth - 1||new_args.1.type.ref_depth|[]>(*|return_args.1.name|);\n \tsize_t i = 0;\n \tfor (auto [key, value] : (*resultMap)) {\n - \t\tres[i] = |reverse_template_nested_expression_1_start|(key)|reverse_template_nested_expression_1_end|;\n + \t\tapiRes[i] = |reverse_template_nested_expression_1_start|(key)|reverse_template_nested_expression_1_end|;\n \t\t(*|return_args.0.name|)[i] = |reverse_template_nested_expression_2_start|(value)|reverse_template_nested_expression_2_end|;\n \t\t++i;\n \t}" @@ -1175,7 +1175,7 @@ change_types: namespace: 'checker::' cast: expression: >- - auto |arg_name|E2p = + auto &|arg_name|E2p = *(reinterpret_cast(|arg_name|)); var_name: '|arg_name|E2p' @@ -1942,7 +1942,7 @@ change_types: max_ptr_depth: 1 new_args: cast: - expression: auto |es2panda_arg.type.ptr_depth||arg_name|E2p = reinterpret_cast(context)->checker; + expression: auto |es2panda_arg.type.ptr_depth||arg_name|E2p = reinterpret_cast(context)->GetChecker(); call_cast: start: >- (reinterpret_cast(context)->checker)-> @@ -1997,7 +1997,7 @@ change_types: new_args: cast: expression: >- - auto *|arg_name|E2p = reinterpret_cast(context)->checker->AsETSChecker(); + auto *|arg_name|E2p = reinterpret_cast(context)->GetChecker()->AsETSChecker(); call_cast: start: >- (reinterpret_cast(context)->checker->AsETSChecker())-> @@ -2289,7 +2289,7 @@ change_types: namespace: 'lexer::' cast: expression: >- - auto |arg_name|E2p = *reinterpret_cast(|arg_name|); + auto &|arg_name|E2p = *reinterpret_cast(|arg_name|); reverse_cast: start: >- reinterpret_cast( @@ -2344,7 +2344,7 @@ change_types: namespace: 'lexer::' cast: expression: >- - auto |arg_name|E2p = *reinterpret_cast(|arg_name|); + auto &|arg_name|E2p = *reinterpret_cast(|arg_name|); reverse_cast: start: >- reinterpret_cast( @@ -2378,7 +2378,7 @@ change_types: name: es2panda_ErrorLogger ptr_depth: 1 start: >- - (reinterpret_cast(ast))-> + (reinterpret_cast(ast))-> constructor_cast: start: >- ctxAllocator->New( @@ -2399,7 +2399,7 @@ change_types: namespace: 'util::' cast: expression: >- - auto |arg_name|E2p = *reinterpret_cast(|arg_name|); + auto &|arg_name|E2p = *(reinterpret_cast(|arg_name|)); var_name: '|arg_name|E2p' - es2panda_arg: @@ -2449,7 +2449,7 @@ change_types: namespace: 'compiler::' cast: expression: >- - auto |arg_name|E2p = *reinterpret_cast(|arg_name|); + auto &|arg_name|E2p = *reinterpret_cast(|arg_name|); reverse_cast: start: >- reinterpret_cast( @@ -2504,7 +2504,7 @@ change_types: namespace: 'compiler::' cast: expression: >- - auto |arg_name|E2p = *reinterpret_cast(|arg_name|); + auto &|arg_name|E2p = *reinterpret_cast(|arg_name|); reverse_cast: start: >- reinterpret_cast( @@ -2892,6 +2892,28 @@ change_types: cast: reverse_cast: '' + - es2panda_arg: + name: '|arg_name|' + type: + name: JsDocInfo + max_ptr_depth: 0 + new_args: + - type: + name: es2panda_JsDocInfo + ptr_depth: 1 + namespace: 'ir::' + name: '|arg_name|' + cast: + expression: "\ + \tir::JsDocInfo |arg_name|ArenaUnorderedMap{reinterpret_cast(context)->allocator->Adapter()};\n + \tfor (size_t j = 0; j < |arg_name|->len; ++j) {\n + \t\t|arg_name|ArenaUnorderedMap.emplace(|arg_name|->strings[j], JsDocRecordToE2p(|arg_name|->jsDocRecords[j]));\n + \t}" + var_name: '|arg_name|ArenaUnorderedMap' + reverse_cast: + start: JsDocInfoFromE2p(reinterpret_cast(context)->allocator, + end: ) + - es2panda_arg: name: '|arg_name|' type: @@ -3005,7 +3027,7 @@ change_types: namespace: 'checker::' cast: expression: >- - auto |arg_name|E2p = + auto &|arg_name|E2p = *(reinterpret_cast(|arg_name|)); reverse_cast: start: >- @@ -3014,34 +3036,6 @@ change_types: end: ) var_name: '|arg_name|E2p' - - es2panda_arg: - name: '|arg_name|' - type: - name: 'CompilerOptions' - max_ptr_depth: 1 - min_ptr_depth: 1 - new_args: - cast: - expression: >- - auto |arg_name|E2p = - &(reinterpret_cast(context)->config->options->CompilerOptions()); - call_cast: - start: >- - (reinterpret_cast(context)->config->options->CompilerOptions(). - var_name: '|arg_name|E2p' - - - es2panda_arg: - name: '|arg_name|' - type: - name: 'CompilerOptions' - max_ptr_depth: 0 - new_args: - cast: - expression: >- - auto |arg_name|E2p = - reinterpret_cast(context)->config->options->CompilerOptions(); - var_name: '|arg_name|E2p' - - es2panda_arg: name: '|arg_name|' type: @@ -3089,7 +3083,7 @@ change_types: namespace: 'checker::' cast: expression: >- - auto |arg_name|E2p = + auto &|arg_name|E2p = *(reinterpret_cast(|arg_name|)); var_name: '|arg_name|E2p' @@ -3259,7 +3253,7 @@ change_types: namespace: 'compiler::ast_verifier::' cast: expression: >- - auto |arg_name|E2p = + auto &|arg_name|E2p = *(reinterpret_cast(|arg_name|)); var_name: '|arg_name|E2p' @@ -3310,7 +3304,7 @@ change_types: namespace: 'compiler::ast_verifier::' cast: expression: >- - auto |arg_name|E2p = + auto &|arg_name|E2p = *(reinterpret_cast(|arg_name|)); var_name: '|arg_name|E2p' @@ -3361,7 +3355,7 @@ change_types: namespace: 'compiler::ast_verifier::' cast: expression: >- - auto |arg_name|E2p = + auto &|arg_name|E2p = *(reinterpret_cast(|arg_name|)); reverse_cast: start: >- @@ -3793,7 +3787,7 @@ change_types: |arg_name|E2p->specifier = |arg_name|specifier;\n |arg_name|E2p->variable = |arg_name|variable;\n" reverse_cast: - start: DynamicImportDataToE2p(reinterpret_cast(context)->allocator, + start: DynamicImportDataToE2pPtr(reinterpret_cast(context)->allocator, end: ) var_name: "|arg_name|E2p" @@ -3823,6 +3817,59 @@ change_types: end: ) var_name: "|arg_name|E2p" + - es2panda_arg: + name: '|arg_name|' + type: + name: OverloadInfo + namespace: ir + max_ptr_depth: 1 + min_ptr_depth: 1 + new_args: + - name: '|arg_name|' + type: + name: es2panda_OverloadInfo + ptr_depth: 1 + namespace: 'ir::' + cast: + expression: "\ + auto |arg_name|E2p = reinterpret_cast(context)->allocator->New(); + |arg_name|E2p->minArg = |arg_name|->minArg;\n + |arg_name|E2p->maxArg = |arg_name|->maxArg;\n + |arg_name|E2p->needHelperOverload = |arg_name|->needHelperOverload;\n + |arg_name|E2p->isDeclare = |arg_name|->isDeclare;\n + |arg_name|E2p->hasRestVar = |arg_name|->hasRestVar;\n + |arg_name|E2p->returnVoid = |arg_name|->returnVoid;\n" + reverse_cast: + start: OverloadInfoToE2pPtr(reinterpret_cast(context)->allocator, + end: ) + var_name: "|arg_name|E2p" + + - es2panda_arg: + name: '|arg_name|' + type: + name: OverloadInfo + namespace: ir + max_ptr_depth: 0 + new_args: + - name: '|arg_name|' + type: + name: es2panda_OverloadInfo + ptr_depth: 0 + namespace: 'ir::' + cast: + expression: "\ + ir::OverloadInfo |arg_name|E2p; + |arg_name|E2p.minArg = |arg_name|.minArg;\n + |arg_name|E2p.maxArg = |arg_name|.maxArg;\n + |arg_name|E2p.needHelperOverload = |arg_name|.needHelperOverload;\n + |arg_name|E2p.isDeclare = |arg_name|.isDeclare;\n + |arg_name|E2p.hasRestVar = |arg_name|.hasRestVar;\n + |arg_name|E2p.returnVoid = |arg_name|.returnVoid;\n" + reverse_cast: + start: OverloadInfoToE2p( + end: ) + var_name: "|arg_name|E2p" + - es2panda_arg: name: '|arg_name|' type: @@ -3883,3 +3930,140 @@ change_types: ctxAllocator->New( end: ) var_name: '|arg_name|E2p' + + - es2panda_arg: + name: '|arg_name|' + type: + name: Path + namespace: util + max_ptr_depth: 0 + new_args: + - type: + name: es2panda_Path + ptr_depth: 1 + name: '|arg_name|' + cast: + expression: >- + auto &|arg_name|E2p = + *(reinterpret_cast(|arg_name|)); + reverse_cast: + start: >- + reinterpret_cast(reinterpret_cast(context)->allocator-> + New + end: ) + var_name: '|arg_name|E2p' + + - es2panda_arg: + name: '|arg_name|' + type: + name: Path + namespace: util + min_ptr_depth: 1 + new_args: + - type: + name: 'es2panda_Path' + ptr_depth: '|es2panda_arg.type.ptr_depth_int|' + name: '|arg_name|' + cast: + expression: >- + auto |es2panda_arg.type.ptr_depth||arg_name|E2p = + reinterpret_cast(|arg_name|); + reverse_cast: + start: >- + reinterpret_cast + call_cast: + call_var: + name: classInstance + type: + name: es2panda_Path + ptr_depth: 1 + start: >- + (reinterpret_cast(classInstance))-> + constructor_cast: + start: >- + ctxAllocator->New( + end: ) + var_name: '|arg_name|E2p' + + - es2panda_arg: + name: '|arg_name|' + type: + name: 'Options' + namespace: 'gen' + min_ptr_depth: 1 + new_args: + - type: + name: 'es2panda_Options' + ptr_depth: '|es2panda_arg.type.ptr_depth_int|' + name: '|arg_name|' + cast: + expression: >- + auto |es2panda_arg.type.ptr_depth||arg_name|E2p = + reinterpret_cast(|arg_name|); + reverse_cast: + start: >- + reinterpret_cast + call_cast: + call_var: + name: classInstance + type: + name: es2panda_Options + ptr_depth: 1 + start: >- + (reinterpret_cast(classInstance))-> + constructor_cast: + start: >- + ctxAllocator->New( + end: ) + var_name: '|arg_name|E2p' + + - es2panda_arg: + name: '|arg_name|' + type: + name: 'Options' + namespace: 'util' + min_ptr_depth: 1 + new_args: + - type: + name: 'es2panda_Options' + ptr_depth: '|es2panda_arg.type.ptr_depth_int|' + name: '|arg_name|' + cast: + expression: >- + auto |es2panda_arg.type.ptr_depth||arg_name|E2p = + reinterpret_cast(|arg_name|); + reverse_cast: + start: >- + reinterpret_cast + call_cast: + call_var: + name: classInstance + type: + name: es2panda_Options + ptr_depth: 1 + start: >- + (reinterpret_cast(classInstance))-> + constructor_cast: + start: >- + ctxAllocator->New( + end: ) + var_name: '|arg_name|E2p' + + - es2panda_arg: + name: '|arg_name|' + type: + name: arg_list_t + namespace: gen + max_ptr_depth: 0 + new_args: + - name: '|arg_name|' + type: + name: vector + namespace: std + ref_depth: 2 + template_args: + - type: + name: string + namespace: std + cast: + reverse_cast: {} diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index dc0c2ac9c2e4377ee99da7c9db9d5d7fe1d45132..8df91d24aff6942c01c70ef14542a277129967cd 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -27,14 +27,12 @@ #include "checker/ETSAnalyzer.h" #include "checker/ETSchecker.h" #include "compiler/core/compileQueue.h" +#include "compiler/core/compilerImpl.h" #include "compiler/core/ETSCompiler.h" #include "compiler/core/ETSemitter.h" #include "compiler/core/ETSGen.h" #include "compiler/core/regSpiller.h" #include "compiler/lowering/phase.h" -#include "compiler/lowering/checkerPhase.h" -#include "compiler/lowering/resolveIdentifiers.h" -#include "compiler/lowering/scopesInit/scopesInitPhase.h" #include "ir/astNode.h" #include "ir/expressions/arrowFunctionExpression.h" #include "ir/ts/tsAsExpression.h" @@ -151,7 +149,7 @@ __attribute__((unused)) es2panda_variantDoubleCharArrayBool EnumMemberResultToEs // NOLINTEND(cppcoreguidelines-pro-type-union-access) } -__attribute__((unused)) es2panda_DynamicImportData *DynamicImportDataToE2p( +__attribute__((unused)) es2panda_DynamicImportData *DynamicImportDataToE2pPtr( ArenaAllocator *allocator, const varbinder::DynamicImportData *dynamicImportData) { auto import = reinterpret_cast(dynamicImportData->import); @@ -177,6 +175,62 @@ __attribute__((unused)) es2panda_DynamicImportData DynamicImportDataToE2p( return es2pandaDynamicImportData; } +__attribute__((unused)) es2panda_OverloadInfo *OverloadInfoToE2pPtr(ArenaAllocator *allocator, + const ir::OverloadInfo *overloadInfo) +{ + auto es2pandaOverloadInfo = allocator->New(); + es2pandaOverloadInfo->minArg = overloadInfo->minArg; + es2pandaOverloadInfo->maxArg = overloadInfo->maxArg; + es2pandaOverloadInfo->needHelperOverload = overloadInfo->needHelperOverload; + es2pandaOverloadInfo->isDeclare = overloadInfo->isDeclare; + es2pandaOverloadInfo->hasRestVar = overloadInfo->hasRestVar; + es2pandaOverloadInfo->returnVoid = overloadInfo->returnVoid; + return es2pandaOverloadInfo; +} + +__attribute__((unused)) es2panda_OverloadInfo OverloadInfoToE2p(const ir::OverloadInfo overloadInfo) +{ + es2panda_OverloadInfo es2pandaOverloadInfo; + es2pandaOverloadInfo.minArg = overloadInfo.minArg; + es2pandaOverloadInfo.maxArg = overloadInfo.maxArg; + es2pandaOverloadInfo.needHelperOverload = overloadInfo.needHelperOverload; + es2pandaOverloadInfo.isDeclare = overloadInfo.isDeclare; + es2pandaOverloadInfo.hasRestVar = overloadInfo.hasRestVar; + es2pandaOverloadInfo.returnVoid = overloadInfo.returnVoid; + return es2pandaOverloadInfo; +} + +__attribute__((unused)) ir::JsDocRecord JsDocRecordToE2p(const es2panda_JsDocRecord *jsDocRecord) +{ + return ir::JsDocRecord(jsDocRecord->name, jsDocRecord->param, jsDocRecord->comment); +} + +__attribute__((unused)) es2panda_JsDocRecord *JsDocRecordFromE2p(ArenaAllocator *allocator, + const ir::JsDocRecord &jsDocRecord) +{ + es2panda_JsDocRecord *res = allocator->New(); + res->name = StringViewToCString(allocator, jsDocRecord.name); + res->param = StringViewToCString(allocator, jsDocRecord.param); + res->comment = StringViewToCString(allocator, jsDocRecord.comment); + return res; +} + +__attribute__((unused)) es2panda_JsDocInfo *JsDocInfoFromE2p(ArenaAllocator *allocator, const ir::JsDocInfo &jsDocInfo) +{ + size_t jsDocInfoLen = jsDocInfo.size(); + es2panda_JsDocInfo *res = allocator->New(); + res->len = jsDocInfoLen; + res->strings = allocator->New(jsDocInfoLen); + res->jsDocRecords = allocator->New(jsDocInfoLen); + size_t i = 0; + for (const auto &[key, value] : jsDocInfo) { + res->strings[i] = StringViewToCString(allocator, key); + res->jsDocRecords[i] = JsDocRecordFromE2p(allocator, value); + ++i; + }; + return res; +} + __attribute__((unused)) char const *ArenaStrdup(ArenaAllocator *allocator, char const *src) { size_t len = strlen(src); @@ -189,10 +243,24 @@ __attribute__((unused)) char const *ArenaStrdup(ArenaAllocator *allocator, char return res; } -extern "C" es2panda_Config *CreateConfig(int args, char const *const *argv) +extern "C" void MemInitialize() { + if (mem::MemConfig::IsInitialized()) { + return; + } mem::MemConfig::Initialize(0, 0, COMPILER_SIZE, 0, 0, 0); PoolManager::Initialize(PoolType::MMAP); +} + +extern "C" void MemFinalize() +{ + PoolManager::Finalize(); + mem::MemConfig::Finalize(); +} + +extern "C" es2panda_Config *CreateConfig(int args, char const *const *argv) +{ + MemInitialize(); auto diagnosticEngine = new util::DiagnosticEngine(); auto *options = new util::Options(argv[0], *diagnosticEngine); if (!options->Parse(Span(argv, args))) { @@ -210,9 +278,6 @@ extern "C" es2panda_Config *CreateConfig(int args, char const *const *argv) extern "C" void DestroyConfig(es2panda_Config *config) { - PoolManager::Finalize(); - mem::MemConfig::Finalize(); - auto *cfg = reinterpret_cast(config); if (cfg == nullptr) { return; @@ -223,6 +288,12 @@ extern "C" void DestroyConfig(es2panda_Config *config) delete cfg; } +extern "C" const es2panda_Options *ConfigGetOptions(es2panda_Config *config) +{ + auto options = reinterpret_cast(config)->options; + return reinterpret_cast(options); +} + static void CompileJob(public_lib::Context *context, varbinder::FunctionScope *scope, compiler::ProgramElement *programElement) { @@ -234,15 +305,81 @@ static void CompileJob(public_lib::Context *context, varbinder::FunctionScope *s funcEmitter.Generate(); } +static void GenerateStdLibCache(es2panda_Config *config, GlobalContext *globalContext, bool LspUsage); + +extern "C" __attribute__((unused)) es2panda_GlobalContext *CreateGlobalContext(es2panda_Config *config, + const char **externalFileList, + size_t fileNum, bool LspUsage) +{ + auto *globalContext = new GlobalContext; + for (size_t i = 0; i < fileNum; i++) { + auto fileName = externalFileList[i]; + auto globalAllocator = new ThreadSafeArenaAllocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true); + globalContext->cachedExternalPrograms.emplace(fileName, nullptr); + globalContext->externalProgramAllocators.emplace(fileName, globalAllocator); + } + + GenerateStdLibCache(config, globalContext, LspUsage); + + return reinterpret_cast(globalContext); +} + +extern "C" __attribute__((unused)) void RemoveFileCache(es2panda_GlobalContext *globalContext, const char *fileName) +{ + auto globalCtx = reinterpret_cast(globalContext); + ES2PANDA_ASSERT(globalCtx->cachedExternalPrograms.count(fileName) == 1); + globalCtx->cachedExternalPrograms.erase(fileName); + delete globalCtx->externalProgramAllocators[fileName]; + globalCtx->externalProgramAllocators.erase(fileName); +} + +extern "C" __attribute__((unused)) void AddFileCache(es2panda_GlobalContext *globalContext, const char *fileName) +{ + auto globalCtx = reinterpret_cast(globalContext); + ES2PANDA_ASSERT(globalCtx->cachedExternalPrograms.count(fileName) == 0); + auto globalAllocator = new ThreadSafeArenaAllocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true); + globalCtx->cachedExternalPrograms.emplace(fileName, nullptr); + globalCtx->externalProgramAllocators.emplace(fileName, globalAllocator); +} + +extern "C" __attribute__((unused)) void InvalidateFileCache(es2panda_GlobalContext *globalContext, const char *fileName) +{ + RemoveFileCache(globalContext, fileName); + AddFileCache(globalContext, fileName); +} + +static void InitializeContext(Context *res) +{ + res->phaseManager = new compiler::PhaseManager(res, ScriptExtension::ETS, res->allocator); + res->queue = new compiler::CompileQueue(res->config->options->GetThread()); + + auto *varbinder = res->allocator->New(res->allocator); + res->parserProgram = res->allocator->New(res->allocator, varbinder); + res->parser = new parser::ETSParser(res->parserProgram, *res->config->options, *res->diagnosticEngine, + parser::ParserStatus::NO_OPTS); + res->parser->SetContext(res); + + res->PushChecker(res->allocator->New(res->allocator, *res->diagnosticEngine, res->allocator)); + res->isolatedDeclgenChecker = new checker::IsolatedDeclgenChecker(*res->diagnosticEngine, *(res->parserProgram)); + res->PushAnalyzer(res->allocator->New(res->GetChecker())); + res->GetChecker()->SetAnalyzer(res->GetAnalyzer()); + + varbinder->SetProgram(res->parserProgram); + varbinder->SetContext(res); + res->codeGenCb = CompileJob; + res->emitter = new compiler::ETSEmitter(res); + res->program = nullptr; + res->state = ES2PANDA_STATE_NEW; +} + __attribute__((unused)) static es2panda_Context *CreateContext(es2panda_Config *config, std::string &&source, - const char *fileName) + const char *fileName, + es2panda_GlobalContext *globalContext, bool isExternal, + bool genStdLib) { auto *cfg = reinterpret_cast(config); auto *res = new Context; - res->input = std::move(source); - res->sourceFileName = fileName; - res->config = cfg; - + res->compiledByCapi = true; if (cfg == nullptr) { res->errorMessage = "Config is nullptr."; res->state = ES2PANDA_STATE_ERROR; @@ -252,61 +389,88 @@ __attribute__((unused)) static es2panda_Context *CreateContext(es2panda_Config * if (cfg->options->GetExtension() != ScriptExtension::ETS) { res->errorMessage = "Invalid extension. Plugin API supports only ETS."; res->state = ES2PANDA_STATE_ERROR; + res->diagnosticEngine = cfg->diagnosticEngine; return reinterpret_cast(res); } - res->sourceFile = new SourceFile(res->sourceFileName, res->input, cfg->options->IsModule()); - res->allocator = new ArenaAllocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true); - res->queue = new compiler::CompileQueue(cfg->options->GetThread()); - - auto *varbinder = res->allocator->New(res->allocator); - res->parserProgram = new parser::Program(res->allocator, varbinder); + res->config = cfg; + res->isExternal = isExternal; + res->globalContext = reinterpret_cast(globalContext); res->diagnosticEngine = cfg->diagnosticEngine; - res->parser = - new parser::ETSParser(res->parserProgram, *cfg->options, *cfg->diagnosticEngine, parser::ParserStatus::NO_OPTS); - res->checker = new checker::ETSChecker(*res->diagnosticEngine); - res->analyzer = new checker::ETSAnalyzer(res->checker); - res->checker->SetAnalyzer(res->analyzer); - varbinder->SetProgram(res->parserProgram); + res->input = std::move(source); + res->sourceFileName = fileName; + res->sourceFile = new SourceFile(res->sourceFileName, res->input, cfg->options->IsModule()); + if (isExternal) { + ir::EnableContextHistory(); + ES2PANDA_ASSERT(res->globalContext != nullptr); + if (genStdLib) { + ES2PANDA_ASSERT(res->globalContext->stdLibAllocator != nullptr); + res->allocator = res->globalContext->stdLibAllocator; + } else { + ES2PANDA_ASSERT(res->globalContext->externalProgramAllocators.count(fileName) != 0); + res->allocator = + reinterpret_cast(res->globalContext->externalProgramAllocators[fileName]); + } + } else { + ir::DisableContextHistory(); + res->allocator = new ThreadSafeArenaAllocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true); + } - varbinder->SetContext(res); - res->codeGenCb = CompileJob; - res->phases = compiler::GetPhaseList(ScriptExtension::ETS); - res->currentPhase = 0; - res->emitter = new compiler::ETSEmitter(res); - res->program = nullptr; - res->state = ES2PANDA_STATE_NEW; + InitializeContext(res); return reinterpret_cast(res); } -extern "C" __attribute__((unused)) es2panda_Context *CreateContextFromFile(es2panda_Config *config, - char const *sourceFileName) +__attribute__((unused)) static std::stringstream ReadFile(char const *sourceFileName, Context *&res) { std::ifstream inputStream; inputStream.open(sourceFileName); if (inputStream.fail()) { - auto *res = new Context; + res = new Context; res->errorMessage = "Failed to open file: "; res->errorMessage.append(sourceFileName); - return reinterpret_cast(res); } std::stringstream ss; ss << inputStream.rdbuf(); if (inputStream.fail()) { - auto *res = new Context; + res = new Context; res->errorMessage = "Failed to read file: "; res->errorMessage.append(sourceFileName); + } + return ss; +} + +extern "C" __attribute__((unused)) es2panda_Context *CreateCacheContextFromFile(es2panda_Config *config, + char const *sourceFileName, + es2panda_GlobalContext *globalContext, + bool isExternal) +{ + Context *res = nullptr; + auto ss = ReadFile(sourceFileName, res); + if (res != nullptr) { + return reinterpret_cast(res); + } + return CreateContext(config, ss.str(), sourceFileName, globalContext, isExternal, false); +} + +extern "C" __attribute__((unused)) es2panda_Context *CreateContextFromFile(es2panda_Config *config, + char const *sourceFileName) +{ + Context *res = nullptr; + auto ss = ReadFile(sourceFileName, res); + if (res != nullptr) { return reinterpret_cast(res); + ; } - return CreateContext(config, ss.str(), sourceFileName); + + return CreateContext(config, ss.str(), sourceFileName, nullptr, false, false); } extern "C" __attribute__((unused)) es2panda_Context *CreateContextFromString(es2panda_Config *config, const char *source, char const *fileName) { // NOTE: gogabr. avoid copying source. - return CreateContext(config, std::string(source), fileName); + return CreateContext(config, std::string(source), fileName, nullptr, false, false); } __attribute__((unused)) static Context *Parse(Context *ctx) @@ -317,15 +481,33 @@ __attribute__((unused)) static Context *Parse(Context *ctx) return ctx; } - ctx->parser->ParseScript(*ctx->sourceFile, - ctx->config->options->GetCompilationMode() == CompilationMode::GEN_STD_LIB); + ctx->phaseManager->Reset(); + if (ctx->isExternal && ctx->allocator != ctx->globalContext->stdLibAllocator) { + 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); + ctx->parserProgram->SetAst(etsModule); + util::ImportPathManager::ImportMetadata importData {util::ImportFlags::NONE}; + importData.resolvedSource = ctx->sourceFileName; + importData.lang = Language::Id::ETS; + importData.declPath = util::ImportPathManager::DUMMY_PATH; + importData.ohmUrl = util::ImportPathManager::DUMMY_PATH; + ctx->parser->AsETSParser()->GetImportPathManager()->AddToParseList(importData); + ctx->parser->AsETSParser()->AddExternalSource(ctx->parser->AsETSParser()->ParseSources(true)); + } else { + ctx->parser->ParseScript(*ctx->sourceFile, + ctx->config->options->GetCompilationMode() == CompilationMode::GEN_STD_LIB); + } ctx->state = !ctx->diagnosticEngine->IsAnyError() ? ES2PANDA_STATE_PARSED : ES2PANDA_STATE_ERROR; + ctx->diagnosticEngine->FlushDiagnostic(); + ctx->phaseManager->SetCurrentPhaseIdToAfterParse(); return ctx; } __attribute__((unused)) static Context *Bind(Context *ctx) { - // NOTE: Remove duplicated code in all phases if (ctx->state < ES2PANDA_STATE_PARSED) { ctx = Parse(ctx); } @@ -334,13 +516,13 @@ __attribute__((unused)) static Context *Bind(Context *ctx) } ES2PANDA_ASSERT(ctx->state == ES2PANDA_STATE_PARSED); - do { - if (ctx->currentPhase >= ctx->phases.size()) { + while (auto phase = ctx->phaseManager->NextPhase()) { + if (phase->Name() == "plugins-after-bind") { break; } - ctx->phases[ctx->currentPhase]->Apply(ctx, ctx->parserProgram); - } while (ctx->phases[ctx->currentPhase++]->Name() != compiler::ResolveIdentifiers::NAME); - ctx->state = !ctx->diagnosticEngine->IsAnyError() ? ES2PANDA_STATE_BOUND : ES2PANDA_STATE_ERROR; + phase->Apply(ctx, ctx->parserProgram); + } + ctx->state = ES2PANDA_STATE_BOUND; return ctx; } @@ -351,22 +533,43 @@ __attribute__((unused)) static Context *Check(Context *ctx) } if (ctx->state == ES2PANDA_STATE_ERROR) { + ctx->diagnosticEngine->FlushDiagnostic(); return ctx; } ES2PANDA_ASSERT(ctx->state >= ES2PANDA_STATE_PARSED && ctx->state < ES2PANDA_STATE_CHECKED); - - do { - if (ctx->currentPhase >= ctx->phases.size()) { + while (auto phase = ctx->phaseManager->NextPhase()) { + if (phase->Name() == "plugins-after-check") { break; } - - ctx->phases[ctx->currentPhase]->Apply(ctx, ctx->parserProgram); - } while (ctx->phases[ctx->currentPhase++]->Name() != compiler::CheckerPhase::NAME); + phase->Apply(ctx, ctx->parserProgram); + } + ctx->phaseManager->SetCurrentPhaseIdToAfterCheck(); ctx->state = !ctx->diagnosticEngine->IsAnyError() ? ES2PANDA_STATE_CHECKED : ES2PANDA_STATE_ERROR; return ctx; } +__attribute__((unused)) static void SaveCache(Context *ctx) +{ + if (ctx->allocator == ctx->globalContext->stdLibAllocator) { + return; + } + ES2PANDA_ASSERT(ctx->globalContext != nullptr && + ctx->globalContext->cachedExternalPrograms.count(ctx->sourceFileName) != 0); + ctx->globalContext->cachedExternalPrograms[ctx->sourceFileName] = &(ctx->parserProgram->ExternalSources()); + + // cycle dependencies + for (auto &[_, extPrograms] : ctx->parserProgram->ExternalSources()) { + for (auto extProgram : extPrograms) { + auto absPath = std::string {extProgram->AbsoluteName()}; + auto &cacheMap = ctx->globalContext->cachedExternalPrograms; + if (cacheMap.count(absPath) == 1 && cacheMap[absPath] == nullptr) { + cacheMap[absPath] = &(ctx->parserProgram->ExternalSources()); + } + } + } +} + __attribute__((unused)) static Context *Lower(Context *ctx) { if (ctx->state < ES2PANDA_STATE_CHECKED) { @@ -374,14 +577,27 @@ __attribute__((unused)) static Context *Lower(Context *ctx) } if (ctx->state == ES2PANDA_STATE_ERROR) { + ctx->diagnosticEngine->FlushDiagnostic(); return ctx; } ES2PANDA_ASSERT(ctx->state == ES2PANDA_STATE_CHECKED); - while (ctx->currentPhase < ctx->phases.size()) { - ctx->phases[ctx->currentPhase++]->Apply(ctx, ctx->parserProgram); + while (auto phase = ctx->phaseManager->NextPhase()) { + phase->Apply(ctx, ctx->parserProgram); } ctx->state = !ctx->diagnosticEngine->IsAnyError() ? ES2PANDA_STATE_LOWERED : ES2PANDA_STATE_ERROR; + + for (auto &[_, extPrograms] : ctx->parserProgram->ExternalSources()) { + for (auto &extProgram : extPrograms) { + if (!extProgram->IsASTLowered()) { + extProgram->MarkASTAsLowered(); + } + } + } + if (ctx->isExternal) { + SaveCache(ctx); + } + return ctx; } @@ -469,6 +685,10 @@ extern "C" __attribute__((unused)) es2panda_Context *ProceedToState(es2panda_Con ctx->state = ES2PANDA_STATE_ERROR; break; } + + if (ctx->state == ES2PANDA_STATE_ERROR) { + ctx->diagnosticEngine->FlushDiagnostic(); + } return reinterpret_cast(ctx); } @@ -477,16 +697,27 @@ extern "C" __attribute__((unused)) void DestroyContext(es2panda_Context *context auto *ctx = reinterpret_cast(context); delete ctx->program; delete ctx->emitter; - delete ctx->analyzer; - delete ctx->checker; delete ctx->parser; - delete ctx->parserProgram; delete ctx->queue; - delete ctx->allocator; delete ctx->sourceFile; + delete ctx->phaseManager; + if (!ctx->isExternal) { + delete ctx->allocator; + } delete ctx; } +extern "C" __attribute__((unused)) void DestroyGlobalContext(es2panda_GlobalContext *globalContext) +{ + auto *globalCtx = reinterpret_cast(globalContext); + for (auto [_, alloctor] : globalCtx->externalProgramAllocators) { + delete alloctor; + } + + delete globalCtx->stdLibAllocator; + delete globalCtx; +} + extern "C" __attribute__((unused)) es2panda_ContextState ContextState(es2panda_Context *context) { auto *s = reinterpret_cast(context); @@ -543,7 +774,7 @@ extern "C" void AstNodeForEach(es2panda_AstNode *ast, void (*func)(es2panda_AstN } #define SET_NUMBER_LITERAL_IMPL(name, type) \ - extern "C" bool SetNumberLiteral##name(es2panda_AstNode *node, type new_value) \ + extern "C" bool NumberLiteralSet##name(es2panda_AstNode *node, type new_value) \ { \ auto &n = reinterpret_cast(node)->Number(); \ if (!n.Is##name()) { \ @@ -584,6 +815,12 @@ es2panda_AstNode *UpdateNumberLiteral(es2panda_Context *ctx, es2panda_AstNode *o return reinterpret_cast(node); } +extern "C" const char *NumberLiteralStrConst(es2panda_Context *context, es2panda_AstNode *classInstance) +{ + auto str = reinterpret_cast(classInstance)->Str(); + return StringViewToCString(reinterpret_cast(context)->allocator, str); +} + extern "C" void *AllocMemory(es2panda_Context *context, size_t numberOfElements, size_t sizeOfElement) { auto *allocator = reinterpret_cast(context)->allocator; @@ -607,14 +844,69 @@ extern "C" es2panda_SourceRange *CreateSourceRange(es2panda_Context *context, es return reinterpret_cast(allocator->New(startE2p, endE2p)); } -extern "C" const es2panda_DiagnosticKind *CreateDiagnosticKind(es2panda_Context *context, const char *dmessage) +extern "C" const es2panda_DiagnosticKind *CreateDiagnosticKind(es2panda_Context *context, const char *dmessage, + es2panda_PluginDiagnosticType etype) { auto ctx = reinterpret_cast(context); auto id = ctx->config->diagnosticKindStorage.size() + 1; - ctx->config->diagnosticKindStorage.emplace_back(util::DiagnosticType::PLUGIN, id, dmessage); + auto type = util::DiagnosticType::SUGGESTION; + if (etype == ES2PANDA_PLUGIN_WARNING) { + type = util::DiagnosticType::PLUGIN_WARNING; + } else if (etype == ES2PANDA_PLUGIN_ERROR) { + type = util::DiagnosticType::PLUGIN_ERROR; + } + ctx->config->diagnosticKindStorage.emplace_back(type, id, dmessage); return reinterpret_cast(&ctx->config->diagnosticKindStorage.back()); } +extern "C" es2panda_DiagnosticInfo *CreateDiagnosticInfo(es2panda_Context *context, const es2panda_DiagnosticKind *kind, + const char **args, size_t argc) +{ + auto *allocator = reinterpret_cast(context)->allocator; + auto diagnosticInfo = allocator->New(); + diagnosticInfo->kind = kind; + diagnosticInfo->args = args; + diagnosticInfo->argc = argc; + return diagnosticInfo; +} + +extern "C" es2panda_SuggestionInfo *CreateSuggestionInfo(es2panda_Context *context, const es2panda_DiagnosticKind *kind, + const char **args, size_t argc, const char *substitutionCode) +{ + auto *allocator = reinterpret_cast(context)->allocator; + auto suggestionInfo = allocator->New(); + suggestionInfo->kind = kind; + suggestionInfo->args = args; + suggestionInfo->argc = argc; + suggestionInfo->substitutionCode = substitutionCode; + return suggestionInfo; +} + +extern "C" void LogDiagnosticWithSuggestion(es2panda_Context *context, const es2panda_DiagnosticInfo *diagnosticInfo, + const es2panda_SuggestionInfo *suggestionInfo, es2panda_SourceRange *range) +{ + auto ctx = reinterpret_cast(context); + auto diagnostickind = reinterpret_cast(diagnosticInfo->kind); + auto suggestionkind = reinterpret_cast(suggestionInfo->kind); + util::DiagnosticMessageParams diagnosticParams; + for (size_t i = 0; i < diagnosticInfo->argc; ++i) { + diagnosticParams.push_back(diagnosticInfo->args[i]); + } + + std::vector suggestionParams; + + for (size_t i = 0; i < suggestionInfo->argc; ++i) { + suggestionParams.push_back(suggestionInfo->args[i]); + } + + auto *allocator = reinterpret_cast(context)->allocator; + auto E2pRange = reinterpret_cast(range); + auto posE2p = allocator->New(E2pRange->start); + auto suggestion = ctx->diagnosticEngine->CreateSuggestion(suggestionkind, suggestionParams, + suggestionInfo->substitutionCode, E2pRange); + ctx->diagnosticEngine->LogDiagnostic(*diagnostickind, diagnosticParams, *posE2p, suggestion); +} + extern "C" void LogDiagnostic(es2panda_Context *context, const es2panda_DiagnosticKind *ekind, const char **args, size_t argc, es2panda_SourcePosition *pos) { @@ -647,7 +939,12 @@ extern "C" const es2panda_DiagnosticStorage *GetSyntaxErrors(es2panda_Context *c extern "C" const es2panda_DiagnosticStorage *GetPluginErrors(es2panda_Context *context) { - return GetDiagnostics(context, util::DiagnosticType::PLUGIN); + return GetDiagnostics(context, util::DiagnosticType::PLUGIN_ERROR); +} + +extern "C" const es2panda_DiagnosticStorage *GetPluginWarnings(es2panda_Context *context) +{ + return GetDiagnostics(context, util::DiagnosticType::PLUGIN_WARNING); } extern "C" const es2panda_DiagnosticStorage *GetWarnings(es2panda_Context *context) @@ -655,6 +952,11 @@ extern "C" const es2panda_DiagnosticStorage *GetWarnings(es2panda_Context *conte return GetDiagnostics(context, util::DiagnosticType::WARNING); } +extern "C" bool IsAnyError(es2panda_Context *context) +{ + return reinterpret_cast(context)->diagnosticEngine->IsAnyError(); +} + extern "C" size_t SourcePositionIndex([[maybe_unused]] es2panda_Context *context, es2panda_SourcePosition *position) { return reinterpret_cast(position)->index; @@ -692,13 +994,14 @@ extern "C" es2panda_Scope *AstNodeRebind(es2panda_Context *ctx, es2panda_AstNode auto E2pNode = reinterpret_cast(node); auto context = reinterpret_cast(ctx); auto varbinder = context->parserProgram->VarBinder()->AsETSBinder(); + auto phaseManager = context->phaseManager; if (E2pNode->IsScriptFunction() || E2pNode->FindChild([](ir::AstNode *n) { return n->IsScriptFunction(); }) != nullptr) { while (!E2pNode->IsProgram()) { E2pNode = E2pNode->Parent(); } } - return reinterpret_cast(compiler::Rebind(varbinder, E2pNode)); + return reinterpret_cast(compiler::Rebind(phaseManager, varbinder, E2pNode)); } extern "C" void AstNodeRecheck(es2panda_Context *ctx, es2panda_AstNode *node) @@ -706,14 +1009,15 @@ extern "C" void AstNodeRecheck(es2panda_Context *ctx, es2panda_AstNode *node) auto E2pNode = reinterpret_cast(node); auto context = reinterpret_cast(ctx); auto varbinder = context->parserProgram->VarBinder()->AsETSBinder(); - auto checker = context->checker->AsETSChecker(); + auto checker = context->GetChecker()->AsETSChecker(); + auto phaseManager = context->phaseManager; if (E2pNode->IsScriptFunction() || E2pNode->FindChild([](ir::AstNode *n) { return n->IsScriptFunction(); }) != nullptr) { while (!E2pNode->IsProgram()) { E2pNode = E2pNode->Parent(); } } - compiler::Recheck(varbinder, checker, E2pNode); + compiler::Recheck(phaseManager, varbinder, checker, E2pNode); context->state = !context->diagnosticEngine->IsAnyError() ? ES2PANDA_STATE_CHECKED : ES2PANDA_STATE_ERROR; return; } @@ -737,12 +1041,138 @@ extern "C" es2panda_AstNode *DeclarationFromIdentifier([[maybe_unused]] es2panda return reinterpret_cast(compiler::DeclarationFromIdentifier(E2pNode)); } +extern "C" es2panda_AstNode *FirstDeclarationByNameFromNode([[maybe_unused]] es2panda_Context *ctx, + const es2panda_AstNode *node, const char *name) +{ + if (node == nullptr) { + return nullptr; + } + + util::StringView nameE2p {name}; + ir::AstNode *res = reinterpret_cast(node)->FindChild([&nameE2p](const ir::AstNode *ast) { + if (ast != nullptr && ast->IsMethodDefinition() && ast->AsMethodDefinition()->Key() != nullptr && + ast->AsMethodDefinition()->Key()->IsIdentifier() && + ast->AsMethodDefinition()->Key()->AsIdentifier()->Name() == nameE2p) { + return true; + } + + return false; + }); + + return reinterpret_cast(res); +} + +extern "C" es2panda_AstNode *FirstDeclarationByNameFromProgram([[maybe_unused]] es2panda_Context *ctx, + const es2panda_Program *program, const char *name) +{ + if (program == nullptr) { + return nullptr; + } + + auto programE2p = reinterpret_cast(program); + es2panda_AstNode *res = + FirstDeclarationByNameFromNode(ctx, reinterpret_cast(programE2p->Ast()), name); + if (res != nullptr) { + return res; + } + + for (const auto &ext_source : programE2p->DirectExternalSources()) { + for (const auto *ext_program : ext_source.second) { + if (ext_program != nullptr) { + res = FirstDeclarationByNameFromNode( + ctx, reinterpret_cast(ext_program->Ast()), name); + } + if (res != nullptr) { + return res; + } + } + } + + return nullptr; +} + +static ArenaSet AllDeclarationsByNameFromNodeHelper(ArenaAllocator *const allocator, + const ir::AstNode *node, + const util::StringView &name) +{ + auto result = ArenaSet {allocator->Adapter()}; + + if (node == nullptr) { + return result; + } + + node->IterateRecursively([&result, &name](ir::AstNode *ast) { + if (ast != nullptr && ast->IsMethodDefinition() && ast->AsMethodDefinition()->Key() != nullptr && + ast->AsMethodDefinition()->Key()->IsIdentifier() && + ast->AsMethodDefinition()->Key()->AsIdentifier()->Name() == name) { + result.insert(ast); + } + }); + + return result; +} + +extern "C" es2panda_AstNode **AllDeclarationsByNameFromNode([[maybe_unused]] es2panda_Context *ctx, + const es2panda_AstNode *node, const char *name, + size_t *declsLen) +{ + util::StringView nameE2p {name}; + auto nodeE2p = reinterpret_cast(node); + auto allocator = reinterpret_cast(ctx)->allocator; + auto result = AllDeclarationsByNameFromNodeHelper(allocator, nodeE2p, nameE2p); + *declsLen = result.size(); + auto apiRes = allocator->New(*declsLen); + size_t i = 0; + for (auto elem : result) { + auto toPush = reinterpret_cast(elem); + apiRes[i++] = toPush; + }; + return apiRes; +} + +extern "C" es2panda_AstNode **AllDeclarationsByNameFromProgram([[maybe_unused]] es2panda_Context *ctx, + const es2panda_Program *program, const char *name, + size_t *declsLen) +{ + auto allocator = reinterpret_cast(ctx)->allocator; + if (program == nullptr) { + *declsLen = 0; + return allocator->New(0); + } + + util::StringView nameE2p {name}; + auto programE2p = reinterpret_cast(program); + auto result = ArenaSet {allocator->Adapter()}; + + ArenaSet res = AllDeclarationsByNameFromNodeHelper(allocator, programE2p->Ast(), nameE2p); + result.insert(res.begin(), res.end()); + + for (const auto &ext_source : programE2p->DirectExternalSources()) { + for (const auto *ext_program : ext_source.second) { + if (ext_program != nullptr) { + res = AllDeclarationsByNameFromNodeHelper(allocator, ext_program->Ast(), nameE2p); + result.insert(res.begin(), res.end()); + } + } + } + + *declsLen = result.size(); + auto apiRes = allocator->New(*declsLen); + size_t i = 0; + for (auto elem : result) { + auto toPush = reinterpret_cast(elem); + apiRes[i++] = toPush; + }; + + return apiRes; +} + extern "C" __attribute__((unused)) int GenerateTsDeclarationsFromContext(es2panda_Context *ctx, const char *outputDeclEts, const char *outputEts, bool exportAll) { auto *ctxImpl = reinterpret_cast(ctx); - auto *checker = reinterpret_cast(ctxImpl->checker); + auto *checker = reinterpret_cast(ctxImpl->GetChecker()); ark::es2panda::declgen_ets2ts::DeclgenOptions declgenOptions; declgenOptions.exportAll = exportAll; @@ -753,14 +1183,29 @@ extern "C" __attribute__((unused)) int GenerateTsDeclarationsFromContext(es2pand : 1; } +// Will be removed after binary import support is fully implemented. +extern "C" __attribute__((unused)) int GenerateStaticDeclarationsFromContext(es2panda_Context *ctx, + const char *outputPath) +{ + auto *ctxImpl = reinterpret_cast(ctx); + if (ctxImpl->state != ES2PANDA_STATE_CHECKED) { + return 1; + } + compiler::HandleGenerateDecl(*ctxImpl->parserProgram, *ctxImpl->diagnosticEngine, outputPath, false); + + return ctxImpl->diagnosticEngine->IsAnyError() ? 1 : 0; +} + extern "C" void InsertETSImportDeclarationAndParse(es2panda_Context *context, es2panda_Program *program, es2panda_AstNode *importDeclaration) { auto *ctx = reinterpret_cast(context); auto *parserProgram = reinterpret_cast(program); auto *importDeclE2p = reinterpret_cast(importDeclaration); + importDeclE2p->AddAstNodeFlags(ir::AstNodeFlags::NOCLEANUP); - parserProgram->Ast()->Statements().insert(parserProgram->Ast()->Statements().begin(), importDeclE2p); + auto &stmt = parserProgram->Ast()->StatementsForUpdates(); + stmt.insert(stmt.begin(), importDeclE2p); importDeclE2p->SetParent(parserProgram->Ast()); ctx->parser->AsETSParser()->AddExternalSource(ctx->parser->AsETSParser()->ParseSources()); @@ -770,25 +1215,50 @@ extern "C" void InsertETSImportDeclarationAndParse(es2panda_Context *context, es } } +__attribute__((unused)) static void GenerateStdLibCache(es2panda_Config *config, GlobalContext *globalContext, + bool LspUsage) +{ + auto cfg = reinterpret_cast(config); + globalContext->stdLibAllocator = new ThreadSafeArenaAllocator(SpaceType::SPACE_TYPE_COMPILER, nullptr, true); + auto ctx = CreateContext(config, std::move(""), cfg->options->SourceFileName().c_str(), + reinterpret_cast(globalContext), true, true); + ProceedToState(ctx, es2panda_ContextState::ES2PANDA_STATE_CHECKED); + if (!LspUsage) { + AstNodeRecheck(ctx, + reinterpret_cast(reinterpret_cast(ctx)->parserProgram->Ast())); + AstNodeRecheck(ctx, + reinterpret_cast(reinterpret_cast(ctx)->parserProgram->Ast())); + } + ProceedToState(ctx, es2panda_ContextState::ES2PANDA_STATE_LOWERED); + globalContext->stdLibAstCache = &(reinterpret_cast(ctx)->parserProgram->ExternalSources()); + DestroyContext(ctx); +} + es2panda_Impl g_impl = { ES2PANDA_LIB_VERSION, + MemInitialize, + MemFinalize, CreateConfig, DestroyConfig, + ConfigGetOptions, CreateContextFromFile, + CreateCacheContextFromFile, CreateContextFromString, ProceedToState, DestroyContext, + CreateGlobalContext, + DestroyGlobalContext, ContextState, ContextErrorMessage, ContextProgram, ExternalSourceName, ExternalSourcePrograms, AstNodeForEach, - SetNumberLiteralInt, - SetNumberLiteralLong, - SetNumberLiteralDouble, - SetNumberLiteralFloat, + NumberLiteralSetInt, + NumberLiteralSetLong, + NumberLiteralSetDouble, + NumberLiteralSetFloat, CreateNumberLiteral, UpdateNumberLiteral, CreateNumberLiteral, @@ -797,6 +1267,7 @@ es2panda_Impl g_impl = { UpdateNumberLiteral, CreateNumberLiteral, UpdateNumberLiteral, + NumberLiteralStrConst, AllocMemory, CreateSourcePosition, CreateSourceRange, @@ -805,19 +1276,31 @@ es2panda_Impl g_impl = { SourceRangeStart, SourceRangeEnd, CreateDiagnosticKind, + CreateDiagnosticInfo, + CreateSuggestionInfo, + LogDiagnosticWithSuggestion, LogDiagnostic, GetSemanticErrors, GetSyntaxErrors, GetPluginErrors, GetWarnings, + IsAnyError, AstNodeFindNearestScope, AstNodeRebind, AstNodeRecheck, Es2pandaEnumFromString, Es2pandaEnumToString, DeclarationFromIdentifier, + FirstDeclarationByNameFromNode, + FirstDeclarationByNameFromProgram, + AllDeclarationsByNameFromNode, + AllDeclarationsByNameFromProgram, GenerateTsDeclarationsFromContext, InsertETSImportDeclarationAndParse, + GenerateStaticDeclarationsFromContext, + InvalidateFileCache, + RemoveFileCache, + AddFileCache, #include "generated/es2panda_lib/es2panda_lib_list.inc" diff --git a/ets2panda/public/es2panda_lib.h b/ets2panda/public/es2panda_lib.h index fd81b6825a3a8e858d135bd8c52a3fb8ee7cbc89..cf927443b4f8927ae3bde32e4da2d471051bb38c 100644 --- a/ets2panda/public/es2panda_lib.h +++ b/ets2panda/public/es2panda_lib.h @@ -43,6 +43,7 @@ extern "C" { typedef struct es2panda_Config es2panda_Config; typedef struct es2panda_Context es2panda_Context; +typedef struct es2panda_GlobalContext es2panda_GlobalContext; typedef struct es2panda_variantDoubleCharArrayBool { int index; @@ -100,6 +101,8 @@ typedef struct es2panda_ImportPathManager es2panda_ImportPathManager; typedef struct es2panda_DiagnosticKind es2panda_DiagnosticKind; typedef struct es2panda_DiagnosticMessageParams es2panda_DiagnosticMessageParams; typedef struct es2panda_DiagnosticStorage es2panda_DiagnosticStorage; +typedef struct es2panda_Path es2panda_Path; +typedef struct es2panda_Options es2panda_Options; typedef void (*NodeTraverser)(es2panda_AstNode *); typedef es2panda_AstNode *(*NodeTransformer)(es2panda_AstNode *); typedef bool (*NodePredicate)(es2panda_AstNode *); @@ -117,10 +120,30 @@ typedef struct es2panda_DynamicImportData { es2panda_Variable *variable; } es2panda_DynamicImportData; +typedef struct es2panda_OverloadInfo { + uint32_t minArg; + size_t maxArg; + bool needHelperOverload; + bool isDeclare; + bool hasRestVar; + bool returnVoid; +} es2panda_OverloadInfo; + +typedef struct es2panda_JsDocRecord { + char *name; + char *param; + char *comment; +} es2panda_JsDocRecord; + +typedef struct es2panda_JsDocInfo { + char **strings; + es2panda_JsDocRecord **jsDocRecords; + size_t len; +} es2panda_JsDocInfo; + enum es2panda_ContextState { ES2PANDA_STATE_NEW, ES2PANDA_STATE_PARSED, - ES2PANDA_STATE_SCOPE_INITED, ES2PANDA_STATE_BOUND, ES2PANDA_STATE_CHECKED, ES2PANDA_STATE_LOWERED, @@ -129,6 +152,23 @@ enum es2panda_ContextState { ES2PANDA_STATE_ERROR }; + +typedef struct es2panda_SuggestionInfo { + const es2panda_DiagnosticKind *kind; + const char **args; + size_t argc; + const char *substitutionCode; +} es2panda_SuggestionInfo; + +typedef struct es2panda_DiagnosticInfo { + const es2panda_DiagnosticKind *kind; + const char **args; + size_t argc; +} es2panda_DiagnosticInfo; + +enum es2panda_PluginDiagnosticType { ES2PANDA_PLUGIN_WARNING, ES2PANDA_PLUGIN_ERROR, ES2PANDA_PLUGIN_SUGGESTION }; + +typedef enum es2panda_PluginDiagnosticType es2panda_PluginDiagnosticType; typedef enum es2panda_ContextState es2panda_ContextState; // CC-OFFNXT(G.INC.08) project code style #include "generated/es2panda_lib/es2panda_lib_enums.inc" @@ -136,14 +176,24 @@ typedef enum es2panda_ContextState es2panda_ContextState; struct CAPI_EXPORT es2panda_Impl { int version; + void (*MemInitialize)(); + void (*MemFinalize)(); + es2panda_Config *(*CreateConfig)(int argc, char const *const *argv); void (*DestroyConfig)(es2panda_Config *config); + const es2panda_Options *(*ConfigGetOptions)(es2panda_Config *config); es2panda_Context *(*CreateContextFromFile)(es2panda_Config *config, char const *source_file_name); + es2panda_Context *(*CreateCacheContextFromFile)(es2panda_Config *config, char const *source_file_name, + es2panda_GlobalContext *globalContext, bool isExternal); es2panda_Context *(*CreateContextFromString)(es2panda_Config *config, const char *source, char const *file_name); es2panda_Context *(*ProceedToState)(es2panda_Context *context, es2panda_ContextState state); // context is consumed void (*DestroyContext)(es2panda_Context *context); + es2panda_GlobalContext *(*CreateGlobalContext)(es2panda_Config *config, const char **externalFileList, + size_t fileNum, bool LspUsage); + void (*DestroyGlobalContext)(es2panda_GlobalContext *globalContext); + es2panda_ContextState (*ContextState)(es2panda_Context *context); char const *(*ContextErrorMessage)(es2panda_Context *context); @@ -152,14 +202,14 @@ struct CAPI_EXPORT es2panda_Impl { es2panda_Program **(*ExternalSourcePrograms)(es2panda_ExternalSource *e_source, size_t *len_p); void (*AstNodeForEach)(es2panda_AstNode *ast, void (*func)(es2panda_AstNode *, void *), void *arg); -#define SET_NUMBER_LITERAL_DECL(name, type) bool (*SetNumberLiteral##name)(es2panda_AstNode * node, type new_value) +#define NUMBER_LITERAL_SET_DECL(name, type) bool (*NumberLiteralSet##name)(es2panda_AstNode * node, type new_value) - SET_NUMBER_LITERAL_DECL(Int, int32_t); - SET_NUMBER_LITERAL_DECL(Long, int64_t); - SET_NUMBER_LITERAL_DECL(Double, double); - SET_NUMBER_LITERAL_DECL(Float, float); + NUMBER_LITERAL_SET_DECL(Int, int32_t); + NUMBER_LITERAL_SET_DECL(Long, int64_t); + NUMBER_LITERAL_SET_DECL(Double, double); + NUMBER_LITERAL_SET_DECL(Float, float); -#undef SET_NUMBER_LITERAL_DECL +#undef NUMBER_LITERAL_SET_DECL #define CREATE_UPDATE_NUMBER_LITERAL_IMPL(num, type) \ es2panda_AstNode *(*CreateNumberLiteral##num)(es2panda_Context * ctx, type value); \ @@ -171,6 +221,7 @@ struct CAPI_EXPORT es2panda_Impl { CREATE_UPDATE_NUMBER_LITERAL_IMPL(3, float); #undef CREATE_UPDATE_NUMBER_LITERAL_IMPL + const char *(*NumberLiteralStrConst)(es2panda_Context *context, es2panda_AstNode *classInstance); void *(*AllocMemory)(es2panda_Context *context, size_t numberOfElements, size_t sizeOfElement); es2panda_SourcePosition *(*CreateSourcePosition)(es2panda_Context *context, size_t index, size_t line); @@ -180,25 +231,45 @@ struct CAPI_EXPORT es2panda_Impl { size_t (*SourcePositionLine)(es2panda_Context *context, es2panda_SourcePosition *position); es2panda_SourcePosition *(*SourceRangeStart)(es2panda_Context *context, es2panda_SourceRange *range); es2panda_SourcePosition *(*SourceRangeEnd)(es2panda_Context *context, es2panda_SourceRange *range); - const es2panda_DiagnosticKind *(*CreateDiagnosticKind)(es2panda_Context *context, const char *dmessage); + const es2panda_DiagnosticKind *(*CreateDiagnosticKind)(es2panda_Context *context, const char *dmessage, + es2panda_PluginDiagnosticType etype); + es2panda_DiagnosticInfo *(*CreateDiagnosticInfo)(es2panda_Context *context, const es2panda_DiagnosticKind *kind, + const char **args, size_t argc); + es2panda_SuggestionInfo *(*CreateSuggestionInfo)(es2panda_Context *context, const es2panda_DiagnosticKind *kind, + const char **args, size_t argc, const char *substitutionCode); + void (*LogDiagnosticWithSuggestion)(es2panda_Context *context, const es2panda_DiagnosticInfo *diagnosticInfo, + const es2panda_SuggestionInfo *suggestionInfo, es2panda_SourceRange *range); void (*LogDiagnostic)(es2panda_Context *context, const es2panda_DiagnosticKind *kind, const char **args, size_t argc, es2panda_SourcePosition *pos); const es2panda_DiagnosticStorage *(*GetSemanticErrors)(es2panda_Context *context); const es2panda_DiagnosticStorage *(*GetSyntaxErrors)(es2panda_Context *context); const es2panda_DiagnosticStorage *(*GetPluginErrors)(es2panda_Context *context); const es2panda_DiagnosticStorage *(*GetWarnings)(es2panda_Context *context); + bool (*IsAnyError)(es2panda_Context *context); es2panda_Scope *(*AstNodeFindNearestScope)(es2panda_Context *ctx, es2panda_AstNode *node); es2panda_Scope *(*AstNodeRebind)(es2panda_Context *ctx, es2panda_AstNode *node); void (*AstNodeRecheck)(es2panda_Context *ctx, es2panda_AstNode *node); Es2pandaEnum (*Es2pandaEnumFromString)(es2panda_Context *ctx, const char *str); char *(*Es2pandaEnumToString)(es2panda_Context *ctx, Es2pandaEnum id); es2panda_AstNode *(*DeclarationFromIdentifier)(es2panda_Context *ctx, es2panda_AstNode *node); + es2panda_AstNode *(*FirstDeclarationByNameFromNode)(es2panda_Context *ctx, const es2panda_AstNode *node, + const char *name); + es2panda_AstNode *(*FirstDeclarationByNameFromProgram)(es2panda_Context *ctx, const es2panda_Program *program, + const char *name); + es2panda_AstNode **(*AllDeclarationsByNameFromNode)(es2panda_Context *ctx, const es2panda_AstNode *node, + const char *name, size_t *declsLen); + es2panda_AstNode **(*AllDeclarationsByNameFromProgram)(es2panda_Context *ctx, const es2panda_Program *program, + const char *name, size_t *declsLen); int (*GenerateTsDeclarationsFromContext)(es2panda_Context *context, const char *outputDeclEts, const char *outputEts, bool exportAll); void (*InsertETSImportDeclarationAndParse)(es2panda_Context *context, es2panda_Program *program, es2panda_AstNode *importDeclaration); + int (*GenerateStaticDeclarationsFromContext)(es2panda_Context *context, const char *outputPath); + void (*InvalidateFileCache)(es2panda_GlobalContext *globalContext, const char *fileName); + void (*RemoveFileCache)(es2panda_GlobalContext *globalContext, const char *fileName); + void (*AddFileCache)(es2panda_GlobalContext *globalContext, const char *fileName); // CC-OFFNXT(G.INC.08) project code style #include "generated/es2panda_lib/es2panda_lib_decl.inc" }; diff --git a/ets2panda/public/es2panda_lib.idl.erb b/ets2panda/public/es2panda_lib.idl.erb index b2e0a9335c6d5c74094de08005e9b63d1ebbc4c7..c884938c36bc0cfcc2990d1184791e6fe8dff87b 100644 --- a/ets2panda/public/es2panda_lib.idl.erb +++ b/ets2panda/public/es2panda_lib.idl.erb @@ -56,62 +56,92 @@ typedef (String or f64 or boolean) es2panda_variantDoubleCharArrayBool; [Entity=Class] interface es2panda_IRNode {}; [Entity=Class] interface es2panda_ErrorLogger {}; [Entity=Class] interface es2panda_VerificationContext {}; +[Entity=Class] interface es2panda_ImportPathManager {}; +[Entity=Class] interface es2panda_Path {}; +[Entity=Class] interface es2panda_Options {}; interface NodeTraverser { - void Do(AstNode e2p_node); + void Do(ir.AstNode e2p_node); }; interface NodeTransformer { - AstNode Do(AstNode e2p_node); + ir.AstNode Do(ir.AstNode e2p_node); }; interface NodePredicate { - boolean Do(AstNode e2p_node); + boolean Do(ir.AstNode e2p_node); }; interface PropertyProcessor { - Variable Do(Variable e2p_variable, Type e2p_type); + varbinder.Variable Do(varbinder.Variable e2p_variable, checker.Type e2p_type); }; interface PropertyTraverser { - void Do(Variable e2p_variable); + void Do(varbinder.Variable e2p_variable); }; interface ClassBuilder { - void Do(sequence e2p_node, u32 size); + void Do(sequence e2p_node, u32 size); }; interface MethodBuilder { - void Do(sequence statements, u32 sizeStatements, sequence expression, - u32 sizeExpression, sequence e2p_type); + void Do(sequence statements, u32 sizeStatements, sequence expression, + u32 sizeExpression, sequence e2p_type); }; interface ClassInitializerBuilder { - void Do(sequence statements, u32 sizeStatements, sequence expression, + void Do(sequence statements, u32 sizeStatements, sequence expression, u32 sizeExpression); }; interface AstNodeForEachFunction { - void Do(AstNode node, VoidPtr arg); + void Do(ir.AstNode node, VoidPtr arg); }; interface es2panda_DynamicImportData { - attribute AstNode import_node; - attribute AstNode specifier; - attribute Variable variable; + attribute ir.ETSImportDeclaration import_node; + attribute ir.AstNode specifier; + attribute varbinder.Variable variable; +}; + +interface es2panda_OverloadInfo { + attribute u32 minArg; + attribute u32 maxArg; + attribute boolean needHelperOverload; + attribute boolean isDeclare; + attribute boolean hasRestVar; + attribute boolean returnVoid; }; dictionary es2panda_ContextState { i32 ES2PANDA_STATE_NEW = 0; i32 ES2PANDA_STATE_PARSED = 1; - i32 ES2PANDA_STATE_SCOPE_INITED = 2; - i32 ES2PANDA_STATE_BOUND = 3; - i32 ES2PANDA_STATE_CHECKED = 4; - i32 ES2PANDA_STATE_LOWERED = 5; - i32 ES2PANDA_STATE_ASM_GENERATED = 6; - i32 ES2PANDA_STATE_BIN_GENERATED = 7; - i32 ES2PANDA_STATE_ERROR = 8; + i32 ES2PANDA_STATE_BOUND = 2; + i32 ES2PANDA_STATE_CHECKED = 3; + i32 ES2PANDA_STATE_LOWERED = 4; + i32 ES2PANDA_STATE_ASM_GENERATED = 5; + i32 ES2PANDA_STATE_BIN_GENERATED = 6; + i32 ES2PANDA_STATE_ERROR = 7; +}; + +interface es2panda_SuggestionInfo { + attribute es2panda_DiagnosticKind kind; + attribute sequence args; + attribute u32 argc; + attribute String substitutionCode; +}; + +interface es2panda_DiagnosticInfo { + attribute es2panda_DiagnosticKind kind; + attribute sequence args; + attribute u32 argc; +}; + +dictionary es2panda_PluginDiagnosticType { + i32 ES2PANDA_PLUGIN_WARNING = 0; + i32 ES2PANDA_PLUGIN_ERROR = 1; + i32 ES2PANDA_PLUGIN_SUGGESTION = 2; }; [Entity=Class] interface VoidPtr {}; // void * @@ -138,6 +168,7 @@ typedef u64 Es2panda<%= name %>; interface es2panda_Impl { es2panda_Config CreateConfig(i32 argc, sequence argv); void DestroyConfig(es2panda_Config config); + es2panda_Options ConfigGetOptions(es2panda_Config config); es2panda_Context CreateContextFromFile(es2panda_Config config, String source_file_name); es2panda_Context CreateContextFromString(es2panda_Config config, String source, String file_name); @@ -148,27 +179,10 @@ interface es2panda_Impl { String ContextErrorMessage(es2panda_Context context); es2panda_Program ContextProgram(es2panda_Context context); - AstNode ProgramAst(es2panda_Program program); - sequence ProgramExternalSources(es2panda_Program program, sequence len_p); String ExternalSourceName(es2panda_ExternalSource e_source); sequence ExternalSourcePrograms(es2panda_ExternalSource e_source, sequence len_p); - void AstNodeForEach(AstNode ast, AstNodeForEachFunction func, VoidPtr arg); - - boolean SetNumberLiteralInt(AstNode node, i32 new_value); - boolean SetNumberLiteralLong(AstNode node, i64 new_value); - boolean SetNumberLiteralDouble(AstNode node, f64 new_value); - boolean SetNumberLiteralFloat(AstNode node, f32 new_value); - - AstNode CreateNumberLiteral(es2panda_Context ctx, i32 value); - AstNode CreateNumberLiteral1(es2panda_Context ctx, i64 value); - AstNode CreateNumberLiteral2(es2panda_Context ctx, f64 value); - AstNode CreateNumberLiteral3(es2panda_Context ctx, f32 value); - - AstNode UpdateNumberLiteral(es2panda_Context ctx, AstNode original, i32 value); - AstNode UpdateNumberLiteral1(es2panda_Context ctx, AstNode original, i64 value); - AstNode UpdateNumberLiteral2(es2panda_Context ctx, AstNode original, f64 value); - AstNode UpdateNumberLiteral3(es2panda_Context ctx, AstNode original, f32 value); + void AstNodeForEach(ir.AstNode ast, AstNodeForEachFunction func, VoidPtr arg); VoidPtr AllocMemory(es2panda_Context context, u32 numberOfElements, u32 sizeOfElement); @@ -179,52 +193,91 @@ interface es2panda_Impl { u32 SourcePositionLine(es2panda_Context context, es2panda_SourcePosition position); es2panda_SourcePosition SourceRangeStart(es2panda_Context context, es2panda_SourceRange range); es2panda_SourcePosition SourceRangeEnd(es2panda_Context context, es2panda_SourceRange range); + es2panda_DiagnosticInfo CreateDiagnosticInfo(es2panda_Context context, es2panda_DiagnosticKind kind, + sequence args, u32 argc); + es2panda_SuggestionInfo CreateDiagnosticInfo(es2panda_Context context, es2panda_DiagnosticKind kind, + sequence args, u32 argc, String substitutionCode); + void LogDiagnosticWithSuggestion(es2panda_Context context, es2panda_DiagnosticInfo diagnosticInfo, + es2panda_SuggestionInfo suggestionInfo, es2panda_SourceRange range); void LogTypeError(es2panda_Context context, String errorMsg, es2panda_SourcePosition pos); void LogWarning(es2panda_Context context, String warnMsg, es2panda_SourcePosition pos); void LogSyntaxError(es2panda_Context context, String errorMsg, es2panda_SourcePosition pos); - Scope AstNodeFindNearestScope(es2panda_Context ctx, AstNode node); - Scope AstNodeRebind(es2panda_Context ctx, AstNode node); - void AstNodeRecheck(es2panda_Context ctx, AstNode node); + boolean IsAnyError(es2panda_Context context); + varbinder.Scope AstNodeFindNearestScope(es2panda_Context ctx, ir.AstNode node); + varbinder.Scope AstNodeRebind(es2panda_Context ctx, ir.AstNode node); + void AstNodeRecheck(es2panda_Context ctx, ir.AstNode node); Es2pandaEnum Es2pandaEnumFromString(es2panda_Context ctx, String str); String Es2pandaEnumToString(es2panda_Context ctx, Es2pandaEnum id); - AstNode DeclarationFromIdentifier(es2panda_Context ctx, Identifier node); + ir.AstNode DeclarationFromIdentifier(es2panda_Context ctx, ir.Identifier node); + ir.AstNode FirstDeclarationByNameFromNode(es2panda_Context ctx, ir.AstNode node, String name); + ir.AstNode FirstDeclarationByNameFromProgram(es2panda_Context ctx, es2panda_Program program, String name); + sequence AllDeclarationsByNameFromNode(es2panda_Context ctx, ir.AstNode node, String name); + sequence AllDeclarationsByNameFromProgram(es2panda_Context ctx, es2panda_Program program, String name); void InsertETSImportDeclarationAndParse(es2panda_Context context, es2panda_Program program, ETSImportDeclaration node); + i32 GenerateStaticDeclarationsFromContext(es2panda_Context context, String outputPath); % Es2pandaLibApi::ast_nodes&.each do |ast_node| % if ast_node != 'AstNode' && ast_node != 'TypeNode' - boolean Is<%= ast_node %>(AstNode ast); + boolean Is<%= ast_node %>(ir.AstNode ast); % end % end % Es2pandaLibApi::scopes&.each do |scope| % if scope != 'Scope' - boolean ScopeIs<%= scope %>(Scope scope); + boolean ScopeIs<%= scope %>(varbinder.Scope scope); % end % end % Es2pandaLibApi::ast_types&.each do |type| % if type != 'Type' - boolean TypeIs<%= type %>(Type type); + boolean TypeIs<%= type %>(checker.Type type); % end % end % Es2pandaLibApi::ast_variables&.each do |variable| % if variable[1] != 'Variable' - boolean VariableIs<%= variable[1] %>(Variable variable); + boolean VariableIs<%= variable[1] %>(varbinder.Variable variable); % end % end - String AstNodeName(AstNode ast); + String AstNodeName(ir.AstNode ast); +}; + + +namespace ir { + +% number_literal_ast_node_type = Enums::enums['AstNodeType'].all_flags_with_value['NUMBER_LITERAL'] +[Entity=Class, Es2pandaAstNodeType=<%= number_literal_ast_node_type %>, c_type=es2panda_AstNode] interface NumberLiteral: Literal { + ir.AstNode Create(es2panda_Context ctx, i32 value); + ir.AstNode Create1(es2panda_Context ctx, i64 value); + ir.AstNode Create2(es2panda_Context ctx, f64 value); + ir.AstNode Create3(es2panda_Context ctx, f32 value); + + ir.AstNode Update(es2panda_Context ctx, ir.AstNode original, i32 value); + ir.AstNode Update1(es2panda_Context ctx, ir.AstNode original, i64 value); + ir.AstNode Update2(es2panda_Context ctx, ir.AstNode original, f64 value); + ir.AstNode Update3(es2panda_Context ctx, ir.AstNode original, f32 value); + + boolean SetInt(ir.AstNode node, i32 new_value); + boolean SetLong(ir.AstNode node, i64 new_value); + boolean SetDouble(ir.AstNode node, f64 new_value); + boolean SetFloat(ir.AstNode node, f32 new_value); + + [get] String StrConst(es2panda_Context context); }; +}; // namespace ir + % Es2pandaLibApi::classes&.each do |namespaceName, namespaceClasses| +namespace <%= namespaceName %> { + % namespaceClasses&.each do |className, classData| [Entity=Class<%= classData.ast_node_type_value ? ", Es2pandaAstNodeType=#{classData.ast_node_type_value}" : '' -%>, cpp_namespace=<%= namespaceName %>] interface <%= className %><%= +%><%= classData.class_c_type %>] interface <%= className %><%= ": #{classData.extends_classname}" if classData && classData.extends_classname %> { % classData.class_constructors&.each_with_index do |constructor, index| @@ -260,4 +313,5 @@ interface es2panda_Impl { }; % end # namespaceClasses +}; // namespace <%= namespaceName %> % end # classes diff --git a/ets2panda/public/es2panda_lib.rb b/ets2panda/public/es2panda_lib.rb index c1cfbf060ab2ffe7c673ea7ac6d97d27097afa27..788b3f43862936a80a556457a3c10d9e7d4f9aaa 100644 --- a/ets2panda/public/es2panda_lib.rb +++ b/ets2panda/public/es2panda_lib.rb @@ -39,7 +39,7 @@ module Es2pandaLibApi # Flags @need_var_cast = false - def check_ptr_depth(change_type, ptr_depth) + def self.check_ptr_depth(change_type, ptr_depth) !((change_type.es2panda_arg['min_ptr_depth'] && ptr_depth < change_type.es2panda_arg['min_ptr_depth']) || (change_type.es2panda_arg['max_ptr_depth'] && ptr_depth > change_type.es2panda_arg['max_ptr_depth'])) end @@ -54,32 +54,33 @@ module Es2pandaLibApi type['ref_depth'] = 0 if type.respond_to?('ref_depth') end - def const - @const = 'const' if @es2panda_arg['type'].respond_to?('prefix') && - @es2panda_arg['type']['prefix'].include?('const') || - @es2panda_arg['type'].respond_to?('other_modifiers') && - @es2panda_arg['type']['other_modifiers'].include?('const') || - @es2panda_arg['type'].respond_to?('const') && - @es2panda_arg['type']['const']&.include?('const') + def self.const(es2panda_arg) + return 'const' if es2panda_arg['type'].respond_to?('prefix') && + es2panda_arg['type']['prefix'].include?('const') || + es2panda_arg['type'].respond_to?('other_modifiers') && + es2panda_arg['type']['other_modifiers'].include?('const') || + es2panda_arg['type'].respond_to?('const') && + es2panda_arg['type']['const']&.include?('const') end - def set_const_modifier(args, value) + def self.set_const_modifier(args, value) args&.map do |arg| unless arg['type']&.respond_to?('const') && arg['type']&.respond_to?('ptr_depth') && arg['type']&.ptr_depth&.positive? - arg['type']['const'] = const || '' + arg['type']['const'] = value || '' end end end def stop_modify_idl_arg - @is_ast_node || @is_ast_node_add_children || @is_ast_type || @is_ast_type_add_children || @is_var_type || @is_scope_type || @is_decl_type + @is_ast_node || @is_ast_node_add_children || @is_ast_type || @is_ast_type_add_children || @is_var_type || + @is_scope_type || @is_decl_type end def modify_template_nested_arg(arg, base_namespace, idl_mode = false) arg['type'] = ClassData.add_base_namespace(arg['type'], base_namespace) tmp = Arg.new(arg, base_namespace) - raise "Unsupported double+ nested complex types: #{arg_info.to_s}\n" if tmp.lib_args.length > 1 + raise "Unsupported double+ nested complex types: #{arg}\n" if tmp.lib_args.length > 1 return nil if tmp.lib_args.nil? || tmp.lib_args[0].nil? return arg if idl_mode && tmp.stop_modify_idl_arg @@ -89,131 +90,180 @@ module Es2pandaLibApi tmp.lib_args[0] end - def unsupported_type_msg() - ptr_depth = @es2panda_arg['type'].ptr_depth || 0 - namespace = @es2panda_arg['type'].namespace + def self.unsupported_type_msg(es2panda_arg) + ptr_depth = es2panda_arg['type'].ptr_depth || 0 + namespace = es2panda_arg['type'].namespace "'#{namespace ? "#{namespace}::" : ''}"\ - "#{@es2panda_arg['type'].name}"\ - "#{' ' * [1, ptr_depth].min + '*' * (ptr_depth)}'" + "#{es2panda_arg['type'].name}"\ + "#{' ' * [1, ptr_depth].min + '*' * ptr_depth}'" end - def initialize(arg_info, base_namespace) - @@primitive_types ||= Es2pandaLibApi.primitive_types - @es2panda_arg = arg_info + def self.is_ast_node(es2panda_arg) + Es2pandaLibApi.ast_nodes.include?(es2panda_arg['type'].name) && + (!es2panda_arg['type']['namespace'] || es2panda_arg['type']['namespace'] == 'ir') + end - @es2panda_arg['const'] = const - @base_namespace = base_namespace + def self.is_ast_node_add_children(es2panda_arg) + Es2pandaLibApi.ast_node_additional_children.include?(es2panda_arg['type'].name) && + (!es2panda_arg['type']['namespace'] || es2panda_arg['type']['namespace'] == 'ir') + end + def self.is_ast_type(es2panda_arg) + Es2pandaLibApi.ast_types.include?(es2panda_arg['type'].name) && + (!es2panda_arg['type']['namespace'] || es2panda_arg['type']['namespace'] == 'checker') + end + + def self.is_ast_type_add_children(es2panda_arg) + Es2pandaLibApi.ast_type_additional_children.include?(es2panda_arg['type'].name) && + (!es2panda_arg['type']['namespace'] || + es2panda_arg['type']['namespace'] == 'checker') + end + + def self.is_var_type(es2panda_arg) + Es2pandaLibApi.ast_variables.any? { |variable| variable[1] == es2panda_arg['type'].name } && + (!es2panda_arg['type']['namespace'] || es2panda_arg['type']['namespace'] == 'varbinder') + end + + def self.is_enum_type(es2panda_arg) + Es2pandaLibApi.enums.include?(es2panda_arg['type'].name) + end + + def self.is_scope_type(es2panda_arg) + Es2pandaLibApi.scopes.include?(es2panda_arg['type'].name) && + (!es2panda_arg['type']['namespace'] || es2panda_arg['type']['namespace'] == 'varbinder') + end + + def self.is_decl_type(es2panda_arg) + Es2pandaLibApi.declarations.include?(es2panda_arg['type'].name) && + (!es2panda_arg['type']['namespace'] || es2panda_arg['type']['namespace'] == 'varbinder') + end + + def self.is_code_gen(es2panda_arg) + Es2pandaLibApi.code_gen_children.include?(es2panda_arg['type'].name) && + (!es2panda_arg['type']['namespace'] || es2panda_arg['type']['namespace'] == 'compiler') + end + + def self.get_change_type_info(es2panda_arg) found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type.respond_to?('name') && x.es2panda_arg.type.name == @es2panda_arg['type']['name'] && + x.es2panda_arg.type.respond_to?('name') && x.es2panda_arg.type.name == es2panda_arg['type']['name'] && (!x.es2panda_arg.type.respond_to?('namespace') || - x.es2panda_arg.type.namespace == @es2panda_arg['type'].namespace) && + x.es2panda_arg.type.namespace == es2panda_arg['type'].namespace) && (!x.es2panda_arg.type.respond_to?('current_class') || - x.es2panda_arg.type['current_class'] == @es2panda_arg['type']['current_class']) && - check_ptr_depth(x, @es2panda_arg['type']['ptr_depth'] || 0) + x.es2panda_arg.type['current_class'] == es2panda_arg['type']['current_class']) && + Arg.check_ptr_depth(x, es2panda_arg['type']['ptr_depth'] || 0) end - unless found_change_type_link - @is_ast_node = Es2pandaLibApi.ast_nodes.include?(@es2panda_arg['type'].name) && - (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'ir') - @is_ast_node_add_children = Es2pandaLibApi.ast_node_additional_children.include?(@es2panda_arg['type'].name) && - (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'ir') - @is_ast_type = Es2pandaLibApi.ast_types.include?(@es2panda_arg['type'].name) && - (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'checker') - @is_ast_type_add_children = Es2pandaLibApi.ast_type_additional_children.include?(@es2panda_arg['type'].name) && - (!@es2panda_arg['type']['namespace'] || - @es2panda_arg['type']['namespace'] == 'checker') - @is_var_type = Es2pandaLibApi.ast_variables.any? { |variable| variable[1] == @es2panda_arg['type'].name } && - (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'varbinder') - @is_enum_type = Es2pandaLibApi.enums.include?(@es2panda_arg['type'].name) - @is_scope_type = Es2pandaLibApi.scopes.include?(@es2panda_arg['type'].name) && - (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'varbinder') - @is_decl_type = Es2pandaLibApi.declarations.include?(@es2panda_arg['type'].name) && - (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'varbinder') - @is_code_gen = Es2pandaLibApi.code_gen_children.include?(@es2panda_arg['type'].name) && - (!@es2panda_arg['type']['namespace'] || @es2panda_arg['type']['namespace'] == 'compiler') - - if @is_ast_type - found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type == '|AstType|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) - end - end + return found_change_type_link if found_change_type_link - if @is_ast_type_add_children - found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type == - '|AstTypeAdditionalChildren|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) - end + if Arg.is_ast_type(es2panda_arg) + found_change_type_link = Es2pandaLibApi.change_types.find do |x| + x.es2panda_arg.type == '|AstType|' && Arg.check_ptr_depth(x, es2panda_arg['type'].ptr_depth || 0) end + end - if @is_ast_node - found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type == '|AstNode|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) - end + if Arg.is_ast_type_add_children(es2panda_arg) + found_change_type_link = Es2pandaLibApi.change_types.find do |x| + x.es2panda_arg.type == + '|AstTypeAdditionalChildren|' && Arg.check_ptr_depth(x, es2panda_arg['type'].ptr_depth || 0) end + end - if @is_ast_node_add_children - found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type == - '|AstNodeAdditionalChildren|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) - end + if Arg.is_ast_node(es2panda_arg) + found_change_type_link = Es2pandaLibApi.change_types.find do |x| + x.es2panda_arg.type == '|AstNode|' && Arg.check_ptr_depth(x, es2panda_arg['type'].ptr_depth || 0) end + end - if @is_var_type - found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type == '|Variable|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) - end + if Arg.is_ast_node_add_children(es2panda_arg) + found_change_type_link = Es2pandaLibApi.change_types.find do |x| + x.es2panda_arg.type == + '|AstNodeAdditionalChildren|' && Arg.check_ptr_depth(x, es2panda_arg['type'].ptr_depth || 0) end + end - if @is_enum_type - found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type == '|Enum|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) - end + if Arg.is_var_type(es2panda_arg) + found_change_type_link = Es2pandaLibApi.change_types.find do |x| + x.es2panda_arg.type == '|Variable|' && Arg.check_ptr_depth(x, es2panda_arg['type'].ptr_depth || 0) end + end - if @is_scope_type - found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type == '|Scope|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) - end + if Arg.is_enum_type(es2panda_arg) + found_change_type_link = Es2pandaLibApi.change_types.find do |x| + x.es2panda_arg.type == '|Enum|' && Arg.check_ptr_depth(x, es2panda_arg['type'].ptr_depth || 0) end + end - if @is_decl_type - found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type == '|Declaration|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) - end + if Arg.is_scope_type(es2panda_arg) + found_change_type_link = Es2pandaLibApi.change_types.find do |x| + x.es2panda_arg.type == '|Scope|' && Arg.check_ptr_depth(x, es2panda_arg['type'].ptr_depth || 0) end + end - if @is_code_gen - found_change_type_link = Es2pandaLibApi.change_types.find do |x| - x.es2panda_arg.type == '|CodeGen|' && check_ptr_depth(x, @es2panda_arg['type'].ptr_depth || 0) - end + if Arg.is_decl_type(es2panda_arg) + found_change_type_link = Es2pandaLibApi.change_types.find do |x| + x.es2panda_arg.type == '|Declaration|' && Arg.check_ptr_depth(x, es2panda_arg['type'].ptr_depth || 0) end end - unless found_change_type_link || @@primitive_types.include?(@es2panda_arg['type'].name) - raise "Unsupported type: #{unsupported_type_msg}" + if Arg.is_code_gen(es2panda_arg) + found_change_type_link = Es2pandaLibApi.change_types.find do |x| + x.es2panda_arg.type == '|CodeGen|' && Arg.check_ptr_depth(x, es2panda_arg['type'].ptr_depth || 0) + end end - ptr_depth = @es2panda_arg['type']['ptr_depth'] || 0 + found_change_type_link + end + + def self.check_is_type_supported(found_change_type_link, es2panda_arg) + unless found_change_type_link || Es2pandaLibApi.primitive_types.include?(es2panda_arg['type'].name) + return "Unsupported type: #{Arg.unsupported_type_msg(es2panda_arg)}" + end - if found_change_type_link && !check_ptr_depth(found_change_type_link, ptr_depth) - raise "Invalid ptr depth for type: #{unsupported_type_msg}" + if found_change_type_link && !Arg.check_ptr_depth(found_change_type_link, es2panda_arg['type']['ptr_depth'] || 0) + return "Invalid ptr depth for type: #{Arg.unsupported_type_msg(es2panda_arg)}" end - if found_change_type_link && @es2panda_arg['name'] == 'returnType' && + if found_change_type_link && es2panda_arg['name'] == 'returnType' && !found_change_type_link.cast.respond_to?('reverse_cast') - raise "Unsupported return type: #{unsupported_type_msg}" + return "Unsupported return type: #{Arg.unsupported_type_msg(es2panda_arg)}" end - if found_change_type_link && @es2panda_arg['name'] == 'callType' && + if found_change_type_link && es2panda_arg['name'] == 'callType' && !found_change_type_link.cast.respond_to?('call_cast') - raise "Unsupported call type: #{unsupported_type_msg}" + return "Unsupported call type: #{Arg.unsupported_type_msg(es2panda_arg)}" end - if found_change_type_link && @es2panda_arg['name'] == 'constructorType' && + if found_change_type_link && es2panda_arg['name'] == 'constructorType' && !found_change_type_link.cast.respond_to?('constructor_cast') - raise "Unsupported constructor type: #{unsupported_type_msg}" + "Unsupported constructor type: #{Arg.unsupported_type_msg(es2panda_arg)}" end + end + + def self.get_change_type_info_with_err_msg(es2panda_arg) + found_change_type_link = Arg.get_change_type_info(es2panda_arg) + err_msg = Arg.check_is_type_supported(found_change_type_link, es2panda_arg) + [found_change_type_link, err_msg] + end + + def initialize(arg_info, base_namespace) + found_change_type_link, err_msg = Arg.get_change_type_info_with_err_msg(arg_info) + raise err_msg unless err_msg.nil? + + @@primitive_types ||= Es2pandaLibApi.primitive_types + @es2panda_arg = arg_info + @const = Arg.const(arg_info) + @es2panda_arg['const'] = @const + @base_namespace = base_namespace + + @is_ast_node = Arg.is_ast_node(es2panda_arg) + @is_ast_node_add_children = Arg.is_ast_node_add_children(es2panda_arg) + @is_ast_type = Arg.is_ast_type(es2panda_arg) + @is_ast_type_add_children = Arg.is_ast_type_add_children(es2panda_arg) + @is_var_type = Arg.is_var_type(es2panda_arg) + @is_enum_type = Arg.is_enum_type(es2panda_arg) + @is_scope_type = Arg.is_scope_type(es2panda_arg) + @is_decl_type = Arg.is_decl_type(es2panda_arg) + @is_code_gen = Arg.is_code_gen(es2panda_arg) if found_change_type_link found_change_type = Marshal.load(Marshal.dump(found_change_type_link)) @@ -250,11 +300,11 @@ module Es2pandaLibApi 'type' => ClassData.add_base_namespace(template_arg_raw['type'], base_namespace) }, base_namespace) - raise "Unsupported double+ nested complex types: #{@es2panda_arg.to_s}\n" if template_arg.lib_args.length > 1 + raise "Unsupported double+ nested complex types: #{@es2panda_arg}\n" if template_arg.lib_args.length > 1 unless template_arg_raw['type']['const'].nil? - template_arg.set_const_modifier(@lib_args, 'const') - template_arg.set_const_modifier(@idl_args, 'const') + Arg.set_const_modifier(@lib_args, 'const') + Arg.set_const_modifier(@idl_args, 'const') end template_args += [template_arg] @@ -337,8 +387,8 @@ module Es2pandaLibApi return unless @es2panda_arg['name'] == 'returnType' - set_const_modifier(@lib_args, const) - set_const_modifier(@idl_args, const) + Arg.set_const_modifier(@lib_args, @const) + Arg.set_const_modifier(@idl_args, @const) end def check_allowed_type(arg) @@ -350,15 +400,16 @@ module Es2pandaLibApi def nested_arg_transform return unless @lib_args && @lib_args.size == 1 && !check_allowed_type(@lib_args[0]) - set_const_modifier(@lib_args, const) - set_const_modifier(@idl_args, const) + Arg.set_const_modifier(@lib_args, @const) + Arg.set_const_modifier(@idl_args, @const) tmp = Arg.new(@lib_args[0], @base_namespace) @lib_args = tmp.lib_args @idl_args = tmp.idl_args @lib_cast = tmp.lib_cast @return_args = tmp.return_args @idl_return_args = tmp.idl_return_args - return unless !tmp.check_allowed_type(@lib_args[0]) + return if tmp.check_allowed_type(@lib_args[0]) + nested_arg_transform end @@ -403,7 +454,7 @@ module Es2pandaLibApi elsif placeholder.end_with?('const|') value = '' else - raise "Unknown int found for placeholder '#{placeholder}', value: #{value.to_s}\n" + raise "Unknown int found for placeholder '#{placeholder}', value: #{value}\n" end end value @@ -456,6 +507,7 @@ module Es2pandaLibApi attr_reader :lib_cast attr_reader :return_args attr_reader :idl_return_args + attr_reader :const def lib_args_to_str @lib_args.map do |lib_arg| @@ -508,10 +560,10 @@ module Es2pandaLibApi 'uint64_t' => 'u64', 'float' => 'f32', 'double' => 'f64', - 'sequence' => 'String', + 'sequence' => 'String' } - c_type = type['name'] + c_type = type['namespace'] && type['namespace'] != 'std' ? "#{type['namespace']}.#{type['name']}" : type['name'] res_sequence_len = @@replace_to_idl_types.key?(c_type) ? (type['ptr_depth'] || 0) : ((type['ptr_depth'] || 1) - 1) res = res_sequence_len.times.reduce(c_type) { |acc, _| "sequence<#{@@replace_to_idl_types[acc] || acc}>" } @@replace_to_idl_types[res] || res @@ -607,7 +659,7 @@ module Es2pandaLibApi return '' unless @idl_return_args @idl_return_args - .select { |arg| arg['name'] != 'returnTypeLen' } + .reject { |arg| arg['name'] == 'returnTypeLen' } .map { |arg| ", #{Arg.arg_to_idl(arg)}" } .join('') end @@ -633,7 +685,7 @@ module Es2pandaLibApi attr_accessor :ast_node_type_value def class_name - Es2pandaLibApi.classes&.each do |namespace_name, namespace_classes| + Es2pandaLibApi.classes&.each do |_namespace_name, namespace_classes| if namespace_classes&.find { |_name, data| data == self } return namespace_classes&.find { |_name, data| data == self }[0] end @@ -641,9 +693,24 @@ module Es2pandaLibApi if Es2pandaLibApi.structs.find { |_name, data| data == self }[0] return Es2pandaLibApi.structs.find { |_name, data| data == self }[0] end + raise 'Unknown class name' end + def class_c_type + change_type_info, err_msg = Arg.get_change_type_info_with_err_msg( + { + 'name' => 'class_c_type', + 'type' => OpenStruct.new({ 'name' => class_name, 'ptr_depth' => 1, 'namespace' => @class_base_namespace }) + } + ) + + return '' if err_msg + + c_type = change_type_info.dig('new_args', 0, 'type', 'name') + ", c_type=#{c_type}" unless c_type.nil? # In some cases new_args = []. E.g. Checker type. + end + def call_cast name = class_name class_type = Type.new(add_base_namespace(OpenStruct.new({ 'name' => name, 'ptr_depth' => 1 })), @@ -703,16 +770,16 @@ module Es2pandaLibApi end def self.add_base_namespace(type, base_namespace) - type['namespace'] = base_namespace unless type.respond_to?('namespace') && !type['namespace'].empty? + type['namespace'] ||= base_namespace unless Es2pandaLibApi.primitive_types.include?(type['name']) type end def error_catch_log(mode, function, err, func_new_name) Es2pandaLibApi.stat_add_unsupported_type(err.message) if err.message.include?('Unsupported type') if mode == 'struct_getter' - Es2pandaLibApi.log('warning', "Error: '#{err.message}'"); + Es2pandaLibApi.log('warning', "Error: '#{err.message}'") Es2pandaLibApi.log('debug', "Field name: #{function.name}\nField type:\n---\n"\ - "#{function.type.to_s}\n---\n\n") + "#{function.type}\n---\n\n") Es2pandaLibApi.log('backtrace', err.backtrace.join("\n"), "\n\n") Es2pandaLibApi.stat_add_method(0, class_name, class_base_namespace, func_new_name) return @@ -759,8 +826,8 @@ module Es2pandaLibApi Es2pandaLibApi.log('info', "Supported constructor for class '#{class_name}'\n") res << { 'overload' => get_new_method_name(constructor_overload, '', ''), - 'idl_overload' => get_new_method_name(idl_constructor_overload, '', '', true), - 'args' => args, 'raw_decl' => constructor.raw_declaration } + 'idl_overload' => get_new_method_name(idl_constructor_overload, '', '', true), + 'args' => args, 'raw_decl' => constructor.raw_declaration } end else Es2pandaLibApi.log('info', "Banned constructor for class '#{class_name}'\n") @@ -780,16 +847,15 @@ module Es2pandaLibApi return false unless Es2pandaLibApi.check_template_type_presents(arg.type) end Es2pandaLibApi.ignored_info['constructors']['call_class']&.each do |call_class| - return false if (call_class['name'] == class_name) + return false if call_class['name'] == class_name end Es2pandaLibApi.ignored_info['template_names']&.each do |template_name| - return false if constructor.respond_to?('template') && (constructor['template'].include?(template_name['name'])) + return false if constructor.respond_to?('template') && constructor['template'].include?(template_name['name']) end # NOTE(nikozer) Need to ban ast verifier default condtructor, will be removed later - if class_name == "ASTVerifier" && constructor.args&.size == 0 - return false - end - return true + return false if class_name == 'ASTVerifier' && constructor.args&.size == 0 + + true end def check_no_gen_method(method) @@ -806,33 +872,36 @@ module Es2pandaLibApi return false unless Es2pandaLibApi.check_template_type_presents(arg.type) end Es2pandaLibApi.ignored_info['return_type']&.each do |return_type| - return false if (method.return_type['name'] == return_type['name'] && (!return_type.respond_to?('namespace') || - return_type['namespace'] == method.return_type['namespace'])) + return false if method.return_type['name'] == return_type['name'] && (!return_type.respond_to?('namespace') || + return_type['namespace'] == method.return_type['namespace']) end Es2pandaLibApi.ignored_info['methods']['call_class']&.each do |call_class| - return false if (call_class['name'] == class_name) + return false if call_class['name'] == class_name end return false unless Es2pandaLibApi.check_template_type_presents(method.return_type) + Es2pandaLibApi.ignored_info['template_names']&.each do |template_name| - return false if method.respond_to?('template') && (method['template'].include?(template_name['name'])) + return false if method.respond_to?('template') && method['template'].include?(template_name['name']) end - return true + true end def check_no_get_field(field) Es2pandaLibApi.ignored_info['return_type']&.each do |return_type| - return false if (field.type['name'] == return_type['name'] && (!return_type.respond_to?('namespace') || - return_type['namespace'] == field.type['namespace'])) + return false if field.type['name'] == return_type['name'] && (!return_type.respond_to?('namespace') || + return_type['namespace'] == field.type['namespace']) end Es2pandaLibApi.ignored_info['methods']['call_class']&.each do |call_class| - return false if (call_class['name'] == class_name) + return false if call_class['name'] == class_name end return false unless Es2pandaLibApi.check_template_type_presents(field.type) - return true + + true end def get_return_expr(return_type, call_cast, consts, method, args, function_type) raise 'Unsupported function type' unless %w[method struct_getter].include?(function_type) + return_expr = '' const, const_return = consts @@ -865,18 +934,18 @@ module Es2pandaLibApi return_expr end - def check_for_same_class_name() + def check_for_same_class_name res = false class_name_for_check = class_name - Es2pandaLibApi.classes&.each do |namespace_name, namespace_classes| + Es2pandaLibApi.classes&.each do |_namespace_name, namespace_classes| res |= namespace_classes&.find { |_name, data| data != self && _name == class_name_for_check } end - return res + res end def get_new_method_name(function_overload, name, const, skip_namespace_overload = false) - function_name = if (check_for_same_class_name && !skip_namespace_overload) then class_base_namespace.capitalize - else '' end + name + (const != '' ? 'Const' : '') + function_name = if check_for_same_class_name && !skip_namespace_overload then class_base_namespace.capitalize + else '' end + name + (const != '' ? 'Const' : '') overload_name = function_name if function_overload.include?(function_name) @@ -912,6 +981,7 @@ module Es2pandaLibApi usings = usings_map methods = dig(:methods) return res unless methods + template_extends.each do |template_extend| methods += Es2pandaLibApi.classes['ir'][template_extend]['methods'] end @@ -1014,13 +1084,12 @@ module Es2pandaLibApi @type_stat_log = false def log(debug_level, *args) - if debug_level == 'info' && @info_log print args.join('').to_s elsif debug_level == 'debug' && @debug_log print args.join('').to_s elsif debug_level == 'warning' && @warning_log - print "WARNING:[e2p_api_generator]: #{args.join('').to_s}" + print "WARNING:[e2p_api_generator]: #{args.join('')}" elsif debug_level == 'backtrace' && @backtrace_log print args.join('').to_s elsif debug_level == 'stat' && @stat_log @@ -1062,11 +1131,11 @@ module Es2pandaLibApi return false unless Es2pandaLibApi.allowed_info['template_types'].include?(template_arg.type.name) if template_arg.type.respond_to?('template_args') - Es2pandaLibApi.log('warning', "Unexpected nested template args in type!"); + Es2pandaLibApi.log('warning', 'Unexpected nested template args in type!') return false end end - return true + true end def check_class_type(class_name, class_base_namespace) @@ -1097,9 +1166,13 @@ module Es2pandaLibApi type = 'AST Verifier functions' elsif class_base_namespace == 'util' type = 'Import path manager' + elsif class_base_namespace == 'gen' + type = 'Compiler options' + elsif class_base_namespace == 'es2panda' + type = 'Arkts config' else - raise "Unsupported class type for stats class name: \"" + - class_name + "\" class namespace: \"" + class_base_namespace + "\"" + raise 'Unsupported class type for stats class name: "' + + class_name + '" class namespace: "' + class_base_namespace + '"' end type end @@ -1127,17 +1200,13 @@ module Es2pandaLibApi def stat_add_method(support, class_name, class_base_namespace, func_new_name) @all_methods += 1 @supported_methods += support - if support == 1 - stat_add_method_type(class_name, class_base_namespace, func_new_name) - end + stat_add_method_type(class_name, class_base_namespace, func_new_name) if support == 1 end def stat_add_constructor(support, class_name, class_base_namespace, constructor_new_name) @all_constructors += 1 @supported_constructors += support - if support == 1 - stat_add_constructor_type(class_name, class_base_namespace, constructor_new_name) - end + stat_add_constructor_type(class_name, class_base_namespace, constructor_new_name) if support == 1 end def stat_add_class(support, class_name) @@ -1159,8 +1228,7 @@ module Es2pandaLibApi "#{(@supported_constructors / @all_constructors * 100).round(2)} % )\n"\ " - Classes: #{@classes_with_supported_constructor.size} / #{@all_classes.size} ( "\ "#{(@classes_with_supported_constructor.size.to_f / @all_classes.size * 100).round(2)} % )\n"\ - "--------------\n" - ) + "--------------\n") end def ast_variables @@ -1207,6 +1275,9 @@ module Es2pandaLibApi CheckMessage Program ImportPathManager + Options + ArkTsConfig + Path ] end @@ -1231,7 +1302,7 @@ module Es2pandaLibApi end def template_extends_classes - %w[Annotated Typed AnnotationAllowed] + %w[Annotated Typed AnnotationAllowed JsDocAllowed] end def primitive_types @@ -1306,6 +1377,11 @@ module Es2pandaLibApi es2panda_AstVerifier es2panda_VerifierMessage es2panda_ImportPathManager + es2panda_Options + es2panda_Path + es2panda_OverloadInfo + es2panda_JsDocRecord + es2panda_JsDocInfo ] end @@ -1334,9 +1410,10 @@ module Es2pandaLibApi def extends_to_idl(extends) return nil unless extends && !extends.include?(',') + if extends.include?('std::') - Es2pandaLibApi.log('warning', "Unsupported inheritance from '#{extends}'\n") - return nil + Es2pandaLibApi.log('warning', "Unsupported inheritance from '#{extends}'\n") + return nil end extends.gsub(/[<>]/, ' ').split.last.split('::').last @@ -1345,12 +1422,26 @@ module Es2pandaLibApi def template_extends(extends) res = [] return res unless extends + template_extends_classes.each do |extend| res << extend if extends.include?(extend) end res end + def extract_classes_in_namespace(data, namespace_name, &is_class_needed) + @classes[namespace_name] = {} unless @classes[namespace_name] + data[namespace_name]&.class_definitions&.each do |class_definition| + if is_class_needed.call(class_definition.name) + class_data = ClassData.new(class_definition&.public) + class_data.class_base_namespace = namespace_name + class_data.extends_classname = extends_to_idl(class_definition.extends) + class_data.template_extends = [] + @classes[namespace_name][class_definition.name] = class_data + end + end + end + def wrap_data(data) return unless data @@ -1405,55 +1496,23 @@ module Es2pandaLibApi class_data.template_extends = template_extends(class_definition.extends) flag_name = @ast_node_mapping.find { |elem| elem[1] == class_definition.name }&.first class_data.ast_node_type_value = Enums.get_astnodetype_value(flag_name) - @classes['ir'][class_definition.name] = class_data - end - - @classes['checker'] = {} unless @classes['checker'] - data['checker']&.class_definitions&.each do |class_definition| - if @ast_types.include?(class_definition.name) || ast_type_additional_children.include?(class_definition.name) || - additional_classes_to_generate.include?(class_definition.name) - class_data = ClassData.new(class_definition&.public) - class_data.class_base_namespace = 'checker' - class_data.extends_classname = extends_to_idl(class_definition.extends) - class_data.template_extends = [] - @classes['checker'][class_definition.name] = class_data - end - end - - @classes['varbinder'] = {} unless @classes['varbinder'] - data['varbinder']&.class_definitions&.each do |class_definition| - if scopes.include?(class_definition.name) || declarations.include?(class_definition.name) || - ast_variables.find { |x| x[1] == class_definition.name } || - additional_classes_to_generate.include?(class_definition.name) - class_data = ClassData.new(class_definition&.public) - class_data.class_base_namespace = 'varbinder' - class_data.extends_classname = extends_to_idl(class_definition.extends) - class_data.template_extends = [] - @classes['varbinder'][class_definition.name] = class_data - end - end + next if class_definition.name == 'NumberLiteral' # it is defined manually - @classes['parser'] = {} unless @classes['parser'] - data['parser']&.class_definitions&.each do |class_definition| - if additional_classes_to_generate.include?(class_definition.name) - class_data = ClassData.new(class_definition&.public) - class_data.class_base_namespace = 'parser' - class_data.extends_classname = extends_to_idl(class_definition.extends) - class_data.template_extends = [] - @classes['parser'][class_definition.name] = class_data - end + @classes['ir'][class_definition.name] = class_data end - @classes['util'] = {} unless @classes['util'] - data['util']&.class_definitions&.each do |class_definition| - if additional_classes_to_generate.include?(class_definition.name) - class_data = ClassData.new(class_definition&.public) - class_data.class_base_namespace = 'util' - class_data.extends_classname = extends_to_idl(class_definition.extends) - class_data.template_extends = [] - @classes['util'][class_definition.name] = class_data - end - end + extract_classes_in_namespace(data, 'checker') { |class_name| + @ast_types.include?(class_name) || ast_type_additional_children.include?(class_name) || + additional_classes_to_generate.include?(class_name) + } + extract_classes_in_namespace(data, 'varbinder') { |class_name| + scopes.include?(class_name) || declarations.include?(class_name) || + ast_variables.find { |x| x[1] == class_name } || additional_classes_to_generate.include?(class_name) + } + extract_classes_in_namespace(data, 'parser') { |class_name| additional_classes_to_generate.include?(class_name) } + extract_classes_in_namespace(data, 'util') { |class_name| additional_classes_to_generate.include?(class_name) } + extract_classes_in_namespace(data, 'gen') { |class_name| additional_classes_to_generate.include?(class_name) } + extract_classes_in_namespace(data, 'es2panda') { |class_name| additional_classes_to_generate.include?(class_name) } @classes['ast_verifier'] = {} unless @classes['ast_verifier'] data['ast_verifier']&.class_definitions&.each do |class_definition| @@ -1472,7 +1531,7 @@ module Es2pandaLibApi :additional_classes_to_generate, :ast_type_additional_children, :scopes, :ast_variables, :deep_to_h, :no_usings_replace_info, :declarations, :check_template_type_presents, :structs, :additional_containers, :stat_add_constructor_type, :stat_add_method_type, :check_class_type, - :extends_to_idl, :template_extends, :template_extends_classes + :extends_to_idl, :template_extends, :template_extends_classes, :extract_classes_in_namespace end def Gen.on_require(data) diff --git a/ets2panda/public/es2panda_lib_impl.inc.erb b/ets2panda/public/es2panda_lib_impl.inc.erb index c2aece82c3b31f532dac76bb83bd472ac06ac82e..e2ecc211727769deef7456b20c04ab0633f0e68c 100644 --- a/ets2panda/public/es2panda_lib_impl.inc.erb +++ b/ets2panda/public/es2panda_lib_impl.inc.erb @@ -186,7 +186,7 @@ char const *AstNodeName(es2panda_AstNode *ast) return "Unknown AstNode"; } -// NOLINTBEGIN(performance-for-range-copy) +// NOLINTBEGIN(performance-for-range-copy, readability-identifier-naming) % Es2pandaLibApi::classes&.each do |namespaceName, namespaceClasses| % namespaceClasses&.each do |className, classData| @@ -306,5 +306,5 @@ then structData.call_cast["call_var_str"] end %>/*return_args:*/<%= method_info[ % Es2pandaLibApi::print_stats -// NOLINTEND(performance-for-range-copy) +// NOLINTEND(performance-for-range-copy, readability-identifier-naming) // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-non-const-parameter) \ No newline at end of file diff --git a/ets2panda/public/headers_parser/cpp_parser.py b/ets2panda/public/headers_parser/cpp_parser.py index e69579d3cf1d9cb5aadee0dd9d29ff010f0f7938..7d33d64f9814056a0f12da273871a0831d4b31c2 100644 --- a/ets2panda/public/headers_parser/cpp_parser.py +++ b/ets2panda/public/headers_parser/cpp_parser.py @@ -58,6 +58,10 @@ class CppParser: elif self.it.is_template(): self.it.end, self.template = parse_template_prefix(self.it.data, self.it.start) + elif self.it.is_using(): + self.it.end, self.parsed = parse_using(self.it.data, self.it.start) + self.res_append_in_modifier("usings") + elif self.it.is_namespace(): self.it.end, self.parsed = parse_namespace(self.it.data, self.it.start) self.res_update() @@ -70,10 +74,6 @@ class CppParser: self.it.end, self.parsed = parse_struct(self.it.data, self.it.start) self.res_append("structs") - elif self.it.is_using(): - self.it.end, self.parsed = parse_using(self.it.data, self.it.start) - self.res_append_in_modifier("usings") - elif self.it.is_define_macro(): self.it.end, self.parsed = parse_define_macros(self.it.data, self.it.start) self.res_append("macros") @@ -130,10 +130,10 @@ class CppParser: return raise RuntimeError("Unreachable") - if key not in self.res[self.current_modifier]: # CC-OFF(G.TYP.07) dict key exist - self.res[self.current_modifier][key] = [] # CC-OFF(G.TYP.07) dict key exist + if key not in self.res[self.current_modifier]: # CC-OFF(G.TYP.07) dict key exist + self.res[self.current_modifier][key] = [] # CC-OFF(G.TYP.07) dict key exist - self.res[self.current_modifier][key].append(deep_copy(self.parsed)) # CC-OFF(G.TYP.07) dict key exist + self.res[self.current_modifier][key].append(deep_copy(self.parsed)) # CC-OFF(G.TYP.07) dict key exist def res_update(self) -> None: if self.parsed: @@ -165,11 +165,11 @@ class CppParser: return # Constructor - if self.parsed["name"] == self.parent_class_name: # CC-OFF(G.TYP.07) dict key exist + if self.parsed["name"] == self.parent_class_name: # CC-OFF(G.TYP.07) dict key exist self.res_append_in_modifier("constructors") # Destructor - elif self.parsed["name"] == "~" + self.parent_class_name: # CC-OFF(G.TYP.07) dict key exist + elif self.parsed["name"] == "~" + self.parent_class_name: # CC-OFF(G.TYP.07) dict key exist self.res_append_in_modifier("destructors") # Method diff --git a/ets2panda/public/headers_parser/line_iterator.py b/ets2panda/public/headers_parser/line_iterator.py index 1a66aa5bc94d206b01e61d58faea4c21a5140f71..734799fb449982aa0e43caf2d2d6d364bd371b27 100644 --- a/ets2panda/public/headers_parser/line_iterator.py +++ b/ets2panda/public/headers_parser/line_iterator.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # coding=utf-8 # -# 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 @@ -61,9 +61,10 @@ class LineIterator: # pylint: disable=C0115 def is_skip_line(self) -> bool: return ( - self.current_line.find("#ifndef") != -1 + self.current_line.find("#if") != -1 # if, ifdef, ifndef + or self.current_line.find("#el") != -1 # else, elif or self.current_line.find("#undef") != -1 - or self.current_line.find("#endif") != -1 + or self.current_line.find("#end") != -1 ) def is_template(self) -> bool: @@ -79,7 +80,11 @@ class LineIterator: # pylint: disable=C0115 return self.current_line.find("struct ") != -1 def is_using(self) -> bool: - return self.current_line.find("using ") != -1 + return ( + self.current_line.find("using ") != -1 + or self.current_line.find("namespace ") != -1 + and self.current_line.find("=") != -1 + ) def is_define_macro(self) -> bool: return self.current_line.find("#define ") != -1 diff --git a/ets2panda/public/headers_parser/parse_using.py b/ets2panda/public/headers_parser/parse_using.py index 3287f616186fb19052e3da1e4bd034c0fe6b6dd4..7db27fbf23e13fe704bf5cb107ddf6e097b1be05 100644 --- a/ets2panda/public/headers_parser/parse_using.py +++ b/ets2panda/public/headers_parser/parse_using.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # coding=utf-8 # -# 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 @@ -23,7 +23,19 @@ from parse_arguments import parse_type def parse_using(data: str, start: int = 0) -> Tuple[int, Dict]: res: Dict[str, Any] = {} - start_of_name = find_first_not_restricted_character(" ", data, data.find("using ", start) + len("using ")) + using_pos = data.find("using ", start) + if using_pos == -1: + using_pos = len(data) + + namespace_pos = data.find("namespace ", start) + if namespace_pos == -1: + namespace_pos = len(data) + + if using_pos < namespace_pos: + start_of_name = find_first_not_restricted_character(" ", data, using_pos + len("using ")) + else: + start_of_name = find_first_not_restricted_character(" ", data, namespace_pos + len("namespace ")) + end_of_name = find_first_of_characters(" =;\n", data, start_of_name) res["name"] = data[start_of_name:end_of_name] @@ -38,6 +50,6 @@ def parse_using(data: str, start: int = 0) -> Tuple[int, Dict]: var_end = len(data) value = parse_type(data[var_start:var_end].strip(" ;=")) - res["type"] = value # NOTE(morlovsky): Not doing res["value"] = parse_argument(value) + res["type"] = value # NOTE(morlovsky): Not doing res["value"] = parse_argument(value) return var_end, res diff --git a/ets2panda/public/headers_parser/supported_types.py b/ets2panda/public/headers_parser/supported_types.py index 50b417c028e573f5c1e4974df1e05cecad6fee5d..be10e6eb989b06f89d3a2769433e6efdf34dd94c 100644 --- a/ets2panda/public/headers_parser/supported_types.py +++ b/ets2panda/public/headers_parser/supported_types.py @@ -89,7 +89,6 @@ ast_nodes_supported = [ "ETSTypeReferencePart", "ETSUnionType", "ETSKeyofType", - "ETSLaunchExpression", "ETSNewArrayInstanceExpression", "ETSNewMultiDimArrayInstanceExpression", "ETSNewClassInstanceExpression", @@ -175,7 +174,6 @@ ast_nodes_supported = [ ] all_types_supported = [ - # Cpp types "char", "short", @@ -187,7 +185,6 @@ all_types_supported = [ "long double", "bool", "void", - # enums "AstNodeFlags", "BoxingUnboxingFlags", @@ -196,7 +193,6 @@ all_types_supported = [ "TSOperatorType", "MappedOption", "PrivateFieldKind", - # astType "Type", "ArrayType", @@ -247,7 +243,6 @@ all_types_supported = [ "TupleType", "ObjectLiteralType", "InterfaceType", - # Variable "Variable", "LocalVariable", @@ -257,7 +252,6 @@ all_types_supported = [ "NamespaceVariable", "ImportEqualsVariable", "EnumLiteralVariable", - # others "StringView", "ArenaAllocator", @@ -300,14 +294,17 @@ def is_method_supported(function: dict) -> bool: def need_to_gen(function: dict) -> bool: if "postfix" in function: - for ban in no_gen_keywords["postfix"]: # CC-OFF(G.TYP.07) dict key exist + for ban in no_gen_keywords["postfix"]: # CC-OFF(G.TYP.07) dict key exist if function["postfix"].find(ban) != -1: return False - for name_start in no_gen_keywords["name_starts_with"]: # CC-OFF(G.TYP.07) dict key exist + for name_start in no_gen_keywords["name_starts_with"]: # CC-OFF(G.TYP.07) dict key exist if function["name"].startswith(name_start): return False if "return_type" in function: - for ban in no_gen_keywords["return_type"]: # CC-OFF(G.TYP.07) dict key exist - if "name" in function["return_type"] and function["return_type"]["name"].find(ban) != -1: + for ban in no_gen_keywords["return_type"]: # CC-OFF(G.TYP.07) dict key exist + if ( + "name" in function["return_type"] + and function["return_type"]["name"].find(ban) != -1 + ): return False return True diff --git a/ets2panda/public/ignoredAllowed.yaml b/ets2panda/public/ignoredAllowed.yaml index 0833906292d9910c4fc59a410fc794004411f57d..ec92b68d4549a4df1b0aca010da5aeb809d6c77e 100644 --- a/ets2panda/public/ignoredAllowed.yaml +++ b/ets2panda/public/ignoredAllowed.yaml @@ -104,7 +104,12 @@ ignored_list: - name: ScriptExtension - name: function namespace: std + - name: path + namespace: fs - name: ImportData + - name: PathsMap + - name: Level + namespace: Logger # Method and constructors will not be generated if c++ postfix contains any element listed below @@ -181,8 +186,11 @@ ignored_list: name: function namespace: std - type: - name: Path - namespace: 'util' + name: DiagnosticMessageParams + namespace: util + - type: + name: PandArgParser + namespace: gen - type: name: T - type: @@ -242,3 +250,5 @@ allowed_list: - ClassDefinition - StringView - TypeNode + - ArkTsConfig + - JsDocInfo diff --git a/ets2panda/public/public.cpp b/ets2panda/public/public.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b3754328b24bec031f0deeb8d601690722e2dca --- /dev/null +++ b/ets2panda/public/public.cpp @@ -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. + */ + +#include "public/public.h" +#include "compiler/lowering/phase.h" + +namespace ark::es2panda::public_lib { + +checker::Checker *Context::GetChecker() const +{ + return checkers_[compiler::GetPhaseManager()->GetCurrentMajor()]; +} + +checker::SemanticAnalyzer *Context::GetAnalyzer() const +{ + return analyzers_[compiler::GetPhaseManager()->GetCurrentMajor()]; +} + +} // namespace ark::es2panda::public_lib diff --git a/ets2panda/public/public.h b/ets2panda/public/public.h index 9c04354d321061de2385329ee45981090dc6aeda..46ddf91b4cf5295d74d5a601958c7b5ac833a853 100644 --- a/ets2panda/public/public.h +++ b/ets2panda/public/public.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_PUBLIC_PUBLIC_H #define ES2PANDA_PUBLIC_PUBLIC_H +#include #include "public/es2panda_lib.h" #include "assembler/assembly-program.h" @@ -24,6 +25,7 @@ #include "compiler/core/compileQueue.h" #include "parser/ETSparser.h" #include "checker/checker.h" +#include "checker/IsolatedDeclgenChecker.h" #include "compiler/core/emitter.h" namespace ark::es2panda::util { @@ -31,36 +33,186 @@ class Options; } // namespace ark::es2panda::util namespace ark::es2panda::compiler { -class Phase; +class PhaseManager; +void SetPhaseManager(PhaseManager *phaseManager); +PhaseManager *GetPhaseManager(); } // namespace ark::es2panda::compiler namespace ark::es2panda::public_lib { + +enum class CompilingState : unsigned int { + NONE_COMPILING = 0, + SINGLE_COMPILING = 1, + MULTI_COMPILING_INIT = 2, + MULTI_COMPILING_FOLLOW = 3, +}; + struct ConfigImpl { const util::Options *options = nullptr; util::DiagnosticEngine *diagnosticEngine = nullptr; - std::vector diagnosticKindStorage; + std::list diagnosticKindStorage; +}; + +using ExternalSources = std::unordered_map>; +using ExternalSource = ArenaUnorderedMap>; +using ComputedAbstracts = + ArenaUnorderedMap, ArenaUnorderedSet>>; + +class TransitionMemory { +public: + explicit TransitionMemory(ThreadSafeArenaAllocator *allocator) + : permanentAllocator_(allocator), compiledPrograms_(allocator->Adapter()) + { + compiledPrograms_ = {}; + } + + NO_COPY_SEMANTIC(TransitionMemory); + DEFAULT_MOVE_SEMANTIC(TransitionMemory); + + ~TransitionMemory() = default; + + ThreadSafeArenaAllocator *PermanentAllocator() const + { + return permanentAllocator_.get(); + } + + const varbinder::VarBinder *VarBinder() const + { + return varbinder_; + } + + varbinder::VarBinder *VarBinder() + { + return varbinder_; + } + + void SetVarBinder(varbinder::VarBinder *varbinder) + { + varbinder_ = varbinder; + } + + const checker::GlobalTypesHolder *GlobalTypes() const + { + return globalTypes_; + } + + checker::GlobalTypesHolder *GlobalTypes() + { + return globalTypes_; + } + + void SetGlobalTypes(checker::GlobalTypesHolder *globalTypes) + { + globalTypes_ = globalTypes; + } + + void AddCompiledProgram(parser::Program *program) + { + compiledPrograms_.push_back(program); + } + + ArenaVector &CompiledSources() + { + return compiledPrograms_; + } + + const ArenaVector &CompiledPrograms() const + { + return compiledPrograms_; + } + + const ComputedAbstracts *CachedComputedAbstracts() const + { + return cachedComputedAbstracts_; + } + + ComputedAbstracts *CachedComputedAbstracts() + { + return cachedComputedAbstracts_; + } + + void SetCachechedComputedAbstracts(ComputedAbstracts *cachedComputedAbstracts) + { + cachedComputedAbstracts_ = cachedComputedAbstracts; + } + +private: + std::unique_ptr permanentAllocator_; + ArenaVector compiledPrograms_; + varbinder::VarBinder *varbinder_ {nullptr}; + checker::GlobalTypesHolder *globalTypes_ {nullptr}; + ComputedAbstracts *cachedComputedAbstracts_ {nullptr}; +}; + +struct GlobalContext { + std::unordered_map externalProgramAllocators; + std::unordered_map cachedExternalPrograms; + ThreadSafeArenaAllocator *stdLibAllocator = nullptr; + ExternalSource *stdLibAstCache = nullptr; }; struct Context { + // NOLINTBEGIN(misc-non-private-member-variables-in-classes) using CodeGenCb = std::function; + ArenaAllocator *Allocator() const + { + return allocator; + } + + template + T *AllocNode(Args &&...args) + { + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + return util::NodeAllocator::ForceSetParent(Allocator(), std::forward(args)...); + } + + checker::Checker *GetChecker() const; + + void PushChecker(checker::Checker *checker) + { + parserProgram->PushChecker(checker); + checkers_.push_back(checker); + } + + void DestoryCheckers() + { + for (auto item : checkers_) { + delete item; + } + } + + checker::SemanticAnalyzer *GetAnalyzer() const; + + void PushAnalyzer(checker::SemanticAnalyzer *analyzer) + { + return analyzers_.push_back(analyzer); + } + + void DestoryAnalyzers() + { + for (auto item : analyzers_) { + delete item; + } + } + ConfigImpl *config = nullptr; + GlobalContext *globalContext = nullptr; std::string sourceFileName; std::string input; SourceFile const *sourceFile = nullptr; - ArenaAllocator *allocator = nullptr; + ThreadSafeArenaAllocator *allocator = nullptr; compiler::CompileQueue *queue = nullptr; std::vector const *plugins = nullptr; - std::vector phases; std::vector contextLiterals; CodeGenCb codeGenCb; - size_t currentPhase = 0; + compiler::PhaseManager *phaseManager = nullptr; parser::Program *parserProgram = nullptr; parser::ParserImpl *parser = nullptr; - checker::Checker *checker = nullptr; - checker::SemanticAnalyzer *analyzer = nullptr; + compiler::Emitter *emitter = nullptr; pandasm::Program *program = nullptr; util::DiagnosticEngine *diagnosticEngine = nullptr; @@ -68,7 +220,20 @@ struct Context { es2panda_ContextState state = ES2PANDA_STATE_NEW; std::string errorMessage; lexer::SourcePosition errorPos; + + CompilingState compilingState {CompilingState::NONE_COMPILING}; + ExternalSources externalSources; + TransitionMemory *transitionMemory {nullptr}; + bool isExternal = false; + bool compiledByCapi = false; + checker::IsolatedDeclgenChecker *isolatedDeclgenChecker {nullptr}; + // NOLINTEND(misc-non-private-member-variables-in-classes) + +private: + std::vector checkers_; + std::vector analyzers_; }; + } // namespace ark::es2panda::public_lib #endif diff --git a/ets2panda/scripts/arkui-setup.sh b/ets2panda/scripts/arkui-setup.sh index 262db820725e53724eeb4ffb88c8a35197e619a3..4ad11ccf3adf991e0ff65fe4503293f7c64e9792 100644 --- a/ets2panda/scripts/arkui-setup.sh +++ b/ets2panda/scripts/arkui-setup.sh @@ -106,15 +106,20 @@ function do_checkout() { git checkout FETCH_HEAD || exit 1 [ -n "${patch}" ] && git apply "${patch}" } + git log -1 popd >/dev/null 2>&1 || exit 1 } -GIT_URL=https://gitee.com/rri_opensource/koala_projects.git -DEST="${DEST:-koala-sig}" +SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" +source "${SCRIPT_DIR}"/arkui.properties -do_checkout "${GIT_URL}" panda_rev_7 "${DEST}" +ARKUI_DEV_REPO="${ARKUI_DEV_REPO:-https://gitee.com/rri_opensource/koala_projects.git}" +ARKUI_DEV_BRANCH="${ARKUI_DEV_BRANCH:-master}" +ARKUI_DEST="${ARKUI_DEST:-koala-sig}" -cd "${DEST}" || exit 1 +do_checkout "${ARKUI_DEV_REPO}" "${ARKUI_DEV_BRANCH}" "${ARKUI_DEST}" + +cd "${ARKUI_DEST}" || exit 1 npm config set package-lock false npm config set strict-ssl false diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties new file mode 100644 index 0000000000000000000000000000000000000000..0cbcc384399ca9b927b8745ddac7de4204957a67 --- /dev/null +++ b/ets2panda/scripts/arkui.properties @@ -0,0 +1,3 @@ +ARKUI_DEV_REPO=https://gitee.com/rri_opensource/koala_projects.git +ARKUI_DEV_BRANCH=panda_rev_8 +ARKUI_DEST=koala-sig diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets index 096ea205fb004bcf4a6061178ffce203f27af6bc..3de018767341ea54bfa6a78c5aff26f2e82fc7bd 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets @@ -26,8 +26,8 @@ enum Size{S, M, L, XL, XXL} /* @@? 20:29 Error TypeError: Type 'int' cannot be assigned to type 'String' */ /* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 22:39 Error TypeError: Array element type 'double' is not assignable to explicit type 'int' */ -/* @@? 22:44 Error TypeError: Array element type 'double' is not assignable to explicit type 'int' */ +/* @@? 22:39 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'int' */ +/* @@? 22:44 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'int' */ /* @@? 23:28 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ -/* @@? 24:40 Error TypeError: Array element type 'Color' is not assignable to explicit type 'Size' */ -/* @@? 24:53 Error TypeError: Array element type 'Color' is not assignable to explicit type 'Size' */ +/* @@? 24:40 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ +/* @@? 24:53 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets index c0abf7fe95a0b09ba0f8c1c4b6d7a8872cd84ee3..dc97fe475cf0e40b547aaae9d3aadfb2f4f030b9 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets @@ -37,8 +37,8 @@ class B{ /* @@? 29:24 Error TypeError: Type 'int' cannot be assigned to type 'String' */ /* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 31:25 Error TypeError: Array element type 'double' is not assignable to explicit type 'int' */ -/* @@? 31:30 Error TypeError: Array element type 'double' is not assignable to explicit type 'int' */ +/* @@? 31:25 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'int' */ +/* @@? 31:30 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'int' */ /* @@? 32:24 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ -/* @@? 33:25 Error TypeError: Array element type 'Color' is not assignable to explicit type 'Size' */ -/* @@? 33:38 Error TypeError: Array element type 'Color' is not assignable to explicit type 'Size' */ +/* @@? 33:25 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ +/* @@? 33:38 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/extension_function_tests/extension_function_return_this_neg2.ets b/ets2panda/test/ast/compiler/ets/FixedArray/extension_function_tests/extension_function_return_this_neg2.ets index 95f10a69461ecf146dfd2de929a2ca091585d204..8d78af6ed5af37abd32ad3078bbe9078d8c3b36f 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/extension_function_tests/extension_function_return_this_neg2.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/extension_function_tests/extension_function_return_this_neg2.ets @@ -21,4 +21,5 @@ function f1(this : B): FixedArray { } /* @@? 19:35 Error SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct and extension functions. */ -/* @@? 20:12 Error TypeError: Type 'B' is not compatible with the enclosing method's return type 'ETSGLOBAL[]' */ +/* @@? 19:35 Error TypeError: A 'this' cannot be used as type of array. */ +/* @@? 20:12 Error TypeError: Type 'B' is not compatible with the enclosing method's return type 'FixedArray' */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/lambda_type_mismatch.ets b/ets2panda/test/ast/compiler/ets/FixedArray/lambda_type_mismatch.ets index b26ab7b8d7524fe51b312ddf160cfe5a729fe706..0a1736214bc11a78f8bd38b481a968a66f867cc8 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/lambda_type_mismatch.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/lambda_type_mismatch.ets @@ -19,6 +19,6 @@ let fob:(...args:FixedArray)=>number = (...args:FixedArray) =>{} let foc:(c:string, ...args:FixedArray)=>string = (c:number, ...args:FixedArray):string=>{} -/* @@? 16:56 Error TypeError: Type '(c: Double, ...args: double[]) => void' cannot be assigned to type '(c: String, ...args: double[]) => void' */ -/* @@? 18:48 Error TypeError: Type '(...args: double[]) => void' cannot be assigned to type '(...args: double[]) => Double' */ -/* @@? 20:58 Error TypeError: Type '(c: Double, ...args: String[]) => String' cannot be assigned to type '(c: String, ...args: double[]) => String' */ +/* @@? 16:56 Error TypeError: Type '(c: Double, ...args: FixedArray) => void' cannot be assigned to type '(c: String, ...args: FixedArray) => void' */ +/* @@? 18:48 Error TypeError: Type '(...args: FixedArray) => void' cannot be assigned to type '(...args: FixedArray) => Double' */ +/* @@? 20:58 Error TypeError: Type '(c: Double, ...args: FixedArray) => String' cannot be assigned to type '(c: String, ...args: FixedArray) => String' */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets b/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets index ba8226128ab860ae9c64be9eb88376229fbb3a85..e53edf414f6b30acaca6e1866c99198e6b8b1df5 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets @@ -26,6 +26,3 @@ function main() { let c: C = new C() c.met() } - -/* @@? 27:5 Error TypeError: Call to `met` is ambiguous */ -/* @@? 27:5 Error TypeError: Reference to met is ambiguous */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/callExpr_pos.ets b/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/callExpr_pos.ets index 8a61a46702b9e295f91100c76a9b69d2b2fcdf99..d341281cb7096819659f7507636630a144eb233c 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/callExpr_pos.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/callExpr_pos.ets @@ -26,5 +26,4 @@ foo(1.1) /* @@? 17:1 Warning Warning: Function foo with this assembly signature already declared. */ -/* @@? 23:1 Warning Warning: Detect duplicate signatures, use 'foo(..._: (Object|null|undefined)[]): void' to replace */ -/* @@? 23:5 Warning Warning: Variable 'b' is used before being assigned. */ +/* @@? 23:5 Error TypeError: Variable 'b' is used before being assigned. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets index 0d2bfd7e4df8d043ca0222e278d0e39a8e529f32..e0e6de5b51ffe2678d3d848fca04f41bf324286d 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets @@ -23,12 +23,7 @@ function main(): void { /* @@? 18:32 Error SyntaxError: Unexpected token, expected '>'. */ /* @@? 18:32 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 18:32 Error SyntaxError: Unexpected token '>'. */ -/* @@? 18:32 Error SyntaxError: Unexpected token '>'. */ -/* @@? 18:32 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 18:32 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 18:35 Error SyntaxError: Unexpected token 'number'. */ /* @@? 18:35 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 18:35 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 18:42 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:42 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:42 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:42 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:44 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets index 60e525d2b8268a32cf73a9fd50a87ac39a462437..978f7ce86d5fdc1bfd4b0808bf27313bc64853ab 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets @@ -23,13 +23,7 @@ function main(): void { /* @@? 18:40 Error SyntaxError: Unexpected token, expected '>'. */ /* @@? 18:40 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 18:40 Error SyntaxError: Unexpected token '>'. */ -/* @@? 18:40 Error SyntaxError: Unexpected token '>'. */ -/* @@? 18:40 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 18:40 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 18:43 Error SyntaxError: Unexpected token 'Int'. */ /* @@? 18:43 Error TypeError: Class name 'Int' used in the wrong context */ +/* @@? 18:43 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:49 Error SyntaxError: Unexpected token '='. */ -/* @@? 18:55 Error TypeError: Array element type '"a"' is not assignable to explicit type 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/FunctionType5.ets b/ets2panda/test/ast/compiler/ets/FunctionType5.ets index 61c3a4ea7bb439e9ad53b62e75c04e3da6f68547..f2d64bff1f6a7a665a2b3a08019fd0d7fe6aa670 100644 --- a/ets2panda/test/ast/compiler/ets/FunctionType5.ets +++ b/ets2panda/test/ast/compiler/ets/FunctionType5.ets @@ -19,4 +19,3 @@ function foo (p: number){} let cb = foo; /* @@? 19:10 Error TypeError: Overloaded method is used as value */ -/* @@? 19:10 Error TypeError: Overloaded method is used as value */ \ No newline at end of file diff --git a/ets2panda/test/parser/ets/user_defined_1.ets b/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets similarity index 72% rename from ets2panda/test/parser/ets/user_defined_1.ets rename to ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets index 14809fc3b1fc9f0862660f712be0b7a84c749bf5..3f64bda07d045c37056f9502464d36fbdcbcb0aa 100644 --- a/ets2panda/test/parser/ets/user_defined_1.ets +++ b/ets2panda/test/ast/compiler/ets/Incorrect_arrow_func.ets @@ -13,12 +13,9 @@ * limitations under the License. */ -function main() { - let float : boolean = false; - let double : boolean = false; - let byte : boolean = false; - let short : boolean = false; - let int : boolean = false; - let char : boolean = false; +let f = ()=>int {} +f() -} +/* @@? 16:13 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 16:13 Error TypeError: Unexpected return value, enclosing method return type is void. */ +/* @@? 16:17 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/compiler/ets/MultiPropertyWithSameName.ets b/ets2panda/test/ast/compiler/ets/MultiPropertyWithSameName.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c7d4737be6c08d653a939fd752b78946e9ababd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/MultiPropertyWithSameName.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. + */ + +class A { + field = "" +} + +let a: A = { + field: "1", + "field": '2', +} + +let b: A = { + field: "1", + field: "2", + "field": '3', +} + +let c: A = { + "field": '2', + "field": '3', +} + + +/* @@? 22:5 Error TypeError: An object literal cannot have multiple properties with the same name. */ +/* @@? 27:5 Error TypeError: An object literal cannot have multiple properties with the same name. */ +/* @@? 28:5 Error TypeError: An object literal cannot have multiple properties with the same name. */ +/* @@? 33:5 Error TypeError: An object literal cannot have multiple properties with the same name. */ diff --git a/ets2panda/test/ast/compiler/ets/ambient_indexer_1.ets b/ets2panda/test/ast/compiler/ets/ambient_indexer_1.ets index 15d705fa980ebc2e79b5ac484db59be776b411f7..18ef053143ca187bfd39175f2cddfeaa705280ae 100644 --- a/ets2panda/test/ast/compiler/ets/ambient_indexer_1.ets +++ b/ets2panda/test/ast/compiler/ets/ambient_indexer_1.ets @@ -22,4 +22,3 @@ declare class A { // Extra empty line special for equal position like in file "ambient_indexer_2.ets" // #23399 Error almost has not ideal position, problem in generated code /* @@? 19:5 Error TypeError: Cannot find type 'stringdd'. */ -/* @@? 19:5 Error TypeError: Cannot find type 'stringdd'. */ diff --git a/ets2panda/test/ast/compiler/ets/ambient_indexer_2.ets b/ets2panda/test/ast/compiler/ets/ambient_indexer_2.ets index 2755ade984c7f7f8c712b18660be1949c0304afa..c9c395e184ddb10beedab22dc3eb488cad068306 100644 --- a/ets2panda/test/ast/compiler/ets/ambient_indexer_2.ets +++ b/ets2panda/test/ast/compiler/ets/ambient_indexer_2.ets @@ -21,4 +21,3 @@ declare class A { // #23399 Error almost has not ideal position, problem in generated code /* @@? 19:5 Error TypeError: Cannot find type 'stringdd'. */ -/* @@? 19:5 Error TypeError: Cannot find type 'stringdd'. */ diff --git a/ets2panda/test/ast/compiler/ets/ambient_interface/declare_interface.d.ets b/ets2panda/test/ast/compiler/ets/ambient_interface/declare_interface.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb7b120e4d112e59c15ee9b61803a0475b5b6b4a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/ambient_interface/declare_interface.d.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 declare interface A { + field: T; +} diff --git a/ets2panda/test/ast/compiler/ets/ambient_interface/use_interface.ets b/ets2panda/test/ast/compiler/ets/ambient_interface/use_interface.ets new file mode 100644 index 0000000000000000000000000000000000000000..04da0b06fb01f50522fe7cf38e0846bd91dec31a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/ambient_interface/use_interface.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. + */ + +import {A} from "./declare_interface" + +class B { + /* @@ label */a: A; + + foo() { + this.a.field = "test"; + } +} + +/* @@@ label Error TypeError: Property 'a' might not have been initialized. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/Retension_invalid_params.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/Retension_invalid_params.ets new file mode 100644 index 0000000000000000000000000000000000000000..7bd3abdd3cc641f583600d29fb0eca12d125ab9b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/Retension_invalid_params.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. + */ + +@Retention(policy = "RUNTIME") +@interface Anno { + +} + +/* @@? 16:12 Error SyntaxError: Invalid value for annotation field, expected a constant literal. */ +/* @@? 16:12 Error TypeError: Invalid value for 'policy' field. The policy must be one of the following:'SOURCE', 'CLASS', or 'RUNTIME'. */ +/* @@? 16:12 Error TypeError: Unresolved reference policy */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/ambient_annotations_bad_type01.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/ambient_annotations_bad_type01.ets index a157318885402160fb0e0727b2ebbc73c9b269a7..60dcc4d0140383b1ae6b9dbb6c82999b5aff68aa 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/ambient_annotations_bad_type01.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/ambient_annotations_bad_type01.ets @@ -20,11 +20,11 @@ import * as Src from "./annotation_src" /* @@ label2 */authorAge: number = /* @@ label3 */-35.1 /* @@ label4 */testBool: boolean = /* @@ label5 */true /* @@ label6 */favorColor: Src.Color = /* @@ label7 */Src.Color.RED - /* @@ label8 */color: FixedArray = /* @@ label9 */[/* @@ label10 */Src.Color.GREEN, Src.Color.BLUE] - /* @@ label11 */reviewers: FixedArray = /* @@ label12 */["Bob", "Jim", /* @@ label13 */"Tome"] - /* @@ label14 */reviewersAge: FixedArray = /* @@ label15 */[/* @@ label16 */11, 12, 32] - /* @@ label17 */testBools: FixedArray = /* @@ label18 */[/* @@ label19 */true, true, false] - mutiArray: FixedArray> = [ + /* @@ label8 */color: Src.Color[] = /* @@ label9 */[/* @@ label10 */Src.Color.GREEN, Src.Color.BLUE] + /* @@ label11 */reviewers: string[] = /* @@ label12 */["Bob", "Jim", /* @@ label13 */"Tome"] + /* @@ label14 */reviewersAge: double[] = /* @@ label15 */[/* @@ label16 */11, 12, 32] + /* @@ label17 */testBools: boolean[] = /* @@ label18 */[/* @@ label19 */true, true, false] + mutiArray: number[][] = [ [1, 2, 3], [4, +5, 6], [7, 8, -9] diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/ambient_annotations_bad_type02.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/ambient_annotations_bad_type02.ets index 3d3d767fb3013ef42fe728ee4e1594ea2dd0bce8..9d4d6a8a2d00caf4034e0791dae2f7e10ee09f12 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/ambient_annotations_bad_type02.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/ambient_annotations_bad_type02.ets @@ -20,11 +20,11 @@ import {ClassAuthor, Color} from "./annotation_src" /* @@ label */authorAge: /* @@ label1 */int = /* @@ label2 */32 /* @@ label3 */testBool: /* @@ label4 */string = "false" /* @@ label5 */favorColor: Color - /* @@ label6 */color: FixedArray - reviewers: FixedArray = ["Bob", "Jim", "Tom"] + /* @@ label6 */color: Color[] + reviewers: string[] = ["Bob", "Jim", "Tom"] reviewersAge: int/* @@ label7 */[] = [18, 21, 32] - testBools: FixedArray = [false, true, false] - mutiArray: FixedArray> = [ + testBools: boolean[] = [false, true, false] + mutiArray: number[][] = [ [1, 2, 3], [4, +5, 6], [7, 8, -9] diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets index e58f365ee02a73373f352f846f276e2a4ac24d5c..6e6a14c6ef3fcb5d6801b66753fc64e7a80025eb 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets @@ -19,15 +19,15 @@ enum Size{S, M, L, XL, XXL} @interface MyAnno { testProperty1: string = 1 testProperty2: boolean = "false" - testProperty3: FixedArray = [1.1, 3.14] + testProperty3: int[] = [1.1, 3.14] testProperty4: Color = Size.L - testProperty5: FixedArray = [Color.GREEN, Color.BLUE] + testProperty5: Size[] = [Color.GREEN, Color.BLUE] } /* @@? 20:29 Error TypeError: Type 'int' cannot be assigned to type 'String' */ /* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 22:39 Error TypeError: Array element type 'double' is not assignable to explicit type 'int' */ -/* @@? 22:44 Error TypeError: Array element type 'double' is not assignable to explicit type 'int' */ +/* @@? 22:29 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'Int' */ +/* @@? 22:34 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'Int' */ /* @@? 23:28 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ -/* @@? 24:40 Error TypeError: Array element type 'Color' is not assignable to explicit type 'Size' */ -/* @@? 24:53 Error TypeError: Array element type 'Color' is not assignable to explicit type 'Size' */ +/* @@? 24:30 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ +/* @@? 24:43 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_type.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_type.ets index 29879dd5ee1691b31187e0d1868a28ff62e7e668..aa59307bf838dfe22ac9bb991790d5574e80bbef 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_type.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_type.ets @@ -17,10 +17,8 @@ class OtherType{} @interface MyAnno { /* @@ label */testProperty1: OtherType; - /* @@ label1 */testProperty2: Array; - /* @@ label2 */testProperty3: [int ,number, string] + /* @@ label1 */testProperty3: [int ,number, string] } /* @@@ label Error TypeError: Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for annotation fields. */ -/* @@@ label1 Error TypeError: Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for annotation fields. */ -/* @@@ label2 Error TypeError: Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for annotation fields. */ \ No newline at end of file +/* @@@ label1 Error TypeError: Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for annotation fields. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type01.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type01.ets index fdb3b51c40498b1ef83794b1949bd913e97c8b47..861565a709b38982a256471866ab7299ac288c1f 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type01.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type01.ets @@ -19,4 +19,3 @@ let a = new MyAnno() /* @@? 19:13 Error TypeError: Annotations cannot be used as a type. */ -/* @@? 19:13 Error TypeError: Annotations cannot be used as a type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type09.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type09.ets index c29879f9c5f91ab43e1cf0aa8d5e2279a6369890..0aaa1cd95c12b46781c38e8fe04323d9b3e4cfbf 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type09.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type09.ets @@ -19,4 +19,3 @@ let a = 1 as MyAnno /* @@? 19:14 Error TypeError: Annotations cannot be used as a type. */ -/* @@? 19:14 Error TypeError: Annotations cannot be used as a type. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets index 09e201db4e66456a897ea0610492e2ee2808dd88..6c78910e89c339f98bea2f7de6e023ce47f16e85 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets @@ -20,5 +20,3 @@ let a = 1 instanceof MyAnno /* @@? 19:22 Error TypeError: Annotations cannot be used as a type. */ /* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ -/* @@? 19:22 Error TypeError: Annotations cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type11.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type11.ets index b1fb66925690b64d0e0c69b37100ec39ac6f2ab9..1d1235096c154b8e474dc25b3597b96f2a70c553 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type11.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type11.ets @@ -19,4 +19,3 @@ let a = MyAnno.a /* @@? 19:9 Error TypeError: Annotation missing '@' symbol before annotation name. */ -/* @@? 19:9 Error TypeError: Annotation missing '@' symbol before annotation name. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type12.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type12.ets index c44a9295afc25de584c2d60e7186f598ba3ee4c1..ed071143292c2638f8ee876afc66d756c09ee89d 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type12.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type12.ets @@ -20,5 +20,3 @@ let a = /* @@ label */MyAnno /* @@@ label Error TypeError: Annotation missing '@' symbol before annotation name. */ /* @@@ label Error TypeError: Annotation name 'MyAnno' used in the wrong context */ -/* @@@ label Error TypeError: Annotation missing '@' symbol before annotation name. */ -/* @@@ label Error TypeError: Annotation name 'MyAnno' used in the wrong context */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets index fbf5947300071ae087db8f84b85d4ea7d1cf0c3c..ba05db9e1354c3cbd4356e5eca2529fe64a20e5d 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets @@ -16,9 +16,9 @@ @interface MyAnno { testProperty1: string testProperty2: boolean - testProperty3: FixedArray + testProperty3: int[] testProperty4: Color - testProperty5: FixedArray + testProperty5: Size[] } enum Color{GREEN, RED, BLUE} @@ -37,8 +37,8 @@ class B{ /* @@? 29:24 Error TypeError: Type 'int' cannot be assigned to type 'String' */ /* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 31:25 Error TypeError: Array element type 'double' is not assignable to explicit type 'int' */ -/* @@? 31:30 Error TypeError: Array element type 'double' is not assignable to explicit type 'int' */ +/* @@? 31:25 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'Int' */ +/* @@? 31:30 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'Int' */ /* @@? 32:24 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ -/* @@? 33:25 Error TypeError: Array element type 'Color' is not assignable to explicit type 'Size' */ -/* @@? 33:38 Error TypeError: Array element type 'Color' is not assignable to explicit type 'Size' */ +/* @@? 33:25 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ +/* @@? 33:38 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfaceproperty.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfaceproperty.ets index 12f9a0d39f1ee9a63a2b79196555cb2709750e5e..cd013b0eafd30ae7058b13ba5406f0e0f30f9f06 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfaceproperty.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfaceproperty.ets @@ -24,5 +24,3 @@ interface itf { } /* @@? 22:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ -/* @@? 22:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ -/* @@? 22:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_variable_decl.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_variable_decl.ets index cfcdcf804ee8743b59b1774b6c49da1a081eb08d..a3d0435da084681a3f71479106fb559908b98a97 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_variable_decl.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_variable_decl.ets @@ -29,6 +29,5 @@ function main() : void { let x2 = 1, y2 = "abc" } -/* @@? 23:2 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ /* @@? 23:2 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ /* @@? 28:6 Error TypeError: Duplicate annotations are not allowed. The annotation 'MyAnno' has already been applied to this element. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_on_extension_lambda.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_on_extension_lambda.ets index 3c679ce0b6a82f1ab93feaac59402ad07a6bd620..025b88d8e8e040134856aa20c860271ac76c64c1 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_on_extension_lambda.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_duplicate_on_extension_lambda.ets @@ -22,4 +22,3 @@ let show = @Anno()@/* @@ label */Anno(this: A): string => { return "Hello," + this.name; } /* @@@ label Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ -/* @@@ label Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_interface.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_interface.ets index 604a52a56ba0b0ef4395ee388cf8a3308a530086..a5ac15f1c758258672c4dbbbb51ed6e1bc7d6472 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_interface.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_interface.ets @@ -29,5 +29,3 @@ interface itf { /* @@? 21:2 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ /* @@? 23:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ /* @@? 25:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ -/* @@? 25:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ -/* @@? 25:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_variable_decl.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_variable_decl.ets index 737ff0a53a13b01aee5d106961c336fcc783ba37..a3ac67098cce5e025339f37cc8b942c6eba46624 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_variable_decl.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_variable_decl.ets @@ -27,6 +27,5 @@ function main() : void { let x2 = 1, y2 = "abc" } -/* @@? 22:2 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ /* @@? 22:2 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ /* @@? 26:6 Error TypeError: The number of arguments provided for the annotation exceeds the number of fields defined. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_interface.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_interface.ets index 67bddf34e10e9b4ccba1b9c5c3908a20263f91c6..5e990b139a3fe68e5975d037d1653c3242a9a392 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_interface.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_interface.ets @@ -29,5 +29,3 @@ interface itf { /* @@? 21:2 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ /* @@? 23:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ /* @@? 25:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ -/* @@? 25:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ -/* @@? 25:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_variable_decl.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_variable_decl.ets index 1a62a07ba6985779ed2f6694788743ebbc949c95..f2b703a98ffe5df0506fa46315308f4bd517038b 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_variable_decl.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_variable_decl.ets @@ -27,8 +27,6 @@ function main() : void { let x2 = 1, y2 = "abc" } -/* @@? 22:2 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ -/* @@? 22:2 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ /* @@? 22:2 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ /* @@? 22:2 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ /* @@? 26:6 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_array_type01.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_array_type01.ets index 364408d6886ff7306a55b850ab84bc826b16ef68..c2bf21da691329d79896559019bb72c5d47eb9d9 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_array_type01.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_array_type01.ets @@ -18,9 +18,9 @@ } // annotations for elementType of array -let array: @Anno @Anno FixedArray> -let deepArray: @Anno @Anno FixedArray>>>> +let array: @Anno @Anno Int[][] +let deepArray: @Anno @Anno Number[][][][][] -/* @@? 21:19 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ -/* @@? 22:23 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ \ No newline at end of file +/* @@? 21:29 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ +/* @@? 22:42 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_array_type02.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_array_type02.ets index 2a5c20f0f865c73b65c033d5002cde79626373cb..557e4bc100adcc23637908e568ff5e2a3de8e67a 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_array_type02.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_array_type02.ets @@ -17,8 +17,8 @@ } // annotataions for different dimensions of array -let a: FixedArray @Anno [] +let a: Int[] @Anno [] -/* @@? 20:24 Error SyntaxError: Unexpected token '@'. */ -/* @@? 20:30 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 20:30 Error TypeError: Can't resolve array type */ +/* @@? 20:14 Error SyntaxError: Unexpected token '@'. */ +/* @@? 20:20 Error SyntaxError: Annotations are not allowed on this type of declaration. */ +/* @@? 20:20 Error TypeError: Can't resolve array type */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_function_type.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_function_type.ets index 8a10af81ea18a72fba059b4a207d0556a5d12109..1fc45026251fc64c5286765a2de5127232fc9dc9 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_function_type.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_function_type.ets @@ -26,4 +26,3 @@ let foo: @Anno @Anno (a?: @Anno @Anno string) => @Anno @Anno Int /* @@? 21:17 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ /* @@? 21:57 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ /* @@? 21:34 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ -/* @@? 21:57 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_readonly_type.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_readonly_type.ets index d64b33d1d7afc2cc55031b5d63c0b1d2a28c6111..7b02aaed57f886526c596652db455450c696e549 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_readonly_type.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_readonly_type.ets @@ -17,7 +17,7 @@ // annotations for readonly Type let readonlyArray: readonly @Anno @Anno() Int[][] -let readonlyTuple: readonly @Anno @Anno() [Int, String, Float, FixedArray] +let readonlyTuple: readonly @Anno @Anno() [Int, String, Float, Object[]] /* @@? 19:36 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ /* @@? 20:36 Error TypeError: Duplicate annotations are not allowed. The annotation 'Anno' has already been applied to this element. */ \ No newline at end of file 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 e3bb5eb3fb1b85806e7e13956f08bf0f391c32b3..e4e023e3bb7415dd532ce7ed78fe4471820ce15b 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 @@ -27,13 +27,11 @@ class A{ function foo(){} foo<@Anno T>() -/* @@? 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 SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 23:22 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 28:11 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 28:11 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 28:11 Error TypeError: Cannot find type 'T'. */ +/* @@? 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'. */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_src.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_src.ets index 426d7ba786c2b773801b471565bbaf253987996e..7c2c76398e9d23da651a16aa6ceeea528a19c290 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_src.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_src.ets @@ -20,11 +20,11 @@ export declare @interface ClassAuthor { authorAge: number = -35 testBool: boolean = false favorColor: Color = Color.BLUE - color: FixedArray = [Color.RED, Color.BLUE] - reviewers: FixedArray = ["Bob", "Jim", "Tom"] - reviewersAge: FixedArray = [18, 21, 32] - testBools: FixedArray = [false, true, false] - mutiArray: FixedArray> = [ + color: Color[] = [Color.RED, Color.BLUE] + reviewers: string[] = ["Bob", "Jim", "Tom"] + reviewersAge: number[] = [18, 21, 32] + testBools: boolean[] = [false, true, false] + mutiArray: number[][] = [ [1, 2, 3], [4, +5, 6], [7, 8, -9] diff --git a/ets2panda/test/compiler/ets/array_indexing_with_chaining_non_nullish.ets b/ets2panda/test/ast/compiler/ets/array_indexing_with_chaining_non_nullish.ets similarity index 100% rename from ets2panda/test/compiler/ets/array_indexing_with_chaining_non_nullish.ets rename to ets2panda/test/ast/compiler/ets/array_indexing_with_chaining_non_nullish.ets diff --git a/ets2panda/test/compiler/ets/array_indexing_with_chaining_nullish.ets b/ets2panda/test/ast/compiler/ets/array_indexing_with_chaining_nullish.ets similarity index 100% rename from ets2panda/test/compiler/ets/array_indexing_with_chaining_nullish.ets rename to ets2panda/test/ast/compiler/ets/array_indexing_with_chaining_nullish.ets diff --git a/ets2panda/test/ast/compiler/ets/boxingConversion1.ets b/ets2panda/test/ast/compiler/ets/boxingConversion1.ets index c4d703e4a25f9c17408d978147e9471016b71002..656ce82e1ba4b0967f0c894a649cbc255b0304d0 100644 --- a/ets2panda/test/ast/compiler/ets/boxingConversion1.ets +++ b/ets2panda/test/ast/compiler/ets/boxingConversion1.ets @@ -18,4 +18,6 @@ function main() : void { let b: Byte = /* @@ label */new Byte(2); } +/* @@@ label Error TypeError: Expected 0 arguments, got 1. */ /* @@@ label Error TypeError: No matching construct signature for std.core.Byte(int) */ +/* @@? 18:42 Error TypeError: Type 'int' is not compatible with type 'byte' at index 1 */ diff --git a/ets2panda/test/ast/compiler/ets/boxingConversion4.ets b/ets2panda/test/ast/compiler/ets/boxingConversion4.ets index 219921314be7d2169d4de6cd525622a94fefc1ed..ff64829de2438ffcabd1b87b2bccb1b4f584f0df 100644 --- a/ets2panda/test/ast/compiler/ets/boxingConversion4.ets +++ b/ets2panda/test/ast/compiler/ets/boxingConversion4.ets @@ -23,6 +23,8 @@ function main() : void { refInt(b); // primitive widening before boxing is not allowed } +/* @@@ label Error TypeError: Expected 0 arguments, got 1. */ /* @@@ label Error TypeError: No matching construct signature for std.core.Short(int) */ +/* @@? 19:44 Error TypeError: Type 'int' is not compatible with type 'short' at index 1 */ /* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type 'short' */ /* @@@ label2 Error TypeError: Type 'int' cannot be assigned to type 'short' */ diff --git a/ets2panda/test/ast/compiler/ets/circular_inheritance.ets b/ets2panda/test/ast/compiler/ets/circular_inheritance.ets new file mode 100644 index 0000000000000000000000000000000000000000..3039b89682e9263866006ecda10437ce01a462a1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/circular_inheritance.ets @@ -0,0 +1,30 @@ +/* + * 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 I1 extends I2 { + foo1():void; +} + +interface I2 extends I1 { + foo2():void; +} + +class cls implements I1 { + foo1():void {} + foo2():void {} +} + +/* @@? 16:11 Error TypeError: Cyclic inheritance involving I1. */ + diff --git a/ets2panda/test/ast/compiler/ets/circular_inheritance_class.ets b/ets2panda/test/ast/compiler/ets/circular_inheritance_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..d6f8d2deb534611f9ac63a263092579616287874 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/circular_inheritance_class.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 A extends B { + foo1():int{} +} + +class B extends A { + foo2():int{} +} + +class C extends A { + foo1(){ + return 1; + } + foo2(){ + return 2; + } +} + +/* @@? 16:7 Error TypeError: Cyclic inheritance involving A. */ + diff --git a/ets2panda/test/ast/compiler/ets/comparability_of_never_type01.ets b/ets2panda/test/ast/compiler/ets/comparability_of_never_type01.ets new file mode 100644 index 0000000000000000000000000000000000000000..02cf672e62a5a8b326cc98737d85e2f6790be9bc --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/comparability_of_never_type01.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. + */ + +const a: readonly Array> = new Array>() +const b: readonly Array> = new Array>() +const c: readonly Array> = new Array>() diff --git a/ets2panda/test/ast/compiler/ets/comparability_of_never_type02.ets b/ets2panda/test/ast/compiler/ets/comparability_of_never_type02.ets new file mode 100644 index 0000000000000000000000000000000000000000..04e270a8c1859ef8d6ec8bae8b5c8d23c159339f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/comparability_of_never_type02.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. + */ + +function foo(a:readonly Array){} +function bar(a:Array){ + foo(a) +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/comparability_of_never_type03.ets b/ets2panda/test/ast/compiler/ets/comparability_of_never_type03.ets new file mode 100644 index 0000000000000000000000000000000000000000..582677c3d48af5b87eeb019d8894a0f8454fdc68 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/comparability_of_never_type03.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. + */ + +function foo(a:readonly Array){} +function bar(a:readonly Array){ + foo(a) +} \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/constant_variable_import_tests/enum_import_constant.ets b/ets2panda/test/ast/compiler/ets/constant_variable_import_tests/enum_import_constant.ets index 96125e6d71eeec0c41907ae3178be45295af4fdb..8685ee6c0d26087365b43d6635eab628151cdc44 100644 --- a/ets2panda/test/ast/compiler/ets/constant_variable_import_tests/enum_import_constant.ets +++ b/ets2panda/test/ast/compiler/ets/constant_variable_import_tests/enum_import_constant.ets @@ -20,4 +20,4 @@ enum Color { C = /* @@ label */constVar } -/* @@@ label Error SyntaxError: Invalid enum initialization value */ \ No newline at end of file +/* @@@ label 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/compiler/ets/FixedArray/tuple_types_1_neg.ets b/ets2panda/test/ast/compiler/ets/debugger-statement.ets similarity index 74% rename from ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_1_neg.ets rename to ets2panda/test/ast/compiler/ets/debugger-statement.ets index 9d8ca3b4304ca2f177b6f8b4cd53e8bfad418ec8..0f2f52cc71b62cdcaa15bba42ed472a4e2832de4 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_1_neg.ets +++ b/ets2panda/test/ast/compiler/ets/debugger-statement.ets @@ -13,9 +13,13 @@ * limitations under the License. */ +// (arkts-no-debugger-stmt) function main(): void { - const tuple: [number, number, boolean] = [1, 3.14, true] - const array: (number|boolean) [] = tuple + for (let i = 0; i < 10; i++) + { + debugger; + console.log(i); + } } -/* @@? 18:40 Error TypeError: Type '[Double, Double, Boolean]' cannot be assigned to type '(Double|Boolean)[]' */ +/* @@? 20:9 Error SyntaxError: Debugger statement is not supported! */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/declaration_merging.ets b/ets2panda/test/ast/compiler/ets/declaration_merging.ets new file mode 100644 index 0000000000000000000000000000000000000000..b553f41948fd1da83fef303b788c009d1f0cf3c9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/declaration_merging.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// (arkts-no-decl-merging) + class C { + field: int = 0; + setField(f: int): void { + this.field = f; + } + } + + class C { + setField(s: string): void { + this.field = s.length; + } + } + +/* @@? 24:8 Error TypeError: Variable 'C' has already been declared. */ +/* @@? 24:8 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ + \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/declareType_neg_1.ets b/ets2panda/test/ast/compiler/ets/declareType_neg_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..3ba2dfbb74eb2fb78e457e85c01bc1a5dfee7b5d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_1.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 const type typeA = int; + +/* @@? 16:20 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 16:20 Error SyntaxError: Unexpected token 'typeA'. */ +/* @@? 16:20 Error TypeError: Unresolved reference typeA */ +/* @@? 16:28 Error SyntaxError: Unexpected token 'int'. */ diff --git a/ets2panda/test/ast/compiler/ets/declareType_neg_2.ets b/ets2panda/test/ast/compiler/ets/declareType_neg_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..2a64b2993b798f8eb67ec9c00adf5d859d8cea94 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_2.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 Issue { + title : string + description : string +} +declare type type_utility = Partial; + +let a : type_utility = {description : 1234} + +/* @@? 22:39 Error TypeError: Type 'int' is not compatible with type 'String|undefined' at property 'description' */ + diff --git a/ets2panda/test/ast/compiler/ets/declareType_neg_3.ets b/ets2panda/test/ast/compiler/ets/declareType_neg_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..ee618b7cbe8c02d83036de67d9bd6db5e0b1d711 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_3.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. + */ + +interface Issue { + title?: string + description?: string +} +declare type type_utility = Required; + +let a : type_utility = {title : "declare type alias test"} + + +/* @@? 22:24 Error TypeError: Class property 'description' needs to be initialized for Required. */ + diff --git a/ets2panda/test/ast/compiler/ets/declareType_neg_4.ets b/ets2panda/test/ast/compiler/ets/declareType_neg_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..76fdc63e58a654c1e154b920bab032e16ce05c35 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_4.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. + */ + +declare type type_array_1 = Array; +declare type type_array_2 = T[]; +declare type type_array_alias = Array> | type_array_2 + +let a : int[] = [1,2,3] +let b : type_array_alias = a; + + +/* @@? 21:37 Error TypeError: Type 'Array' cannot be assigned to type 'Array>|Array' */ + diff --git a/ets2panda/test/ast/compiler/ets/declareType_neg_export.ets b/ets2panda/test/ast/compiler/ets/declareType_neg_export.ets new file mode 100644 index 0000000000000000000000000000000000000000..d17bf7578aedc88d9a240439927d53ab45cb1931 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_export.ets @@ -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 default declare type typeA = T[] | Array + diff --git a/ets2panda/test/ast/compiler/ets/declareType_neg_import.ets b/ets2panda/test/ast/compiler/ets/declareType_neg_import.ets new file mode 100644 index 0000000000000000000000000000000000000000..0b54a5df0f2ab504e466b38470ddcd6e2707e4ae --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/declareType_neg_import.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. + */ +import typeA from './declareType_neg_export' +let a : typeA = new Array() + + +/* @@? 16:22 Error TypeError: Type 'Array' cannot be assigned to type 'Array' */ + diff --git a/ets2panda/test/ast/compiler/ets/default_param_tuple_infer.ets b/ets2panda/test/ast/compiler/ets/default_param_tuple_infer.ets new file mode 100644 index 0000000000000000000000000000000000000000..e2be2398aeaf5716b13ef3c9418a4c3ca7d5b2ac --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/default_param_tuple_infer.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. + */ + +type TupleAlias = [ number, string ] + +function handleTupleAlias_notCast(tuple: TupleAlias = [ 1, 'string' ]) {} +function handleTupleAdHoc_notCast(tuple: [ number, string ] = [ 1, 'string' ]) {} +function handleByte_notCast(arg: byte = 1): byte { return arg; } + +function handleTupleAlias_cast(tuple: TupleAlias = [ 1, 'string' ] as TupleAlias) {} +function handleTupleAdHoc_cast(tuple: [ number, string ] = [ 1, 'string' ] as [ number, string ]) {} +function handleByte_cast(arg: byte = 1 as byte): byte { return arg; } diff --git a/ets2panda/test/ast/compiler/ets/dynamic-field-declaration.ets b/ets2panda/test/ast/compiler/ets/dynamic-field-declaration.ets new file mode 100644 index 0000000000000000000000000000000000000000..1213452ed79f3ff389fc5fb8a009094cf82e2c2c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/dynamic-field-declaration.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 Point { + x: number = 0 + y: number = 0 +} +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 diff --git a/ets2panda/test/ast/compiler/ets/enum-mixed-types.ets b/ets2panda/test/ast/compiler/ets/enum-mixed-types.ets new file mode 100644 index 0000000000000000000000000000000000000000..456bb88409431a29e385cc77ecf07b9cfda0806f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/enum-mixed-types.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. + */ + +// (arkts-no-enum-mixed-types) + enum E { + A = 0xa, + B = 0xb, + C, + D = Math.random(), + E = "0xd", +} + +/* @@? 21:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@? 22: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/compiler/ets/enum_not_constant_var.ets b/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets index b7deb047d7dd4c8f59c3a772c07c0fb3e3e0cc33..4e8de04927902450c06edab1068f8b4189b4f64b 100644 --- a/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets +++ b/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets @@ -21,4 +21,4 @@ enum Color { } /* @@@ label Error SyntaxError: Only constant expression is expected in the field */ -/* @@@ label Error SyntaxError: Invalid enum initialization value */ +/* @@@ label 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/compiler/ets/export_and_export_type_class.ets b/ets2panda/test/ast/compiler/ets/export_and_export_type_class.ets index 36d209517b2ae58d0c5a8c33be62ef643e152268..57d8b40dda03b0dd27436131530e014f8aed9172 100644 --- a/ets2panda/test/ast/compiler/ets/export_and_export_type_class.ets +++ b/ets2panda/test/ast/compiler/ets/export_and_export_type_class.ets @@ -16,4 +16,4 @@ export class A {} export type {/* @@ label */A} -/* @@@ label Error SyntaxError: Name 'A' cannot be exported and type exported at the same time. */ +/* @@@ label Error SyntaxError: Cannot export 'A', it was already exported. */ diff --git a/ets2panda/test/ast/compiler/ets/export_and_export_type_interface.ets b/ets2panda/test/ast/compiler/ets/export_and_export_type_interface.ets index b8f2de7f9d95e46f4d8d95486faebd66840053cb..0b4bef4431094310a46587df4152ce66aec47e84 100644 --- a/ets2panda/test/ast/compiler/ets/export_and_export_type_interface.ets +++ b/ets2panda/test/ast/compiler/ets/export_and_export_type_interface.ets @@ -16,4 +16,4 @@ export interface I {} export type {/* @@ label */I} -/* @@@ label Error SyntaxError: Name 'I' cannot be exported and type exported at the same time. */ +/* @@@ label Error SyntaxError: Cannot export 'I', it was already exported. */ diff --git a/ets2panda/test/ast/compiler/ets/export_same_type_at_decl_and_selective_binding.ets b/ets2panda/test/ast/compiler/ets/export_same_type_at_decl_and_selective_binding.ets index b9201e9fffd10ef9123777425438fc56987c3a13..e566df5aae04642896e431ed25cc40269097d0df 100644 --- a/ets2panda/test/ast/compiler/ets/export_same_type_at_decl_and_selective_binding.ets +++ b/ets2panda/test/ast/compiler/ets/export_same_type_at_decl_and_selective_binding.ets @@ -17,4 +17,4 @@ export type class A {} export type {/* @@ label */A} -/* @@@ label Error SyntaxError: Cannot export the same 'A' type twice. */ +/* @@@ label Error SyntaxError: Cannot export 'A', it was already exported. */ diff --git a/ets2panda/test/ast/compiler/ets/export_type_class_multiple_times.ets b/ets2panda/test/ast/compiler/ets/export_type_class_multiple_times.ets index 16a10a56e12ba30a60d9407f152a486f238a34ff..4609849c5dd6816c3d4ec31b3166efbc84023691 100644 --- a/ets2panda/test/ast/compiler/ets/export_type_class_multiple_times.ets +++ b/ets2panda/test/ast/compiler/ets/export_type_class_multiple_times.ets @@ -17,6 +17,7 @@ class A {} export type {A} export type MyA = A -export type {/* @@ label */MyA} +export type {MyA} -/* @@@ label Error SyntaxError: Cannot export the same 'MyA' type twice. */ +/* @@? 20:14 Error SyntaxError: The given name 'MyA' is already used in another export. */ +/* @@? 20:14 Error SyntaxError: Cannot export 'MyA', it was already exported. */ diff --git a/ets2panda/test/ast/compiler/ets/export_type_enum.ets b/ets2panda/test/ast/compiler/ets/export_type_enum.ets index 2c8cef647fb480eb64455e6b453857511c44a9c9..ff49a9f828cf81fbf39c9922db0f5cbb61b7c9a9 100644 --- a/ets2panda/test/ast/compiler/ets/export_type_enum.ets +++ b/ets2panda/test/ast/compiler/ets/export_type_enum.ets @@ -15,6 +15,4 @@ enum E { A = 5, B = 5 } -export type {/* @@ label */E} - -/* @@@ label Error SyntaxError: Can only type export class or interface. */ +export type {E} diff --git a/ets2panda/test/ast/compiler/ets/export_type_function.ets b/ets2panda/test/ast/compiler/ets/export_type_function.ets index 08b0bf57bd79238250b398b39fab9e367f578c7a..f2bf3629c92f80737243820a322abd46929e3c18 100644 --- a/ets2panda/test/ast/compiler/ets/export_type_function.ets +++ b/ets2panda/test/ast/compiler/ets/export_type_function.ets @@ -17,6 +17,4 @@ function f(){ return 1; } -export type {/* @@ label */f} - -/* @@@ label Error SyntaxError: Can only type export class or interface. */ +export type {f} diff --git a/ets2panda/test/ast/compiler/ets/export_type_interface_multiple_times.ets b/ets2panda/test/ast/compiler/ets/export_type_interface_multiple_times.ets index 75369ab75ee5274861ad93e11e42521b933aa1d1..0a34b8a2ccc76dfe13ec1f5db9f8a32b69a1f350 100644 --- a/ets2panda/test/ast/compiler/ets/export_type_interface_multiple_times.ets +++ b/ets2panda/test/ast/compiler/ets/export_type_interface_multiple_times.ets @@ -17,6 +17,7 @@ interface I {} export type {I} export type MyI = I -export type {/* @@ label */MyI} +export type {MyI} -/* @@@ label Error SyntaxError: Cannot export the same 'MyI' type twice. */ +/* @@? 20:14 Error SyntaxError: The given name 'MyI' is already used in another export. */ +/* @@? 20:14 Error SyntaxError: Cannot export 'MyI', it was already exported. */ diff --git a/ets2panda/test/ast/compiler/ets/export_type_variable.ets b/ets2panda/test/ast/compiler/ets/export_type_variable.ets index 118db2c2b469c10095e531d09d91ffdffd913fe4..7c809f9e3a4ed8353dcf20ebc532f73129f5f54b 100644 --- a/ets2panda/test/ast/compiler/ets/export_type_variable.ets +++ b/ets2panda/test/ast/compiler/ets/export_type_variable.ets @@ -15,6 +15,4 @@ let a = 5; -export type {/* @@ label */a} - -/* @@@ label Error SyntaxError: Can only type export class or interface. */ +export type {a} diff --git a/ets2panda/test/ast/compiler/ets/export_type_variable_at_definition.ets b/ets2panda/test/ast/compiler/ets/export_type_variable_at_definition.ets index 757726185e6f929f29023c0acdc14ebf55f50b9d..ae99c01e8485b6c31725cba82cad649250c73a60 100644 --- a/ets2panda/test/ast/compiler/ets/export_type_variable_at_definition.ets +++ b/ets2panda/test/ast/compiler/ets/export_type_variable_at_definition.ets @@ -13,7 +13,4 @@ * limitations under the License. */ -export type /* @@ label */let a = 5; - -/* @@@ label Error SyntaxError: Can only type export class or interface. */ -/* @@@ label Error SyntaxError: Can only type export class or interface. */ +export type let a = 5; diff --git a/ets2panda/test/ast/compiler/ets/expression/this_expression/undefined_class_for_this_1.ets b/ets2panda/test/ast/compiler/ets/expression/this_expression/undefined_class_for_this_1.ets index ee5be74e6b40e7f0e0120755eb24dab8ca746a9e..4b1fd444fd52fa35d0072b01985e404dc75830c0 100644 --- a/ets2panda/test/ast/compiler/ets/expression/this_expression/undefined_class_for_this_1.ets +++ b/ets2panda/test/ast/compiler/ets/expression/this_expression/undefined_class_for_this_1.ets @@ -23,14 +23,9 @@ let fecthResult = await checkAsyncDelay(async (): Promise< AA.B > => { return await this.photoAccessHelper.getAssets(options); }, 'getPhotoAssetByUri --> getAssets'); -/* @@? 19:25 Error TypeError: Unresolved reference checkAsyncDelay */ -/* @@? 19:25 Error TypeError: 'await' expressions require Promise object as argument. */ /* @@? 19:25 Error TypeError: Unresolved reference checkAsyncDelay */ /* @@? 19:25 Error TypeError: 'await' expressions require Promise object as argument. */ /* @@? 20:10 Error TypeError: Bad operand type, the type of the operand must be boolean type. */ /* @@? 21:16 Error TypeError: Type 'undefined' is not compatible with the enclosing method's return type 'Promise>' */ /* @@? 23:18 Error TypeError: 'await' expressions require Promise object as argument. */ /* @@? 1:1 Error TypeError: Cannot reference 'this' in this context. */ -/* @@? 20:10 Error TypeError: Bad operand type, the type of the operand must be boolean type. */ -/* @@? 23:18 Error TypeError: 'await' expressions require Promise object as argument. */ -/* @@? 1:1 Error TypeError: Cannot reference 'this' in this context. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/expression/this_expression/undefined_class_for_this_2.ets b/ets2panda/test/ast/compiler/ets/expression/this_expression/undefined_class_for_this_2.ets index f4d7bcf939fed879674872660b83e5d752635ba7..388f3e55c980d29f40ca316cf9ed6241617aa12e 100644 --- a/ets2panda/test/ast/compiler/ets/expression/this_expression/undefined_class_for_this_2.ets +++ b/ets2panda/test/ast/compiler/ets/expression/this_expression/undefined_class_for_this_2.ets @@ -17,6 +17,4 @@ }) /* @@? 15:11 Error TypeError: Unresolved reference ca */ - /* @@? 15:11 Error TypeError: Unresolved reference ca */ - /* @@? 1:1 Error TypeError: Cannot reference 'this' in this context. */ /* @@? 1:1 Error TypeError: Cannot reference 'this' in this context. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets index df828b5b4043b7892e177c270a41cb4d075cbf85..ce04738954f909eec61ab7a417b29fbcc22d1ce5 100644 --- a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets +++ b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets @@ -30,4 +30,3 @@ set name/* @@ label2 */(this: B, n: string) { /* @@@ label1 Error TypeError: Function name with this assembly signature already declared. */ /* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets index df828b5b4043b7892e177c270a41cb4d075cbf85..ce04738954f909eec61ab7a417b29fbcc22d1ce5 100644 --- a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets +++ b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets @@ -30,4 +30,3 @@ set name/* @@ label2 */(this: B, n: string) { /* @@@ label1 Error TypeError: Function name with this assembly signature already declared. */ /* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionGetterOnly.sts b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionGetterOnly.ets similarity index 100% rename from ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionGetterOnly.sts rename to ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionGetterOnly.ets diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionGetterOnly2.sts b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionGetterOnly2.ets similarity index 100% rename from ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionGetterOnly2.sts rename to ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionGetterOnly2.ets diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionSetterOnly.sts b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionSetterOnly.ets similarity index 100% rename from ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionSetterOnly.sts rename to ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionSetterOnly.ets diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionSetterOnly2.sts b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionSetterOnly2.ets similarity index 100% rename from ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionSetterOnly2.sts rename to ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionSetterOnly2.ets diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/array_extension_func_dupicated_name_with_builtin.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/array_extension_func_dupicated_name_with_builtin.ets index 743b958ad8d14f890fe206eee897e3f88da10d67..5f973b3f44f310419aa440d90ad94bf59e8a0074 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/array_extension_func_dupicated_name_with_builtin.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/array_extension_func_dupicated_name_with_builtin.ets @@ -17,4 +17,5 @@ function toString(this: double[]) /* @@ label */{ return "ext-func" } -/* @@@ label Error TypeError: The extension function 'toString' has the same name with public method in class Object */ +/* @@? 16:49 Error TypeError: The extension function 'toString' has the same name with public method in class Array */ +/* @@? 16:49 Error TypeError: The extension function 'toString' has the same name with public method in class Object */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets index a40c3a1069bf44d9132e8496caa134cbb684b294..4ce3aa69d463542459e921bbb5c5f6aecacd63a6 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets @@ -28,4 +28,4 @@ function main() { console.println(/* @@label */banana.name(2)); } -/* @@@ label Error TypeError: No matching call signature for name(int) */ +/* @@? 28:34 Error TypeError: No matching call signature for name(int) */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets index 8f4bc74639125ea1e604b87980abcc2a80482418..e35530840d96f946bc7d373a46feb7c8434035d7 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets @@ -39,6 +39,6 @@ function main() { asMethodCall(); } -/* @@? 30:5 Error TypeError: Expected 2 arguments, got 3. */ -/* @@? 30:5 Error TypeError: No matching call signature for foo(Fruit, double, double) */ -/* @@? 34:5 Error TypeError: No matching call signature for foo(double, double) */ +/* @@? 30:5 Error TypeError: Expected 2 arguments, got 3. */ +/* @@? 30:5 Error TypeError: No matching call signature for foo(Fruit, double, double) */ +/* @@? 34:5 Error TypeError: No matching call signature for foo(double, double) */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg2.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg2.ets index 852e0b732e1d07d19e1f42104a8b29b3ae479f39..e0e2bf5db7fccc506b67db6f0367f13a4ec63ffb 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg2.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg2.ets @@ -21,4 +21,4 @@ function f1(this : B): /* @@ label*/this[] { } /* @@@ label Error SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct and extension functions. */ -/* @@? 20:12 Error TypeError: Type 'B' is not compatible with the enclosing method's return type 'ETSGLOBAL[]' */ +/* @@? 20:12 Error TypeError: Type 'B' is not compatible with the enclosing method's return type 'Array' */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union.ets index 227c44ca6ebf354d25f6bfdb88274e2b7ade0512..c3776e2b05917273baf9fe26eefbed5f73f96dee 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union.ets @@ -20,5 +20,5 @@ function f1(this : B): /* @@ label*/this | A { return this; } /* @@@ label Error SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct and extension functions. */ +/* @@? 19:37 Error TypeError: A 'this' cannot be used as a part of union type. */ /* @@? 20:12 Error TypeError: Type 'B' is not compatible with the enclosing method's return type 'ETSGLOBAL|A' */ - diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union2.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union2.ets index 05f4e6b1cff6e7488a27904c68d9bf836d0b2101..05f1930cee0c9306d8164c966c82480a797edfa0 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union2.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union2.ets @@ -19,3 +19,4 @@ function f1(this : B): /* @@ label*/this | B { return this; } /* @@@ label Error SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct and extension functions. */ +/* @@? 18:37 Error TypeError: A 'this' cannot be used as a part of union type. */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union3.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union3.ets index cb304e0bbf3407eb112278a99e8037de67622dcf..404e72c9c8681d85448e4621214c89c5f45ef080 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union3.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_union3.ets @@ -21,4 +21,5 @@ function f1(this : B): A | /* @@ label*/this { } /* @@@ label Error SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct and extension functions. */ +/* @@? 19:41 Error TypeError: A 'this' cannot be used as a part of union type. */ /* @@? 20:12 Error TypeError: Type 'B' is not compatible with the enclosing method's return type 'A|ETSGLOBAL' */ diff --git a/ets2panda/test/ast/compiler/ets/func_as_param.ets b/ets2panda/test/ast/compiler/ets/func_as_param.ets index e78a161c811a95e6622a5d3a1448c51ead6bd841..43f1c47d80e957c7619da2512f1e419be36ac96f 100644 --- a/ets2panda/test/ast/compiler/ets/func_as_param.ets +++ b/ets2panda/test/ast/compiler/ets/func_as_param.ets @@ -16,7 +16,7 @@ function getFuncWithArgsZero(func: (() => void) | (() => Promise)) { return new Promise(async (resolve: (value: PromiseLike) => void) => { await (func as () => Promise)(); - const funcStr = (func as object).toString() + const funcStr = Type.of(func as object).getLiteral() const argsCount = getFunctionArgumentsCount(funcStr) const isAsync = checkIsAsyncFunction(funcStr) resolve(Promise.resolve()); @@ -26,7 +26,8 @@ function getFuncWithArgsZero(func: (() => void) | (() => Promise)) { function getFunctionArgumentsCount(funcStr: string): number { const regex = new RegExp("^[0123456789]$", "g") let count = "" - for(let str of funcStr) { + for(let ch of funcStr) { + let str = new Char(ch).toString(); if(regex.test(str)) { count = str } @@ -47,4 +48,69 @@ function checkIsAsyncFunction(funcStr: string): boolean { } } +async function testAsyncGetFuncWithArgsZeroSafe() { + let success = false; + try { + await getFuncWithArgsZero( async () => {}); + success = true; + } catch (e) { + success = false; + } + assertEQ(success, true, "getFuncWithArgsZero with async should not throw"); +} + +function testGetFuncWithArgsZeroSafe() { + let success = false; + try { + getFuncWithArgsZero(() => {}); + success = true; + } catch (e) { + success = false; + } + assertEQ(success, true, "getFuncWithArgsZero should not throw"); +} + +function main(): void { + const func1 = (a: number, b: number): number => { + return a + b; + }; + + const func2 = async (): Promise => {}; + + const func3 = (): number => { + return 42; + }; + + const func4 = async (x: number, y: number, z: number): Promise => {}; + + const funcStr1: string = Type.of(func1 as object).getLiteral(); + const funcStr2: string = Type.of(func2 as object).getLiteral(); + const funcStr3: string = Type.of(func3 as object).getLiteral(); + const funcStr4: string = Type.of(func4 as object).getLiteral(); + + // Test getLiteral() + assertEQ(funcStr1, "(1: std.core.Double, 2: std.core.Double): std.core.Double", "func1 literal check"); + assertEQ(funcStr2, "(): std.core.Promise", "func2 literal check"); + assertEQ(funcStr3, "(): std.core.Double", "func3 literal check"); + assertEQ(funcStr4, "(1: std.core.Double, 2: std.core.Double, 3: std.core.Double): std.core.Promise", "func4 literal check"); + + // Test getFunctionArgumentsCount + assertEQ(getFunctionArgumentsCount(funcStr1), 2, "func1 should have 2 arguments"); + assertEQ(getFunctionArgumentsCount(funcStr2), 0, "func2 should have 0 arguments"); + assertEQ(getFunctionArgumentsCount(funcStr3), 0, "func3 should have 0 arguments"); + assertEQ(getFunctionArgumentsCount(funcStr4), 3, "func4 should have 3 arguments"); + + // Test checkIsAsyncFunction + assertEQ(checkIsAsyncFunction(funcStr1), false, "func1 should not be async"); + assertEQ(checkIsAsyncFunction(funcStr2), true, "func2 should be async"); + assertEQ(checkIsAsyncFunction(funcStr3), false, "func3 should not be async"); + assertEQ(checkIsAsyncFunction(funcStr4), true, "func4 should be async"); + + // execute getFuncWithArgsZero with async + testAsyncGetFuncWithArgsZeroSafe() + + // execute getFuncWithArgsZero with sync + testGetFuncWithArgsZeroSafe() +} + diff --git a/ets2panda/test/ast/compiler/ets/greater_than_neg.ets b/ets2panda/test/ast/compiler/ets/greater_than_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..6b50c26efd3a9db21b44db68ba4459002ab990cd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/greater_than_neg.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. + */ + +let a: Array>>=2 +let b: Array>=2 + +/* @@? 16:21 Error SyntaxError: Unexpected token '>>='. */ +/* @@? 16:24 Error SyntaxError: Unexpected token '2'. */ +/* @@? 17:21 Error SyntaxError: Unexpected token '>='. */ +/* @@? 17:23 Error SyntaxError: Unexpected token '2'. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_4/package_module_1.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_4/package_module_1.ets index 025f58661541fbf89ba83a9c3cda9a950bb38919..60a86f221b1b5f3f0fbd4a6f1254d8c77bd12eb2 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_4/package_module_1.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_4/package_module_1.ets @@ -19,5 +19,4 @@ import {myvar} from "./package_module_2" // compiling this file will fail with import from it's own package /* @@? 17:1 Error SyntaxError: Package module cannot import from a file in it's own package. */ -/* @@? package_module_2.ets:18:12 Error TypeError: Variable 'myvar' has already been declared. */ /* @@? 17:21 Error TypeError: Cannot find import: ./package_module_2 */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_1.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_1.ets index c8f0364c8b88b1875072d4ac2a03445864620d57..904df0697ac5bc8a916eedde2c6e6a9c958fb478 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_1.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_1.ets @@ -17,6 +17,8 @@ package mypack; let myvar: number = wont_exist; +/* @@? package_module_2_neg.ets:22:1 Error SyntaxError: Invalid package toplevel statement */ /* @@? package_module_2_neg.ets:22:1 Error TypeError: Unresolved reference syntax */ /* @@? package_module_2_neg.ets:22:8 Error SyntaxError: Unexpected token 'error'. */ -/* @@? package_module_2_neg.ets:22:8 Error TypeError: Unresolved reference error */ \ No newline at end of file +/* @@? package_module_2_neg.ets:22:8 Error SyntaxError: Invalid package toplevel statement */ +/* @@? package_module_2_neg.ets:22:8 Error TypeError: Unresolved reference error */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_2_neg.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_2_neg.ets index 98e803a52d0db5f1142f378797810a40a2ecd05b..1ee3c41129052ffb25add85b234b83ea8f93ffba 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_2_neg.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_5/package_module_2_neg.ets @@ -21,6 +21,8 @@ let wont_exist: number = 8; syntax error +/* @@? 22:1 Error SyntaxError: Invalid package toplevel statement */ /* @@? 22:1 Error TypeError: Unresolved reference syntax */ /* @@? 22:8 Error SyntaxError: Unexpected token 'error'. */ +/* @@? 22:8 Error SyntaxError: Invalid package toplevel statement */ /* @@? 22:8 Error TypeError: Unresolved reference error */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_8/import_multi_error.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_8/import_multi_error.ets index 1d9762690a969b7b920403559fe7088e3fcca6f0..de22e82f51011f07fd0bc2bec035fe11307e9a6e 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_8/import_multi_error.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_8/import_multi_error.ets @@ -21,8 +21,6 @@ import {myvar2} from "./package_module" export let a: String = "SubpackageA"; /* @@? 18:1 Error SyntaxError: Package module cannot import from a file in it's own package. */ -/* @@? 19:1 Error SyntaxError: Package module cannot import from a file in it's own package. */ -/* @@? package_module.ets:20:12 Error TypeError: Variable 'myvar' has already been declared. */ -/* @@? package_module.ets:21:12 Error TypeError: Variable 'myvar2' has already been declared. */ /* @@? 18:21 Error TypeError: Cannot find import: ./package_module */ +/* @@? 19:1 Error SyntaxError: Package module cannot import from a file in it's own package. */ /* @@? 19:22 Error TypeError: Cannot find import: ./package_module */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets index d04e9a7d1301feb5e8852beddc0a385d12b9f480..633c6b84c81cd08518e7e0b521e70fa9ac8c53e0 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets @@ -20,10 +20,9 @@ package mypack; /* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ +/* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Invalid package toplevel statement */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ +/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Invalid package toplevel statement */ /* @@? package_with_both_errors.ets:21:16 Error TypeError: Cannot find type 'good'. */ /* @@? package_with_both_errors.ets:21:21 Error SyntaxError: Unexpected token 'Day'. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets index 3afb1ceb98da5d4e6e15d10a2c35362e87484d4f..0c0e927f3b802d3d20d8e3dce296db62308552d5 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets @@ -17,15 +17,14 @@ package mypack; let a: int = "I am a number, I promise..."; -/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ - /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ +/* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Invalid package toplevel statement */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ +/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Invalid package toplevel statement */ /* @@? package_with_both_errors.ets:21:16 Error TypeError: Cannot find type 'good'. */ /* @@? package_with_both_errors.ets:21:21 Error SyntaxError: Unexpected token 'Day'. */ /* @@? package_with_both_errors.ets:21:21 Error TypeError: No static $_invoke method and static $_instantiate method in Day. Day() is not allowed. */ -/* @@? package_with_both_errors.ets:21:21 Error TypeError: Type 'Day' has no call signatures. */ \ No newline at end of file +/* @@? package_with_both_errors.ets:21:21 Error TypeError: Type 'Day' has no call signatures. */ + +/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets index eec507c7ea5f4f215057515e21d4f5bedab441c3..e010aad57829f2f89e8b0e2749b999910be954c5 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets @@ -19,13 +19,12 @@ package mypack; /* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ -/* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ - /* @@? package_with_both_errors.ets:21:16 Error TypeError: Cannot find type 'good'. */ /* @@? package_with_both_errors.ets:21:21 Error SyntaxError: Unexpected token 'Day'. */ /* @@? package_with_both_errors.ets:21:21 Error TypeError: No static $_invoke method and static $_instantiate method in Day. Day() is not allowed. */ -/* @@? package_with_both_errors.ets:21:21 Error TypeError: Type 'Day' has no call signatures. */ \ No newline at end of file +/* @@? package_with_both_errors.ets:21:21 Error TypeError: Type 'Day' has no call signatures. */ + +/* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ +/* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Invalid package toplevel statement */ +/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ +/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Invalid package toplevel statement */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets index 0ad4b70b7089ba6b34be269bf24e7e8e21aa4ac9..c90c429c15e3b27a036ef6b9ce64e11cc1bb1b78 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets @@ -24,12 +24,11 @@ function foo(): Day { /* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ +/* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Invalid package toplevel statement */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ +/* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Invalid package toplevel statement */ /* @@? package_with_both_errors.ets:21:16 Error TypeError: Cannot find type 'good'. */ /* @@? package_with_both_errors.ets:21:21 Error SyntaxError: Unexpected token 'Day'. */ /* @@? package_with_both_errors.ets:21:21 Error TypeError: No static $_invoke method and static $_instantiate method in Day. Day() is not allowed. */ -/* @@? package_with_both_errors.ets:21:21 Error TypeError: Type 'Day' has no call signatures. */ \ No newline at end of file +/* @@? package_with_both_errors.ets:21:21 Error TypeError: Type 'Day' has no call signatures. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/scopes_multi_error.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/scopes_multi_error.ets index 56a2fd057a4420cf9be5eee067d212444bf0b386..3a8d9a439000eff96096f75c8833421453b8b7d5 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/scopes_multi_error.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/scopes_multi_error.ets @@ -29,6 +29,7 @@ export default function TestFunc(): void {} export default function TestFuncToo(): void {} /* @@? 20:10 Error TypeError: Main overload is not enabled */ +/* @@? 20:15 Error TypeError: Only 'FixedArray' type argument is allowed. */ /* @@? 24:10 Error TypeError: Main overload is not enabled */ /* @@? 24:10 Error TypeError: 0 or 1 argument are allowed */ /* @@? 29:16 Error TypeError: Only one default export is allowed in a module */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/export_multi_error.ets b/ets2panda/test/ast/compiler/ets/import_tests/export_multi_error.ets index dbb941239ad18e17da85cc963551805f7151ca46..c02f3a526ae875adb5d1ec2014619b77318671c5 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/export_multi_error.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/export_multi_error.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -export { /* @@ label */foo }; +export { foo }; function bar(): int { return 1; @@ -24,45 +24,45 @@ function foo2(): void {} class TestClass {} export {foo2} -export type {TestClass as /* @@ label1 */foo2} +export type {TestClass as foo2} /*-----------------*/ export default function foo3(): void {} export { - foo3 as /* @@ label2 */bar + foo3 as bar } /*-----------------*/ export class A {} -export type {A as /* @@ label3 */AA}; +export type {A as AA}; /*-----------------*/ interface I {} export type {I} export type MyI = I -export type {/* @@ label4 */MyI} +export type {MyI} /*-----------------*/ function f(){ return 1; } -export type {/* @@ label5 */f} +export type {f} /*-----------------*/ -export default /* @@ label6 */function TestFunc(): void {} -export default /* @@ label7 */function TestFuncToo(): void {} +export default function TestFunc(): void {} +export default function TestFuncToo(): void {} /*-----------------*/ -/* @@@ label6 Error TypeError: Only one default export is allowed in a module */ -/* @@@ label7 Error TypeError: Only one default export is allowed in a module */ -/* @@@ label3 Error SyntaxError: Name 'A' cannot be exported and type exported at the same time. */ -/* @@@ label4 Error SyntaxError: Cannot export the same 'MyI' type twice. */ -/* @@@ label5 Error SyntaxError: Can only type export class or interface. */ -/* @@@ label1 Error SyntaxError: The given name 'foo2' is already used in another export. */ -/* @@@ label1 Error SyntaxError: The given name 'foo2' is already used in another export. */ -/* @@@ label2 Error SyntaxError: Cannot export 'foo3', it was already exported. */ -/* @@@ label Error SyntaxError: Cannot find name 'foo' to export. */ +/* @@? 16:10 Error SyntaxError: Cannot find name 'foo' to export. */ +/* @@? 27:14 Error SyntaxError: The given name 'foo2' is already used in another export. */ +/* @@? 27:27 Error SyntaxError: The given name 'foo2' is already used in another export. */ +/* @@? 33:11 Error SyntaxError: Cannot export 'foo3', it was already exported. */ +/* @@? 39:19 Error SyntaxError: Cannot export 'A', it was already exported. */ +/* @@? 46:14 Error SyntaxError: The given name 'MyI' is already used in another export. */ +/* @@? 46:14 Error SyntaxError: Cannot export 'MyI', it was already exported. */ +/* @@? 56:16 Error TypeError: Only one default export is allowed in a module */ +/* @@? 57:16 Error TypeError: Only one default export is allowed in a module */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets index c53d4298efae98c7136ec7b2427bad3fe3170442..0f43b46007aeedb11f1c09148d686e1a7685edc8 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets @@ -29,4 +29,4 @@ let 1: number // Second level import import with both types of error /* @@? import_2.ets:17:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? import_2.ets:20:5 Error SyntaxError: Unexpected token 'not_ok'. */ +/* @@? import_2.ets:20:5 Error SyntaxError: 'var' keyword is not supported. Use 'let' instead. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets index 5cfa82f173e8067a554b60b304d03177c9094e0f..0af436edc7483e0c212e19cdd304e4410a8f30f5 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets @@ -21,6 +21,4 @@ var not_ok = false // Second level import import with both types of error /* @@? import_2.ets:17:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? import_2.ets:20:1 Error TypeError: Unresolved reference var */ -/* @@? import_2.ets:20:5 Error SyntaxError: Unexpected token 'not_ok'. */ -/* @@? import_2.ets:20:5 Error TypeError: Unresolved reference not_ok */ +/* @@? import_2.ets:20:5 Error SyntaxError: 'var' keyword is not supported. Use 'let' instead. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets index a516db733330db00fc8e4f815b46dc13be2cbbfa..787a60dba2c143441e4024ab1227049f6754bb36 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets @@ -23,10 +23,8 @@ let b = new B(10); // Second level import import with both types of error /* @@? import_2.ets:17:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? import_2.ets:20:5 Error SyntaxError: Unexpected token 'not_ok'. */ +/* @@? import_2.ets:20:5 Error SyntaxError: 'var' keyword is not supported. Use 'let' instead. */ // Error in main file based on class from the most distant file /* @@? master_file.ets:18:9 Error TypeError: Expected 0 arguments, got 1. */ /* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(int) */ -/* @@? master_file.ets:18:9 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(int) */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/master_file.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/master_file.ets index b79cd9f90295c0a0219e9b8f3960523cf757b7d8..1264a414c922edffd392d85549c050cf6580dd6b 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/master_file.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/master_file.ets @@ -17,17 +17,17 @@ import { moreImportantInfo, notInit, notExist } from "./package_with_errors" console.log(notExist) - /* @@? import_in_package_with_error.ets:20:17 Error TypeError: Cannot find type 'notInit'. */ /* @@? import_in_package_with_error.ets:20:29 Error SyntaxError: Unexpected token '='. */ +/* @@? import_in_package_with_error.ets:20:30 Error SyntaxError: Unexpected token, expected ')'. */ /* @@? import_in_package_with_error.ets:20:32 Error SyntaxError: Unexpected token ')'. */ -/* @@? distant_package.ets:22:21 Error TypeError: Missing initializer in const declaration */ -/* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? package_with_errors_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ + +/* @@? package_with_errors_2.ets:19:16 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ /* @@? package_with_errors_2.ets:19:16 Error TypeError: Unresolved reference foo */ /* @@? master_file.ets:16:54 Error TypeError: Cannot find imported element 'notExist' */ -/* @@? master_file.ets:18:13 Error TypeError: Unresolved reference notExist */ \ No newline at end of file +/* @@? master_file.ets:18:13 Error TypeError: Unresolved reference notExist */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.ets index 54e4cccb276b200ee58534a4e97fe1737f786a88..27ee426de39198d083481cdfee1cadeac15efeee 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.ets @@ -19,16 +19,15 @@ import { notInit, importantInfo } from "./inner_package_with_errors" function bar(x: notInit) { (=_=) } -/* @@? distant_package.ets:22:21 Error TypeError: Missing initializer in const declaration */ /* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ - -/* @@? import_in_package_with_error.ets:20:17 Error TypeError: Cannot find type 'notInit'. */ -/* @@? import_in_package_with_error.ets:20:29 Error SyntaxError: Unexpected token '='. */ -/* @@? import_in_package_with_error.ets:20:30 Error TypeError: Unresolved reference _ */ -/* @@? import_in_package_with_error.ets:20:32 Error SyntaxError: Unexpected token ')'. */ /* @@? package_with_errors_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ -/* @@? package_with_errors_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ + +/* @@? package_with_errors_2.ets:19:16 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ /* @@? package_with_errors_2.ets:19:16 Error TypeError: Unresolved reference foo */ /* @@? package_with_errors_2.ets:19:16 Error TypeError: This expression is not callable. */ + +/* @@? import_in_package_with_error.ets:20:17 Error TypeError: Cannot find type 'notInit'. */ +/* @@? import_in_package_with_error.ets:20:29 Error SyntaxError: Unexpected token '='. */ +/* @@? import_in_package_with_error.ets:20:30 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? import_in_package_with_error.ets:20:32 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/inner_package_with_errors/distant_package.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/inner_package_with_errors/distant_package.ets index e298275bf548338fcf1164e69bbd634ba08e3a08..fb0a7d4075fe3387546adf09baf2bd27eb747baf 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/inner_package_with_errors/distant_package.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/inner_package_with_errors/distant_package.ets @@ -21,6 +21,5 @@ export let importantInfo = "All good!" export const notInit ; -/* @@? distant_package.ets:22:21 Error TypeError: Missing initializer in const declaration */ -/* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? distant_package.ets:22:14 Error SyntaxError: Missing initialization for const package property */ /* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_1.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_1.ets index c18e1bd06cbcbf5f292399310cb972a4505f361f..59fdefced0706fc68fe5cdf40d4bb6989c257da9 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_1.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_1.ets @@ -18,16 +18,15 @@ package package_with_errors // "importantInfo" is imported in "import_in_package_with_error.ets" export let moreImportantInfo = importantInfo as number; -/* @@? distant_package.ets:22:21 Error TypeError: Missing initializer in const declaration */ -/* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ - /* @@? import_in_package_with_error.ets:20:17 Error TypeError: Cannot find type 'notInit'. */ /* @@? import_in_package_with_error.ets:20:29 Error SyntaxError: Unexpected token '='. */ -/* @@? import_in_package_with_error.ets:20:30 Error TypeError: Unresolved reference _ */ +/* @@? import_in_package_with_error.ets:20:30 Error SyntaxError: Unexpected token, expected ')'. */ /* @@? import_in_package_with_error.ets:20:32 Error SyntaxError: Unexpected token ')'. */ -/* @@? package_with_errors_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ -/* @@? package_with_errors_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ +/* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ + +/* @@? package_with_errors_2.ets:19:16 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ /* @@? package_with_errors_2.ets:19:16 Error TypeError: Unresolved reference foo */ /* @@? package_with_errors_2.ets:19:16 Error TypeError: This expression is not callable. */ + +/* @@? package_with_errors_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_2.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_2.ets index bf686e3c781f84da1735c224f2ee99d2ef2ab379..e3daaf55a4228defeaa20580eb59c061dea2380c 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_2.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_2.ets @@ -20,16 +20,15 @@ let newValue = foo(notInit) export notInit -/* @@? distant_package.ets:22:21 Error TypeError: Missing initializer in const declaration */ -/* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ - /* @@? import_in_package_with_error.ets:20:17 Error TypeError: Cannot find type 'notInit'. */ /* @@? import_in_package_with_error.ets:20:29 Error SyntaxError: Unexpected token '='. */ -/* @@? import_in_package_with_error.ets:20:30 Error TypeError: Unresolved reference _ */ +/* @@? import_in_package_with_error.ets:20:30 Error SyntaxError: Unexpected token, expected ')'. */ /* @@? import_in_package_with_error.ets:20:32 Error SyntaxError: Unexpected token ')'. */ +/* @@? distant_package.ets:22:22 Error SyntaxError: Variable must be initialized or it's type must be declared. */ + /* @@? package_with_errors_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ -/* @@? package_with_errors_1.ets:19:32 Error TypeError: Cannot cast type 'String' to 'double' */ + +/* @@? package_with_errors_2.ets:19:16 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ /* @@? package_with_errors_2.ets:19:16 Error TypeError: Unresolved reference foo */ /* @@? package_with_errors_2.ets:19:16 Error TypeError: This expression is not callable. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name.ets index 1e2232585b89f3185d09b988b33a16a287908c26..b594028cb9d22c2c9804e7b8ec750f0f97a245ec 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name.ets @@ -18,4 +18,3 @@ import * as all from "./selective_export" let test_var = new all.TestClass(); /* @@? 18:24 Error TypeError: 'TestClass' type does not exist. */ -/* @@? 18:24 Error TypeError: 'TestClass' type does not exist. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3.ets index cdc798c64d751404d584782311699fc207466269..b9e214dc37854c00fae258439648f56e534c9f3e 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3.ets @@ -18,7 +18,7 @@ export function foo(): void {} let msg = "hello"; export { - msg as /* @@ label */foo + msg as foo } -/* @@@ label Error SyntaxError: The given name 'foo' is already used in another export. */ +/* @@? 21:10 Error SyntaxError: The given name 'foo' is already used in another export. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4.ets b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4.ets index 123d063b09fc2fe6e9be1cd2337a3feb2f43f09a..38dc700daf9b2798b0969c51cae97bd61eb8bd58 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4.ets @@ -18,7 +18,7 @@ export default function foo(): void {} let msg = "hello"; export { - msg as /* @@ label */foo + msg as foo } -/* @@@ label Error SyntaxError: The given name 'foo' is already used in another export. */ +/* @@? 21:10 Error SyntaxError: The given name 'foo' is already used in another export. */ diff --git a/ets2panda/test/ast/compiler/ets/import_type_without_export.ets b/ets2panda/test/ast/compiler/ets/import_type_without_export.ets index 43203bd4398dbe58c5f21e1ec3b21bc8f36b40e7..c831615f2abbad58c2f7b45462aae91973378283 100644 --- a/ets2panda/test/ast/compiler/ets/import_type_without_export.ets +++ b/ets2panda/test/ast/compiler/ets/import_type_without_export.ets @@ -17,5 +17,3 @@ import type {A, C} from /* @@ label */'./export_type.ets' let a = new A(); let b = new C(); - -/* @@@ label Error TypeError: Cannot import 'C', imported type imports only exported types. */ diff --git a/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.ets b/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.ets new file mode 100644 index 0000000000000000000000000000000000000000..c4664c65f9cf5e0a697f63f35e31d162ac6309ce --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/inferTypeLambda_0.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(arr:T[], f:(a:T[])=>string){ + return f(arr[0]) // CTE +} + +function bar(arr:number[]){ + return foo(arr, (a):string=>{ + let res = a.toString(); + return res + }) +} + +/* @@? 17:12 Error TypeError: No matching call signature for (T) */ +/* @@? 17:14 Error TypeError: Type 'T' is not compatible with type 'Array' at index 1 */ diff --git a/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative2.ets b/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative2.ets index 948c1c93fe83cf3e5c75dfa81084b35169ee393c..b0f2d51def4648f80f50a76557359097f32c0c7a 100644 --- a/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative2.ets +++ b/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative2.ets @@ -19,4 +19,3 @@ a[1] = "1" let b = a[0] + a[1] /* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be numeric type, enum or String. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be numeric type, enum or String. */ diff --git a/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative3.ets b/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative3.ets index 4a568f118d26826ea71cea35b777fd30d07a562f..7ccba2d83e8e9f611c7bf8c9fe5ca2eb6c42e95b 100644 --- a/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative3.ets +++ b/ets2panda/test/ast/compiler/ets/inferTypeOfArrayNegative3.ets @@ -16,4 +16,7 @@ let a = [1, 2, 3] a[0] = /* @@ label */"1" -/* @@@ label Error TypeError: Type '"1"' cannot be assigned to type 'double' */ +/* @@? 17:1 Error TypeError: No matching indexing signature for $_set(int, "1") */ +/* @@? 17:3 Error TypeError: Type 'int' is not compatible with type 'double' at index 1 */ +/* @@? 17:3 Error TypeError: Cannot find index access method with the required signature. */ +/* @@? 17:22 Error TypeError: Type '"1"' is not compatible with type 'Double' at index 2 */ diff --git a/ets2panda/test/ast/compiler/ets/invalidPrivateAccess3.ets b/ets2panda/test/ast/compiler/ets/invalidPrivateAccess3.ets index 25579258e19ebe54785d73f2ecdf31e2b1c30453..511ee961f9e200c9f2b685f6f2ab8297c7f5fa23 100644 --- a/ets2panda/test/ast/compiler/ets/invalidPrivateAccess3.ets +++ b/ets2panda/test/ast/compiler/ets/invalidPrivateAccess3.ets @@ -35,5 +35,6 @@ function main(): void { klass.foo(); } +/* @@? 35:5 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 35:5 Error TypeError: Signature foo(): void is not visible here. */ /* @@? 35:5 Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/compiler/ets/invalidPrivateAccess4.ets b/ets2panda/test/ast/compiler/ets/invalidPrivateAccess4.ets index 06cc048a718a78ac064360bcf185107f02dbd3e4..575b66b45373ee271a72c3c47e64679275dfe475 100644 --- a/ets2panda/test/ast/compiler/ets/invalidPrivateAccess4.ets +++ b/ets2panda/test/ast/compiler/ets/invalidPrivateAccess4.ets @@ -23,4 +23,5 @@ class B extends A { } } +/* @@@ label Error TypeError: Class field 'a' defined by the parent class is not accessible in the child class via super. */ /* @@@ label Error TypeError: Property a is not visible here. */ diff --git a/ets2panda/test/ast/compiler/ets/invalidProtectedAccess3.ets b/ets2panda/test/ast/compiler/ets/invalidProtectedAccess3.ets index d943387afb5bc572b61cee0ae0dec20303425d5e..eeaa22daaa3be3ac557d17a03cd89c106fbbd1c4 100644 --- a/ets2panda/test/ast/compiler/ets/invalidProtectedAccess3.ets +++ b/ets2panda/test/ast/compiler/ets/invalidProtectedAccess3.ets @@ -35,5 +35,6 @@ function main(): void { klass.foo(); } +/* @@? 35:5 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 35:5 Error TypeError: Signature foo(): void is not visible here. */ /* @@? 35:5 Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/compiler/ets/invalid_two_functions.ets b/ets2panda/test/ast/compiler/ets/invalid_two_functions.ets new file mode 100644 index 0000000000000000000000000000000000000000..62d52f75f5cb2155a2d76209841e60a88aca9c41 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_two_functions.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. + */ + +(function () {})(); + +const a = [1]; +const b = a.map(function (e) { + return e * 2; +}); + +/* @@? 16:2 Error SyntaxError: Unexpected token 'function'. */ +/* @@? 19:17 Error SyntaxError: Unexpected token 'function'. */ diff --git a/ets2panda/test/ast/compiler/ets/lambda_override.ets b/ets2panda/test/ast/compiler/ets/lambda_override.ets new file mode 100644 index 0000000000000000000000000000000000000000..f48a63238c12fc801387720540122a7685dc9fe8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/lambda_override.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. + */ + +class aaa { + /* @@ label */x: ()=>string +} +class bbb extends aaa { + /* @@ label1 */x: ()=>string +} + +/* @@@ label Error TypeError: Property 'x' might not have been initialized. */ +/* @@@ label1 Error TypeError: Property 'x' might not have been initialized. */ diff --git a/ets2panda/test/ast/compiler/ets/lambda_short.ets b/ets2panda/test/ast/compiler/ets/lambda_short.ets index d57eb421b4a2ff5f97d835a50ee7b6bb661a5a91..e891be27576d743e379d3181dbfee4d60af70ffb 100644 --- a/ets2panda/test/ast/compiler/ets/lambda_short.ets +++ b/ets2panda/test/ast/compiler/ets/lambda_short.ets @@ -14,6 +14,6 @@ */ function main(): void { - let nums: int[] = [ 1, 2, 3, 123, 321 ] + let nums: FixedArray = [ 1, 2, 3, 123, 321 ] forEach(nums, num => console.log(num)) } diff --git a/ets2panda/test/ast/compiler/ets/lambda_type_mismatch.ets b/ets2panda/test/ast/compiler/ets/lambda_type_mismatch.ets index 124875eb97884c63e1d48fe9d2c1e89df6db20cd..4c0ce6a576b1d685825b47b74ca37bb049b0f71c 100644 --- a/ets2panda/test/ast/compiler/ets/lambda_type_mismatch.ets +++ b/ets2panda/test/ast/compiler/ets/lambda_type_mismatch.ets @@ -19,6 +19,6 @@ let fob:(...args:number[])=>number = (...args:number[]) =>{} let foc:(c:string, ...args:number[])=>string = (c:number, ...args:string[]):string=>{} -/* @@? 16:46 Error TypeError: Type '(c: Double, ...args: double[]) => void' cannot be assigned to type '(c: String, ...args: double[]) => void' */ -/* @@? 18:38 Error TypeError: Type '(...args: double[]) => void' cannot be assigned to type '(...args: double[]) => Double' */ -/* @@? 20:48 Error TypeError: Type '(c: Double, ...args: String[]) => String' cannot be assigned to type '(c: String, ...args: double[]) => String' */ +/* @@? 16:46 Error TypeError: Type '(c: Double, ...args: Array) => void' cannot be assigned to type '(c: String, ...args: Array) => void' */ +/* @@? 18:38 Error TypeError: Type '(...args: Array) => void' cannot be assigned to type '(...args: Array) => Double' */ +/* @@? 20:48 Error TypeError: Type '(c: Double, ...args: Array) => String' cannot be assigned to type '(c: String, ...args: Array) => String' */ diff --git a/ets2panda/test/ast/compiler/ets/literal_init_parameterless_constructor.ets b/ets2panda/test/ast/compiler/ets/literal_init_parameterless_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..17cdbda3903a17fed1740c448d0679a6b4e0ae65 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/literal_init_parameterless_constructor.ets @@ -0,0 +1,30 @@ +/* + * 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. + */ + +// (arkts-no-untyped-obj-literals) +class C { + field: int = 0; + + constructor(f: int){ + this.field = f; + } +} + +function main(): void { + let c: C = { field: 42 } +} + + + /* @@? 26:14 Error TypeError: Type C 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! */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets b/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets index cd1e04e08693d21b40319500b80407de63485d3a..731f743e07e8ff1b9e3f6cbc36eee4dfb10be4d5 100644 --- a/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets +++ b/ets2panda/test/ast/compiler/ets/math_const_as_identifier.ets @@ -23,7 +23,8 @@ function foo1() { let undefined }; +/* @@? 21:9 Error TypeError: Variable 'NaN' has already been declared. */ +/* @@? 22:9 Error TypeError: Variable 'Infinity' has already been declared. */ /* @@? 22:20 Error TypeError: Unresolved reference test */ /* @@? 23:9 Error SyntaxError: Identifier expected, got 'undefined'. */ /* @@? 24:1 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? 24:1 Error SyntaxError: Variable must be initialized or it's type must be declared. */ diff --git a/ets2panda/test/ast/compiler/ets/most_specific_method_with_empty_rest_param.ets b/ets2panda/test/ast/compiler/ets/most_specific_method_with_empty_rest_param.ets index ff1d8b5339a062b87d489d5a85628ccacc8869c7..7ec8ba7d899bf8deb6ce500629a6e5559edda128 100644 --- a/ets2panda/test/ast/compiler/ets/most_specific_method_with_empty_rest_param.ets +++ b/ets2panda/test/ast/compiler/ets/most_specific_method_with_empty_rest_param.ets @@ -27,5 +27,4 @@ function main() { c.met() } -/* @@? 27:5 Error TypeError: Call to `met` is ambiguous */ -/* @@? 27:5 Error TypeError: Reference to met is ambiguous */ +/* @@? 20:5 Error TypeError: Function met with this assembly signature already declared. */ diff --git a/ets2panda/test/ast/compiler/ets/multiple_interface_inheritance_n_1.sts b/ets2panda/test/ast/compiler/ets/multiple_interface_inheritance_n_1.sts new file mode 100644 index 0000000000000000000000000000000000000000..299d99292c0af2a383b339e0dfdfd69d16deec4d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/multiple_interface_inheritance_n_1.sts @@ -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. + */ + +let res: number = 0; + +interface I { + foo(i: number) { + return 1; + } +} + +interface J { + foo(j: string) { + return 2; + } + foo(i: number) { + return 1; + } +} + +class A implements I, J /* @@ label */{} + +/* @@@ label Error TypeError: Method 'foo' is declared in I and J interfaces. */ \ No newline at end of file diff --git a/ets2panda/linter/test/interop/ts_decorator.ets b/ets2panda/test/ast/compiler/ets/multiple_interface_inheritance_n_2.sts similarity index 65% rename from ets2panda/linter/test/interop/ts_decorator.ets rename to ets2panda/test/ast/compiler/ets/multiple_interface_inheritance_n_2.sts index 8ce1c11817408d298182c7cf8160fe8100d3aa98..ef84118c3826dbb728e17e8855460bf89b2de4c3 100644 --- a/ets2panda/linter/test/interop/ts_decorator.ets +++ b/ets2panda/test/ast/compiler/ets/multiple_interface_inheritance_n_2.sts @@ -13,22 +13,23 @@ * limitations under the License. */ -import {MyClassDecorator, MyClassDecorator2} from "./oh_modules/ts_decorator" -import { MyDecorator } from "./oh_modules/ets_decorator"; +let res: number = 0; -@MyClassDecorator -class K {} - -@Entry //legal -class X {} +interface I { + foo(i: number) { + return 1; + } +} -@MyDecorator //legal -class Y {} +interface J extends I { + foo(j: string) { + return 2; + } + foo(i: number) { + return 1; + } +} -@MyClassDecorator2 -class Z {} +class A implements I, J /* @@ label */{} -class Example { - @MyClassDecorator2 //legal - doSomething() {} -} +/* @@@ label Error TypeError: Method 'foo' is declared in I and J interfaces. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/multiple_interface_inheritance_n_3.sts b/ets2panda/test/ast/compiler/ets/multiple_interface_inheritance_n_3.sts new file mode 100644 index 0000000000000000000000000000000000000000..1329c83040160d1acd27dc975ad657eb2c3fee74 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/multiple_interface_inheritance_n_3.sts @@ -0,0 +1,32 @@ +// /* +// * Copyright (c) 2025 Huawei Device Co., Ltd. +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ + +let res: number = 0; + +interface I { + foo(i: number): string { + return "str"; + } +} +interface J { + foo(i: number): int { + return 3; + } + +} + +class A implements J, I /* @@ label */{} + +/* @@@ label Error TypeError: Method 'foo' is declared in J and I interfaces. */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_modifiers.ets b/ets2panda/test/ast/compiler/ets/namespace_modifiers.ets new file mode 100644 index 0000000000000000000000000000000000000000..d019c77f6ee3a4e7892b8bf6ecf7d51d3ab7492f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/namespace_modifiers.ets @@ -0,0 +1,49 @@ +/* + * 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 V { + class A { + readonly const P = 0 + } +} + +class B { + readonly const Q = 0 +} + +namespace W { + readonly R = 0 +} + +namespace X { + namespace W { + const S = 0 + } +} + +namespace M { + namespace N { + namespace O { + const T = 0 + } + } +} + +/* @@? 18:18 Error SyntaxError: Unexpected token 'const'. */ +/* @@? 23:14 Error SyntaxError: Unexpected token 'const'. */ +/* @@? 27:5 Error TypeError: Unresolved reference readonly */ +/* @@? 27:14 Error SyntaxError: Unexpected token 'R'. */ +/* @@? 27:14 Error TypeError: Unresolved reference R */ +/* @@? 27:16 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation.ets index 561c6cc4bf4476195425a47b1b2e2715a47a98de..b94f23b4016ab073b35e697e29f7b2e348fcfb81 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation.ets @@ -61,7 +61,6 @@ MySpace.C.a // CTE /* @@? 49:9 Error TypeError: 'privateVariable' is not exported in 'MySpace' */ /* @@? 51:9 Error TypeError: 'foo' is not exported in 'MySpace' */ /* @@? 53:13 Error TypeError: 'C' is not exported in 'MySpace' */ -/* @@? 55:27 Error TypeError: 'C' is not exported in 'MySpace' */ /* @@? 57:9 Error TypeError: 'C' is not exported in 'MySpace' */ /* @@? 42:28 Error TypeError: 'myInterface' is not exported in 'MySpace' */ /* @@? 46:10 Error TypeError: 'Anno' is not exported in 'MySpace' */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_conflicts.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_conflicts.ets index 9c698b6464bc549d0e81d036fe28e09f4cd02933..04395a85772b0621c5da314b119a718d92bfbf44 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_conflicts.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_conflicts.ets @@ -21,4 +21,5 @@ namespace ConflictedSpace { } } -/* @@? 19:22 Error TypeError: Variable 'InnerSpace' has already been declared. */ \ No newline at end of file +/* @@? 19:22 Error TypeError: Variable 'InnerSpace' has already been declared. */ +/* @@? 19:22 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_nested_scopes.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_nested_scopes.ets index 832daa5f49f57d3d7488fae1f82bad21760c6fcc..d0b7b04d91b522573f278fad8776243238c355a7 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_nested_scopes.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_nested_scopes.ets @@ -53,7 +53,6 @@ OuterSpace.InnerSpace.privateVariable = 456; // CTE /* @@? 45:16 Error TypeError: 'InnerSpace' is not exported in 'OuterSpace' */ /* @@? 45:27 Error TypeError: 'innerClass' is not exported in 'InnerSpace' */ /* @@? 40:27 Error TypeError: 'privateVariable' is not exported in 'InnerSpace' */ -/* @@? 40:27 Error TypeError: 'privateVariable' is not exported in 'InnerSpace' */ /* @@? 50:12 Error TypeError: 'InnerSpace' is not exported in 'OuterSpace' */ /* @@? 50:23 Error TypeError: 'privateVariable' is not exported in 'InnerSpace' */ /* @@? 43:31 Error TypeError: 'InnerSpace' is not exported in 'OuterSpace' */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_undefined_scopes.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_undefined_scopes.ets index 5b73a9e4cdd7e110885c198ef52a5456286e3f86..a30b66e6de35580a1adf3eb3b5acdfea1af73904 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_undefined_scopes.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_undefined_scopes.ets @@ -22,4 +22,3 @@ namespace ParentSpace { let result = ParentSpace.ChildSpace.value; // Error: 'ChildSpace' is not defined /* @@? 22:26 Error TypeError: Property 'ChildSpace' does not exist on type 'ParentSpace' */ -/* @@? 22:26 Error TypeError: Property 'ChildSpace' does not exist on type 'ParentSpace' */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type01.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type01.ets index 5e1450e44a700e7b0ce0bfd89b25eb067cc2a3b8..bdda95648857545e37fcdc5b95d65630f1d09362 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type01.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type01.ets @@ -19,4 +19,3 @@ namespace MySpace { let a = new MySpace() /* @@? 19:13 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ -/* @@? 19:13 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type09.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type09.ets index 3afc1b752be72de40821bcb0b6ec85b3f746531e..34b0e476d3ec5b3b5765b22e98acc2e3e4ec0fc0 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type09.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type09.ets @@ -19,4 +19,3 @@ namespace MySpace { let a = 1 as MySpace /* @@? 19:14 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ -/* @@? 19:14 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets index 713dbc66bc9ac5473222676835646d607b26c10c..73967a0bb8fa429d24e9731a4dc7627021a37f87 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets @@ -20,5 +20,3 @@ let a = 1 instanceof MySpace /* @@? 19:22 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ /* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ -/* @@? 19:22 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type11.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type11.ets index fdef3178fe307b3cd54768787c50cb0b0ef1adf6..b9f5b38405f8671f4c91af084fa7f3298efd7396 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type11.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type11.ets @@ -19,4 +19,3 @@ namespace MySpace { let a = /* @@ label */MySpace /* @@@ label Error TypeError: Namespace name 'MySpace' used in the wrong context */ -/* @@@ label Error TypeError: Namespace name 'MySpace' used in the wrong context */ diff --git a/ets2panda/test/ast/compiler/ets/nonNullishType.ets b/ets2panda/test/ast/compiler/ets/nonNullishType.ets new file mode 100644 index 0000000000000000000000000000000000000000..1d1dcdf5c2b9a56ac81e61e6ecd01231940995fb --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/nonNullishType.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 A { + foo(a: T):T!{ + return a!; + } +} diff --git a/ets2panda/test/ast/compiler/ets/nonNullishType_n.ets b/ets2panda/test/ast/compiler/ets/nonNullishType_n.ets new file mode 100644 index 0000000000000000000000000000000000000000..825f28300e385113ea8ed73a77a9ac6e9e07c158 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/nonNullishType_n.ets @@ -0,0 +1,30 @@ +/* + * 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 Test{} + +class A { + foo(a: T):Test!{ + let b : Object! = new Object(); + let c : (int)! = 0; + return a!; + } +} + +/* @@? 19:13 Error TypeError: Only type parameters can be used as a nonnullish type */ +/* @@? 20:13 Error TypeError: Only type parameters can be used as a nonnullish type */ +/* @@? 21:13 Error TypeError: Only type parameters can be used as a nonnullish type */ +/* @@? 22:12 Error TypeError: Type 'NonNullable' is not compatible with the enclosing method's return type 'Test' */ +/* @@? 22:12 Error TypeError: Type 'NonNullable' is not compatible with the enclosing method's return type 'Test' */ diff --git a/ets2panda/test/ast/compiler/ets/not_initialized_variable/complex_types.ets b/ets2panda/test/ast/compiler/ets/not_initialized_variable/complex_types.ets index 2efce245ce8f60f4b23f388ae7e13f418ef72bb2..793e440b548f0bf9b07068f2763a75eb2d03ae88 100644 --- a/ets2panda/test/ast/compiler/ets/not_initialized_variable/complex_types.ets +++ b/ets2panda/test/ast/compiler/ets/not_initialized_variable/complex_types.ets @@ -35,8 +35,8 @@ export let plug: Plug console.log(car, animal, mutant, jsvalue, plug) -/* @@? 36:13 Warning Warning: Variable 'car' is used before being assigned. */ -/* @@? 36:18 Warning Warning: Variable 'animal' is used before being assigned. */ -/* @@? 36:26 Warning Warning: Variable 'mutant' is used before being assigned. */ -/* @@? 36:34 Warning Warning: Variable 'jsvalue' is used before being assigned. */ -/* @@? 36:43 Warning Warning: Variable 'plug' is used before being assigned. */ +/* @@? 36:13 Error TypeError: Variable 'car' is used before being assigned. */ +/* @@? 36:18 Error TypeError: Variable 'animal' is used before being assigned. */ +/* @@? 36:26 Error TypeError: Variable 'mutant' is used before being assigned. */ +/* @@? 36:34 Error TypeError: Variable 'jsvalue' is used before being assigned. */ +/* @@? 36:43 Error TypeError: Variable 'plug' is used before being assigned. */ diff --git a/ets2panda/test/ast/compiler/ets/not_initialized_variable/primitive_types.ets b/ets2panda/test/ast/compiler/ets/not_initialized_variable/primitive_types.ets index 630841636564b114777e1f997050cc7b54ea3e02..41b5889e007711981dfb64a5061d482fc4ce38a1 100644 --- a/ets2panda/test/ast/compiler/ets/not_initialized_variable/primitive_types.ets +++ b/ets2panda/test/ast/compiler/ets/not_initialized_variable/primitive_types.ets @@ -19,4 +19,4 @@ let c: number console.log(a, b, c) -/* @@? 20:16 Warning Warning: Variable 'b' is used before being assigned. */ +/* @@? 20:16 Error TypeError: Variable 'b' is used before being assigned. */ diff --git a/ets2panda/test/ast/compiler/ets/objectLiteralNoParameterlessConstructor.ets b/ets2panda/test/ast/compiler/ets/objectLiteralNoParameterlessConstructor.ets index ac67e8b5d0279bda8c59521c837fb8b62481d696..35d389ecbf6f78a1c8d410b6bba21dc320c13ad8 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteralNoParameterlessConstructor.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteralNoParameterlessConstructor.ets @@ -19,4 +19,4 @@ class C { let c: C = /* @@ label */{}; -/* @@@ label Error TypeError: type C has no parameterless constructor */ +/* @@@ label Error TypeError: Type C 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! */ diff --git a/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets b/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets index 80d6e714825665db3d72c9b4b4851f9f82c88e76..b7c21affb1e0d382710ffc1f6b9d4989b8172929 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets @@ -41,5 +41,5 @@ function main(){ /* @@@ label Error TypeError: type C has no property named field3 */ /* @@@ label2 Error TypeError: Property field2 is not visible here. */ /* @@@ label3 Error TypeError: Type '"some str"' is not compatible with type 'double' at property 'field1' */ -/* @@@ label4 Error TypeError: type C2 has no parameterless constructor */ +/* @@@ label4 Error TypeError: Type C2 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! */ /* @@@ label5 Error TypeError: Signature constructor(): void is not visible here. */ diff --git a/ets2panda/test/compiler/ets/optionalLambdaParameter.ets b/ets2panda/test/ast/compiler/ets/optionalLambdaParameter.ets similarity index 100% rename from ets2panda/test/compiler/ets/optionalLambdaParameter.ets rename to ets2panda/test/ast/compiler/ets/optionalLambdaParameter.ets diff --git a/ets2panda/test/ast/compiler/ets/overload-resolution-rest.ets b/ets2panda/test/ast/compiler/ets/overload-resolution-rest.ets new file mode 100644 index 0000000000000000000000000000000000000000..f73c7e1334be4b34c39e151eacdbbb48af131b42 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/overload-resolution-rest.ets @@ -0,0 +1,30 @@ +/* + * 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 res: number = 0 + +function foo(a: Int, ...p: Int[]) { + res = 1 +} + +function foo(...p: Int[]) { + res = 2 +} + +function main() { + /* @@ label */foo(1, 2, 3) +} + +/* @@@ label Error TypeError: Reference to foo is ambiguous */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/package_invalid_initializer/P3/P3.ets b/ets2panda/test/ast/compiler/ets/package_invalid_initializer/P3/P3.ets new file mode 100644 index 0000000000000000000000000000000000000000..3609cbb822433097e51adf6a68531a869e015874 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_invalid_initializer/P3/P3.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. + */ + +package P3 + +class A { + data:number = 1; +} + +function foo(): int { + return 1; +} + +export let nn: number = new A().data +export let nn1: int = foo(); +export let nn2: number = 1; +export const c_nn; +export const c_nn1: number = foo(); +export const c_nn2: number = 1; // initialized twice. +nn = foo(); +foo(); +console.log(foo()) +static { + c_nn2 = 2 +} + +export const var_tobe_shadowed: number; +static { + let var_tobe_shadowed: number = 10; + var_tobe_shadowed = 2; +} + +/* @@? P3.ets:26:25 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ +/* @@? P3.ets:27:23 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ +/* @@? P3.ets:29:14 Error SyntaxError: Missing initialization for const package property */ +/* @@? P3.ets:29:18 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? P3.ets:30:30 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ +/* @@? P3.ets:31:14 Error TypeError: Cannot reassign constant c_nn2 */ +/* @@? P3.ets:32:6 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ +/* @@? P3.ets:33:1 Error SyntaxError: Invalid package toplevel statement */ +/* @@? P3.ets:34:1 Error SyntaxError: Invalid package toplevel statement */ +/* @@? P3.ets:39:14 Error SyntaxError: Missing initialization for const package property */ diff --git a/ets2panda/test/ast/compiler/ets/package_invalid_initializer/main_test.ets b/ets2panda/test/ast/compiler/ets/package_invalid_initializer/main_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..241151b6461a23c0f6494d44460e212e3cb73052 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_invalid_initializer/main_test.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. + */ + +import {nn, nn1, nn2} from "./P3" + +/* @@? P3.ets:26:25 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ +/* @@? P3.ets:27:23 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ +/* @@? P3.ets:29:18 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? P3.ets:30:30 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ +/* @@? P3.ets:32:6 Error SyntaxError: Non-constant initializer of Package should be apply in Initializer Block. */ +/* @@? P3.ets:33:1 Error SyntaxError: Invalid package toplevel statement */ +/* @@? P3.ets:34:1 Error SyntaxError: Invalid package toplevel statement */ diff --git a/ets2panda/test/ast/compiler/ets/package_namespace_static_block_multi/main_test.ets b/ets2panda/test/ast/compiler/ets/package_namespace_static_block_multi/main_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..c0790ae4e613411c2095e420376f8d9cff46b878 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_namespace_static_block_multi/main_test.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. + */ + +import {NS} from "./package" + +/* @@? P2_01.ets:21:9 Error SyntaxError: Only one static block is allowed in one namespace or class. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/package_namespace_static_block_multi/package/P2_01.ets b/ets2panda/test/ast/compiler/ets/package_namespace_static_block_multi/package/P2_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..bd3c4a657f6dffe284672e3feaae36f189d30da9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_namespace_static_block_multi/package/P2_01.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. + */ + +package P2 + +export namespace NS { + export let a:number; + static { + a = 1; + } +} + +/* @@? P2_01.ets:21:9 Error SyntaxError: Only one static block is allowed in one namespace or class. */ diff --git a/ets2panda/test/ast/compiler/ets/package_namespace_static_block_multi/package/P2_02.ets b/ets2panda/test/ast/compiler/ets/package_namespace_static_block_multi/package/P2_02.ets new file mode 100644 index 0000000000000000000000000000000000000000..2a88481c53ef9b343187034be105013c855851a9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_namespace_static_block_multi/package/P2_02.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. + */ + +package P2 + +export namespace NS { + static { + a = 3 + } +} + +/* @@? P2_02.ets:20:9 Error SyntaxError: Only one static block is allowed in one namespace or class. */ diff --git a/ets2panda/test/ast/compiler/ets/package_static_block_multi_files/P1/P1_0.ets b/ets2panda/test/ast/compiler/ets/package_static_block_multi_files/P1/P1_0.ets new file mode 100644 index 0000000000000000000000000000000000000000..ebeef75215ce5eb3436624e6d83c1fee44611bd8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_static_block_multi_files/P1/P1_0.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. + */ + +package P1 + +export let nn3: number = 1 +static { + nn3 = 2 +} diff --git a/ets2panda/test/ast/compiler/ets/package_static_block_multi_files/P1/P1_1.ets b/ets2panda/test/ast/compiler/ets/package_static_block_multi_files/P1/P1_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..7a707967fac6e39f261e9c4ef679594b47792f67 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_static_block_multi_files/P1/P1_1.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. + */ + +package P1 + +export let nn4: number = 1 +static { + nn4 = 2 +} diff --git a/ets2panda/test/ast/compiler/ets/package_static_block_multi_files/main_test.ets b/ets2panda/test/ast/compiler/ets/package_static_block_multi_files/main_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..dfb039f82efa6e9b2698f9d40ce3ac6467fe3d4a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/package_static_block_multi_files/main_test.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. + */ + +import {nn3, nn4} from "./P1" + +/* @@? P1_1.ets:20:5 Error SyntaxError: static block cannot apply to multi-files for one package */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/param_sort_1.ets b/ets2panda/test/ast/compiler/ets/param_sort_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..bba3a5f57043e0bd5aaff4c0caa008ead1061f3a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/param_sort_1.ets @@ -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. + */ +function foo(p1: int, p2?: int, /* @@ label */p3: int) { } + +/* @@@ label Error SyntaxError: A required parameter cannot follow an optional parameter. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/param_sort_2.ets b/ets2panda/test/ast/compiler/ets/param_sort_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..17b9a79e2ee2a79c88673bb1f7dd9d798cb9e8bb --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/param_sort_2.ets @@ -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. + */ +function foo(p1: boolean, p2?: int, /* @@ label */p3: string) { } + +/* @@@ label Error SyntaxError: A required parameter cannot follow an optional parameter. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/param_sort_3.ets b/ets2panda/test/ast/compiler/ets/param_sort_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..8a38d4cdace43bbd2497c7d874ad9e446c334b81 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/param_sort_3.ets @@ -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. + */ +function foo(p1: int, p2: int = 44, /* @@ label */p3: int) { } + +/* @@@ label Error SyntaxError: A required parameter cannot follow an optional parameter. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/private_field_declaration.ets b/ets2panda/test/ast/compiler/ets/private_field_declaration.ets new file mode 100644 index 0000000000000000000000000000000000000000..153546fc726d2b85669b7c39e72ec5821a105010 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/private_field_declaration.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. + */ + + // (arkts-no-private-identifiers) + class C { + #field: int = 0; + } + + /* @@? 18:5 Error SyntaxError: Use 'private' keyword to declare an identifier as private. */ + /* @@? 18:5 Error SyntaxError: Unexpected token '{'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/readonly-type-reassignment0.ets b/ets2panda/test/ast/compiler/ets/readonly-type-reassignment0.ets new file mode 100755 index 0000000000000000000000000000000000000000..9a07282a7a7d536dc9472ac92964d0d670469dc8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly-type-reassignment0.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. + */ + +interface I { + i: number; + j: string; +} + +function main() { + let z: Readonly = { i: 1.9, j: "some str"} + /* @@ label */z.i = 2.9 +} + +/* @@@ label Error TypeError: The 'Readonly' property cannot be reassigned. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly-type-reassignment1.ets b/ets2panda/test/ast/compiler/ets/readonly-type-reassignment1.ets new file mode 100755 index 0000000000000000000000000000000000000000..974a88ae5f338857829d266e7a168c774dba52b8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly-type-reassignment1.ets @@ -0,0 +1,36 @@ +/* + * 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. + */ + +/*--- +desc: Type Readonly constructs a type with all properties of T set to readonly. + It means that the properties of the constructed value cannot be reassigned. T must + be a class or an interface type +name: readonly_type_reassignment_1 +tags: +- compile-only +- negative +---*/ + +interface I { + i: number; + j: string; +} + +function main() { + let z: Readonly = { i: 1.9, j: "some str"} + /* @@ label */z.j = "new str" +} + +/* @@@ label Error TypeError: The 'Readonly' property cannot be reassigned. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets b/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.ets new file mode 100644 index 0000000000000000000000000000000000000000..e096cf9167ce19c2b1a7c62d4469d1c0463ce34c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/label_readonly_true.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. + */ + +WE: readonly true; +let: readonly; + +/* @@? 16:5 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 16:5 Error TypeError: Unresolved reference readonly */ +/* @@? 16:14 Error SyntaxError: Invalid Type. */ +/* @@? 16:14 Error SyntaxError: Unexpected token 'true'. */ +/* @@? 17:4 Error SyntaxError: Identifier expected, got ':'. */ +/* @@? 17:6 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 17:6 Error SyntaxError: Unexpected token 'readonly'. */ +/* @@? 17:14 Error SyntaxError: Invalid Type. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_array.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_array.ets new file mode 100644 index 0000000000000000000000000000000000000000..9df99d0e45be9a3cb4f45fa3819aa2f858b710d1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_array.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. + */ + +let a: readonly int [""]; + +/* @@? 16:22 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 16:22 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@? 16:22 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:24 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_as_args_type.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_args_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe4d6158f78c51023de89e1f32803c86ea9f73d9 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_args_type.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(param1: readonly/* @@ foo_param1 */, param2: readonly /* @@ foo_param2 */true) {} + +/* @@@ foo_param1 Error SyntaxError: Invalid Type. */ +/* @@@ foo_param1 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ + +/* @@@ foo_param2 Error SyntaxError: Invalid Type. */ +/* @@@ foo_param2 Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_as_fields_type.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_fields_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..3830a00052e10a05e2dadd2cd1222756c99a44be --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_as_fields_type.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. + */ + +class A { + a: readonly/* @@ A_a */; + b: readonly /* @@ A_b */false; + c: readonly /* @@ A_c */1; +} + +/* @@@ A_a Error SyntaxError: Invalid Type. */ +/* @@@ A_a Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ + +/* @@@ A_b Error SyntaxError: Invalid Type. */ +/* @@@ A_b Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@@ A_b Error SyntaxError: Unexpected token 'false'. */ + +/* @@@ A_c Error SyntaxError: Invalid Type. */ +/* @@@ A_c Error SyntaxError: 'readonly' type modifier is only permitted on resizable array and tuple types. */ +/* @@@ A_c Error SyntaxError: Unexpected token '1'. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets b/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.ets new file mode 100644 index 0000000000000000000000000000000000000000..b29d1d1ad68cfe5ff313ee53f6153e376e1eae60 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly/readonly_static_var.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. + */ + +readonly static S = c' '; + +/* @@? 16:1 Error TypeError: Unresolved reference readonly */ +/* @@? 16:10 Error SyntaxError: Invalid Type. */ +/* @@? 16:10 Error SyntaxError: Unexpected token 'static'. */ +/* @@? 16:17 Error SyntaxError: Unexpected token 'S'. */ +/* @@? 16:17 Error TypeError: Unresolved reference S */ diff --git a/ets2panda/test/ast/compiler/ets/readonlyType_1.ets b/ets2panda/test/ast/compiler/ets/readonlyType_1.ets index bd3c6a1de676a586a7edaf92248e13c62a4ae79d..8a677d6521e06a57899f2117b5776990490dbb97 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyType_1.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyType_1.ets @@ -22,8 +22,9 @@ class A { function foo(a0: A) { let a: Readonly = new A(2) - a.fld = 5 + /* @@ label2 */a.fld = 5 } /* @@@ label Error TypeError: Cannot assign to a readonly variable fld */ +/* @@@ label2 Error TypeError: The 'Readonly' property cannot be reassigned. */ diff --git a/ets2panda/test/ast/compiler/ets/readonlyType_2.ets b/ets2panda/test/ast/compiler/ets/readonlyType_2.ets index 8556004ad48610f2628cbedb6502100710e9ed05..17d1eaf99c29a370fbcc440273606bed37a10746 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyType_2.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyType_2.ets @@ -19,7 +19,8 @@ class A { function foo(a0: A) { let a: Readonly = {fld: 3} - a.fld = 5 + /* @@ label2 */a.fld = 5 } /* @@@ label Error TypeError: Cannot assign to a readonly variable fld */ +/* @@@ label2 Error TypeError: The 'Readonly' property cannot be reassigned. */ diff --git a/ets2panda/test/ast/compiler/ets/readonlyType_3.ets b/ets2panda/test/ast/compiler/ets/readonlyType_3.ets index 35524e1793e69f92dd2d17139f4b5a46b7181ac6..9c5e0a1b2d1a3bd2e3d5f1ac5ab95cde0cdd0bf9 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyType_3.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyType_3.ets @@ -16,8 +16,9 @@ class A { /* @@ label */fld: Number = 2 foo (a0: Readonly) { - a0.fld = 5 + /* @@ label2 */a0.fld = 5 } } /* @@@ label Error TypeError: Cannot assign to a readonly variable fld */ +/* @@@ label2 Error TypeError: The 'Readonly' property cannot be reassigned. */ diff --git a/ets2panda/test/ast/compiler/ets/readonlyType_4.ets b/ets2panda/test/ast/compiler/ets/readonlyType_4.ets index 29a6e2383c608daf8cc7ae02a647935e311c6b51..82d154132b47ae32d209acffbfd80d41d9cbb49f 100644 --- a/ets2panda/test/ast/compiler/ets/readonlyType_4.ets +++ b/ets2panda/test/ast/compiler/ets/readonlyType_4.ets @@ -25,8 +25,9 @@ class B extends A {} class C extends B { fld: Number = 2 foo (a0: Readonly) { - a0.fld = 6 + /* @@ label2 */a0.fld = 6 } } /* @@@ label Error TypeError: Cannot assign to a readonly variable fld */ +/* @@@ label2 Error TypeError: The 'Readonly' property cannot be reassigned. */ diff --git a/ets2panda/test/ast/compiler/ets/readonly_array01.ets b/ets2panda/test/ast/compiler/ets/readonly_array01.ets new file mode 100644 index 0000000000000000000000000000000000000000..d377fa27f9c66e4041ebb53d2585c89e9f1e938b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly_array01.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. + */ + +function main() { + let v: readonly number[][] = [[1.0,2.0]] + v[0][0] = 3.0 // ok + v[0] = [] // CTE +} + +/* @@? 19:5 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ + diff --git a/ets2panda/test/ast/compiler/ets/readonly_array02.ets b/ets2panda/test/ast/compiler/ets/readonly_array02.ets new file mode 100644 index 0000000000000000000000000000000000000000..282f2fcfbabaad2e18007c28b8ee53be17fd62bc --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/readonly_array02.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. + */ + +type U1 = number[][] | string[] +type U2 = (readonly number[][]) | (readonly string[]) + +function main() { + let v: U1 | U2 = [[1.0,2.0]] + v[0] = [1.0,3.0] // CTE, readonly array +} + +/* @@? 21:5 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ + diff --git a/ets2panda/test/ast/compiler/ets/recordWithLambdaFunction2.ets b/ets2panda/test/ast/compiler/ets/recordWithLambdaFunction2.ets index 10e6cc1ed1ca895f6ce24c3ad28d7a7282c0904a..799b915f1086b036a2c6992dd65f930e67813d79 100644 --- a/ets2panda/test/ast/compiler/ets/recordWithLambdaFunction2.ets +++ b/ets2panda/test/ast/compiler/ets/recordWithLambdaFunction2.ets @@ -20,7 +20,9 @@ function main(): void { 2: (param: Number):string => { return "1" }, } - handlerMap[/* @@ label */2] = 1 + handlerMap[2] = 1 } -/* @@@ label Error TypeError: Cannot find index access method with the required signature. */ +/* @@? 23:5 Error TypeError: No matching indexing signature for $_set(int, int) */ +/* @@? 23:16 Error TypeError: Cannot find index access method with the required signature. */ +/* @@? 23:21 Error TypeError: Type 'int' is not compatible with type '(param: Double) => String' at index 2 */ diff --git a/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type.ets b/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type.ets index 96838d3c4b7680a6786094a01a6c6a95365fdc8c..4c1d8884cfd9d2829f8aa49d9764dd9b4cf80531 100644 --- a/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type.ets +++ b/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type.ets @@ -27,3 +27,4 @@ function main() { /* @@? 24:17 Error TypeError: Type '() => Double' cannot be assigned to type '() => void|Double' */ /* @@? 25:16 Error TypeError: Cannot use type 'void' as value. */ +/* @@? 25:17 Error TypeError: Cannot cast type '() => Double' to '() => void' */ diff --git a/ets2panda/test/ast/compiler/ets/this_type_invalid_return_type.ets b/ets2panda/test/ast/compiler/ets/return_this/this_type_invalid_return_type.ets similarity index 100% rename from ets2panda/test/ast/compiler/ets/this_type_invalid_return_type.ets rename to ets2panda/test/ast/compiler/ets/return_this/this_type_invalid_return_type.ets diff --git a/ets2panda/test/ast/compiler/ets/return_this/this_type_overridden_by_child_class.ets b/ets2panda/test/ast/compiler/ets/return_this/this_type_overridden_by_child_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..ad094e2accb9617483c103b67a911eaac1ba118f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/return_this/this_type_overridden_by_child_class.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 I { + foo(): this; +} + +abstract class A implements I { + foo/* @@ label */(): A { + return this; + } +} + +/* @@@ label Error TypeError: foo(): A in A cannot override foo(): I in I because overriding return type is not compatible with the other return type. */ +/* @@@ label Error TypeError: Method foo(): A in A not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/callExpr_pos.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/callExpr_pos.ets index 2b571996e4d9b78220e352142bf1f53fa5590ca5..cfaac5fee92c3b01b1df8f65227b7f3cb872f8a5 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/callExpr_pos.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/callExpr_pos.ets @@ -25,5 +25,4 @@ foo(1,2) foo(1.1) /* @@? 17:1 Warning Warning: Function foo with this assembly signature already declared. */ -/* @@? 23:1 Warning Warning: Detect duplicate signatures, use 'foo(..._: (Object|null|undefined)[]): void' to replace */ -/* @@? 23:5 Warning Warning: Variable 'b' is used before being assigned. */ +/* @@? 23:5 Error TypeError: Variable 'b' is used before being assigned. */ diff --git a/ets2panda/test/ast/compiler/ets/setArrayLength1.ets b/ets2panda/test/ast/compiler/ets/setArrayLength1.ets index efbc6f2a47ed4afc1b46a489eef90689a96360f4..2362ec8e7c8d72d5abaafc87ba005e7af8b23359 100644 --- a/ets2panda/test/ast/compiler/ets/setArrayLength1.ets +++ b/ets2panda/test/ast/compiler/ets/setArrayLength1.ets @@ -21,5 +21,3 @@ function main(): void { let test_var = new TestClass(); /* @@ label */test_var.test_array.length = 0; } - -/* @@@ label Error TypeError: Setting the length of an array is not permitted */ diff --git a/ets2panda/test/ast/compiler/ets/setArrayLength2.ets b/ets2panda/test/ast/compiler/ets/setArrayLength2.ets index 30fec02a972b8a0ac7e25b5e2b3fbd1aa4a4326c..fe0140ea69d6b5860c8690776489efb02cc51f2d 100644 --- a/ets2panda/test/ast/compiler/ets/setArrayLength2.ets +++ b/ets2panda/test/ast/compiler/ets/setArrayLength2.ets @@ -17,5 +17,3 @@ function main(): void { let test_array: int[] = [1, 2, 3]; /* @@ label */test_array.length = 0; } - -/* @@@ label Error TypeError: Setting the length of an array is not permitted */ diff --git a/ets2panda/test/ast/compiler/ets/setArrayLength3.ets b/ets2panda/test/ast/compiler/ets/setArrayLength3.ets index 43bb76acf3b94d52f5365960359082a1d17d4650..860ed277380b381acc4b481525ae1637d0d3985f 100644 --- a/ets2panda/test/ast/compiler/ets/setArrayLength3.ets +++ b/ets2panda/test/ast/compiler/ets/setArrayLength3.ets @@ -17,5 +17,3 @@ function main(): void { let test_array: int[] = [1, 2, 3] /* @@ label */test_array.length += 1 } - -/* @@@ label Error TypeError: Setting the length of an array is not permitted */ diff --git a/ets2panda/test/ast/compiler/ets/spreadMultiArrayInTuple.ets b/ets2panda/test/ast/compiler/ets/spreadMultiArrayInTuple.ets index cd474b876f3748250e6591fbde59fa06228dcbaa..de366a4ce9c8977af5dafbc712422a52ccb5c62b 100644 --- a/ets2panda/test/ast/compiler/ets/spreadMultiArrayInTuple.ets +++ b/ets2panda/test/ast/compiler/ets/spreadMultiArrayInTuple.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 @@ -21,9 +21,9 @@ function main() { let y2: [boolean, int, string, string] = /* @@ label3 */[true, /* @@ label4 */...x2, /* @@ label5 */...x3] } -/* @@@ label1 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ -/* @@@ label2 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ -/* @@@ label Error TypeError: Initializer has 2 elements, but tuple requires 4 */ -/* @@@ label4 Error TypeError: 'double[]' cannot be spread in tuple. */ -/* @@@ label5 Error TypeError: 'String[]' cannot be spread in tuple. */ -/* @@@ label3 Error TypeError: Initializer has 3 elements, but tuple requires 4 */ +/* @@? 18:56 Error TypeError: Initializer has 2 elements, but tuple requires 4 */ +/* @@? 18:72 Error TypeError: 'Array' cannot be spread in tuple. */ +/* @@? 18:94 Error TypeError: 'Array' cannot be spread in tuple. */ +/* @@? 21:61 Error TypeError: Initializer has 3 elements, but tuple requires 4 */ +/* @@? 21:83 Error TypeError: 'Array' cannot be spread in tuple. */ +/* @@? 21:105 Error TypeError: 'Array' cannot be spread in tuple. */ diff --git a/ets2panda/test/ast/compiler/ets/string_tuple_type_neg.ets b/ets2panda/test/ast/compiler/ets/string_tuple_type_neg.ets index 73023dd24bbe0810d50bc1f966ca7e86f39994b9..aa876db24447a59041e4bfb7238aeaa8d248a23f 100644 --- a/ets2panda/test/ast/compiler/ets/string_tuple_type_neg.ets +++ b/ets2panda/test/ast/compiler/ets/string_tuple_type_neg.ets @@ -18,13 +18,10 @@ type A = [n1:string, n2:string] /* @@? 16:11 Error TypeError: Cannot find type 'n1'. */ /* @@? 16:13 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 16:13 Error SyntaxError: Unexpected token ':'. */ -/* @@? 16:13 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:14 Error SyntaxError: Unexpected token 'string'. */ /* @@? 16:14 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 16:20 Error SyntaxError: Unexpected token ','. */ -/* @@? 16:20 Error SyntaxError: Unexpected token ','. */ -/* @@? 16:20 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:22 Error SyntaxError: Unexpected token 'n2'. */ /* @@? 16:25 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 16:25 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 16:31 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:31 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:31 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/superReferenceFromStaticContext.ets b/ets2panda/test/ast/compiler/ets/superReferenceFromStaticContext.ets index 1869f791d029a0686945d7f0dd025eca23315dff..0299dda17c0d864e191166a09f844f385760d404 100644 --- a/ets2panda/test/ast/compiler/ets/superReferenceFromStaticContext.ets +++ b/ets2panda/test/ast/compiler/ets/superReferenceFromStaticContext.ets @@ -14,7 +14,11 @@ */ class A { - a: int = 1; + private _a: int = 1; + + set a(p: int) { + this._a = p; + } } class B extends A { diff --git a/ets2panda/test/ast/compiler/ets/tolocalString.ets b/ets2panda/test/ast/compiler/ets/tolocalString.ets new file mode 100644 index 0000000000000000000000000000000000000000..e2576c4fd4f6f5090b1070e2e577071dae29c3c0 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/tolocalString.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 A { + toLocaleString = () => {} +} + +/* @@? 16:7 Error TypeError: Cannot inherit from class Object, because field toLocaleString is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_generic_function_param.ets b/ets2panda/test/ast/compiler/ets/tuple_generic_function_param.ets new file mode 100644 index 0000000000000000000000000000000000000000..541ffd049e6951c228db4be063ff9b5f3c1ae6bd --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/tuple_generic_function_param.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. + */ + +function foo(a: T[]): void {} + +foo<[int, string]>([[1, "a"]]) diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets index 9d8ca3b4304ca2f177b6f8b4cd53e8bfad418ec8..55c0a6e370ab4f429b1abf49c52bd226c2291929 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets @@ -18,4 +18,4 @@ function main(): void { const array: (number|boolean) [] = tuple } -/* @@? 18:40 Error TypeError: Type '[Double, Double, Boolean]' cannot be assigned to type '(Double|Boolean)[]' */ +/* @@? 18:40 Error TypeError: Type '[double, double, boolean]' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_5_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_5_neg.ets index 8b023e07d7280d915a96ef50d6d5bec66d1de7dd..6ccc172df0ffdffd33487c0ac07d36213729e7da 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_5_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_5_neg.ets @@ -21,9 +21,5 @@ function main(): void { /* @@? 18:21 Error SyntaxError: Invalid Type. */ /* @@? 18:21 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 18:21 Error SyntaxError: Unexpected token '...'. */ -/* @@? 18:21 Error SyntaxError: Unexpected token '...'. */ -/* @@? 18:21 Error SyntaxError: Unexpected token '...'. */ -/* @@? 18:32 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:32 Error SyntaxError: Unexpected token ']'. */ +/* @@? 18:24 Error SyntaxError: Unexpected token 'number'. */ /* @@? 18:32 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:34 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets index 866c00616fb831e8de44da3d0514e48391a702a5..d4b386b23d37f95e751d310215d7aaff283a47fd 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets @@ -22,11 +22,6 @@ function main(): void { /* @@? 18:29 Error SyntaxError: Invalid Type. */ /* @@? 18:29 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 18:29 Error SyntaxError: Unexpected token '...'. */ -/* @@? 18:29 Error SyntaxError: Unexpected token '...'. */ -/* @@? 18:29 Error SyntaxError: Unexpected token '...'. */ -/* @@? 18:37 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:37 Error SyntaxError: Unexpected token ']'. */ +/* @@? 18:32 Error SyntaxError: Unexpected token 'Int'. */ /* @@? 18:37 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:39 Error SyntaxError: Unexpected token '='. */ -/* @@? 18:45 Error TypeError: Array element type '"a"' is not assignable to explicit type 'int' */ -/* @@@ label Error TypeError: Type '[Double, String, *ERROR_TYPE*]' cannot be assigned to type '[Double, String, Int]' */ +/* @@@ label Error TypeError: Type '[double, String, *ERROR_TYPE*]' cannot be assigned to type '[double, String, Int]' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_union_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_union_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..34a2d31c5a5412e10a0a02a091d94183e2ffbf59 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/tuple_union_neg.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. + */ +let v: [number]|null = ["A"] + +/* @@? 15:25 Error TypeError: Array initializer's type is not assignable to tuple type at index: 0 */ + diff --git a/ets2panda/test/ast/compiler/ets/type_binding_neg_01.ets b/ets2panda/test/ast/compiler/ets/type_binding_01.ets similarity index 87% rename from ets2panda/test/ast/compiler/ets/type_binding_neg_01.ets rename to ets2panda/test/ast/compiler/ets/type_binding_01.ets index 923001a957774567cf2c621b582646f4efc09316..009b7a28b2430c1efd543177725ffc55592fa502 100644 --- a/ets2panda/test/ast/compiler/ets/type_binding_neg_01.ets +++ b/ets2panda/test/ast/compiler/ets/type_binding_01.ets @@ -19,5 +19,3 @@ import type {StandardExportedClass as IT1, ClassForExport as IT2} from /* @@ lab function main () { let c1 = new IT1 // compile-time error: cannot create objects of type IT1 } - -/* @@@ label Error TypeError: Cannot import 'StandardExportedClass', imported type imports only exported types. */ diff --git a/ets2panda/test/ast/compiler/ets/type_binding_neg_02.ets b/ets2panda/test/ast/compiler/ets/type_binding_02.ets similarity index 87% rename from ets2panda/test/ast/compiler/ets/type_binding_neg_02.ets rename to ets2panda/test/ast/compiler/ets/type_binding_02.ets index 3e4b0774c925082fef61ddb64db63a713a85eec5..417f0159e16e714e1b03e214a75041b19ba6b1cc 100644 --- a/ets2panda/test/ast/compiler/ets/type_binding_neg_02.ets +++ b/ets2panda/test/ast/compiler/ets/type_binding_02.ets @@ -19,5 +19,3 @@ import type {StandardExportedClass as IT1, ClassForExport as IT2} from /* @@ lab function main () { let c2 = new IT2 // compile-time error: cannot create objects of type IT2 } - -/* @@@ label Error TypeError: Cannot import 'StandardExportedClass', imported type imports only exported types. */ 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 c5da5e0c8230eaab5804519d338d12d57f6aa957..05eb89b3ebd56f196cad0dda0f033f5582055905 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 @@ -28,13 +28,12 @@ WeakSet [12] = new undefined() // *NOTE* error has printed twice, that is known issue #20560 -/* @@? 16:9 Error TypeError: Type 'null' is not constructible. */ /* @@? 16:9 Error TypeError: Type 'null' is not constructible. */ /* @@? 17:1 Error TypeError: Type 'null' is not constructible. */ /* @@? 18:1 Error TypeError: Type 'undefined' is not constructible. */ /* @@? 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: Class name 'WeakSet' used in the wrong context */ -/* @@? 26:1 Error TypeError: Object type doesn't have proper index access method. */ /* @@? 26:16 Error TypeError: Type 'undefined' is not constructible. */ diff --git a/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.ets b/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.ets index e183093f43332c10f492f6b8946756f152ee63cd..39be4eb79ae1de0b0bfcc5da375cd306abe800a6 100644 --- a/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.ets +++ b/ets2panda/test/ast/compiler/ets/type_error_processing/var_without_def.ets @@ -26,5 +26,5 @@ function foo() { /* @@? 16:1 Error TypeError: Unresolved reference a */ /* @@? 20:1 Error TypeError: Unresolved reference c */ -/* @@? 24:5 Error TypeError: Unresolved reference void */ +/* @@? 24:5 Error SyntaxError: Unexpected token 'void'. */ /* @@? 24:18 Error TypeError: Unresolved reference asyncGenerator */ diff --git a/ets2panda/test/runtime/ets/compate_with_void.ets b/ets2panda/test/ast/compiler/ets/typeof_on_primitive_and_ref_types.ets similarity index 60% rename from ets2panda/test/runtime/ets/compate_with_void.ets rename to ets2panda/test/ast/compiler/ets/typeof_on_primitive_and_ref_types.ets index 767d0c6bc308a556e1ac058e9cbe8ef38fba0712..11c112c76c0ee4180ad3b6836080bb83e7bc9a0c 100644 --- a/ets2panda/test/runtime/ets/compate_with_void.ets +++ b/ets2panda/test/ast/compiler/ets/typeof_on_primitive_and_ref_types.ets @@ -15,22 +15,26 @@ class A {} -function foo() {} - function main() { - let v = launch foo(); - assertTrue((await v) == undefined); - assertTrue((await v) === undefined); - - assertFalse((await v) == 123); - assertFalse((await v) === 123); + let a1: A ; + let a2: A ; + a1 = new A(); - assertFalse((await v) == new A()); - assertFalse((await v) === new A()) + let b1 : int; + let b2 : int; + b1 = 1; - assertTrue((await v) == null); - assertFalse((await v) === null); + let c1 = a1; + let c2 = /* @@ label1 */a2; - assertTrue((await v) == (await v)); - assertTrue((await v) === (await v)); + typeof a1; + typeof /* @@ label2 */a2; + typeof b1; + typeof b2; + typeof c1; + typeof c2; } + + +/* @@@ label1 Error TypeError: Variable 'a2' is used before being assigned. */ +/* @@@ label2 Error TypeError: Variable 'a2' is used before being assigned. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets b/ets2panda/test/ast/compiler/ets/union_generic_class_neg.ets similarity index 45% rename from ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets rename to ets2panda/test/ast/compiler/ets/union_generic_class_neg.ets index 555c100c078481c32e38300fd99a6310d4c8b66a..7bfd2cf937262bf035483ffce67df1e3bf0bd467 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets +++ b/ets2panda/test/ast/compiler/ets/union_generic_class_neg.ets @@ -13,17 +13,36 @@ * limitations under the License. */ +class A { + fld: T + constructor(p: T) { + this.fld = p + } +} + +class B { + fld: string = 'b' +} + +class C { + fld: Int = 10 +} + +let u1: B|C = new B +let u2: B|C = new C + +let u3: A|A = new A(11) +let u4: A|A = new A('a') + function main() { - let x1 = [1, "a"] - let y1: [int, string, int, string] = /* @@ label */[/* @@ label1 */...x1, /* @@ label2 */...x1] - let x2 = [2] - let x3 = ["abc", "abc"] - let y2: [boolean, int, string, string] = /* @@ label3 */[true, /* @@ label4 */...x2, /* @@ label5 */...x3] + assertEQ(u1.fld, 'b') + assertEQ(u2.fld, 10) + + assertEQ(u3.fld, 11) + assertEQ(u4.fld, 'a') } -/* @@? 18:56 Error TypeError: Initializer has 2 elements, but tuple requires 4 */ -/* @@? 18:72 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ -/* @@? 18:94 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ -/* @@? 21:61 Error TypeError: Initializer has 3 elements, but tuple requires 4 */ -/* @@? 21:83 Error TypeError: 'double[]' cannot be spread in tuple. */ -/* @@? 21:105 Error TypeError: 'String[]' cannot be spread in tuple. */ +/* @@? 38:14 Error TypeError: Member type must be the same for all union objects. */ +/* @@? 39:14 Error TypeError: Member type must be the same for all union objects. */ +/* @@? 41:14 Error TypeError: Member type must be the same for all union objects. */ +/* @@? 42:14 Error TypeError: Member type must be the same for all union objects. */ diff --git a/ets2panda/test/ast/compiler/ets/union_method.ets b/ets2panda/test/ast/compiler/ets/union_method.ets new file mode 100644 index 0000000000000000000000000000000000000000..9a46c72c4006ccf34fbd15d2ddb6a7f1098b2c1b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_method.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + shorting(v: string): void {} + ordinary(a: int, b: int, c: int): void {} + range(a: int, b: int, c: int, d: int, e: int, f: int): void {} +} + +class B { + shorting(v: string): void {} + ordinary(a: int, b: int, c: int): void {} + range(a: int, b: int, c: int, d: int, e: int, f: int): void {} +} + +function shorting(x: A|B) { + x.shorting("123") +} + +function ordinary(x: A|B) { + x.ordinary(1, 2, 3) +} + +function range(x: A|B) { + x.range(1, 2, 3, 4, 5, 6) +} diff --git a/ets2panda/test/ast/compiler/ets/union_method_2.ets b/ets2panda/test/ast/compiler/ets/union_method_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..73d2e9bd7e59175dd713f8491f76be2d6db1565e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_method_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. + */ + +class A { + foo(v: string): void {} + foo(v: int): void {} +} + +class B { + foo(v: string): void {} +} + +function foo(x: A|B) { + x.foo("123") +} diff --git a/ets2panda/test/ast/compiler/ets/union_method_3.ets b/ets2panda/test/ast/compiler/ets/union_method_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..80b3ba46de8235c370adad7a14ca5a2a1b568125 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_method_3.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + foo(v: string): void {} + foo(v: int): void {} +} + +class B { + foo(v: string): void {} + foo(v: int): void {} +} + +function foo(x: A|B) { + x.foo("123") +} diff --git a/ets2panda/test/ast/compiler/ets/union_method_4.ets b/ets2panda/test/ast/compiler/ets/union_method_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..ec919acd347782273ac29d284e84064e1767b3e6 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_method_4.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. + */ + +class A { + private foo(v: string): void {} + private bar(v: string): void {} +} + +class B { + foo(v: string): void {} + private bar(v: string): void {} +} + +function foo(x: A|B) { + /* @@ label */x.foo("123") +} + +function bar(x: A|B) { + /* @@ label2 */x.bar("123") +} + +/* @@@ label Error TypeError: Member type must be the same for all union objects. */ +/* @@@ label Error TypeError: No matching call signature */ +/* @@@ label2 Error TypeError: Signature bar(v: String): void is not visible here. */ +/* @@@ label2 Error TypeError: No matching call signature for bar("123") */ diff --git a/ets2panda/test/ast/compiler/ets/union_method_5.ets b/ets2panda/test/ast/compiler/ets/union_method_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..53e5d863680953786df967b54cb7e32fb1792406 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/union_method_5.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 { + foo(v: string) { console.log("A:" + v) } +} + +class B extends A { + foo(v: string) { console.log("B:" + v) } +} + +class C { + foo(v: string) { console.log("C:" + v) } +} + +class D extends C {} + +function test1(v: A|C) { + v.foo("123") +} + +function test2(v: B|C) { + v.foo("123") +} + +function test3(v: B|D) { + v.foo("123") +} + +test1(new A()) +test1(new C()) +test2(new B()) +test3(new D()) diff --git a/ets2panda/test/ast/compiler/ets/union_string_literals_7.ets b/ets2panda/test/ast/compiler/ets/union_string_literals_7.ets index ec12116eff5600e244b70b4f604c0ad2b888f131..f723e13d1855feb0f698a8d6201b7a32216c8abf 100644 --- a/ets2panda/test/ast/compiler/ets/union_string_literals_7.ets +++ b/ets2panda/test/ast/compiler/ets/union_string_literals_7.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 @@ -17,10 +17,8 @@ function foo(a: "aa"|"bb") { return a } -let x = ["aa", "bb", "aa"] // type of x is string[] +let x = ["aa", "bb", "aa"] // type of x is FixedArray let y = foo(x) -/* @@? 21:13 Error TypeError: Type 'String[]' is not compatible with type '"aa"|"bb"' at index 1 */ -/* @@? 21:9 Error TypeError: No matching call signature for foo(String[]) */ -/* @@? 21:13 Error TypeError: Type 'String[]' is not compatible with type '"aa"|"bb"' at index 1 */ -/* @@? 21:9 Error TypeError: No matching call signature for foo(String[]) */ +/* @@? 21:9 Error TypeError: No matching call signature for foo(Array) */ +/* @@? 21:13 Error TypeError: Type 'Array' is not compatible with type '"aa"|"bb"' at index 1 */ diff --git a/ets2panda/test/ast/compiler/ets/union_string_literals_8.ets b/ets2panda/test/ast/compiler/ets/union_string_literals_8.ets index 612cee173aaf576c84ce806d384dae321a7ef621..1b84b36edde24468edab05646668cef6652e663a 100644 --- a/ets2panda/test/ast/compiler/ets/union_string_literals_8.ets +++ b/ets2panda/test/ast/compiler/ets/union_string_literals_8.ets @@ -24,5 +24,3 @@ let y = foo(x) /* @@? 23:13 Error TypeError: Type 'String' is not compatible with type '"aa"|"bb"' at index 1 */ /* @@? 23:9 Error TypeError: No matching call signature for foo(String) */ -/* @@? 23:13 Error TypeError: Type 'String' is not compatible with type '"aa"|"bb"' at index 1 */ -/* @@? 23:9 Error TypeError: No matching call signature for foo(String) */ diff --git a/ets2panda/test/ast/compiler/ets/unmatch_arg_for_trailing_lambda.ets b/ets2panda/test/ast/compiler/ets/unmatch_arg_for_trailing_lambda.ets new file mode 100644 index 0000000000000000000000000000000000000000..b77849bcc5fe809180adaf9ae25c59e6a8b43f84 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/unmatch_arg_for_trailing_lambda.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. + */ + +function foo(a?: number, f?: () => void) { } + +foo(1, "2") +foo(1, 1) +foo(1, () => { return "1" }) + +/* @@? 18:1 Error TypeError: No matching call signature for foo(int, "2") */ +/* @@? 18:8 Error TypeError: Type '"2"' is not compatible with type '() => void|undefined' at index 2 */ +/* @@? 19:1 Error TypeError: No matching call signature for foo(int, int) */ +/* @@? 19:8 Error TypeError: Type 'int' is not compatible with type '() => void|undefined' at index 2 */ +/* @@? 20:23 Error TypeError: Unexpected return value, enclosing method return type is void. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets index 61acb173f6c4f7637e2e3033e6e6cbf5fa815909..43dba88366d7689ba0df603127b3152e737a3e09 100644 --- a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets +++ b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets @@ -17,4 +17,6 @@ function main() : void { let a: Byte = /* @@ label */new Byte(2); } +/* @@@ label Error TypeError: Expected 0 arguments, got 1. */ /* @@@ label Error TypeError: No matching construct signature for std.core.Byte(int) */ +/* @@? 17:42 Error TypeError: Type 'int' is not compatible with type 'byte' at index 1 */ diff --git a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets index 2727c5fe2cd30fa543645706d3ee1ce8aae15318..d918e3e7d3ef1c2fbb1d9d73a122a4e029d8f444 100644 --- a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets +++ b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets @@ -17,4 +17,6 @@ function main() : void { let e: Float = /* @@ label */new Float(6,"3"); } +/* @@@ label Error TypeError: Expected 0 arguments, got 2. */ +/* @@@ label Error TypeError: Expected 1 arguments, got 2. */ /* @@@ label Error TypeError: No matching construct signature for std.core.Float(int, "3") */ diff --git a/ets2panda/test/ast/compiler/ets/var_declaration.ets b/ets2panda/test/ast/compiler/ets/var_declaration.ets new file mode 100644 index 0000000000000000000000000000000000000000..2411ac75f8b68f3d74141204a32e2d5459a9dd67 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/var_declaration.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. + */ + +// (arkts-no-var) + var x = 42; + + /* @@? 17:6 Error SyntaxError: 'var' keyword is not supported. Use 'let' instead. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/variable_declaretion_neg_1.ets b/ets2panda/test/ast/compiler/ets/variable_declaretion_neg_1.ets index 7e3e9315ce71d6d64ef7ebba2c7c70242a40a5da..b4321b87c8349b7bd85ca6f199d131785c80f05d 100644 --- a/ets2panda/test/ast/compiler/ets/variable_declaretion_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/variable_declaretion_neg_1.ets @@ -16,8 +16,5 @@ let negative%%_ = 1 /* @@? 16:13 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? 16:13 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? 16:13 Error SyntaxError: Unexpected token '%'. */ /* @@? 16:13 Error SyntaxError: Unexpected token '%'. */ -/* @@? 16:14 Error SyntaxError: Unexpected token '%'. */ /* @@? 16:15 Error TypeError: Unresolved reference _ */ diff --git a/ets2panda/test/ast/compiler/ets/variance_typeparam_transmit.ets b/ets2panda/test/ast/compiler/ets/variance_typeparam_transmit.ets index a4b8860eac8d2e0df4c9de045623dee2649063de..9c96f4d42102cd61568283dfbf20e9f9b687c464 100644 --- a/ets2panda/test/ast/compiler/ets/variance_typeparam_transmit.ets +++ b/ets2panda/test/ast/compiler/ets/variance_typeparam_transmit.ets @@ -19,19 +19,20 @@ class B {} class A123{ readonly readonlyfield1:InB; - readonly readonlyfield2:/* @@ label1 */InB; //CTE + readonly readonlyfield2:/* @@ label1 */InB; //CTE readonly readonlyfield3:InB; readonly readonlyfield4:InB; - readonly readonlyfield5:InB<[T1,T3,number]>; - readonly readonlyfield7:/* @@ label2 */OutB; //CTE + readonly readonlyfield5:/* @@ label2 */InB<[T1,T3,number]>; //CTE + readonly readonlyfield7:/* @@ label3 */OutB; //CTE readonly readonlyfield8:OutB; readonly readonlyfield9:OutB; - readonly readonlyfield10:/* @@ label3 */B; //CTE - readonly readonlyfield11:/* @@ label4 */B; //CTE + readonly readonlyfield10:/* @@ label4 */B; //CTE + readonly readonlyfield11:/* @@ label5 */B; //CTE readonly readonlyfield12:B; } /* @@@ label1 Error TypeError: Type Parameter 'T2' is declared as 'out' but occurs in 'in' position. */ -/* @@@ label2 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'out' position. */ -/* @@@ label3 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'invariant' position. */ -/* @@@ label4 Error TypeError: Type Parameter 'T2' is declared as 'out' but occurs in 'invariant' position. */ +/* @@@ label2 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'invariant' position. */ +/* @@@ label3 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'out' position. */ +/* @@@ label4 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'invariant' position. */ +/* @@@ label5 Error TypeError: Type Parameter 'T2' is declared as 'out' but occurs in 'invariant' position. */ diff --git a/ets2panda/test/ast/compiler/ets/variance_typeparam_tuple.ets b/ets2panda/test/ast/compiler/ets/variance_typeparam_tuple.ets index bfa550babcb2d981d4798d92eaf227212615bed6..374aa69fb398b383fc39f012f7754d29379ba28e 100644 --- a/ets2panda/test/ast/compiler/ets/variance_typeparam_tuple.ets +++ b/ets2panda/test/ast/compiler/ets/variance_typeparam_tuple.ets @@ -18,14 +18,14 @@ class A{ field2:/* @@ label2 */[number,T2,string]; //CTE field3:[number,T3,string]; readonly readonlyfield1:/* @@ label3 */[number,T1,string]; //CTE - readonly readonlyfield2:[number,T2,string]; + readonly readonlyfield2:/* @@ label4 */[number,T2,string]; //CTE readonly readonlyfield3:[number,T3,string]; - returnTypeFunc1():/* @@ label4 */[number,T1,string]{ //CTE + returnTypeFunc1():/* @@ label5 */[number,T1,string]{ //CTE return this.readonlyfield1; } - returnTypeFunc2():[number,T2,string]{ + returnTypeFunc2():/* @@ label6 */[number,T2,string]{ //CTE return this.readonlyfield2; } @@ -33,13 +33,16 @@ class A{ return this.readonlyfield3; } - paramsFunc1(a:[number,T1,string]){} - paramsFunc2(a:/* @@ label5 */[number,T2,string]){} //CTE + paramsFunc1(a:/* @@ label7 */[number,T1,string]){} //CTE + paramsFunc2(a:/* @@ label8 */[number,T2,string]){} //CTE paramsFunc3(a:[number,T3,string]){} } -/* @@@ label1 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'invariant' position. */ -/* @@@ label2 Error TypeError: Type Parameter 'T2' is declared as 'out' but occurs in 'invariant' position. */ -/* @@@ label3 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'out' position. */ -/* @@@ label4 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'out' position. */ -/* @@@ label5 Error TypeError: Type Parameter 'T2' is declared as 'out' but occurs in 'in' position. */ +/* @@@ label1 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'invariant' position. */ +/* @@@ label2 Error TypeError: Type Parameter 'T2' is declared as 'out' but occurs in 'invariant' position. */ +/* @@@ label3 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'invariant' position. */ +/* @@@ label4 Error TypeError: Type Parameter 'T2' is declared as 'out' but occurs in 'invariant' position. */ +/* @@@ label5 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'invariant' position. */ +/* @@@ label6 Error TypeError: Type Parameter 'T2' is declared as 'out' but occurs in 'invariant' position. */ +/* @@@ label7 Error TypeError: Type Parameter 'T1' is declared as 'in' but occurs in 'invariant' position. */ +/* @@@ label8 Error TypeError: Type Parameter 'T2' is declared as 'out' but occurs in 'invariant' position. */ diff --git a/ets2panda/test/ast/compiler/ets/void_as_return_type_neg_1.ets b/ets2panda/test/ast/compiler/ets/void_as_return_type_neg_1.ets index 1626420399e8ddec4a2ba0c8ecc8e237cd7ee27e..619efc697f18b060d9318c7234fe8cccdeaad6aa 100644 --- a/ets2panda/test/ast/compiler/ets/void_as_return_type_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/void_as_return_type_neg_1.ets @@ -17,4 +17,4 @@ async function foo():Promise{ return void; } -/* @@? 17:12 Error TypeError: Unresolved reference void */ \ No newline at end of file +/* @@? 17:12 Error SyntaxError: Unexpected token 'void'. */ diff --git a/ets2panda/test/ast/compiler/ets/void_as_typeAnnotation_neg_1.ets b/ets2panda/test/ast/compiler/ets/void_as_typeAnnotation_neg_1.ets index 213354f0748fe34b26a7c83c767ce323b51f16ed..3b5b16d39b2cd293e8eeb4ac660f6ffdd005322c 100644 --- a/ets2panda/test/ast/compiler/ets/void_as_typeAnnotation_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/void_as_typeAnnotation_neg_1.ets @@ -15,5 +15,4 @@ function foo (): void let y = foo() /* @@? 16:9 Error TypeError: Cannot use type 'void' as value. */ -/* @@? 16:9 Error TypeError: Cannot use type 'void' as value. */ /* @@? 15:10 Error TypeError: Only abstract or native methods can't have body. */ diff --git a/ets2panda/test/ast/compiler/ets/void_as_value_neg_3.ets b/ets2panda/test/ast/compiler/ets/void_as_value_neg_3.ets index a292b7d1761aa0c0ded64a8031e5bf505359aefd..3608ddbfd289273e9dc87643256cd10b891e0306 100644 --- a/ets2panda/test/ast/compiler/ets/void_as_value_neg_3.ets +++ b/ets2panda/test/ast/compiler/ets/void_as_value_neg_3.ets @@ -15,7 +15,6 @@ function foo(x: T) {} -foo(/* @@ label */void) - -/* @@@ label Error TypeError: Unresolved reference void */ +foo(void) +/* @@? 18:11 Error SyntaxError: Unexpected token 'void'. */ diff --git a/ets2panda/test/ast/parser/ets/AllowSequence.ets b/ets2panda/test/ast/parser/ets/AllowSequence.ets index 3e72a4ceecf450336af8c0be3eb7c813c5bb51f8..1cba4591b8a47022f7352367060ace1bd3400b12 100644 --- a/ets2panda/test/ast/parser/ets/AllowSequence.ets +++ b/ets2panda/test/ast/parser/ets/AllowSequence.ets @@ -24,5 +24,3 @@ function main(): void { /* @@? 19:17 Error SyntaxError: Unexpected token, expected ')'. */ /* @@? 19:19 Error SyntaxError: Unexpected token 'x'. */ /* @@? 19:22 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:22 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:22 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/FunctionalTypeAsArrayElement.ets b/ets2panda/test/ast/parser/ets/FixedArray/FunctionalTypeAsArrayElement.ets index 43ec5bf3168e11e89ef8eedfe57a560f43c1e3f8..e6559e42e9ff6ba90dee5124c1222bc67a0ecfd8 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/FunctionalTypeAsArrayElement.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/FunctionalTypeAsArrayElement.ets @@ -19,4 +19,4 @@ function main(){ ] } -/* @@? 17:48 Error TypeError: Expected type for array literal should be an array type, got () => int[] */ +/* @@? 17:48 Error TypeError: Expected type for array literal should be an array type, got () => FixedArray */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/InvalidStatements3.ets b/ets2panda/test/ast/parser/ets/FixedArray/InvalidStatements3.ets index b9334bb5d7603461956eec9c9b1c04b0bf9755dd..6017bb34e3487ac7b9d70714377d954c4b3719e2 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/InvalidStatements3.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/InvalidStatements3.ets @@ -44,19 +44,21 @@ for (let i = 1 in [0, 1, 2]) {} /* @@? 18:9 Error TypeError: Argument must be an instance of 'Exception' or 'Error' */ /* @@? 18:12 Error TypeError: Cannot find type 'exception'. */ /* @@? 19:1 Error SyntaxError: Expected '{', got '}'. */ -/* @@? 19:1 Error SyntaxError: Expected '{', got '}'. */ /* @@? 22:5 Error SyntaxError: Expected '{', got 'let'. */ /* @@? 23:11 Error SyntaxError: Expected '{', got '('. */ +/* @@? 23:11 Error TypeError: Unresolved reference x */ /* @@? 27:7 Error SyntaxError: Expected '(', got '{'. */ /* @@? 27:7 Error TypeError: need to specify target type for class composite */ /* @@? 29:1 Error SyntaxError: Expected ')', got 'while'. */ /* @@? 29:7 Error SyntaxError: Expected '(', got 'identification literal'. */ +/* @@? 29:7 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 29:13 Error SyntaxError: Expected ')', got '{'. */ /* @@? 31:9 Error SyntaxError: Unexpected token 'let'. */ -/* @@? 31:9 Error SyntaxError: Unexpected token 'let'. */ +/* @@? 31:13 Error SyntaxError: Unexpected token 'x'. */ /* @@? 34:5 Error SyntaxError: Illegal 'use strict' directive in function with non-simple parameter list. */ -/* @@? 38:5 Error SyntaxError: Annotation declaration can not have access modifier. */ /* @@? 38:5 Error SyntaxError: Unexpected token 'private'. */ +/* @@? 38:5 Error SyntaxError: Annotation declaration can not have access modifier. */ +/* @@? 38:13 Error SyntaxError: Unexpected token '@'. */ /* @@? 38:14 Error TypeError: Cannot find type 'annotate'. */ /* @@? 42:16 Error SyntaxError: for-in loop variable declaration may not have an initializer. */ /* @@? 42:16 Error SyntaxError: Unexpected token 'in'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets b/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets index f5772aef2e96b242720055254163b45d9a40c694..d92079e5b4a5e99d81ab92bffd85ada1603e6b00 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets @@ -18,7 +18,7 @@ function foo(param? : Object) for (let i? of "blablabla") { } } -function foo(a : int = 10, b : int, c : int = 15) : int +function foo(b : int, a : int = 10, c : int = 15) : int { return a + b; } @@ -170,104 +170,101 @@ function main(): void { /* @@? 28:29 Error TypeError: Native, Abstract and Declare methods cannot have body. */ /* @@? 34:14 Error SyntaxError: The modifier for a constructor should be limited to access modifiers (private, internal, protected, public), and 'native' modifiers. */ /* @@? 37:41 Error SyntaxError: Only 'throws' can be used with function types. */ -/* @@? 39:14 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 39:14 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 39:14 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 39:14 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 39:24 Error TypeError: Unresolved reference int */ -/* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ -/* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ /* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ +/* @@? 39:29 Error SyntaxError: Unexpected token '{'. */ /* @@? 39:31 Error SyntaxError: return keyword should be used in function body. */ /* @@? 39:38 Error TypeError: All return statements in the function should be empty or have a value. */ -/* @@? 41:6 Error SyntaxError: Identifier expected, got 'number literal'. */ -/* @@? 43:6 Error SyntaxError: Type alias name cannot be 'null'. */ -/* @@? 43:6 Error SyntaxError: Identifier expected, got 'null'. */ -/* @@? 45:6 Error SyntaxError: Identifier expected, got 'this'. */ -/* @@? 47:8 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 41:1 Error TypeError: Unresolved reference type */ +/* @@? 41:6 Error SyntaxError: Unexpected token '123'. */ +/* @@? 41:6 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 41:10 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 41:12 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 43:6 Error SyntaxError: Unexpected token 'null'. */ +/* @@? 43:6 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 43:11 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 43:13 Error SyntaxError: Unexpected token 'byte'. */ +/* @@? 45:6 Error SyntaxError: Unexpected token 'this'. */ +/* @@? 45:6 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 45:6 Error TypeError: Cannot reference 'this' in this context. */ +/* @@? 45:11 Error SyntaxError: Invalid left-hand side in assignment expression. */ /* @@? 47:8 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 47:8 Error TypeError: Missing initializer in const declaration */ /* @@? 49:12 Error TypeError: The type of parameter 'a' cannot be inferred */ /* @@? 49:13 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 51:35 Error SyntaxError: Rest parameter must be the last formal parameter. */ /* @@? 51:37 Error SyntaxError: Unexpected token '...'. */ -/* @@? 51:37 Error SyntaxError: Unexpected token '...'. */ +/* @@? 51:40 Error SyntaxError: Unexpected token 'p'. */ /* @@? 51:43 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 51:43 Error TypeError: Unresolved reference FixedArray */ /* @@? 51:58 Error SyntaxError: Unexpected token, expected '('. */ -/* @@? 51:59 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ -/* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ -/* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ /* @@? 51:59 Error SyntaxError: Unexpected token ':'. */ +/* @@? 51:61 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 51:61 Error SyntaxError: Unexpected token 'int'. */ /* @@? 51:65 Error SyntaxError: Unexpected token '{'. */ /* @@? 52:5 Error SyntaxError: return keyword should be used in function body. */ -/* @@? 52:12 Error TypeError: Unresolved reference q */ /* @@? 52:12 Error TypeError: All return statements in the function should be empty or have a value. */ +/* @@? 52:12 Error TypeError: Unresolved reference q */ /* @@? 52:23 Error TypeError: Unresolved reference p */ -/* @@? 55:26 Error SyntaxError: Rest parameter should be of an array type. */ -/* @@? 59:23 Error SyntaxError: Rest parameter should be of an array type. */ +/* @@? 55:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ /* @@? 63:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 67:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 67:7 Error TypeError: Variable 'A' has already been declared. */ /* @@? 68:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ +/* @@? 73:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 73:7 Error TypeError: Variable 'A' has already been declared. */ /* @@? 74:11 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 77:20 Error TypeError: Interface expected here. */ /* @@? 77:22 Error TypeError: 'I' type does not exist. */ /* @@? 78:22 Error TypeError: Method fee(): int in B not overriding any method */ +/* @@? 83:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 83:7 Error TypeError: Variable 'A' has already been declared. */ /* @@? 84:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 92:7 Error TypeError: Variable 'A' has already been declared. */ +/* @@? 92:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 93:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 103:25 Error SyntaxError: Rest parameter should be of an array type. */ -/* @@? 104:32 Error SyntaxError: Rest parameter should be of an array type. */ -/* @@? 115:26 Error SyntaxError: Unexpected token 'case'. */ -/* @@? 115:26 Error SyntaxError: Unexpected token 'case'. */ -/* @@? 115:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 115:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 115:26 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 115:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 115:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 115:26 Error SyntaxError: Unexpected token 'case'. */ /* @@? 115:30 Error SyntaxError: Unexpected token ':'. */ -/* @@? 115:30 Error SyntaxError: Unexpected token ':'. */ +/* @@? 115:32 Error SyntaxError: Unexpected token 'U'. */ /* @@? 115:32 Error TypeError: Unresolved reference U */ /* @@? 115:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 115:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 115:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 115:34 Error SyntaxError: Unexpected token ':'. */ /* @@? 115:34 Error SyntaxError: Unexpected token ':'. */ +/* @@? 115:36 Error SyntaxError: Unexpected token 'T'. */ /* @@? 115:36 Error TypeError: Unresolved reference T */ /* @@? 115:38 Error SyntaxError: Unexpected token '{'. */ /* @@? 116:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 116:12 Error TypeError: All return statements in the function should be empty or have a value. */ -/* @@? 119:26 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 119:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ -/* @@? 119:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 119:26 Error SyntaxError: Unexpected token 'case'. */ /* @@? 119:26 Error SyntaxError: Unexpected token 'case'. */ +/* @@? 119:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 119:26 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 119:30 Error SyntaxError: Unexpected token ':'. */ -/* @@? 119:30 Error SyntaxError: Unexpected token ':'. */ -/* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ +/* @@? 119:32 Error SyntaxError: Unexpected token 'U'. */ /* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ /* @@? 119:34 Error SyntaxError: Unexpected token ':'. */ -/* @@? 119:34 Error SyntaxError: Unexpected token ':'. */ +/* @@? 119:36 Error SyntaxError: Unexpected token 'T'. */ /* @@? 119:38 Error SyntaxError: Unexpected token '{'. */ /* @@? 120:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 120:12 Error TypeError: All return statements in the function should be empty or have a value. */ /* @@? 123:5 Error SyntaxError: Identifier expected, got ','. */ /* @@? 123:6 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? 123:6 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 123:6 Error SyntaxError: Unexpected token 'abc'. */ /* @@? 123:6 Error TypeError: Unresolved reference abc */ /* @@? 127:1 Error SyntaxError: The modifier async cannot be used in an ambient context. */ /* @@? 132:14 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 137:16 Error SyntaxError: Catch clause variable cannot have an initializer. */ -/* @@? 137:16 Error SyntaxError: Expected ')', got '='. */ -/* @@? 137:16 Error SyntaxError: Expected '{', got '='. */ /* @@? 137:16 Error SyntaxError: Unexpected token '='. */ /* @@? 137:16 Error SyntaxError: Expected '{', got '='. */ +/* @@? 137:16 Error SyntaxError: Expected ')', got '='. */ +/* @@? 137:16 Error SyntaxError: Catch clause variable cannot have an initializer. */ +/* @@? 137:18 Error SyntaxError: Unexpected token '0'. */ /* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ -/* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ -/* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ +/* @@? 137:21 Error SyntaxError: Unexpected token '{'. */ /* @@? 141:16 Error TypeError: This expression is not callable. */ /* @@? 145:18 Error TypeError: A is abstract therefore cannot be instantiated. */ /* @@? 146:16 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ @@ -284,4 +281,4 @@ function main(): void { /* @@? 165:5 Error TypeError: This expression is not callable. */ /* @@? 166:5 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 166:5 Error TypeError: No matching call signature */ -/* @@? 288:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 285:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets b/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets index 76ed96a9dbab145115f8603718f98c3f9cfa11bf..b9680ece6b519c7de324906dd36facc03da5ac1d 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets @@ -171,16 +171,13 @@ function main(): void { /* @@? 112:16 Error TypeError: Static property 'fastaRepeat' must be accessed through it's class 'StringFasta' */ /* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ -/* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 112:48 Error TypeError: Static property 'ALU' must be accessed through it's class 'StringFasta' */ /* @@? 113:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ /* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ -/* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 113:46 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 114:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ /* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ -/* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 114:46 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 116:28 Error TypeError: 'expected' is a static property of 'StringFasta' */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/array_2.ets b/ets2panda/test/ast/parser/ets/FixedArray/array_2.ets index 84baaf71414aa7a3c62d580449689ad31ef562fc..4001142bd14ed4aef7788fdf0c2925ba790e279e 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/array_2.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/array_2.ets @@ -15,9 +15,7 @@ let c: FixedArray = [0.33 /* @@ label */0.66 0.99] -/* @@? 16:49 Error SyntaxError: Unexpected token, expected ',' or ']'. */ -/* @@? 16:49 Error SyntaxError: Unexpected token '0.66'. */ +/* @@@ label Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@@ label Error SyntaxError: Unexpected token '0.66'. */ /* @@? 16:54 Error SyntaxError: Unexpected token '0.99'. */ /* @@? 16:58 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:58 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:58 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/array_missing_element.ets b/ets2panda/test/ast/parser/ets/FixedArray/array_missing_element.ets index 5dad4dde778b63b2a8e8366d594a75d6b5c89d1c..e61d897a805f82ff6f47969324a282bb00025261 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/array_missing_element.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/array_missing_element.ets @@ -18,3 +18,7 @@ function foo(): void { } /* @@? 17:53 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:55 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 17:55 Error SyntaxError: Unexpected token '4'. */ +/* @@? 17:56 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:58 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/array_type.ets b/ets2panda/test/ast/parser/ets/FixedArray/array_type.ets index 61f88fea8fec09a7cac91d203a1e244d2f9aebdd..39c8b1c969a52b4b3a09a5482f9d9fca8da7ea95 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/array_type.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/array_type.ets @@ -24,8 +24,8 @@ class array_type { } } +/* @@@ label Error TypeError: Property 'a' might not have been initialized. */ +/* @@@ label1 Error TypeError: Property 'f' might not have been initialized. */ /* @@@ label2 Error TypeError: Function with a non void return type must return a value. */ /* @@@ label3 Error TypeError: Function with a non void return type must return a value. */ -/* @@@ label Warning Warning: Property 'a' might not have been initialized. */ -/* @@@ label1 Warning Warning: Property 'f' might not have been initialized. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/default_parameters_multi_error.ets b/ets2panda/test/ast/parser/ets/FixedArray/default_parameters_multi_error.ets index 90383e9969b424b3ce3ceac38673537c6bfcff3c..f69963fdb3b112e24ede6e29a8049815d988cdb2 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/default_parameters_multi_error.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/default_parameters_multi_error.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -function foo(a : int = 10, b : int, c : int = 15) : int +function foo(b : int, a : int = 10, c : int = 15) : int { return a + b; } diff --git a/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets index b5811a66f5d7fc3dbb31dd0dab0c422404e172e2..fd74b049d9cf1f7fa1811afceca01c352bfc419e 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets @@ -32,4 +32,4 @@ function main(): void { } } -/* @@@ label Error TypeError: Source element type 'double' is not assignable to the loop iterator type 'float'. */ +/* @@? 30:17 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'float'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets b/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets index 5267d9b7a5991204ceb7126c7f3c1b47da829788..8e4083148a5f190ec911fb41311e7eb5b43d70f3 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets @@ -19,8 +19,5 @@ function main(): void { s.toString() let a: int [] = [1, 2] let b = s ?? a; - /* @@ label */b.toString(); + b.toString(); } - -/* @@? 22:19 Error TypeError: Member type must be the same for all union objects. */ -/* @@? 22:19 Error TypeError: Type String|int[] is illegal in union member expression. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets b/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets index e3fef3a17680db97880f0a0704eb882207e3cc01..718311fef0baa8fad8657edc940faafe4c31ce89 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/invalidTypes.ets @@ -43,71 +43,46 @@ let var6: [a0: , a1: ]; /* @@? 24:23 Error SyntaxError: Unexpected token, expected '>'. */ /* @@? 24:23 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 24:23 Error SyntaxError: Unexpected token '>'. */ -/* @@? 24:23 Error SyntaxError: Unexpected token '>'. */ -/* @@? 24:23 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 24:23 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 24:26 Error SyntaxError: Unexpected token 'number'. */ /* @@? 24:26 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 24:26 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 24:33 Error SyntaxError: Unexpected token ','. */ -/* @@? 24:33 Error SyntaxError: Unexpected token ','. */ -/* @@? 24:33 Error SyntaxError: Unexpected token ','. */ -/* @@? 24:33 Error SyntaxError: Unexpected token ','. */ +/* @@? 24:35 Error SyntaxError: Unexpected token 'FixedArray'. */ /* @@? 24:35 Error TypeError: Unresolved reference FixedArray */ /* @@? 24:46 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:46 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:46 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:46 Error SyntaxError: Unexpected token '...'. */ +/* @@? 24:49 Error SyntaxError: Unexpected token 'string'. */ /* @@? 24:49 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 24:56 Error SyntaxError: Unexpected token ']'. */ -/* @@? 24:56 Error SyntaxError: Unexpected token ']'. */ -/* @@? 24:56 Error SyntaxError: Unexpected token ']'. */ -/* @@? 24:56 Error SyntaxError: Unexpected token ']'. */ /* @@? 26:12 Error TypeError: FixedArray must have only one type parameter. */ /* @@? 26:23 Error SyntaxError: Invalid Type. */ /* @@? 26:23 Error SyntaxError: Unexpected token, expected '>'. */ /* @@? 26:23 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 26:23 Error SyntaxError: Unexpected token '>'. */ -/* @@? 26:23 Error SyntaxError: Unexpected token '>'. */ -/* @@? 26:23 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 26:23 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 26:26 Error SyntaxError: Unexpected token 'number'. */ +/* @@? 26:26 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 26:26 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 26:33 Error SyntaxError: Unexpected token ','. */ -/* @@? 26:33 Error SyntaxError: Unexpected token ','. */ -/* @@? 26:33 Error SyntaxError: Unexpected token ','. */ -/* @@? 26:33 Error SyntaxError: Unexpected token ','. */ +/* @@? 26:35 Error SyntaxError: Unexpected token 'string'. */ /* @@? 26:35 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 26:41 Error SyntaxError: Unexpected token ']'. */ -/* @@? 26:41 Error SyntaxError: Unexpected token ']'. */ -/* @@? 26:41 Error SyntaxError: Unexpected token ']'. */ /* @@? 28:18 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 28:18 Error SyntaxError: Unexpected token '?'. */ -/* @@? 28:18 Error SyntaxError: Unexpected token '?'. */ /* @@? 28:19 Error SyntaxError: Unexpected token ']'. */ -/* @@? 28:19 Error SyntaxError: Unexpected token, expected ':'. */ -/* @@? 28:20 Error SyntaxError: Unexpected token ';'. */ /* @@? 30:18 Error SyntaxError: Unexpected token ':'. */ /* @@? 30:18 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 30:18 Error SyntaxError: Unexpected token ':'. */ -/* @@? 30:18 Error SyntaxError: Unexpected token ':'. */ /* @@? 30:20 Error SyntaxError: Unexpected token '...'. */ -/* @@? 30:20 Error SyntaxError: Unexpected token '...'. */ -/* @@? 30:23 Error TypeError: Unresolved reference int */ -/* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ -/* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ +/* @@? 30:23 Error SyntaxError: Unexpected token 'int'. */ /* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ /* @@? 32:19 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 32:19 Error SyntaxError: Unexpected token 'number'. */ /* @@? 32:19 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ -/* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ -/* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ /* @@? 35:21 Error SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct and extension functions. */ /* @@? 38:12 Error TypeError: Cannot find type 'a0'. */ /* @@? 38:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 38:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 38:14 Error SyntaxError: Unexpected token ':'. */ /* @@? 38:14 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 38:16 Error SyntaxError: Unexpected token ','. */ -/* @@? 38:16 Error SyntaxError: Unexpected token ','. */ -/* @@? 38:22 Error SyntaxError: Unexpected token ']'. */ +/* @@? 38:18 Error SyntaxError: Unexpected token 'a1'. */ /* @@? 38:22 Error SyntaxError: Unexpected token ']'. */ /* @@? 38:22 Error SyntaxError: Label must be followed by a loop statement. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/main_entry_point_3.ets b/ets2panda/test/ast/parser/ets/FixedArray/main_entry_point_3.ets index 8cb86d35d9153f12b192925a2cb4429a2d359e11..333c113df0a429d9d7606eb372f34b4c2ee5b024 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/main_entry_point_3.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/main_entry_point_3.ets @@ -17,4 +17,4 @@ function main(/* @@ label */i : FixedArray): void { return; } -/* @@? 16:29 Error TypeError: Only 'string[]' type argument is allowed. */ +/* @@? 16:29 Error TypeError: Only 'FixedArray' type argument is allowed. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/n_arrayHoldingNullValue.ets b/ets2panda/test/ast/parser/ets/FixedArray/n_arrayHoldingNullValue.ets index 0c383d07e26ae0e0b88aa9cdbe50d79706c6412d..89238cd2b0e11ef99f20abce231316bb180c907f 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/n_arrayHoldingNullValue.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/n_arrayHoldingNullValue.ets @@ -18,5 +18,5 @@ function main(): void { let d: FixedArray = /* @@ label1 */null; } -/* @@? 17:48 Error TypeError: Type 'null' cannot be assigned to type 'float[]' */ -/* @@? 18:46 Error TypeError: Type 'null' cannot be assigned to type 'char[]' */ +/* @@? 17:48 Error TypeError: Type 'null' cannot be assigned to type 'FixedArray' */ +/* @@? 18:46 Error TypeError: Type 'null' cannot be assigned to type 'FixedArray' */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test1.ets b/ets2panda/test/ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test1.ets index e6e3685fd8b3c889bfc56b31b54979a81c8d823e..2ca4a147db10bcc9a0838995452394b5d9056bfe 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test1.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test1.ets @@ -19,5 +19,5 @@ function foo (p: FixedArray) { let x: Readonly> = [] /* @@ label */foo(/* @@ label1 */x) -/* @@? 20:15 Error TypeError: No matching call signature for foo(readonly int[]) */ -/* @@? 20:34 Error TypeError: Type 'readonly int[]' is not compatible with type 'int[]' at index 1 */ +/* @@? 20:15 Error TypeError: No matching call signature for foo(readonly FixedArray) */ +/* @@? 20:34 Error TypeError: Type 'readonly FixedArray' is not compatible with type 'FixedArray' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test4.ets b/ets2panda/test/ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test4.ets index 1ab798fd94fc9bfd063833ba0d1fd546b5b75ff5..4b0401da4408ab8d8146fd663d5641c0995539a4 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test4.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test4.ets @@ -18,4 +18,4 @@ function foo (x: Readonly>) { let x1 : FixedArray x1 = /* @@ label */x } -/* @@? 19:24 Error TypeError: Type 'readonly int[]' cannot be assigned to type 'int[]' */ +/* @@? 19:24 Error TypeError: Type 'readonly FixedArray' cannot be assigned to type 'FixedArray' */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/rest_parameter_04.ets b/ets2panda/test/ast/parser/ets/FixedArray/rest_parameter_04.ets index 37e28e816e2e71d9ba76c1f351726c16037d2f60..6d283778e6ae84845907e4991fad635243dae781 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/rest_parameter_04.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/rest_parameter_04.ets @@ -18,6 +18,6 @@ function hehe(...items: FixedArray/* @@ label */: void /* @@ label1 */{ } /* @@? 16:10 Error TypeError: Only abstract or native methods can't have body. */ -/* @@? 16:57 Error SyntaxError: Rest parameter must be the last formal parameter. */ -/* @@? 16:59 Error TypeError: Unresolved reference void */ -/* @@? 16:79 Error SyntaxError: Unexpected token '{'. */ +/* @@@ label Error SyntaxError: Rest parameter must be the last formal parameter. */ +/* @@? 16:59 Error SyntaxError: Unexpected token 'void'. */ +/* @@@ label1 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/spreadArrayInTuple.ets b/ets2panda/test/ast/parser/ets/FixedArray/spreadArrayInTuple.ets index 2b0ded62187d79d4cfcad0fc3e273da95a603a0c..b663614e7a9ab639b15eb5038e0c0e358497b8c1 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/spreadArrayInTuple.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/spreadArrayInTuple.ets @@ -21,6 +21,6 @@ function main() { } /* @@? 18:43 Error TypeError: Initializer has 1 elements, but tuple requires 2 */ -/* @@? 18:59 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ +/* @@? 18:59 Error TypeError: 'Array' cannot be spread in tuple. */ /* @@? 20:53 Error TypeError: Initializer has 2 elements, but tuple requires 3 */ -/* @@? 20:75 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ +/* @@? 20:75 Error TypeError: 'Array' cannot be spread in tuple. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/superInConstructor3.ets b/ets2panda/test/ast/parser/ets/FixedArray/superInConstructor3.ets index adea5db47524e7ef337b4b9b6ca231e9f1c57b3c..cd7cb9cd0ec039d824c527c5438c83095118f661 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/superInConstructor3.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/superInConstructor3.ets @@ -14,10 +14,14 @@ */ class A { - public x: int; + private _x: int; + + get x(): int{ + return this._x; + } public constructor() { - this.x = 1; + this._x = 1; } public constructor(arg: boolean) { diff --git a/ets2panda/test/ast/parser/ets/FixedArray/trailing_comma_1.ets b/ets2panda/test/ast/parser/ets/FixedArray/trailing_comma_1.ets index 2c036d74f106c5a616f7269b16f4c3e885121f6c..0a9abed75eba10b27082aa120249b6941158b3da 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/trailing_comma_1.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/trailing_comma_1.ets @@ -39,6 +39,10 @@ foo(,) /* @@? 24:15 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 24:15 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 28:12 Error SyntaxError: Unexpected token ','. */ +/* @@? 28:14 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 28:14 Error SyntaxError: Unexpected token '2'. */ +/* @@? 28:15 Error SyntaxError: Unexpected token ','. */ +/* @@? 28:16 Error SyntaxError: Unexpected token ']'. */ /* @@? 30:5 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 31:1 Error TypeError: No matching call signature for foo(a[0], a[1], ...a) */ /* @@? 31:5 Error TypeError: Indexed access is not supported for such expression type. */ @@ -46,16 +50,20 @@ foo(,) /* @@? 31:17 Error TypeError: Spread argument for the rest parameter can be only one. */ /* @@? 32:5 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 32:10 Error SyntaxError: Unexpected token ','. */ +/* @@? 32:11 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 32:11 Error SyntaxError: Unexpected token 'a'. */ /* @@? 32:11 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 32:15 Error SyntaxError: Unexpected token ')'. */ /* @@? 33:5 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 33:10 Error SyntaxError: Unexpected token ','. */ /* @@? 34:5 Error SyntaxError: Unexpected token ','. */ +/* @@? 34:6 Error SyntaxError: Unexpected token 'a'. */ +/* @@? 34:6 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 34:6 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 34:10 Error SyntaxError: Unexpected token ')'. */ /* @@? 35:5 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 35:10 Error SyntaxError: Unexpected token 'a'. */ /* @@? 35:10 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 35:10 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 35:14 Error SyntaxError: Unexpected token ')'. */ -/* @@? 35:14 Error SyntaxError: Unexpected token ')'. */ -/* @@? 35:14 Error SyntaxError: Unexpected token ')'. */ /* @@? 36:5 Error SyntaxError: Unexpected token ','. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/tuple_type_2_neg.ets b/ets2panda/test/ast/parser/ets/FixedArray/tuple_type_2_neg.ets index cb10ec2a93c1f225bd7558bc928c8180eb25f748..fb10b017ca1fed99c4c0cc5a090da5bf4703f893 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/tuple_type_2_neg.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/tuple_type_2_neg.ets @@ -17,20 +17,14 @@ let a: [number, FixedArray<...number>, number] = [1, 2, 3]; /* @@? 17:17 Error TypeError: FixedArray must have only one type parameter. */ +/* @@? 17:28 Error SyntaxError: Invalid Type. */ /* @@? 17:28 Error SyntaxError: Unexpected token, expected '>'. */ -/* @@? 17:28 Error SyntaxError: Unexpected token '>'. */ -/* @@? 17:28 Error SyntaxError: Unexpected token '>'. */ /* @@? 17:28 Error SyntaxError: Unexpected token, expected ',' or ']'. */ -/* @@? 17:28 Error SyntaxError: Invalid Type. */ -/* @@? 17:28 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 17:28 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@? 17:28 Error SyntaxError: Unexpected token '>'. */ +/* @@? 17:31 Error SyntaxError: Unexpected token 'number'. */ /* @@? 17:31 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 17:31 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 17:38 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:38 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:38 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:38 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:40 Error SyntaxError: Unexpected token 'number'. */ /* @@? 17:40 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:46 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:46 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:46 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:48 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/type_argument_conversion.ets b/ets2panda/test/ast/parser/ets/FixedArray/type_argument_conversion.ets index 19e6582ccccb56d90f0cf7e8cd6e23602a727706..28ab42744129648f800023dd0aac170f54a5e4e6 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/type_argument_conversion.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/type_argument_conversion.ets @@ -30,11 +30,8 @@ function main(): int { return 0; } -/* @@? 29:34 Error TypeError: No matching construct signature for type_argument_conversion.A(A[]) */ -/* @@? 29:58 Error TypeError: No Matching Parameterless Constructor, parameter count 1 */ -/* @@? 29:58 Error TypeError: No matching parameterless constructor */ -/* @@? 29:58 Error TypeError: Signature is not available here. */ -/* @@? 29:58 Error TypeError: Type 'A[]' is not compatible with type 'A[]' at index 1 */ +/* @@? 29:34 Error TypeError: No matching construct signature for type_argument_conversion.A(Array>) */ /* @@? 29:58 Error TypeError: No Matching Parameterless Constructor, parameter count 1 */ /* @@? 29:58 Error TypeError: No matching parameterless constructor */ /* @@? 29:58 Error TypeError: Signature is not available here. */ +/* @@? 29:58 Error TypeError: Type 'Array>' is not compatible with type 'FixedArray>' at index 1 */ 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 f3c1bde715740ef2b3570df6573fd346bdc0ea83..e53b749a075a392a54ed6b4d42e8755c957f0e14 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets @@ -22,10 +22,8 @@ function foo(...^number: FixedArray): int { /* @@? 16:18 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 16:18 Error SyntaxError: Rest parameter must be the last formal parameter. */ /* @@? 16:41 Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:41 Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:42 Error SyntaxError: Unexpected token ':'. */ /* @@? 16:42 Error SyntaxError: Unexpected token ':'. */ -/* @@? 16:44 Error TypeError: Unresolved reference int */ +/* @@? 16:44 Error SyntaxError: Unexpected token '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 */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets index 35bf7c584f538d138a257f1db0d8c9e60706c409..aa83ad803abe5bd92d608f036d21617bc56dcb92 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_36.ets @@ -36,13 +36,8 @@ export class AccessNSieve { /* @@? 29:13 Error TypeError: Unresolved reference i */ /* @@? 29:14 Error SyntaxError: Expected ';', got ':'. */ /* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:14 Error SyntaxError: Expected ')', got ':'. */ -/* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:16 Error TypeError: Unresolved reference int */ +/* @@? 29:16 Error SyntaxError: Expected ')', got 'int'. */ +/* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ /* @@? 29:25 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ -/* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ -/* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ +/* @@? 29:38 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_38.ets b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_38.ets index 444527e09fc4cd6cbd77340dc5e1ea2e41851c46..f46c984335d7ec8f5e7826f18f5c08ae13da2d26 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_38.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_38.ets @@ -23,7 +23,6 @@ let func3: (f: (a: number, b: string) => FixedArray): FixedArray // let func3: (f: (a: number, b: string) => FixedArray): FixedArray) => (a: number, b: boolean) => true; -/* @@? 19:8 Error TypeError: 'void' used as type annotation. */ /* @@? 19:8 Error TypeError: 'void' used as type annotation. */ /* @@? 22:61 Error SyntaxError: Unexpected token, expected '=>'. */ /* @@? 22:61 Error SyntaxError: Unexpected token, expected '('. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_42.ets b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_42.ets index 0eebb0e52d702e1efe68b3c3223b138d77b4cf33..69c59a936f4ae1a8d4ac3a37828c1cccbcb1da58 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_42.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_42.ets @@ -15,5 +15,5 @@ // Int[1,2,3,4,5] let a: number = new Int[1 -/* @@? 16:17 Error TypeError: Type 'Int[]' cannot be assigned to type 'double' */ -/* @@? 20:1 Error SyntaxError: Expected ']', got 'eos'. */ +/* @@? 16:17 Error TypeError: Type 'FixedArray' cannot be assigned to type 'double' */ +/* @@? 20:1 Error SyntaxError: Expected ']', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_47.ets b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_47.ets index b2c56eccbd2651df9700758fa4e1a911ac65818a..fd6345344435a3617b6b71ea48864d9189c6f265 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_47.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_47.ets @@ -15,7 +15,7 @@ let isPrime: FixedArray = new int[[]][[] -/* @@? 16:32 Error TypeError: Type 'int[][]' cannot be assigned to type 'int[]' */ +/* @@? 16:32 Error TypeError: Type 'FixedArray>' cannot be assigned to type 'FixedArray' */ /* @@? 16:40 Error TypeError: Can't resolve array type */ /* @@? 16:44 Error TypeError: Can't resolve array type */ -/* @@? 22:1 Error SyntaxError: Expected ']', got 'eos'. */ +/* @@? 22:1 Error SyntaxError: Expected ']', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/wrong-union-array-assignment.ets b/ets2panda/test/ast/parser/ets/FixedArray/wrong-union-array-assignment.ets index 3f5cb64de4c2fb2f9eb95453f8d437140e892063..287b7a65a58659fd02a510b1fb55677a071ceba4 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/wrong-union-array-assignment.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/wrong-union-array-assignment.ets @@ -24,4 +24,4 @@ function main() array = /* @@ label */new Bad(); } -/* @@? 24:27 Error TypeError: Type 'Bad' cannot be assigned to type '(Int|Double|String)[]' */ +/* @@? 24:27 Error TypeError: Type 'Bad' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/parser/ets/FunctionalTypeAsArrayElement.ets b/ets2panda/test/ast/parser/ets/FunctionalTypeAsArrayElement.ets index e722a6f371f99f579363d977085e192bbd4dc00b..4e6298318b225a5247e2ccc51396fddc999dd435 100644 --- a/ets2panda/test/ast/parser/ets/FunctionalTypeAsArrayElement.ets +++ b/ets2panda/test/ast/parser/ets/FunctionalTypeAsArrayElement.ets @@ -19,4 +19,4 @@ function main(){ ] } -/* @@@ label Error TypeError: Expected type for array literal should be an array type, got () => int[] */ +/* @@? 17:38 Error TypeError: Expected type for array literal should be an array type, got () => Array */ diff --git a/ets2panda/test/ast/parser/ets/InitialCheckForGeneric.ets b/ets2panda/test/ast/parser/ets/InitialCheckForGeneric.ets index 199526bf1ad922508fedc624e5c0889da71a7d67..42a51a43a820e9bf4dc5f2e6af4cc21bb4ff18fa 100644 --- a/ets2panda/test/ast/parser/ets/InitialCheckForGeneric.ets +++ b/ets2panda/test/ast/parser/ets/InitialCheckForGeneric.ets @@ -26,5 +26,5 @@ function main(): void { foo() } -/* @@@ label Warning Warning: Variable 'u' is used before being assigned. */ -/* @@@ label1 Warning Warning: Variable 'v' is used before being assigned. */ +/* @@@ label Error TypeError: Variable 'u' is used before being assigned. */ +/* @@@ label1 Error TypeError: Variable 'v' is used before being assigned. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidClasses.ets b/ets2panda/test/ast/parser/ets/InvalidClasses.ets index 9e535a9aadcd0c9e74f176ea0b0635f7b8db9055..85d1c1fbf9e80b6d9045d25c5e6e0a15da8f7904 100644 --- a/ets2panda/test/ast/parser/ets/InvalidClasses.ets +++ b/ets2panda/test/ast/parser/ets/InvalidClasses.ets @@ -90,7 +90,7 @@ interface I1 { /* @@? 26:18 Error SyntaxError: Native method cannot be async. */ /* @@? 27:5 Error TypeError: Non abstract class has abstract method. */ /* @@? 27:20 Error SyntaxError: Abstract method cannot be async. */ -/* @@? 35:5 Error SyntaxError: Only one static block is allowed. */ +/* @@? 35:5 Error SyntaxError: Only one static block is allowed in one namespace or class. */ /* @@? 38:10 Error SyntaxError: Duplicated modifier is not allowed. */ /* @@? 41:5 Error SyntaxError: The special predefined method '$_get' should have exactly one required parameter. */ /* @@? 41:5 Error SyntaxError: The special predefined method '$_get' cannot be asynchronous. */ @@ -128,4 +128,3 @@ interface I1 { /* @@? 78:8 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 78:8 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 79:1 Error SyntaxError: Unexpected token '}'. */ -/* @@? 79:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidExpressions.ets b/ets2panda/test/ast/parser/ets/InvalidExpressions.ets index 728819299f84b6df4331c44d6700375e948bdbfc..4a96a1fe0bef86b137e37cc7ba6366f84e05f169 100644 --- a/ets2panda/test/ast/parser/ets/InvalidExpressions.ets +++ b/ets2panda/test/ast/parser/ets/InvalidExpressions.ets @@ -106,7 +106,6 @@ function f7(a: (b: int = 0) => int): void { /* @@? 55:10 Error TypeError: Only abstract or native methods can't have body. */ /* @@? 55:24 Error SyntaxError: Unexpected token '@@'. */ /* @@? 55:24 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 55:24 Error SyntaxError: Unexpected token '@@'. */ /* @@? 55:26 Error SyntaxError: Unexpected token ')'. */ /* @@? 55:27 Error SyntaxError: Unexpected token ':'. */ /* @@? 55:29 Error TypeError: Unresolved reference void */ diff --git a/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets b/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets index 72316999b9d5a269d4916313f7ad5e702584fd67..0509c0f38ca13380e5d3620346a366f04b3692f3 100644 --- a/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets +++ b/ets2panda/test/ast/parser/ets/InvalidExpressions1.ets @@ -36,65 +36,45 @@ function f(x: int): void { a?.[1+2); let a = [1, 2, 3); -// This line should be the last line to correctly test closing brace. - /* @@? 16:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:18 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 16:18 Error SyntaxError: Unexpected token '2'. */ +/* @@? 16:19 Error SyntaxError: Unexpected token ']'. */ /* @@? 18:3 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 18:3 Error SyntaxError: Unexpected token '...'. */ -/* @@? 18:3 Error SyntaxError: Unexpected token '...'. */ -/* @@? 18:3 Error SyntaxError: Unexpected token '...'. */ -/* @@? 18:6 Error SyntaxError: Unexpected token ','. */ /* @@? 18:6 Error SyntaxError: Unexpected token ','. */ +/* @@? 18:8 Error SyntaxError: Unexpected token '55'. */ /* @@? 18:10 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:10 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:10 Error SyntaxError: Unexpected token ']'. */ -/* @@? 18:12 Error SyntaxError: Unexpected token '='. */ /* @@? 20:5 Error TypeError: Unresolved reference x */ /* @@? 20:6 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 20:6 Error SyntaxError: Unexpected token '...'. */ -/* @@? 20:6 Error SyntaxError: Unexpected token '...'. */ -/* @@? 20:6 Error SyntaxError: Unexpected token '...'. */ -/* @@? 20:9 Error SyntaxError: Unexpected token ','. */ /* @@? 20:9 Error SyntaxError: Unexpected token ','. */ -/* @@? 20:13 Error SyntaxError: Unexpected token ']'. */ -/* @@? 20:13 Error SyntaxError: Unexpected token ']'. */ +/* @@? 20:11 Error SyntaxError: Unexpected token '78'. */ /* @@? 20:13 Error SyntaxError: Unexpected token ']'. */ /* @@? 22:11 Error SyntaxError: Unexpected token '=>'. */ /* @@? 22:11 Error SyntaxError: Unexpected token. */ /* @@? 24:5 Error TypeError: Variable 'a' has already been declared. */ /* @@? 24:18 Error TypeError: The type of parameter 'y' cannot be inferred */ -/* @@? 24:18 Error TypeError: The type of parameter 'y' cannot be inferred */ -/* @@? 24:19 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:19 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:19 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:19 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:19 Error SyntaxError: Expected '=>', got '...'. */ /* @@? 24:19 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 24:22 Error SyntaxError: Unexpected token ','. */ -/* @@? 24:22 Error SyntaxError: Unexpected token ','. */ -/* @@? 24:24 Error SyntaxError: Unexpected token ')'. */ -/* @@? 24:24 Error SyntaxError: Unexpected token ')'. */ -/* @@? 24:25 Error SyntaxError: Unexpected token ':'. */ -/* @@? 24:25 Error SyntaxError: Unexpected token ':'. */ -/* @@? 24:27 Error TypeError: The type of parameter 'void' cannot be inferred */ +/* @@? 24:19 Error SyntaxError: Expected '=>', got '...'. */ +/* @@? 24:19 Error SyntaxError: Unexpected token '...'. */ +/* @@? 24:24 Error SyntaxError: Identifier expected, got ')'. */ +/* @@? 24:32 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 24:35 Error SyntaxError: Unexpected token '{'. */ /* @@? 26:7 Error SyntaxError: Unexpected token '||='. */ /* @@? 28:5 Error TypeError: Variable 'a' has already been declared. */ -/* @@? 28:16 Error TypeError: Bad operand type, the types of the operands must be numeric type, enum or String. */ /* @@? 28:20 Error SyntaxError: Expected '}', got ')'. */ /* @@? 30:5 Error TypeError: Variable 'a' has already been declared. */ -/* @@? 30:13 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ /* @@? 30:13 Error SyntaxError: Unexpected token 'import'. */ +/* @@? 30:13 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ /* @@? 30:13 Error SyntaxError: Invalid Type. */ /* @@? 32:10 Error TypeError: Variable 'f' has already been declared. */ -/* @@? 32:10 Error TypeError: Variable 'f' has already been declared. */ -/* @@? 33:5 Error TypeError: No matching call signature for std.core.Object(int) */ -/* @@? 33:5 Error TypeError: Expected 0 arguments, got 1. */ /* @@? 33:5 Error TypeError: Call to 'super' must be first statement in constructor */ +/* @@? 33:5 Error TypeError: Expected 0 arguments, got 1. */ +/* @@? 33:5 Error TypeError: No matching call signature for std.core.Object(int) */ /* @@? 33:10 Error SyntaxError: Unexpected super keyword. */ /* @@? 36:1 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 36:8 Error SyntaxError: Unexpected token, expected ']'. */ /* @@? 38:5 Error TypeError: Variable 'a' has already been declared. */ /* @@? 38:17 Error SyntaxError: Unexpected token ')'. */ -/* @@? 38:17 Error SyntaxError: Unexpected token ')'. */ -/* @@? 38:17 Error SyntaxError: Unexpected token ')'. */ /* @@? 38:17 Error SyntaxError: Unexpected token, expected ',' or ']'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidLexer.ets b/ets2panda/test/ast/parser/ets/InvalidLexer.ets index 004e44aff4c65c2a08c3f180dae8706a3ed18327..bc3bdedcb1f8c9b977a5d8fc2a21d8515c7c760b 100644 --- a/ets2panda/test/ast/parser/ets/InvalidLexer.ets +++ b/ets2panda/test/ast/parser/ets/InvalidLexer.ets @@ -63,24 +63,18 @@ const n5 = 02n /* @@? 16:16 Error SyntaxError: Newline is not allowed in strings */ /* @@? 16:16 Error SyntaxError: Unexpected token 'identification literal'. */ -/* @@? 16:16 Error SyntaxError: Newline is not allowed in strings */ -/* @@? 16:16 Error SyntaxError: Newline is not allowed in strings */ -/* @@? 16:16 Error SyntaxError: Newline is not allowed in strings */ /* @@? 16:16 Error SyntaxError: Unexpected token 'string literal'. */ /* @@? 17:3 Error SyntaxError: Invalid unicode escape sequence */ /* @@? 19:19 Error SyntaxError: Invalid digit */ /* @@? 19:19 Error SyntaxError: Invalid numeric literal */ /* @@? 19:19 Error SyntaxError: Unexpected token 'identification literal'. */ /* @@? 21:26 Error SyntaxError: Invalid numeric separator */ -/* @@? 21:26 Error SyntaxError: Invalid numeric separator */ -/* @@? 21:26 Error SyntaxError: Invalid numeric separator */ /* @@? 23:13 Error SyntaxError: Numeric separators are not allowed at the end of numeric literals */ /* @@? 23:13 Error SyntaxError: Invalid numeric literal */ /* @@? 23:13 Error SyntaxError: Unexpected token 'identification literal'. */ /* @@? 25:10 Error SyntaxError: Expected an identifier */ /* @@? 27:14 Error SyntaxError: Invalid unicode escape sequence */ /* @@? 27:14 Error SyntaxError: Invalid identifier part */ -/* @@? 27:14 Error SyntaxError: Invalid identifier part */ /* @@? 29:18 Error SyntaxError: Invalid character literal */ /* @@? 30:1 Error SyntaxError: Unterminated character literal */ /* @@? 30:1 Error SyntaxError: Unexpected token 'identification literal'. */ @@ -89,13 +83,9 @@ const n5 = 02n /* @@? 34:1 Error SyntaxError: Invalid numeric literal */ /* @@? 34:1 Error SyntaxError: Unexpected token 'identification literal'. */ /* @@? 36:1 Error SyntaxError: Invalid unicode escape sequence */ -/* @@? 36:1 Error SyntaxError: Invalid unicode escape sequence */ -/* @@? 36:1 Error SyntaxError: Invalid unicode escape sequence */ /* @@? 38:1 Error SyntaxError: Invalid numeric literal */ /* @@? 38:1 Error SyntaxError: Unexpected token 'identification literal'. */ /* @@? 40:1 Error SyntaxError: Invalid numeric separator */ -/* @@? 40:1 Error SyntaxError: Invalid numeric separator */ -/* @@? 40:1 Error SyntaxError: Invalid numeric separator */ /* @@? 42:1 Error SyntaxError: Invalid BigInt number */ /* @@? 44:1 Error SyntaxError: Invalid numeric literal */ /* @@? 44:1 Error SyntaxError: Unexpected token 'identification literal'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets b/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets index 2439731f6e6e6cbd537dce1eac79e8a8de16e4b0..f1a1bac9355051e04eba42620f38d97b2d736581 100644 --- a/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets +++ b/ets2panda/test/ast/parser/ets/InvalidParserImpl.ets @@ -15,14 +15,15 @@ class A { get abc(x: number) {} - /* @@ label */set abc(x: number, a: string) {} -/* @@ label1 */} + set abc(x: number, a: string) {} +} function fun(this: A) {} -class /* @@ label2 */int {} +class int {} -/* @@@ label Error SyntaxError: Getter must not have formal parameters. */ -/* @@@ label1 Error SyntaxError: Setter must have exactly one formal parameter. */ -/* @@@ label2 Error SyntaxError: Cannot be used as user-defined type. */ /* @@? 17:12 Error TypeError: Getter must return a value */ +/* @@? 18:5 Error SyntaxError: Getter must not have formal parameters. */ +/* @@? 19:1 Error SyntaxError: Setter must have exactly one formal parameter. */ +/* @@? 23:7 Error SyntaxError: Cannot be used as user-defined type. */ +/* @@? 23:7 Error SyntaxError: Identifier expected, got 'int'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidStatements1.ets b/ets2panda/test/ast/parser/ets/InvalidStatements1.ets index d1736c1bb8bf7762f8911d53f8fb364e8e70cbb3..0e78be95d10c0d13e4a54489979b6529dda3f8fb 100644 --- a/ets2panda/test/ast/parser/ets/InvalidStatements1.ets +++ b/ets2panda/test/ast/parser/ets/InvalidStatements1.ets @@ -51,10 +51,6 @@ class A { throw "abc" // there were more errors -/* @@? 16:13 Error SyntaxError: Can only type export class or interface. */ -/* @@? 16:13 Error SyntaxError: Can only type export class or interface. */ -/* @@? 19:13 Error SyntaxError: Can only type export class or interface. */ -/* @@? 19:13 Error SyntaxError: Can only type export class or interface. */ /* @@? 22:1 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 22:5 Error TypeError: Variable 'x' has already been declared. */ /* @@? 25:5 Error SyntaxError: Unexpected token 'let'. */ @@ -71,5 +67,4 @@ throw /* @@? 45:9 Error SyntaxError: Unexpected token '{'. */ /* @@? 48:5 Error SyntaxError: Unexpected token 'let'. */ /* @@? 52:1 Error SyntaxError: Illegal newline after throw. */ -/* @@? 76:1 Error SyntaxError: Expected '}', got 'eos'. */ -/* @@? 76:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 71:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidStatements2.ets b/ets2panda/test/ast/parser/ets/InvalidStatements2.ets index d29b054da0683c3b5565315d53ce987f03a08533..c3d305e4249c2ac2c82749f9db262728a249e0e3 100644 --- a/ets2panda/test/ast/parser/ets/InvalidStatements2.ets +++ b/ets2panda/test/ast/parser/ets/InvalidStatements2.ets @@ -60,6 +60,5 @@ function g(x: int): int { /* @@? 44:9 Error SyntaxError: Expected ')', got 'case'. */ /* @@? 44:9 Error SyntaxError: Expected '{', got 'case'. */ /* @@? 46:15 Error SyntaxError: Unexpected token ':'. */ -/* @@? 46:15 Error SyntaxError: Unexpected token ':'. */ -/* @@? 46:15 Error SyntaxError: Unexpected token ':'. */ +/* @@? 46:17 Error SyntaxError: Unexpected token 'return'. */ /* @@? 48:9 Error SyntaxError: Multiple default clauses. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidStatements3.ets b/ets2panda/test/ast/parser/ets/InvalidStatements3.ets index 5a4d92ed91e2e66af763aa705865401ee82b8754..3e4c28cd0eed9df8c65bd289837ab58fab846d33 100644 --- a/ets2panda/test/ast/parser/ets/InvalidStatements3.ets +++ b/ets2panda/test/ast/parser/ets/InvalidStatements3.ets @@ -44,19 +44,21 @@ for (let i = 1 in [0, 1, 2]) {} /* @@? 18:9 Error TypeError: Argument must be an instance of 'Exception' or 'Error' */ /* @@? 18:12 Error TypeError: Cannot find type 'exception'. */ /* @@? 19:1 Error SyntaxError: Expected '{', got '}'. */ -/* @@? 19:1 Error SyntaxError: Expected '{', got '}'. */ /* @@? 22:5 Error SyntaxError: Expected '{', got 'let'. */ /* @@? 23:11 Error SyntaxError: Expected '{', got '('. */ +/* @@? 23:11 Error TypeError: Unresolved reference x */ /* @@? 27:7 Error SyntaxError: Expected '(', got '{'. */ /* @@? 27:7 Error TypeError: need to specify target type for class composite */ /* @@? 29:1 Error SyntaxError: Expected ')', got 'while'. */ /* @@? 29:7 Error SyntaxError: Expected '(', got 'identification literal'. */ +/* @@? 29:7 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 29:13 Error SyntaxError: Expected ')', got '{'. */ /* @@? 31:9 Error SyntaxError: Unexpected token 'let'. */ -/* @@? 31:9 Error SyntaxError: Unexpected token 'let'. */ +/* @@? 31:13 Error SyntaxError: Unexpected token 'x'. */ /* @@? 34:5 Error SyntaxError: Illegal 'use strict' directive in function with non-simple parameter list. */ -/* @@? 38:5 Error SyntaxError: Annotation declaration can not have access modifier. */ /* @@? 38:5 Error SyntaxError: Unexpected token 'private'. */ +/* @@? 38:5 Error SyntaxError: Annotation declaration can not have access modifier. */ +/* @@? 38:13 Error SyntaxError: Unexpected token '@'. */ /* @@? 38:14 Error TypeError: Cannot find type 'annotate'. */ /* @@? 42:16 Error SyntaxError: for-in loop variable declaration may not have an initializer. */ /* @@? 42:16 Error SyntaxError: Unexpected token 'in'. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidTyped.ets b/ets2panda/test/ast/parser/ets/InvalidTyped.ets index 2f734bc55f6d6e01cfe70304a7efa5cac8546b58..c194bd8831123932fdc3792308b26288e5ad64c2 100644 --- a/ets2panda/test/ast/parser/ets/InvalidTyped.ets +++ b/ets2panda/test/ast/parser/ets/InvalidTyped.ets @@ -35,17 +35,21 @@ interface I { /* @@? 16:21 Error TypeError: Interface expected here. */ /* @@? 16:23 Error SyntaxError: Identifier expected. */ /* @@? 16:23 Error TypeError: Interface expected here. */ +/* @@? 18:1 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 18:1 Error TypeError: Variable 'C' has already been declared. */ /* @@? 18:23 Error SyntaxError: Unexpected token, expected ','. */ /* @@? 18:25 Error SyntaxError: Identifier expected. */ /* @@? 20:1 Error TypeError: Variable 'C' has already been declared. */ +/* @@? 20:1 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 20:21 Error SyntaxError: Identifier expected. */ /* @@? 22:20 Error SyntaxError: Implements clause can not be empty. */ /* @@? 24:7 Error TypeError: Variable 'A' has already been declared. */ -/* @@? 24:21 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 24:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 24:21 Error SyntaxError: Expected '{', got ','. */ +/* @@? 24:21 Error SyntaxError: Unexpected token, expected ','. */ /* @@? 24:23 Error SyntaxError: Unexpected token '{'. */ /* @@? 26:13 Error SyntaxError: Interface declaration cannot have 'implements' clause. */ /* @@? 28:1 Error TypeError: Variable 'I' has already been declared. */ +/* @@? 28:1 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 29:5 Error SyntaxError: 'override' modifier cannot appear in interfaces. */ -/* @@? 52:1 Error SyntaxError: Unexpected token, expected '}'. */ +/* @@? 56:1 Error SyntaxError: Unexpected token, expected '}'. */ diff --git a/ets2panda/test/ast/parser/ets/Multiline_string_escape_char.ets b/ets2panda/test/ast/parser/ets/Multiline_string_escape_char.ets index 675fb903ce205d0b8fe63d1476334c47b30cd673..e12b75a22010e67e0599e6c0f7f2ce614efea58f 100644 --- a/ets2panda/test/ast/parser/ets/Multiline_string_escape_char.ets +++ b/ets2panda/test/ast/parser/ets/Multiline_string_escape_char.ets @@ -18,6 +18,5 @@ function main(){ Test escape characters` | "X"; } -/* @@? 17:15 Error SyntaxError: Invalid character escape sequence. */ /* @@? 17:15 Error SyntaxError: Invalid character escape sequence. */ /* @@? 17:15 Error SyntaxError: Invalid Unicode escape. */ diff --git a/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets b/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets index 0790ded53ca3e65ebcba9a26f52e7afc87bde879..99cbb1119e592def1e4da6322224d88a8606f62b 100644 --- a/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets +++ b/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets @@ -36,4 +36,4 @@ class /* @@ label4 */{/* @@ label5 */} /* @@? 28:22 Error SyntaxError: Identifier expected, got 'number literal'. */ /* @@? 30:22 Error SyntaxError: Identifier expected, got '{'. */ /* @@? 30:38 Error SyntaxError: Expected '{', got '}'. */ -/* @@? 40:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 40:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets b/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets index 2da22547a52d86dbd33fd488795b7c37e853537b..79258115c1b265ff059e5928db99445395570d16 100644 --- a/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets +++ b/ets2panda/test/ast/parser/ets/MultipleParserErrors.ets @@ -18,7 +18,7 @@ function foo(param? : Object) for (let i? of "blablabla") { } } -function foo(a : int = 10, b : int, c : int = 15) : int +function foo(b : int, a : int = 10, c : int = 15) : int { return a + b; } @@ -170,68 +170,70 @@ function main(): void { /* @@? 28:29 Error TypeError: Native, Abstract and Declare methods cannot have body. */ /* @@? 34:14 Error SyntaxError: The modifier for a constructor should be limited to access modifiers (private, internal, protected, public), and 'native' modifiers. */ /* @@? 37:41 Error SyntaxError: Only 'throws' can be used with function types. */ -/* @@? 39:14 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 39:14 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 39:14 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 39:14 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 39:24 Error SyntaxError: Unexpected token 'int'. */ -/* @@? 39:24 Error TypeError: Unresolved reference int */ -/* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ -/* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ /* @@? 39:27 Error SyntaxError: Unexpected token ')'. */ +/* @@? 39:29 Error SyntaxError: Unexpected token '{'. */ /* @@? 39:31 Error SyntaxError: return keyword should be used in function body. */ /* @@? 39:38 Error TypeError: All return statements in the function should be empty or have a value. */ -/* @@? 41:6 Error SyntaxError: Identifier expected, got 'number literal'. */ -/* @@? 43:6 Error SyntaxError: Type alias name cannot be 'null'. */ -/* @@? 43:6 Error SyntaxError: Identifier expected, got 'null'. */ -/* @@? 45:6 Error SyntaxError: Identifier expected, got 'this'. */ -/* @@? 47:8 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 41:1 Error TypeError: Unresolved reference type */ +/* @@? 41:6 Error SyntaxError: Unexpected token '123'. */ +/* @@? 41:6 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 41:10 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 41:12 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 43:6 Error SyntaxError: Unexpected token 'null'. */ +/* @@? 43:6 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 43:11 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 43:13 Error SyntaxError: Unexpected token 'byte'. */ +/* @@? 45:6 Error SyntaxError: Unexpected token 'this'. */ +/* @@? 45:6 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 45:6 Error TypeError: Cannot reference 'this' in this context. */ +/* @@? 45:11 Error SyntaxError: Invalid left-hand side in assignment expression. */ /* @@? 47:8 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 47:8 Error TypeError: Missing initializer in const declaration */ /* @@? 49:12 Error TypeError: The type of parameter 'a' cannot be inferred */ /* @@? 49:13 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 51:25 Error SyntaxError: Rest parameter must be the last formal parameter. */ /* @@? 51:27 Error SyntaxError: Unexpected token '...'. */ -/* @@? 51:27 Error SyntaxError: Unexpected token '...'. */ +/* @@? 51:30 Error SyntaxError: Unexpected token 'p'. */ /* @@? 51:33 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 51:38 Error SyntaxError: Unexpected token ')'. */ -/* @@? 51:38 Error SyntaxError: Unexpected token ')'. */ -/* @@? 51:38 Error SyntaxError: Unexpected token ')'. */ -/* @@? 51:39 Error SyntaxError: Unexpected token ':'. */ /* @@? 51:39 Error SyntaxError: Unexpected token ':'. */ +/* @@? 51:41 Error SyntaxError: Unexpected token 'int'. */ /* @@? 51:45 Error SyntaxError: Unexpected token '{'. */ /* @@? 52:5 Error SyntaxError: return keyword should be used in function body. */ -/* @@? 52:12 Error TypeError: Unresolved reference q */ /* @@? 52:12 Error TypeError: All return statements in the function should be empty or have a value. */ +/* @@? 52:12 Error TypeError: Unresolved reference q */ /* @@? 52:23 Error TypeError: Unresolved reference p */ -/* @@? 55:26 Error SyntaxError: Rest parameter should be of an array type. */ -/* @@? 59:23 Error SyntaxError: Rest parameter should be of an array type. */ +/* @@? 55:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ /* @@? 63:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 67:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 67:7 Error TypeError: Variable 'A' has already been declared. */ /* @@? 68:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ +/* @@? 73:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 73:7 Error TypeError: Variable 'A' has already been declared. */ /* @@? 74:11 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 77:20 Error TypeError: Interface expected here. */ /* @@? 77:22 Error TypeError: 'I' type does not exist. */ /* @@? 78:22 Error TypeError: Method fee(): int in B not overriding any method */ +/* @@? 83:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 83:7 Error TypeError: Variable 'A' has already been declared. */ /* @@? 84:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 92:7 Error TypeError: Variable 'A' has already been declared. */ +/* @@? 92:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 93:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 103:25 Error SyntaxError: Rest parameter should be of an array type. */ -/* @@? 104:32 Error SyntaxError: Rest parameter should be of an array type. */ /* @@? 115:26 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 115:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 115:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 115:26 Error SyntaxError: Unexpected token 'case'. */ -/* @@? 115:26 Error SyntaxError: Unexpected token 'case'. */ -/* @@? 115:30 Error SyntaxError: Unexpected token ':'. */ /* @@? 115:30 Error SyntaxError: Unexpected token ':'. */ +/* @@? 115:32 Error SyntaxError: Unexpected token 'U'. */ /* @@? 115:32 Error TypeError: Unresolved reference U */ /* @@? 115:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 115:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 115:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 115:34 Error SyntaxError: Unexpected token ':'. */ /* @@? 115:34 Error SyntaxError: Unexpected token ':'. */ +/* @@? 115:36 Error SyntaxError: Unexpected token 'T'. */ /* @@? 115:36 Error TypeError: Unresolved reference T */ /* @@? 115:38 Error SyntaxError: Unexpected token '{'. */ /* @@? 116:5 Error SyntaxError: return keyword should be used in function body. */ @@ -240,32 +242,27 @@ function main(): void { /* @@? 119:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 119:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 119:26 Error SyntaxError: Unexpected token 'case'. */ -/* @@? 119:26 Error SyntaxError: Unexpected token 'case'. */ /* @@? 119:30 Error SyntaxError: Unexpected token ':'. */ -/* @@? 119:30 Error SyntaxError: Unexpected token ':'. */ -/* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ +/* @@? 119:32 Error SyntaxError: Unexpected token 'U'. */ /* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 119:33 Error SyntaxError: Unexpected token ')'. */ -/* @@? 119:34 Error SyntaxError: Unexpected token ':'. */ /* @@? 119:34 Error SyntaxError: Unexpected token ':'. */ +/* @@? 119:36 Error SyntaxError: Unexpected token 'T'. */ /* @@? 119:38 Error SyntaxError: Unexpected token '{'. */ /* @@? 120:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 120:12 Error TypeError: All return statements in the function should be empty or have a value. */ /* @@? 123:5 Error SyntaxError: Identifier expected, got ','. */ -/* @@? 123:6 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? 123:6 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 123:6 Error SyntaxError: Unexpected token 'abc'. */ +/* @@? 123:6 Error SyntaxError: Variable must be initialized or it's type must be declared. */ /* @@? 123:6 Error TypeError: Unresolved reference abc */ /* @@? 127:1 Error SyntaxError: The modifier async cannot be used in an ambient context. */ /* @@? 132:14 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 137:16 Error SyntaxError: Unexpected token '='. */ -/* @@? 137:16 Error SyntaxError: Expected '{', got '='. */ /* @@? 137:16 Error SyntaxError: Expected '{', got '='. */ /* @@? 137:16 Error SyntaxError: Expected ')', got '='. */ /* @@? 137:16 Error SyntaxError: Catch clause variable cannot have an initializer. */ +/* @@? 137:16 Error SyntaxError: Unexpected token '='. */ +/* @@? 137:18 Error SyntaxError: Unexpected token '0'. */ /* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ -/* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ -/* @@? 137:19 Error SyntaxError: Unexpected token ')'. */ +/* @@? 137:21 Error SyntaxError: Unexpected token '{'. */ /* @@? 141:16 Error TypeError: This expression is not callable. */ /* @@? 145:18 Error TypeError: A is abstract therefore cannot be instantiated. */ /* @@? 146:16 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ @@ -282,4 +279,4 @@ function main(): void { /* @@? 165:5 Error TypeError: This expression is not callable. */ /* @@? 166:5 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 166:5 Error TypeError: No matching call signature */ -/* @@? 286:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 283:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/StringFasta.ets b/ets2panda/test/ast/parser/ets/StringFasta.ets index a536da1d477f00880f75919bd76b830240e07b27..a448ec8c0235063598c23be6eeabd4aa41eaf7d3 100644 --- a/ets2panda/test/ast/parser/ets/StringFasta.ets +++ b/ets2panda/test/ast/parser/ets/StringFasta.ets @@ -171,16 +171,13 @@ function main(): void { /* @@? 112:16 Error TypeError: Static property 'fastaRepeat' must be accessed through it's class 'StringFasta' */ /* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ -/* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 112:48 Error TypeError: Static property 'ALU' must be accessed through it's class 'StringFasta' */ /* @@? 113:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ /* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ -/* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 113:46 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 114:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ /* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ -/* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 114:46 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 116:28 Error TypeError: 'expected' is a static property of 'StringFasta' */ diff --git a/ets2panda/test/ast/parser/ets/UnexpectedToken.ets b/ets2panda/test/ast/parser/ets/UnexpectedToken.ets index 6f85639581dfb8f5d6d1e473e733b9d3df68d30a..7e6119a0261f6b405434189a12bb3c00daabb979 100644 --- a/ets2panda/test/ast/parser/ets/UnexpectedToken.ets +++ b/ets2panda/test/ast/parser/ets/UnexpectedToken.ets @@ -22,16 +22,12 @@ function main(): void { /* @@? 18:19 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 18:25 Error SyntaxError: Unexpected token 'let'. */ -/* @@? 18:25 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 18:29 Error SyntaxError: Expected ';', got 'identification literal'. */ -/* @@? 18:29 Error TypeError: Unresolved reference f */ +/* @@? 18:29 Error SyntaxError: Unexpected token, expected ')'. */ /* @@? 18:38 Error TypeError: Cannot find type 'A'. */ /* @@? 18:68 Error TypeError: Cannot find type 'A'. */ -/* @@? 18:70 Error SyntaxError: Expected ')', got ';'. */ -/* @@? 18:72 Error TypeError: This expression is not callable. */ +/* @@? 18:72 Error TypeError: Unresolved reference f */ /* @@? 18:78 Error TypeError: Cannot find type 'A'. */ -/* @@? 19:1 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:82 Error SyntaxError: Expected ')', got ';'. */ /* @@? 19:4 Error TypeError: Unresolved reference i */ /* @@? 19:10 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:10 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:10 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:12 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets index 345790b76ac2915ef5a5bac2a5fc5a0838556068..7b5c41ba881ae1ae8068e8473f0fd3e9d8cc432a 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets @@ -23,6 +23,7 @@ function main() { /* @@? 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 ':'. */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_4.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_4.ets index 26857e6ececae6f412f4f848b8d32cb34f066ef0..7f0b37538a5524649eb0a6a217402813a7afa477 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_4.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_4.ets @@ -24,5 +24,5 @@ declare class A { /* @@@ label Error SyntaxError: An index signature must have a type annotation. */ /* @@@ label1 Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ /* @@@ label3 Error TypeError: Native and Declare methods should have explicit return type. */ -/* @@@ label2 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label2 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label2 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_7.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_7.ets index aace691a4e8c3ca1de775117e00346db0c7c2caa..e387d2b7d7ab0be06ff4bc541ab4b772a01cb384 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_7.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_7.ets @@ -26,5 +26,5 @@ declare class A { /* @@@ label2 Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ /* @@@ label3 Error SyntaxError: Unexpected token 'function'. */ /* @@@ label5 Error TypeError: Native and Declare methods should have explicit return type. */ -/* @@@ label4 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label4 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label4 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets index 3f3942b7968f4e420d38be3ace67071626c117cd..4afa270c8c14ed1ff5dd66fca45e968926dea725 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets @@ -27,5 +27,5 @@ declare class A { /* @@@ label3 Error SyntaxError: An index signature must have a type annotation. */ /* @@@ label4 Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ /* @@@ label6 Error TypeError: Native and Declare methods should have explicit return type. */ -/* @@@ label5 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label5 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label5 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_classDecl_conflict.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_classDecl_conflict.ets index f76395b8f3a93580feadf3831b81411946291c79..9a1ce8d5b94a01523f3c686265f93b76f89210e3 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_classDecl_conflict.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_classDecl_conflict.ets @@ -16,4 +16,5 @@ @interface MyAnno {} class /* @@ label */MyAnno {} -/* @@@ label Error TypeError: Variable 'MyAnno' has already been declared. */ +/* @@@ label Error TypeError: Variable 'MyAnno' has already been declared. */ +/* @@@ label Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_interface_conflict.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_interface_conflict.ets index 6fb0a66e33f230c2550efbbcb96ee1649777a6de..12d9c22c9d9e34ce3df656a39c2159ab36dfbf63 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_interface_conflict.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_interface_conflict.ets @@ -16,4 +16,5 @@ @interface MyAnno {} /* @@ label */interface MyAnno {} -/* @@@ label Error TypeError: Variable 'MyAnno' has already been declared. */ +/* @@@ label Error TypeError: Variable 'MyAnno' has already been declared. */ +/* @@@ label Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token02.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token02.ets index 0034ba7e5097447bd94ceb994424a1509e905004..837d0ff78785f46c096efd0cea1e638c4ef0ead7 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token02.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token02.ets @@ -19,6 +19,7 @@ } /* @@? 18:18 Error SyntaxError: Identifier expected, got ':'. */ -/* @@? 19:1 Error SyntaxError: Missing type annotation for property 'number'. */ +/* @@? 18:20 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ +/* @@? 19:1 Error SyntaxError: Identifier expected, got '}'. */ /* @@? 18:5 Error TypeError: Unresolved reference testProperty2 */ /* @@? 18:5 Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token03.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token03.ets index 5fa3741fd078367f0c555bf428433bd0a45fb42d..59e11cb6caf990ea7a4c24658883d9ed8e38779d 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token03.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token03.ets @@ -15,9 +15,10 @@ @interface MyAnno { testProperty1: string = testProperty2/* @@ label1 */: number -/* @@ label3 */} +} /* @@@ label1 Error SyntaxError: Identifier expected, got ':'. */ -/* @@@ label3 Error SyntaxError: Missing type annotation for property 'number'. */ +/* @@? 17:35 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ +/* @@? 18:1 Error SyntaxError: Identifier expected, got '}'. */ /* @@? 17:5 Error TypeError: Unresolved reference testProperty2 */ /* @@? 17:5 Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier01.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier01.ets index 2323182109e9a0c97a199c2387629c774fa58555..00384aaf2365eda385865d6547482185b57fd7d4 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier01.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier01.ets @@ -18,3 +18,4 @@ public @interface MyAnno { /* @@? 15:1 Error SyntaxError: Annotation declaration can not have access modifier. */ /* @@? 15:1 Error SyntaxError: Unexpected token 'public'. */ +/* @@? 15:8 Error SyntaxError: Unexpected token '@'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier02.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier02.ets index c0cf670759ab3da454245f4fdbc3475b3024e11e..4e855e39f4c46cc5a1a0c3c4ae8403db031d732c 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier02.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier02.ets @@ -18,3 +18,4 @@ private @interface MyAnno { /* @@? 15:1 Error SyntaxError: Annotation declaration can not have access modifier. */ /* @@? 15:1 Error SyntaxError: Unexpected token 'private'. */ +/* @@? 15:9 Error SyntaxError: Unexpected token '@'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_method.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_method.ets index cfe8712847ac4c60d34b8b7c1ed23665c6fea165..328a7d5feade1a5c4508dc5092a965246db75937 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_method.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationDecl_with_method.ets @@ -22,8 +22,6 @@ /* @@? 17:8 Error SyntaxError: Missing type annotation for property 'foo'. */ /* @@? 17:8 Error SyntaxError: Identifier expected, got '('. */ /* @@? 17:9 Error SyntaxError: Identifier expected, got ')'. */ -/* @@? 17:9 Error SyntaxError: Identifier expected, got ')'. */ -/* @@? 17:10 Error SyntaxError: Identifier expected, got '{'. */ /* @@? 17:10 Error SyntaxError: Identifier expected, got '{'. */ /* @@? 17:11 Error SyntaxError: Identifier expected, got '}'. */ /* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.ets index 0262653495ab65b55d254a03d36c5943582a40a1..87ea5db60576f9067c9ff478d31f58bff3a0cd47 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.ets @@ -28,6 +28,3 @@ interface itf { /* @@@ label Error TypeError: Class name 'A' used in the wrong context */ /* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ /* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ -/* @@@ label Error TypeError: Class name 'A' used in the wrong context */ -/* @@@ label Error TypeError: Type 'A' cannot be assigned to type 'String' */ -/* @@@ label Error TypeError: Invalid value for annotation field, expected a constant literal. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.ets index 4e5c7ed46cbcdc44b6a92bdc0efa05a7bdd63e5c..a87e83104e6429bc3e96a54ea7f42dcc4735732d 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.ets @@ -31,11 +31,10 @@ function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: /* @@? 19:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 19:20 Error TypeError: need to specify target type for class composite */ /* @@? 19:42 Error SyntaxError: Unexpected token 'x'. */ +/* @@? 19:45 Error SyntaxError: Unexpected token 'int'. */ /* @@? 19:45 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 19:45 Error TypeError: Unresolved reference int */ -/* @@? 19:48 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:48 Error SyntaxError: Unexpected token ')'. */ /* @@? 19:48 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:50 Error SyntaxError: Unexpected token '{'. */ /* @@? 22:1 Error TypeError: Function foo is already declared. */ /* @@? 22:14 Error TypeError: The type of parameter 'MyAnno' cannot be inferred */ /* @@? 22:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ @@ -43,33 +42,30 @@ function foo(MyAnno({testProperty1: ""}) x: int, MyAnno({testProperty1: ""}) y: /* @@? 22:20 Error TypeError: need to specify target type for class composite */ /* @@? 22:42 Error SyntaxError: Unexpected token 'x'. */ /* @@? 22:45 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 22:45 Error SyntaxError: Unexpected token 'int'. */ /* @@? 22:48 Error SyntaxError: Unexpected token ','. */ -/* @@? 22:48 Error SyntaxError: Unexpected token ','. */ -/* @@? 22:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:50 Error SyntaxError: Unexpected token 'MyAnno'. */ /* @@? 22:50 Error TypeError: This expression is not callable. */ /* @@? 22:50 Error TypeError: Annotation missing '@' symbol before annotation name. */ /* @@? 22:78 Error SyntaxError: Unexpected token 'y'. */ /* @@? 22:81 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 22:81 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 22:87 Error SyntaxError: Unexpected token ')'. */ -/* @@? 22:87 Error SyntaxError: Unexpected token ')'. */ -/* @@? 22:87 Error SyntaxError: Unexpected token ')'. */ -/* @@? 25:1 Error TypeError: Function foo is already declared. */ +/* @@? 22:89 Error SyntaxError: Unexpected token '{'. */ /* @@? 25:1 Error TypeError: Function foo is already declared. */ /* @@? 25:14 Error TypeError: The type of parameter 'MyAnno' cannot be inferred */ /* @@? 25:20 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 25:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 25:20 Error TypeError: need to specify target type for class composite */ /* @@? 25:42 Error SyntaxError: Unexpected token 'x'. */ +/* @@? 25:45 Error SyntaxError: Unexpected token 'int'. */ /* @@? 25:45 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 25:48 Error SyntaxError: Unexpected token ','. */ -/* @@? 25:48 Error SyntaxError: Unexpected token ','. */ -/* @@? 25:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 25:50 Error SyntaxError: Unexpected token 'MyAnno'. */ /* @@? 25:50 Error TypeError: Annotation missing '@' symbol before annotation name. */ /* @@? 25:50 Error TypeError: This expression is not callable. */ /* @@? 25:78 Error SyntaxError: Unexpected token 'y'. */ /* @@? 25:81 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 25:81 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 25:87 Error SyntaxError: Unexpected token ')'. */ -/* @@? 25:87 Error SyntaxError: Unexpected token ')'. */ -/* @@? 25:87 Error SyntaxError: Unexpected token ')'. */ +/* @@? 25:89 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_class.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_class.ets index e036c1ef952cc59f485639bc4a343421efa9812d..b42c1ed5f230a2989c89d5c0cc852b61038a772c 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_class.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_class.ets @@ -18,6 +18,4 @@ } @MyAnno({testProperty1: "Bob", testProperty2: 1}) -/* @@ label */abstract class A {} - -/* @@@ label Error SyntaxError: Annotations are not allowed on an abstract class or methods. */ +abstract class A {} diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_method.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_method.ets index b40fc2b0c627f6a580bee5a74c127910ee36f823..18116592d3e37713933d9c71275a174cf42f9676 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_method.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_on_abstract_method.ets @@ -18,14 +18,9 @@ } abstract class A { - @MyAnno() + @MyAnno({testProperty1: "123", testProperty2: 123}) foo1(){} // OK - @MyAnno() - abstract foo2() //CTE -} - -/* @@? 25:14 Error SyntaxError: Annotations are not allowed on an abstract class or methods. */ -/* @@? 25:14 Error SyntaxError: Annotations are not allowed on an abstract class or methods. */ -/* @@? 21:6 Error TypeError: The required field 'testProperty2' must be specified. Fields without default values cannot be omitted. */ -/* @@? 21:6 Error TypeError: The required field 'testProperty1' must be specified. Fields without default values cannot be omitted. */ + @MyAnno({testProperty1: "123", testProperty2: 123}) + abstract foo2() // OK +} diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token01.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token01.ets index 0a6c4dfc3b073ac850f6d40d38397d89d8ec9d43..f7664657d2ef16b3580a5be9d1f08dfefd261fc3 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token01.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token01.ets @@ -22,5 +22,5 @@ class A{} /* @@@ label Error SyntaxError: Expected ')', got ','. */ /* @@@ label Error SyntaxError: Unexpected token ','. */ /* @@@ label Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@@ label Error SyntaxError: Unexpected token ','. */ +/* @@? 19:30 Error SyntaxError: Unexpected token '1'. */ /* @@@ label1 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token04.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token04.ets index 3ae3ffab2809168071fef481ffbc4a9c5095ce1d..44730b44be644f563c713caf76cf382396764f2b 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token04.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token04.ets @@ -18,8 +18,7 @@ const invalidUsage1 = @Log("value")) ()=>{} +/* @@? 19:24 Error TypeError: Annotations without 'SOURCE' cannot be used on lambda expressions, local declarations, or types. */ /* @@? 19:36 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:36 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 19:36 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:36 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:36 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:40 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 19:40 Error SyntaxError: Unexpected token. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token05.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token05.ets index 3b95ded68d8bfe8e53ccd011e40d3c76b9fd9dfd..8fefd099851bdb02cfc41fceac94460fad0e1925 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token05.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token05.ets @@ -21,5 +21,4 @@ const invalidUsage1 = @@Log("value") ()=>{} /* @@? 19:23 Error SyntaxError: Unexpected token '@@'. */ /* @@? 19:25 Error SyntaxError: Unexpected token 'Log'. */ /* @@? 19:40 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 19:40 Error SyntaxError: Unexpected token '=>'. */ /* @@? 19:40 Error SyntaxError: Unexpected token. */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotation_export_type.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotation_export_type.ets index 024fd7e241a5fb98cba81965111b5537cdd20469..32dcf800590a260691d25b021501626b69027ee4 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotation_export_type.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotation_export_type.ets @@ -13,7 +13,4 @@ * limitations under the License. */ -export type @/* @@ label */interface MyAnno {} - -/* @@@ label Error SyntaxError: Can only type export class or interface. */ -/* @@@ label Error SyntaxError: Can only type export class or interface. */ +export type @interface MyAnno {} diff --git a/ets2panda/test/ast/parser/ets/arrAsArray.ets b/ets2panda/test/ast/parser/ets/arrAsArray.ets index 707bb0952710a9c3fb98a78fdec1b1493de0a1ba..4422772546899cb93ca70cf28acbbb04e5d250d2 100644 --- a/ets2panda/test/ast/parser/ets/arrAsArray.ets +++ b/ets2panda/test/ast/parser/ets/arrAsArray.ets @@ -19,5 +19,3 @@ function main() { 2, 3, 5, 7, 11 ] as Array } - -/* @@@ label Error TypeError: Expected type for array literal should be an array type, got Array */ diff --git a/ets2panda/test/ast/parser/ets/array_2.ets b/ets2panda/test/ast/parser/ets/array_2.ets index 75bbe2c9fa54167a0800a1513a7feeb269711bf2..f949a62c20d12ba66be8e74514326f168709c2ba 100644 --- a/ets2panda/test/ast/parser/ets/array_2.ets +++ b/ets2panda/test/ast/parser/ets/array_2.ets @@ -15,9 +15,7 @@ let c: Double[] = [0.33 /* @@ label */0.66 0.99] -/* @@@ label Error SyntaxError: Unexpected token, expected ',' or ']'. */ -/* @@? 16:39 Error SyntaxError: Unexpected token '0.66'. */ -/* @@? 16:44 Error SyntaxError: Unexpected token '0.99'. */ -/* @@? 16:48 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:48 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:48 Error SyntaxError: Unexpected token ']'. */ +/* @@@ label Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@@ label Error SyntaxError: Unexpected token '0.66'. */ +/* @@? 16:44 Error SyntaxError: Unexpected token '0.99'. */ +/* @@? 16:48 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/array_missing_element.ets b/ets2panda/test/ast/parser/ets/array_missing_element.ets index 305f9314280ebc0c972946443544d3beaaa8f6fb..0c7d5208318709383dda61f601a1d2b4b588fb0e 100644 --- a/ets2panda/test/ast/parser/ets/array_missing_element.ets +++ b/ets2panda/test/ast/parser/ets/array_missing_element.ets @@ -18,3 +18,7 @@ function foo(): void { } /* @@? 17:45 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:47 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 17:47 Error SyntaxError: Unexpected token '4'. */ +/* @@? 17:48 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:50 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/array_type.ets b/ets2panda/test/ast/parser/ets/array_type.ets index 32dcb5a981b469d4b95350bb8566bc5c7f39f306..98f77116906351ca937ad3cb5bb91663820c2f7a 100644 --- a/ets2panda/test/ast/parser/ets/array_type.ets +++ b/ets2panda/test/ast/parser/ets/array_type.ets @@ -24,8 +24,8 @@ class array_type { } } +/* @@@ label Error TypeError: Property 'a' might not have been initialized. */ +/* @@@ label1 Error TypeError: Property 'f' might not have been initialized. */ /* @@@ label2 Error TypeError: Function with a non void return type must return a value. */ /* @@@ label3 Error TypeError: Function with a non void return type must return a value. */ -/* @@@ label Warning Warning: Property 'a' might not have been initialized. */ -/* @@@ label1 Warning Warning: Property 'f' might not have been initialized. */ diff --git a/ets2panda/test/ast/parser/ets/assign_bad.ets b/ets2panda/test/ast/parser/ets/assign_bad.ets index 3614858b2c519add02991cd4b97e55488fadd41c..11de990c99fcf4f8600b370c2a5ed09c363cd88d 100644 --- a/ets2panda/test/ast/parser/ets/assign_bad.ets +++ b/ets2panda/test/ast/parser/ets/assign_bad.ets @@ -25,3 +25,4 @@ function main(): void { /* @@? 16:5 Error TypeError: Unresolved reference a */ /* @@? 20:6 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 20:6 Error SyntaxError: Unexpected token '='. */ +/* @@? 20:8 Error SyntaxError: Unexpected token 'b'. */ diff --git a/ets2panda/test/ast/parser/ets/async_function_bad.ets b/ets2panda/test/ast/parser/ets/async_function_bad.ets index 6d7733236c198b36703f05e352da1db8143931fa..6b628497f9291e4a57ff00c489c763c7a5fbf594 100644 --- a/ets2panda/test/ast/parser/ets/async_function_bad.ets +++ b/ets2panda/test/ast/parser/ets/async_function_bad.ets @@ -23,7 +23,6 @@ async native function foo(): Promise; /* @@? 16:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 16:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 16:27 Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:28 Error SyntaxError: Unexpected token ':'. */ -/* @@? 16:28 Error SyntaxError: Unexpected token ':'. */ -/* @@? 16:28 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:28 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 16:30 Error SyntaxError: Unexpected token 'Promise'. */ /* @@? 16:30 Error TypeError: Class name 'Promise' used in the wrong context */ diff --git a/ets2panda/test/ast/parser/ets/await_as_priority.ets b/ets2panda/test/ast/parser/ets/await_as_priority.ets new file mode 100644 index 0000000000000000000000000000000000000000..58be29ee093e2a220bd83f21b19bcb47cd3021fd --- /dev/null +++ b/ets2panda/test/ast/parser/ets/await_as_priority.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A{} +class B{} + +async function func(): Promise{ + let a: number[] = [0, 1]; + return a; +} +async function main() { + let b: Array = await func(); +} +async function func1(): Promise{ + let a: A = new A(); + return a; +} +async function main1(){ + let b: B = await func1() as B; +} \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/await_priority.ets b/ets2panda/test/ast/parser/ets/await_priority.ets new file mode 100644 index 0000000000000000000000000000000000000000..aeb70a252155fa6701bf2ef6323d4475dbc40ae7 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/await_priority.ets @@ -0,0 +1,48 @@ +/* + * 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 main(){ + await test(); + +} + +async function test() { + let p = Promise.resolve(6); + assertEQ(await p, 6); + assertEQ(await p * 2, 12); + assertEQ(await p / 2, 3); + assertEQ(await p % 3, 0); + assertEQ(await p + 1, 7); + assertEQ(await p - 2, 4); + assertEQ(await p === 6, true); + assertEQ(await p != 4, true); + assertEQ(1 << await p, 64); + assertEQ(await p > 3, true); + assertEQ(await p < 3, false); + assertEQ(await p == 6, true); + assertEQ(await p != 1, true); + assertEQ(await p & 3, 2); + assertEQ(await p ^ 2, 4); + assertEQ(await p | 1, 7); + + let b = Promise.resolve(false); + assertEQ(await b || true, true); + let n = Promise.resolve(null); + assertEQ(await n ?? 42, 42); + let r = await p > 3 ? "yes" : "no"; + assertEQ(r, "yes"); + let x = await p; + assertEQ(x, 6); +} \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/cast_expressions10.ets b/ets2panda/test/ast/parser/ets/cast_expressions10.ets index 84a10797a73b5b97c21fbf18fd9b7ac1530c4109..8ac8ebd670fa49383494ee20d84df9610dc2ad99 100644 --- a/ets2panda/test/ast/parser/ets/cast_expressions10.ets +++ b/ets2panda/test/ast/parser/ets/cast_expressions10.ets @@ -22,7 +22,9 @@ function main(): void { let Object_: Object = Int_a as Object; let Int_a4: Int[][] = Object_ as Int[][]; - let Long_a: Long[][] = /* @@ label */Int_a as Long[][]; + let Long_a: Long[][] = Int_a as Long[][]; } -/* @@@ label Error TypeError: Cannot cast type 'Int[][]' to 'Long[][]' */ +/* @@? 19:30 Error TypeError: Cannot cast type 'Array>' to 'Array>' */ +/* @@? 20:25 Error TypeError: Cannot cast type 'Array>' to 'Array>' */ +/* @@? 25:26 Error TypeError: Cannot cast type 'Array>' to 'Array>' */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/cast_expressions7.ets b/ets2panda/test/ast/parser/ets/cast_expressions7.ets index aa4013307e3aae6e793482e674e80552d5004ff9..7247dfdf88ee5b60713d5c8811b88bf925291ace 100644 --- a/ets2panda/test/ast/parser/ets/cast_expressions7.ets +++ b/ets2panda/test/ast/parser/ets/cast_expressions7.ets @@ -24,7 +24,9 @@ function main(): void { let int_a: int[] = [1,2,3]; let int_a2 = int_a as int[]; - let long_a: long[] = /* @@ label */int_a as long[]; + let long_a: long[] = int_a as long[]; } -/* @@@ label Error TypeError: Cannot cast type 'int[]' to 'long[]' */ +/* @@? 21:16 Error TypeError: Cannot cast type 'Array' to 'Array' */ +/* @@? 22:17 Error TypeError: Cannot cast type 'Array' to 'Array' */ +/* @@? 27:24 Error TypeError: Cannot cast type 'Array' to 'Array' */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/cast_expressions8.ets b/ets2panda/test/ast/parser/ets/cast_expressions8.ets index fecf5bceca3293fe4cb65e2b84623b1fa1d52a93..cefd85c3c241835a00aeda338ad995cc9daed724 100644 --- a/ets2panda/test/ast/parser/ets/cast_expressions8.ets +++ b/ets2panda/test/ast/parser/ets/cast_expressions8.ets @@ -13,12 +13,7 @@ * limitations under the License. */ -class A {} -class B extends A {} - function main(): void { let int_a: int[] = [1,2,3]; - let Int_a: Int[] = /* @@ label */int_a as Int[]; -} - -/* @@@ label Error TypeError: Cannot cast type 'int[]' to 'Int[]' */ + let Int_a: Int[] = int_a as Int[]; +} \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/cast_expressions9.ets b/ets2panda/test/ast/parser/ets/cast_expressions9.ets index b5ef6a663fcc9c03eabfd3d88fbf7a3437f8824d..02e25d9248dc7c65d461c79ccee78286e2c69a4f 100644 --- a/ets2panda/test/ast/parser/ets/cast_expressions9.ets +++ b/ets2panda/test/ast/parser/ets/cast_expressions9.ets @@ -16,7 +16,7 @@ function main(): void { let int_a: int[][] = [[1],[2],[3]]; let int_a2: int[][] = int_a as int[][]; - let long_a: long[][] = /* @@ label */int_a as long[][]; + let long_a: long[][] = int_a as long[][]; } -/* @@@ label Error TypeError: Cannot cast type 'int[][]' to 'long[][]' */ +/* @@? 19:26 Error TypeError: Cannot cast type 'Array>' to 'Array>' */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/class_as_object_1.ets b/ets2panda/test/ast/parser/ets/class_as_object_1.ets index a1e5679d2f5247411360d32e3fbb016e72177de7..e9d0cfa6ea03dee3f006ba2f56dda00e68c5e0e9 100644 --- a/ets2panda/test/ast/parser/ets/class_as_object_1.ets +++ b/ets2panda/test/ast/parser/ets/class_as_object_1.ets @@ -17,20 +17,3 @@ console.log(Object) /* @@? 16:13 Error TypeError: Class or interface 'Object' cannot be used as object */ /* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ -/* @@? 16:13 Error TypeError: Class name can't be the argument of function or method. */ diff --git a/ets2panda/test/ast/parser/ets/class_late_initialization_conflict_modifier.ets b/ets2panda/test/ast/parser/ets/class_late_initialization_conflict_modifier.ets new file mode 100644 index 0000000000000000000000000000000000000000..f6d963475fc44e697b7b9d1ff935724d1161deb5 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/class_late_initialization_conflict_modifier.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. + */ + +class A { + f1?!:string + f2!?:number +} + +/* @@? 17:7 Error SyntaxError: Conflicting modifiers '!' and '?' on field. */ +/* @@? 17:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ +/* @@? 18:7 Error SyntaxError: Conflicting modifiers '!' and '?' on field. */ +/* @@? 18:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ diff --git a/ets2panda/test/ast/parser/ets/class_late_initialization_with_initalizer_01.ets b/ets2panda/test/ast/parser/ets/class_late_initialization_with_initalizer_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..7f42ec5dc782c39877807cf5e95eef0a2594d655 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/class_late_initialization_with_initalizer_01.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. + */ + +class A { + f!: string = "abc" +} +/* @@? 17:6 Error SyntaxError: Late-initialized field cannot have default value. */ diff --git a/ets2panda/test/ast/parser/ets/class_late_initialization_with_initalizer_02.ets b/ets2panda/test/ast/parser/ets/class_late_initialization_with_initalizer_02.ets new file mode 100644 index 0000000000000000000000000000000000000000..14556b9e588b823a5ad84def4bdd177f9995f407 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/class_late_initialization_with_initalizer_02.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. + */ + +interface A { + f!: string = "abc" +} + +/* @@? 17:16 Error SyntaxError: Interface member initialization is prohibited. */ +/* @@? 17:18 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:18 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 18:1 Error SyntaxError: Identifier expected. */ diff --git a/ets2panda/test/ast/parser/ets/class_late_initialization_with_initalizer_03.ets b/ets2panda/test/ast/parser/ets/class_late_initialization_with_initalizer_03.ets new file mode 100644 index 0000000000000000000000000000000000000000..5e773322d49f9279a92568f07921f9e750df5965 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/class_late_initialization_with_initalizer_03.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. + */ + +type A = String | undefined; +class B { + f!: A = undefined; +}; + +/* @@? 18:6 Error SyntaxError: Late-initialized field cannot have default value. */ +/* @@? 18:9 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ diff --git a/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_01.ets b/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..fc9d3639e59c44a1b3691072005f80a1c1cb85ee --- /dev/null +++ b/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_01.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. + */ + +class A { + f1!: undefined + f2!: number | undefined + f3!: null + f4!: number | null +} + +/* @@? 17:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ +/* @@? 18:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ +/* @@? 19:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ +/* @@? 20:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_02.ets b/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_02.ets new file mode 100644 index 0000000000000000000000000000000000000000..080bad8136ffec17c47c958f3a6d2393ca0d78b6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_02.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + f1!: T // cte + f2!: T | undefined // cte + f3!: T | null // cte +} + +class B { + f1!: T + f2!: T | undefined // cte + f3!: T | null // cte +} + +/* @@? 17:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ +/* @@? 18:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ +/* @@? 19:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ +/* @@? 24:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ +/* @@? 25:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_03.ets b/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_03.ets new file mode 100644 index 0000000000000000000000000000000000000000..59ae5937555ac3ca8d98d80e724be3f11176ebba --- /dev/null +++ b/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_03.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. + */ + +class A { + f1!: T // cte +} + +class B extends A{ + +} + +class C extends A{ + f1!: T //OK +} + +class D extends A{ + f1!: T //OK +} + +class E extends A{ + f1!: T // cte +} + +/* @@? 17:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ +/* @@? 33:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ diff --git a/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_04.ets b/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_04.ets new file mode 100644 index 0000000000000000000000000000000000000000..876ca3f3af1b4b292e6f6fe7f22e7f438b470553 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/class_late_initialization_with_invalid_type_04.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. + */ + +interface A { + f1!: T +} + +class B implements A{ + f1!: string +} + +class C implements A{ + f1!: T //OK +} + +class D implements A{ + f1!: T //OK +} + +class E implements A{ + f1!: T // cte +} + + +/* @@? 33:10 Error TypeError: Late-initialized field cannot be nullish types or possibly nullish types. */ diff --git a/ets2panda/test/ast/parser/ets/class_static_late_initialization_assignment_error.ets b/ets2panda/test/ast/parser/ets/class_static_late_initialization_assignment_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..2dd6dec533f97610e1990cbf7bd84c3311b761a6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/class_static_late_initialization_assignment_error.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 A{ + static f!:string +} + +/* @@? 17:13 Error SyntaxError: Late-initialized field cannot be defined as static. */ diff --git a/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.ets b/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.ets new file mode 100644 index 0000000000000000000000000000000000000000..d31d7c3e7a9b63085039b91a46b9988c1aaa4024 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/constructor_type_inference_crash.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 C { + constructor(x: number, y: string); + constructor(s: string); + constructor(xs: any, y?: any) {} +} +let c = new C(10, 'foo'); + +/* @@? 17:14 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 19:3 Error TypeError: No matching call signature for constructor */ +/* @@? 19:19 Error TypeError: Cannot find type 'any'. */ +/* @@? 19:28 Error TypeError: Cannot find type 'any'. */ + diff --git a/ets2panda/test/ast/parser/ets/cycle_constructor.ets b/ets2panda/test/ast/parser/ets/cycle_constructor.ets index cfcd15c37117e8191d1a1c808a0252497119475f..9640362745691deda14a096378fb540c14cca119 100644 --- a/ets2panda/test/ast/parser/ets/cycle_constructor.ets +++ b/ets2panda/test/ast/parser/ets/cycle_constructor.ets @@ -14,7 +14,10 @@ */ class A { - parentField: int; + private _parentField: int; + get parentField(): int { + return this._parentField; + } public constructor() { } } @@ -26,7 +29,7 @@ class B extends A { } } -/* @@? 25:9 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? 25:9 Error TypeError: No matching call signature for cycle_constructor.B(int) */ -/* @@? 25:9 Error TypeError: No matching call signature for constructor */ -/* @@? 25:14 Error TypeError: Using super is not allowed in constructor */ +/* @@? 28:9 Error TypeError: Expected 0 arguments, got 1. */ +/* @@? 28:9 Error TypeError: No matching call signature for cycle_constructor.B(int) */ +/* @@? 28:9 Error TypeError: No matching call signature for constructor */ +/* @@? 28:14 Error TypeError: Using super is not allowed in constructor */ diff --git a/ets2panda/test/ast/parser/ets/default_parameter2.ets b/ets2panda/test/ast/parser/ets/default_parameter2.ets index de4e98af760ec414fc3a9890b6756dddb154d5a1..be81d6ef8449081a84985e1bb611a482fc3de737 100644 --- a/ets2panda/test/ast/parser/ets/default_parameter2.ets +++ b/ets2panda/test/ast/parser/ets/default_parameter2.ets @@ -15,7 +15,7 @@ function main() : void { - foo(); + /* @@ label */foo(); } function foo(a : int, b : int = 10) : int @@ -28,4 +28,5 @@ function foo(a : int) : int return a; } -/* @@? 18:5 Error TypeError: No matching call signature */ +/* @@@ label Error TypeError: Expected 1 arguments, got 0. */ +/* @@@ label Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/parser/ets/do_while_with_empty_body.ets b/ets2panda/test/ast/parser/ets/do_while_with_empty_body.ets new file mode 100644 index 0000000000000000000000000000000000000000..9edf5999e6b1b07060ae2678c603e7fedcbea118 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/do_while_with_empty_body.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. + */ + +do export Boolean [1] = delete + while(true) + +/* @@? 16:4 Error SyntaxError: Unexpected token 'export'. */ +/* @@? 16:4 Error SyntaxError: Missing body in do while statement */ +/* @@? 16:4 Error SyntaxError: Unexpected token, expected 'while'. */ +/* @@? 16:12 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 16:20 Error SyntaxError: Invalid left-hand side in array destructuring pattern. */ +/* @@? 16:20 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 17:4 Error SyntaxError: Expected ')', got 'while'. */ +/* @@? 27:1 Error SyntaxError: Unexpected token 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/do_while_with_empty_condition.ets b/ets2panda/test/ast/parser/ets/do_while_with_empty_condition.ets new file mode 100644 index 0000000000000000000000000000000000000000..afaa9713f487bc5088e27f613bb2fb79a0974bec --- /dev/null +++ b/ets2panda/test/ast/parser/ets/do_while_with_empty_condition.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. + */ + +do {} + while() + +/* @@? 17:10 Error SyntaxError: Unexpected token ')'. */ +/* @@? 22:1 Error SyntaxError: Missing condition in do while statement */ +/* @@? 22:1 Error SyntaxError: Expected ')', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/duplicated_identifier.ets b/ets2panda/test/ast/parser/ets/duplicated_identifier.ets new file mode 100644 index 0000000000000000000000000000000000000000..b36f9db2dfe8b309828223807620c75b323ab72e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/duplicated_identifier.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. + */ + +export async function testGC(){} + +export class testGC{ + static async func(){ + } +} + +/* @@? 16:23 Error TypeError: Identifier 'testGC' has already been declared. */ diff --git a/ets2panda/test/ast/parser/ets/dynmicImportUnimplemented.ets b/ets2panda/test/ast/parser/ets/dynmicImportUnimplemented.ets index 48d3448c4ef1913dfb83a09d79412d4b504f8d20..bfb3a33ce005c9b9a92d9b921f1e4644b214d9a3 100644 --- a/ets2panda/test/ast/parser/ets/dynmicImportUnimplemented.ets +++ b/ets2panda/test/ast/parser/ets/dynmicImportUnimplemented.ets @@ -27,7 +27,5 @@ function main() { assertTrue(!"nothing was thrown") } -/* @@? 18:15 Error TypeError: 'await' expressions require Promise object as argument. */ /* @@? 18:15 Error SyntaxError: Unexpected token 'import'. */ -/* @@? 18:15 Error SyntaxError: Import declarations can only be used on the top level and before any other declaration, top level statement or directive. */ -/* @@? 19:14 Error TypeError: Property 'then' does not exist on type 'String' */ +/* @@? 18:15 Error TypeError: 'await' expressions require Promise object as argument. */ diff --git a/ets2panda/test/ast/parser/ets/empty_array_map_inference_fail.ets b/ets2panda/test/ast/parser/ets/empty_array_map_inference_fail.ets new file mode 100644 index 0000000000000000000000000000000000000000..0d648f4ea72508aa1f13ee99f58bafac51877434 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/empty_array_map_inference_fail.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. + */ + +(function() { + return 37; +})(); + +[].map(function(x) { + return x+1; +}); + +/* @@? 16:2 Error SyntaxError: Unexpected token 'function'. */ +/* @@? 20:1 Error TypeError: Can't resolve array type */ +/* @@? 20:8 Error SyntaxError: Unexpected token 'function'. */ diff --git a/ets2panda/test/ast/parser/ets/enum10.ets b/ets2panda/test/ast/parser/ets/enum10.ets index 7afc83c3a6c38d1ce374a6f15f6e1e1ad69f7855..9a31b18a0a43cc6f0da23e269b695b73fc21cad7 100644 --- a/ets2panda/test/ast/parser/ets/enum10.ets +++ b/ets2panda/test/ast/parser/ets/enum10.ets @@ -16,7 +16,7 @@ enum Color { Red } function main(): void { - let values: Color[] = Color.values(); + let values: FixedArray = Color.values(); // Note(daizihan): values() becomes static method in enum, so no CTE - let valuesFail: Color[] = values[0].values(); + let valuesFail: FixedArray = values[0].values(); } diff --git a/ets2panda/test/ast/parser/ets/enum15.ets b/ets2panda/test/ast/parser/ets/enum15.ets index 94ef7cd8c0f89f505c029a468c3069637df8e66f..f6460b88db75dcdb0f75c9392f7f2f1bd26a72ce 100644 --- a/ets2panda/test/ast/parser/ets/enum15.ets +++ b/ets2panda/test/ast/parser/ets/enum15.ets @@ -20,6 +20,6 @@ enum InvalidInitTypeEnum { } -/* @@? 18:11 Error SyntaxError: Invalid enum initialization value */ +/* @@? 18:11 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ /* @@? 19:7 Error SyntaxError: Only constant expression is expected in the field */ -/* @@? 19:7 Error SyntaxError: Invalid enum initialization value */ +/* @@? 19:7 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/enum16.ets b/ets2panda/test/ast/parser/ets/enum16.ets index 2095786b0f2fe651bb34b7e5cd5a07d814e44a50..4b48931d3d476fb68d4b3b31bb00c84f625dffb5 100644 --- a/ets2panda/test/ast/parser/ets/enum16.ets +++ b/ets2panda/test/ast/parser/ets/enum16.ets @@ -22,7 +22,5 @@ enum InvalidInitTypeEnum { /* @@? 18:13 Error SyntaxError: Unexpected token, expected ',' or '}'. */ /* @@? 18:13 Error TypeError: Unresolved reference b7 */ /* @@? 18:15 Error SyntaxError: Unexpected token ','. */ -/* @@? 18:15 Error SyntaxError: Unexpected token ','. */ -/* @@? 18:15 Error SyntaxError: Unexpected token ','. */ /* @@? 19:3 Error TypeError: Unresolved reference Blue */ /* @@? 20:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/enum17.ets b/ets2panda/test/ast/parser/ets/enum17.ets index cff3d1cde89aaddc4726b05b9e44de3fe7492a60..31bc25f6dad59ea0e9720d405c832d65e523555e 100644 --- a/ets2panda/test/ast/parser/ets/enum17.ets +++ b/ets2panda/test/ast/parser/ets/enum17.ets @@ -19,4 +19,4 @@ enum InvalidInitTypeEnum { Blue } -/* @@? 19:7 Error SyntaxError: Invalid enum initialization value */ +/* @@? 19:7 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/enum18.ets b/ets2panda/test/ast/parser/ets/enum18.ets index 8263fd1a3025e9c90aeab124894c66b18c6de110..8c34ab054c1f9a06c835f2351fa23d3412bc4f56 100644 --- a/ets2panda/test/ast/parser/ets/enum18.ets +++ b/ets2panda/test/ast/parser/ets/enum18.ets @@ -19,5 +19,5 @@ enum InvalidInitTypeEnum { Blue } -/* @@@ label Error SyntaxError: Invalid enum initialization value */ -/* @@? 19:7 Error SyntaxError: Invalid enum initialization value */ +/* @@@ label Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@? 19:7 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/enum22.ets b/ets2panda/test/ast/parser/ets/enum22.ets index 518e1e39a8017d3e369ad8744f8ab684ce22b4c5..1205a10d2bd28bec3efe710fa465df924a2036c3 100644 --- a/ets2panda/test/ast/parser/ets/enum22.ets +++ b/ets2panda/test/ast/parser/ets/enum22.ets @@ -18,5 +18,4 @@ enum duplicateKeysStringCase { /* @@ label */Gray = "#ff808080" } /* @@@ label Error TypeError: Variable 'Gray' has already been declared. */ -/* @@@ label Error TypeError: Variable 'Gray' has already been declared. */ /* @@@ label Error TypeError: Static property 'Gray' must be accessed through it's class 'duplicateKeysStringCase' */ diff --git a/ets2panda/test/ast/parser/ets/enum23.ets b/ets2panda/test/ast/parser/ets/enum23.ets index db791f543c12f1c3e992f98c5c80167401fc6a1f..800c35446e74cec12e57ace55229ce00085a88af 100644 --- a/ets2panda/test/ast/parser/ets/enum23.ets +++ b/ets2panda/test/ast/parser/ets/enum23.ets @@ -18,5 +18,4 @@ enum duplicateKeysNumCase { /* @@ label */Red = 1 } /* @@@ label Error TypeError: Variable 'Red' has already been declared. */ -/* @@@ label Error TypeError: Variable 'Red' has already been declared. */ /* @@@ label Error TypeError: Static property 'Red' must be accessed through it's class 'duplicateKeysNumCase' */ diff --git a/ets2panda/test/ast/parser/ets/enum24.ets b/ets2panda/test/ast/parser/ets/enum24.ets index 8bb6bc737422370932237e488a869be792258623..fd80f213a4d2e583a79223123e03042be85a6203 100644 --- a/ets2panda/test/ast/parser/ets/enum24.ets +++ b/ets2panda/test/ast/parser/ets/enum24.ets @@ -21,4 +21,4 @@ enum Direction { } -/* @@@ label Error SyntaxError: Invalid enum initialization value */ +/* @@@ label 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/enum26.ets b/ets2panda/test/ast/parser/ets/enum26.ets index 4d14efdc799b4c562014f2fc5993893c68b659fa..8a4845c43b47b781e121fce5ef0a367c9028e392 100644 --- a/ets2panda/test/ast/parser/ets/enum26.ets +++ b/ets2panda/test/ast/parser/ets/enum26.ets @@ -21,5 +21,5 @@ enum Direction { /* @@ label1 */} /* @@@ label Error SyntaxError: Unexpected token, expected ',' or '}'. */ -/* @@? 20:17 Error TypeError: Unresolved reference Right */ +/* @@@ label Error TypeError: Unresolved reference Right */ /* @@@ label1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/enum27.ets b/ets2panda/test/ast/parser/ets/enum27.ets index c9e82b92ff51c59e5fb5b0234ff0d0affd87821b..f55d7a45a77d4e09155f856ff66fdd0a6d1df781 100644 --- a/ets2panda/test/ast/parser/ets/enum27.ets +++ b/ets2panda/test/ast/parser/ets/enum27.ets @@ -1,3 +1,4 @@ +/* @@ label2 */ /* * Copyright (c) 2024-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,5 +22,6 @@ enum Date { Day = /* @@ label1 */Date.now() } -/* @@@ label Error SyntaxError: Invalid enum initialization value */ -/* @@@ label1 Error SyntaxError: Invalid enum initialization value */ +/* @@@ 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. */ diff --git a/ets2panda/test/ast/parser/ets/enum28.ets b/ets2panda/test/ast/parser/ets/enum28.ets index 33106ea5190a93c219388b338778a7e4fee9f6e2..3c63eabaad9684e38fa8c2f8518015dbadb2bde5 100644 --- a/ets2panda/test/ast/parser/ets/enum28.ets +++ b/ets2panda/test/ast/parser/ets/enum28.ets @@ -17,5 +17,5 @@ enum Color { Red = /* @@ label */`Line 1\nLine 2 ${1}`, } -/* @@@ label Error SyntaxError: String Interpolation Expression is not constant expression. */ -/* @@@ label Error SyntaxError: Invalid enum initialization value */ +/* @@@ label Error SyntaxError: String Interpolation Expression is not constant expression. */ +/* @@@ label 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/enum29.ets b/ets2panda/test/ast/parser/ets/enum29.ets index bc59731b22ff6b23a2a4c23b77e5bcdf0b749dab..b7981e02d0b9b36ccf68c7f7bf932d9fa6b9fa27 100644 --- a/ets2panda/test/ast/parser/ets/enum29.ets +++ b/ets2panda/test/ast/parser/ets/enum29.ets @@ -61,9 +61,10 @@ function main(): void { const red = Color.Red; switch (Color.Green) { case Color.Blue: break; - case red: break; + case /* @@ label1 */red: break; case Color.Green: break; } } -/* @@@ label Error SyntaxError: Invalid enum initialization value */ \ No newline at end of file +/* @@@ label Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@@ label1 Error TypeError: Enum switch case must be unqualified name of an enum constant */ diff --git a/ets2panda/test/ast/parser/ets/enum3.ets b/ets2panda/test/ast/parser/ets/enum3.ets index ce66860a394a77b50009d303513023789bf27695..553b552a78aa95b2cef021ee43f4a83eb9f0af10 100644 --- a/ets2panda/test/ast/parser/ets/enum3.ets +++ b/ets2panda/test/ast/parser/ets/enum3.ets @@ -16,6 +16,3 @@ enum EmptyEnum { } - -/* @@? 18:1 Error SyntaxError: An enum must have at least one enum constant. */ -/* @@? 18:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/enum31.ets b/ets2panda/test/ast/parser/ets/enum31.ets index 3af1f2679b74f3d343dfcfbb648e7ae525e592c9..94610107964319c20eed08a7350f2eb8bca6c816 100644 --- a/ets2panda/test/ast/parser/ets/enum31.ets +++ b/ets2panda/test/ast/parser/ets/enum31.ets @@ -24,5 +24,5 @@ enum ColorC { Green = /* @@ label1 */ColorB.Green } -/* @@@ label Error SyntaxError: Invalid enum initialization value */ -/* @@@ label1 Error SyntaxError: Invalid enum initialization value */ +/* @@@ 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. */ diff --git a/ets2panda/test/ast/parser/ets/enum32.ets b/ets2panda/test/ast/parser/ets/enum32.ets index eed57284a5d5ac0c0db5c4f713c27dd11c1cae3b..0201bd17b91dc3cbb9d27e83a5801fd9499bfe53 100644 --- a/ets2panda/test/ast/parser/ets/enum32.ets +++ b/ets2panda/test/ast/parser/ets/enum32.ets @@ -18,7 +18,7 @@ enum Color2 { Red = /* @@ label1 */Color.Red } enum Color3 { Red = /* @@ label2 */Color2.Red } enum Color4 { Red = /* @@ label3 */Color3.Red } -/* @@@ label Error SyntaxError: Invalid enum initialization value */ -/* @@@ label1 Error SyntaxError: Invalid enum initialization value */ -/* @@@ label2 Error SyntaxError: Invalid enum initialization value */ -/* @@@ label3 Error SyntaxError: Invalid enum initialization value */ +/* @@@ 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: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@@ label3 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/enum5.ets b/ets2panda/test/ast/parser/ets/enum5.ets index 3a8a33c62a032eacb6ad3d0ae1986590fbfe826e..74fc8ad53d3b69a340ce1d10c14a832d84654a6b 100644 --- a/ets2panda/test/ast/parser/ets/enum5.ets +++ b/ets2panda/test/ast/parser/ets/enum5.ets @@ -19,5 +19,5 @@ enum MissingCommaEnum { /* @@ label1 */} /* @@@ label Error SyntaxError: Unexpected token, expected ',' or '}'. */ -/* @@? 18:17 Error TypeError: Unresolved reference Green */ +/* @@@ label Error TypeError: Unresolved reference Green */ /* @@@ label1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/enum_default_invalid_value_type.ets b/ets2panda/test/ast/parser/ets/enum_default_invalid_value_type.ets index 1ba429cfb151c3e429efd933e50eaaa14d19aa7e..b80dde0c68c448e08594fa236dcb89c3fcc994f4 100644 --- a/ets2panda/test/ast/parser/ets/enum_default_invalid_value_type.ets +++ b/ets2panda/test/ast/parser/ets/enum_default_invalid_value_type.ets @@ -27,6 +27,6 @@ enum C { } -/* @@? 17:9 Error SyntaxError: Invalid enum initialization value */ -/* @@? 21:9 Error SyntaxError: Invalid enum initialization value */ -/* @@? 26:9 Error SyntaxError: Invalid enum initialization value */ +/* @@? 17:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@? 21:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@? 26: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/enum_default_negative.ets b/ets2panda/test/ast/parser/ets/enum_default_negative.ets index 26414dd9703bfd80cdbe4c6c347ffe4a0aec6353..617fe9862870fa33c1b3e93edbe3b0d45f191d20 100644 --- a/ets2panda/test/ast/parser/ets/enum_default_negative.ets +++ b/ets2panda/test/ast/parser/ets/enum_default_negative.ets @@ -26,13 +26,12 @@ enum D { } -/* @@? 17:9 Error SyntaxError: Invalid enum initialization value */ +/* @@? 17:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ /* @@? 17:10 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 20:1 Error SyntaxError: Unexpected token, expected ',' or '}'. */ /* @@? 21:9 Error SyntaxError: Unexpected token ')'. */ -/* @@? 21:9 Error SyntaxError: Unexpected token, expected ',' or '}'. */ -/* @@? 21:9 Error SyntaxError: Unexpected token ')'. */ -/* @@? 21:9 Error SyntaxError: Invalid enum initialization value */ -/* @@? 22:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 21:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ /* @@? 26:1 Error SyntaxError: Unexpected token, expected ':'. */ -/* @@? 39:1 Error SyntaxError: Unexpected token 'eos'. */ -/* @@? 39:1 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 38:1 Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@? 38:1 Error SyntaxError: Unexpected token, expected ',' or '}'. */ diff --git a/ets2panda/test/ast/parser/ets/enum_default_negative1.ets b/ets2panda/test/ast/parser/ets/enum_default_negative1.ets index 4b7f2a8fec4bd05a01349b5c73486c47bcdfa41d..d70a08880a07e46fcf4b7eb1ca56d343d445dc47 100644 --- a/ets2panda/test/ast/parser/ets/enum_default_negative1.ets +++ b/ets2panda/test/ast/parser/ets/enum_default_negative1.ets @@ -24,6 +24,6 @@ enum B { /* @@? 17:9 Error SyntaxError: Unsupported operator for String. */ -/* @@? 17:9 Error SyntaxError: Invalid enum initialization value */ +/* @@? 17:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ /* @@? 22:9 Error SyntaxError: Only constant expression is expected in the field */ -/* @@? 22:9 Error SyntaxError: Invalid enum initialization value */ +/* @@? 22: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/enum_multi_error/enum_empty.ets b/ets2panda/test/ast/parser/ets/enum_multi_error/enum_empty.ets index 5d9b611742f28bb55f1bf3cd9c86e03a84927fdb..5ccbb9811890b06261a8f3f407753078692d141d 100644 --- a/ets2panda/test/ast/parser/ets/enum_multi_error/enum_empty.ets +++ b/ets2panda/test/ast/parser/ets/enum_multi_error/enum_empty.ets @@ -16,7 +16,7 @@ enum // Printed two errors about eos, because there are two attempts to read identifiers: name enum and name property -/* @@@ label Error SyntaxError: Identifier expected, got 'eos'. */ +/* @@@ label Error SyntaxError: Identifier expected, got 'end of stream'. */ /* @@@ label Error SyntaxError: Unexpected token, expected '{'. */ -/* @@@ label Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/enum_multi_error/enum_with_identifier.ets b/ets2panda/test/ast/parser/ets/enum_multi_error/enum_with_identifier.ets index a88630d092b3dd50c5cdd639f3a5210564864833..13fbdd0ad7a008fb996a35f8ad25589064ab68a1 100644 --- a/ets2panda/test/ast/parser/ets/enum_multi_error/enum_with_identifier.ets +++ b/ets2panda/test/ast/parser/ets/enum_multi_error/enum_with_identifier.ets @@ -16,5 +16,5 @@ enum a /* @@@ label Error SyntaxError: Unexpected token, expected '{'. */ -/* @@@ label Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/single_export/single_export_default_lambda.ets b/ets2panda/test/ast/parser/ets/export_after_statement.ets similarity index 79% rename from ets2panda/test/ast/parser/ets/single_export/single_export_default_lambda.ets rename to ets2panda/test/ast/parser/ets/export_after_statement.ets index 1249a99832f29fdd14aae99219b350a0c88b274b..cf56e544dead5fdb081574db5965292a1b5edff0 100644 --- a/ets2panda/test/ast/parser/ets/single_export/single_export_default_lambda.ets +++ b/ets2panda/test/ast/parser/ets/export_after_statement.ets @@ -13,6 +13,8 @@ * limitations under the License. */ -export default /* @@ label */(a: int) => { return a } +while (false) export { +} -/* @@@ label Error SyntaxError: Export is allowed only for declarations. */ +/* @@? 16:15 Error SyntaxError: Unexpected token 'export'. */ +/* @@? 16:15 Error SyntaxError: Missing body in while statement */ diff --git a/ets2panda/test/ast/parser/ets/forOfType.ets b/ets2panda/test/ast/parser/ets/forOfType.ets index 5fa4f92fe16d57a7d38fc2289b1e611ff7cf90f0..32ef6ae505a068762221a4729ebdbca661a6702e 100644 --- a/ets2panda/test/ast/parser/ets/forOfType.ets +++ b/ets2panda/test/ast/parser/ets/forOfType.ets @@ -12,8 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +function k() : long { return 0; } -for ( Fi of /* @@ label */typeof `k` as () => bigint | long ) +for ( Fi of /* @@ label */ k as () => bigint | long ) await this instanceof int /* @@@ label Error TypeError: 'For-of' statement source expression is not of iterable type. */ diff --git a/ets2panda/test/ast/parser/ets/for_of_02.ets b/ets2panda/test/ast/parser/ets/for_of_02.ets index 2488cf4cd9b1e7557335954ae067d5354d5e7a93..535270a5967403b2897ae0740dfcfa0c2a198a0c 100644 --- a/ets2panda/test/ast/parser/ets/for_of_02.ets +++ b/ets2panda/test/ast/parser/ets/for_of_02.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 - 2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-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 @@ -32,4 +32,4 @@ function main(): void { } } -/* @@@ label Error TypeError: Source element type 'double' is not assignable to the loop iterator type 'float'. */ +/* @@? 30:17 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'float'. */ diff --git a/ets2panda/test/ast/parser/ets/for_of_04.ets b/ets2panda/test/ast/parser/ets/for_of_04.ets index 73102569bed6a023ab3e2c2d7e13769bc34e6e6c..85923c87813a1f70bf3d84e688d9be9104371171 100644 --- a/ets2panda/test/ast/parser/ets/for_of_04.ets +++ b/ets2panda/test/ast/parser/ets/for_of_04.ets @@ -26,13 +26,12 @@ for (i in 50) { a += 10 } /* @@? 20:9 Error SyntaxError: Type annotation is not allowed when existing variable is used as loop iterator in 'for' statement. */ -/* @@? 20:11 Error SyntaxError: Expected ';', got 'identification literal'. */ -/* @@? 20:11 Error TypeError: Unresolved reference double */ +/* @@? 20:11 Error SyntaxError: Expected ';', got 'double'. */ +/* @@? 20:11 Error SyntaxError: Unexpected token 'double'. */ /* @@? 20:18 Error SyntaxError: Expected ';', got 'identification literal'. */ /* @@? 20:18 Error TypeError: Unresolved reference of */ /* @@? 20:21 Error SyntaxError: Expected ')', got 'identification literal'. */ /* @@? 20:21 Error TypeError: Unresolved reference a */ /* @@? 20:22 Error SyntaxError: Unexpected token ')'. */ -/* @@? 20:22 Error SyntaxError: Unexpected token ')'. */ -/* @@? 20:22 Error SyntaxError: Unexpected token ')'. */ +/* @@? 20:24 Error SyntaxError: Unexpected token '{'. */ /* @@? 25:11 Error TypeError: 'For-of' statement source expression is not of iterable type. */ diff --git a/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets b/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets index 8b89ebd4efc3e186a7fafa53fcff6e99e252254c..167d3297a19d4909e7ac1081109bba1a9d70224a 100644 --- a/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets +++ b/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets @@ -30,7 +30,7 @@ for (let value = 40 /* @@ label2 */of iterable2) { console.log(value); } -/* @@@ label1 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ -/* @@@ label2 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ -/* @@? 18:1 Error TypeError: Source element type 'double' is not assignable to the loop iterator type 'int'. */ -/* @@? 28:1 Error TypeError: Source element type 'double' is not assignable to the loop iterator type 'int'. */ +/* @@? 18:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'int'. */ +/* @@? 18:38 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ +/* @@? 28:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'int'. */ +/* @@? 28:36 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ diff --git a/ets2panda/test/ast/parser/ets/for_with_empty_body.ets b/ets2panda/test/ast/parser/ets/for_with_empty_body.ets new file mode 100644 index 0000000000000000000000000000000000000000..a1e35845ea6a878d0d19b02859dced6014839eb3 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/for_with_empty_body.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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +for ( ; ; ) + +try { + +} + +/* @@? 22:1 Error SyntaxError: A try statement should contain either finally clause or at least one catch clause. */ diff --git a/ets2panda/test/ast/parser/ets/generic_defined_before_use_neg_5.ets b/ets2panda/test/ast/parser/ets/generic_defined_before_use_neg_5.ets index 3cd51fe7b2069071537a26ac3932929bf538d5d1..807151f8e0e1f84246a66c1c49cb601d2d46dedf 100644 --- a/ets2panda/test/ast/parser/ets/generic_defined_before_use_neg_5.ets +++ b/ets2panda/test/ast/parser/ets/generic_defined_before_use_neg_5.ets @@ -14,4 +14,4 @@ */ class SomeType{} function foo(){} -/* @@@ label Error TypeError: Type Parameter T2 should be defined before use. */ +/* @@? 1:3 Error TypeError: Type Parameter T2 should be defined before use. */ diff --git a/ets2panda/test/ast/parser/ets/generics_1.ets b/ets2panda/test/ast/parser/ets/generics_1.ets index 8a8da729fc8abfdca61e8e9c752013389fdf7eb0..de790ec0e44aeb449c3b38ccda4ba1b85a88fd37 100644 --- a/ets2panda/test/ast/parser/ets/generics_1.ets +++ b/ets2panda/test/ast/parser/ets/generics_1.ets @@ -36,5 +36,5 @@ function main(): void { /* @@ label */d.b.a.c = 127; } -/* @@@ label Warning Warning: Variable 'd' is used before being assigned. */ +/* @@@ label Error TypeError: Variable 'd' is used before being assigned. */ /* @@@ label Error TypeError: There were errors during assign analysis (1) */ diff --git a/ets2panda/test/ast/parser/ets/getter_setter_endless_loop.ets b/ets2panda/test/ast/parser/ets/getter_setter_endless_loop.ets index 497b084e8ca8f7f9090d2e7c2ee867fe588e10f7..0336a0ba77870594f61fb9ae16977f72dea78118 100644 --- a/ets2panda/test/ast/parser/ets/getter_setter_endless_loop.ets +++ b/ets2panda/test/ast/parser/ets/getter_setter_endless_loop.ets @@ -28,4 +28,3 @@ function main() { /* @@? 20:58 Warning Warning: Reading the value of the property inside its getter may lead to an endless loop. */ /* @@? 21:52 Warning Warning: Assigning new value to the property inside its setter may lead to an endless loop. */ -/* @@? 21:52 Warning Warning: Assigning new value to the property inside its setter may lead to an endless loop. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets b/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets index ceba1bde64379296644943ed904b8dac63d2a2cc..fbf2024f41b6adb55f16c4d5531bc5a82e562986 100644 --- a/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets +++ b/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets @@ -19,8 +19,5 @@ function main(): void { s.toString() let a: int [] = [1, 2] let b = s ?? a; - /* @@ label */b.toString(); + b.toString(); } - -/* @@@ label Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label Error TypeError: Type String|int[] is illegal in union member expression. */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/default_import3.ets b/ets2panda/test/ast/parser/ets/import_tests/default_import3.ets index 356d6fbad735ed7c3fd5f0bf5952bb5bf258086b..b9a0fc925dd40d790769244bf0030d9bd04c5c3b 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/default_import3.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/default_import3.ets @@ -16,8 +16,7 @@ import {default/* @@ label */} from /* @@ label1 */"./modules/class_default_module.ets"/* @@ label2 */; /* @@@ label Error SyntaxError: Unexpected token, expected 'as'. */ -/* @@@ label Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@@ label1 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@@ label2 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@@ label3 Error SyntaxError: Expected '}', got 'eos'. */ -/* @@ label3 */ \ No newline at end of file +/* @@@ label Error SyntaxError: Unexpected token '}'. */ +/* @@@ label1 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@@ label1 Error SyntaxError: Unexpected token, expected 'from'. */ +/* @@@ label2 Error SyntaxError: Unexpected token, expected string literal. */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/export_trailing_comma.ets b/ets2panda/test/ast/parser/ets/import_tests/export_trailing_comma.ets index ef13ce923c141edd8f0bc2bbdddf5a53a519f14f..9a2411abe4612dd07bcd19cd111b7105603b3191 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/export_trailing_comma.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/export_trailing_comma.ets @@ -19,4 +19,4 @@ function foo3(): void {} export {foo2,} export {/* @@ label */, foo3} -/* @@@ label Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@@ label Error SyntaxError: Unexpected token ','. */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/import_name_2.ets b/ets2panda/test/ast/parser/ets/import_tests/import_name_2.ets index cc576d3f095d88107f987b3d01c848db8f6746e0..47185e975be32cf0056279b7d9b564aa7492173b 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_name_2.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/import_name_2.ets @@ -19,5 +19,4 @@ import {foo, flt} from "import_tests/packages"; let x = foo(dbl); /* @@? 19:13 Error TypeError: Unresolved reference dbl */ -/* @@? 19:13 Error TypeError: Unresolved reference dbl */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/main_1.ets b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/main_1.ets index a762c4c10874ba646ba842df8faf144a67b9e7f1..31857cd3baa5977409841e142af020aa2cc06f2a 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/main_1.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/main_1.ets @@ -14,9 +14,10 @@ */ import {foo_1 as foo} from "./imported_module_1.ets" -import {foo_2_1param as foo} from /* @@ label */"./imported_module_2.ets" +import {foo_2 as foo} from "./imported_module_2.ets" function main() : void {} -/* @@@ label Error TypeError: Function 'foo' is already defined. */ +// NOTE(kaskov): Add more precise error, when will be suggestions +/* @@? imported_module_2.ets:27:8 Error TypeError: Function foo_1 is already declared. */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/type/type_2.ets b/ets2panda/test/ast/parser/ets/import_tests/type/type_2.ets index beac54746350a1d57a410095964bd897089bb9fd..aa88265896ace1057ed3c5b1512650ac2305064f 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/type/type_2.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/type/type_2.ets @@ -15,6 +15,6 @@ export class A {} -export type {A as /* @@ label */AA}; +export type {A as AA}; -/* @@@ label Error SyntaxError: Name 'A' cannot be exported and type exported at the same time. */ +/* @@? 18:19 Error SyntaxError: Cannot export 'A', it was already exported. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/import_tests/type/type_3.ets b/ets2panda/test/ast/parser/ets/import_tests/type/type_3.ets index ab681c0acc3522edd0b7058fd6cafa21d1dc0e90..0b9164b765f7c06ab2d9555a1be06ff19d4a9ea5 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/type/type_3.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/type/type_3.ets @@ -17,7 +17,7 @@ function foo(): void {} class TestClass {} export {foo} -export type {TestClass as /* @@ label */foo} +export type {TestClass as foo} -/* @@@ label Error SyntaxError: The given name 'foo' is already used in another export. */ -/* @@@ label Error SyntaxError: The given name 'foo' is already used in another export. */ +/* @@? 20:14 Error SyntaxError: The given name 'foo' is already used in another export. */ +/* @@? 20:27 Error SyntaxError: The given name 'foo' is already used in another export. */ diff --git a/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined-invalid.ets b/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined-invalid.ets index 5b3d8c42ad85ae211bb1c29eecb6cc13b5aa45ed..e3b52ed7aeb2e461a67468b93781a1b56ce68a38 100644 --- a/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined-invalid.ets +++ b/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined-invalid.ets @@ -14,9 +14,9 @@ */ function main(){ let a = 1; - a/* @@ label */~!/* @@ label1 */; + a/* @@ label */~/* @@ label1 */!/* @@ label2 */; } -/* @@? 17:19 Error SyntaxError: Unexpected token '~'. */ -/* @@? 17:20 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ -/* @@? 17:36 Error SyntaxError: Unexpected token ';'. */ -/* @@? 17:36 Error TypeError: Bad operand type, the type of the operand must be boolean type. */ +/* @@@ label Error SyntaxError: Unexpected token '~'. */ +/* @@@ label1 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ +/* @@@ label2 Error SyntaxError: Unexpected token ';'. */ +/* @@@ label2 Error TypeError: Bad operand type, the type of the operand must be boolean type. */ diff --git a/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined.ets b/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined.ets index 16985cfec4f38ff643ac629e9def3ef9cd689405..975a0fe9468d1ec9432809dcf607e841c59d8adf 100644 --- a/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined.ets +++ b/ets2panda/test/ast/parser/ets/increment-on-nullish-type-undefined.ets @@ -18,4 +18,6 @@ } /* @@? 17:3 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ - /* @@? 17:3 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ \ No newline at end of file + /* @@? 17:3 Error TypeError: Cannot cast 'null' or 'undefined' to non-nullish type. */ + /* @@? 17:3 Error TypeError: Type 'Double' cannot be assigned to type 'undefined' */ + diff --git a/ets2panda/test/ast/parser/ets/instanceof_with_not_object_type.ets b/ets2panda/test/ast/parser/ets/instanceof_with_not_object_type.ets index 3452b56fedea466145c6d67964f02a52e543a99b..3e3263a00113b3e4cde7f4b31d4290f7d9a6aa88 100644 --- a/ets2panda/test/ast/parser/ets/instanceof_with_not_object_type.ets +++ b/ets2panda/test/ast/parser/ets/instanceof_with_not_object_type.ets @@ -25,4 +25,4 @@ function main() } /* @@@ label Error TypeError: Cannot find type 'a'. */ -/* @@? 24:5 Error TypeError: Bad operand type, the types of the operands must be same type. */ +/* @@? 24:5 Error TypeError: Using the 'instance of' operator with non-object type 'b' */ diff --git a/ets2panda/test/ast/parser/ets/interfaceMethodReadonlyModifier.ets b/ets2panda/test/ast/parser/ets/interfaceMethodReadonlyModifier.ets index 0bcf0c313b351645224b545b3b0f8f836dc4ac51..39dcced0fd57af716fe1df1d7969c1132a68d59e 100644 --- a/ets2panda/test/ast/parser/ets/interfaceMethodReadonlyModifier.ets +++ b/ets2panda/test/ast/parser/ets/interfaceMethodReadonlyModifier.ets @@ -14,7 +14,11 @@ */ interface I { - /* @@ label */readonly foo() + readonly foo() } -/* @@@ label Error SyntaxError: Modifier 'readonly' cannot be applied to an interface method. */ +/* @@? 17:17 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 17:18 Error SyntaxError: Invalid Type. */ +/* @@? 17:18 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:18 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 18:1 Error SyntaxError: Identifier expected. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/interface_ambient_indexer_1.ets b/ets2panda/test/ast/parser/ets/interface_ambient_indexer_1.ets index 0a849d0789d07592610f7d5de704fea1d09d389f..60f624907e9657bba311ec6f64cc86f7a71d5a63 100644 --- a/ets2panda/test/ast/parser/ets/interface_ambient_indexer_1.ets +++ b/ets2panda/test/ast/parser/ets/interface_ambient_indexer_1.ets @@ -20,4 +20,3 @@ declare interface A { } /* @@? 19:5 Error TypeError: Cannot find type 'stringdd'. */ -/* @@? 19:5 Error TypeError: Cannot find type 'stringdd'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/interface_ambient_iterable.ets b/ets2panda/test/ast/parser/ets/interface_ambient_iterable.ets index e53d9af90777195c6d32bd79466303398d0134d4..a186fd0f709b0ffee8baad3e0149ada2b9392fda 100644 --- a/ets2panda/test/ast/parser/ets/interface_ambient_iterable.ets +++ b/ets2panda/test/ast/parser/ets/interface_ambient_iterable.ets @@ -17,4 +17,3 @@ declare interface IterableInterface { [Symbol.iterator]: Iterable } /* @@? 17:22 Error TypeError: Type 'Iterable' is generic but type argument were not provided. */ -/* @@? 17:22 Error TypeError: Type 'Iterable' is generic but type argument were not provided. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/interface_instantiation.ets b/ets2panda/test/ast/parser/ets/interface_instantiation.ets index ef8fdcb57d63a7bd746464760458d9338fb01b63..baa3579c4d6cea316f9eab3e3633b25b4d02d20a 100644 --- a/ets2panda/test/ast/parser/ets/interface_instantiation.ets +++ b/ets2panda/test/ast/parser/ets/interface_instantiation.ets @@ -17,4 +17,3 @@ interface Base {} let b = /* @@ label */new Base /* @@@ label Error TypeError: Base is an interface therefore cannot be instantiated. */ -/* @@@ label Error TypeError: Base is an interface therefore cannot be instantiated. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/interface_late_initialization_conflict_modifier.ets b/ets2panda/test/ast/parser/ets/interface_late_initialization_conflict_modifier.ets new file mode 100644 index 0000000000000000000000000000000000000000..af859301bffdac40ccd71cd19fce7d8dd8631f7d --- /dev/null +++ b/ets2panda/test/ast/parser/ets/interface_late_initialization_conflict_modifier.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. + */ + +interface A { + f1?!:string + f2!?:number +} + +/* @@? 17:7 Error SyntaxError: Conflicting modifiers '!' and '?' on field. */ +/* @@? 18:7 Error SyntaxError: Conflicting modifiers '!' and '?' on field. */ diff --git a/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets b/ets2panda/test/ast/parser/ets/interface_parser_error_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..afa196d8f38516aa48a779213330e93a323eb240 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/interface_parser_error_1.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. + */ + +b: Geit { + t {name(): + +interface I { + readonly : boolean +} +inter + +class A implements I { + reanstructor() { + this.a = f�ls + s A { + @ constructor() { + this.a = ruO; + } +}* +function mdin() { let a = new A(); + ass + +/* @@? 16:4 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 16:4 Error TypeError: Unresolved reference Geit */ +/* @@? 16:9 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:2 Error TypeError: Unresolved reference t */ +/* @@? 17:4 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:5 Error TypeError: Unresolved reference name */ +/* @@? 17:11 Error SyntaxError: Unexpected token ':'. */ +/* @@? 20:5 Error SyntaxError: Identifier expected. */ +/* @@? 20:14 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 20:14 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 20:16 Error SyntaxError: Identifier expected. */ +/* @@? 20:16 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 20:16 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 21:1 Error SyntaxError: Identifier expected. */ +/* @@? 22:1 Error TypeError: Class literal is not yet supported. */ +/* @@? 22:1 Error TypeError: Cannot find type 'inter'. */ +/* @@? 24:7 Error SyntaxError: Unexpected token 'A'. */ +/* @@? 24:7 Error TypeError: Unresolved reference A */ +/* @@? 24:9 Error SyntaxError: Unexpected token 'implements'. */ +/* @@? 24:20 Error SyntaxError: Unexpected token 'I'. */ +/* @@? 24:20 Error TypeError: Interface name 'I' used in the wrong context */ +/* @@? 24:22 Error SyntaxError: Unexpected token '{'. */ +/* @@? 25:4 Error TypeError: Unresolved reference reanstructor */ +/* @@? 26:19 Error SyntaxError: Unexpected token '�ls'. */ +/* @@? 26:19 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 27:5 Error SyntaxError: Unexpected token 'A'. */ +/* @@? 27:7 Error SyntaxError: Unexpected token '{'. */ +/* @@? 28:5 Error SyntaxError: Identifier expected, got 'constructor'. */ +/* @@? 28:19 Error SyntaxError: Annotations are not allowed on this type of declaration. */ +/* @@? 29:18 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 31:2 Error SyntaxError: Unexpected token '*'. */ +/* @@? 32:1 Error SyntaxError: Nested functions are not allowed. */ +/* @@? 68:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/interface_parser_error_2.ets b/ets2panda/test/ast/parser/ets/interface_parser_error_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..b2f0dcd0902a63a54ab92a8ad400b76ac841b95e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/interface_parser_error_2.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. + */ + +interface I { + : boolean +} + +/* @@? 17:5 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 17:7 Error SyntaxError: Identifier expected. */ +/* @@? 17:7 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:7 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 18:1 Error SyntaxError: Identifier expected. */ diff --git a/ets2panda/test/ast/parser/ets/interface_static_late_initialization_assignment_error.ets b/ets2panda/test/ast/parser/ets/interface_static_late_initialization_assignment_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..4eb37bbc788f851d6803f2c99140d4b8f2fe6cc7 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/interface_static_late_initialization_assignment_error.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. + */ + +interface A{ + static f!:string +} + +/* @@? 17:5 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ diff --git a/ets2panda/test/ast/parser/ets/invalidEnums.ets b/ets2panda/test/ast/parser/ets/invalidEnums.ets index 3da156a85b38017714d4e7cf6f66e4388d66129a..7f609a640d5684f5bfee4f5553b759bc3047db16 100644 --- a/ets2panda/test/ast/parser/ets/invalidEnums.ets +++ b/ets2panda/test/ast/parser/ets/invalidEnums.ets @@ -60,19 +60,16 @@ enum MissingLeftBrace /* @@? 16:5 Error SyntaxError: Variable declaration expected. */ /* @@? 22:22 Error SyntaxError: Unexpected token, expected '{'. */ -/* @@? 32:1 Error SyntaxError: Unexpected token ']'. */ /* @@? 32:1 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 32:1 Error SyntaxError: Unexpected token ']'. */ /* @@? 37:10 Error SyntaxError: Only constant expression is expected in the field */ -/* @@? 37:10 Error SyntaxError: Invalid enum initialization value */ +/* @@? 37:10 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ /* @@? 38:1 Error SyntaxError: Unexpected token '}'. */ -/* @@? 43:10 Error SyntaxError: Invalid enum initialization value */ -/* @@? 43:10 Error SyntaxError: Only constant expression is expected in the field */ +/* @@? 40:1 Error SyntaxError: Unexpected token, expected ',' or '}'. */ /* @@? 43:10 Error SyntaxError: Unexpected token '?'. */ -/* @@? 44:1 Error SyntaxError: Unexpected token '}'. */ -/* @@? 44:1 Error SyntaxError: Unexpected token, expected ':'. */ -/* @@? 46:1 Error SyntaxError: Unexpected token 'enum'. */ -/* @@? 46:1 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 43:10 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ /* @@? 48:3 Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@? 48:3 Error TypeError: Unresolved reference Member2 */ /* @@? 49:1 Error SyntaxError: Unexpected token '}'. */ /* @@? 56:3 Error SyntaxError: Unexpected token, expected '{'. */ /* @@? 56:10 Error SyntaxError: Identifier expected, got ','. */ diff --git a/ets2panda/test/ast/parser/ets/invalidEnums1.ets b/ets2panda/test/ast/parser/ets/invalidEnums1.ets index abb5d7d521eb1ef592689a560c56d9b8524544d3..2021d1a65fdf77e5989dc25f8827933ee4ddfeef 100644 --- a/ets2panda/test/ast/parser/ets/invalidEnums1.ets +++ b/ets2panda/test/ast/parser/ets/invalidEnums1.ets @@ -26,7 +26,7 @@ enum EStrNotInit { } -/* @@? 18:15 Error SyntaxError: Invalid enum initialization value */ -/* @@? 19:12 Error SyntaxError: Invalid enum initialization value */ -/* @@? 20:12 Error SyntaxError: Invalid enum initialization value */ +/* @@? 18:15 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@? 19:12 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@? 20:12 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ /* @@? 25:9 Error SyntaxError: All items of string-type enumeration should be explicitly initialized. */ diff --git a/ets2panda/test/ast/parser/ets/invalidTypes.ets b/ets2panda/test/ast/parser/ets/invalidTypes.ets index e67924adcbed0e40dd403ded873ed15729581491..ebd93a9b39d70e3c481bb2da63ef8585ff57aab2 100644 --- a/ets2panda/test/ast/parser/ets/invalidTypes.ets +++ b/ets2panda/test/ast/parser/ets/invalidTypes.ets @@ -39,62 +39,38 @@ let var6: [a0: , a1: ]; /* @@? 18:23 Error SyntaxError: Type annotation isn't allowed for constructor. */ /* @@? 24:12 Error SyntaxError: Invalid Type. */ -/* @@? 24:12 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:12 Error SyntaxError: Unexpected token '...'. */ /* @@? 24:12 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 24:12 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:23 Error SyntaxError: Unexpected token ','. */ -/* @@? 24:23 Error SyntaxError: Unexpected token ','. */ +/* @@? 24:15 Error SyntaxError: Unexpected token 'number'. */ /* @@? 24:23 Error SyntaxError: Unexpected token ','. */ /* @@? 24:25 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:25 Error SyntaxError: Unexpected token '...'. */ -/* @@? 24:36 Error SyntaxError: Unexpected token ']'. */ +/* @@? 24:28 Error SyntaxError: Unexpected token 'string'. */ /* @@? 24:36 Error SyntaxError: Unexpected token ']'. */ -/* @@? 24:36 Error SyntaxError: Unexpected token ']'. */ -/* @@? 26:12 Error SyntaxError: Unexpected token '...'. */ -/* @@? 26:12 Error SyntaxError: Unexpected token '...'. */ -/* @@? 26:12 Error SyntaxError: Unexpected token '...'. */ /* @@? 26:12 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 26:12 Error SyntaxError: Unexpected token '...'. */ /* @@? 26:12 Error SyntaxError: Invalid Type. */ +/* @@? 26:15 Error SyntaxError: Unexpected token 'number'. */ /* @@? 26:23 Error SyntaxError: Unexpected token ','. */ -/* @@? 26:23 Error SyntaxError: Unexpected token ','. */ -/* @@? 26:23 Error SyntaxError: Unexpected token ','. */ +/* @@? 26:25 Error SyntaxError: Unexpected token 'string'. */ /* @@? 26:25 Error TypeError: Type name 'string' used in the wrong context */ /* @@? 26:31 Error SyntaxError: Unexpected token ']'. */ -/* @@? 26:31 Error SyntaxError: Unexpected token ']'. */ -/* @@? 26:31 Error SyntaxError: Unexpected token ']'. */ /* @@? 28:18 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 28:18 Error SyntaxError: Unexpected token '?'. */ -/* @@? 28:18 Error SyntaxError: Unexpected token '?'. */ -/* @@? 28:19 Error SyntaxError: Unexpected token, expected ':'. */ /* @@? 28:19 Error SyntaxError: Unexpected token ']'. */ -/* @@? 28:20 Error SyntaxError: Unexpected token ';'. */ -/* @@? 30:18 Error SyntaxError: Unexpected token, expected ',' or ']'. */ -/* @@? 30:18 Error SyntaxError: Unexpected token ':'. */ /* @@? 30:18 Error SyntaxError: Unexpected token ':'. */ -/* @@? 30:18 Error SyntaxError: Unexpected token ':'. */ -/* @@? 30:20 Error SyntaxError: Unexpected token '...'. */ +/* @@? 30:18 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 30:20 Error SyntaxError: Unexpected token '...'. */ -/* @@? 30:23 Error TypeError: Unresolved reference int */ -/* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ -/* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ +/* @@? 30:23 Error SyntaxError: Unexpected token 'int'. */ /* @@? 30:26 Error SyntaxError: Unexpected token ']'. */ /* @@? 32:19 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 32:19 Error SyntaxError: Unexpected token 'number'. */ /* @@? 32:19 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ -/* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ -/* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ -/* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ -/* @@? 32:25 Error SyntaxError: Unexpected token ']'. */ /* @@? 35:21 Error SyntaxError: A 'this' type is available only as return type in a non-static method of a class or struct and extension functions. */ /* @@? 38:12 Error TypeError: Cannot find type 'a0'. */ /* @@? 38:14 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 38:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 38:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 38:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 38:16 Error SyntaxError: Unexpected token ','. */ /* @@? 38:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 38:18 Error SyntaxError: Unexpected token 'a1'. */ /* @@? 38:22 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 38:22 Error SyntaxError: Unexpected token ']'. */ -/* @@? 38:22 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_decorator_usage.ets b/ets2panda/test/ast/parser/ets/invalid_decorator_usage.ets new file mode 100644 index 0000000000000000000000000000000000000000..30b54d0ce59f4e6954c555689c85ceac7b595ec5 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_decorator_usage.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. + */ + +@ q.M function i ( this : ( this : @ e ( ) [ ] ) => ( @ V ( ) "" ) ) { } + +/* @@? 16:3 Error TypeError: Cannot find type 'q'. */ +/* @@? 16:5 Error TypeError: 'M' is not an annotation. */ +/* @@? 16:5 Error TypeError: 'M' type does not exist. */ +/* @@? 16:16 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 16:29 Error SyntaxError: Unexpected 'this' keyword in non-receiver context. */ +/* @@? 16:44 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 16:44 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 16:44 Error SyntaxError: Invalid Type. */ +/* @@? 16:44 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 16:44 Error SyntaxError: Unexpected token, expected '=>'. */ +/* @@? 16:44 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 16:44 Error SyntaxError: Invalid Type. */ +/* @@? 16:44 Error SyntaxError: Unexpected token, expected '=>'. */ +/* @@? 16:46 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:50 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 16:59 Error SyntaxError: Annotations are not allowed on this type of declaration. */ +/* @@? 16:61 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:63 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 16:68 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:70 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/invalid_type.ets b/ets2panda/test/ast/parser/ets/invalid_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..36b08c0491a44c777dcbbfa168f921f647ed916e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_type.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. + */ + +class Function extends Intl.DateTimeFormat{ +let RegExp = Intl.PluralRules +} + +/* @@? 1:3 Error TypeError: Variable 'Function' is already defined with different type. */ +/* @@? 17:1 Error SyntaxError: Unexpected token 'let'. */ +/* @@? 17:19 Error TypeError: Property 'PluralRules' does not exist on type 'Intl' */ diff --git a/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets b/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets new file mode 100644 index 0000000000000000000000000000000000000000..da4139c843567afddecb1a1a2fdbe69e620823ab --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_type_assignment.ets @@ -0,0 +1,30 @@ +/* + * 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] +---*/ + + type Point = { x: number; y: number }; + type AxeX = Point['x']; + +/* @@? 20:18 Error SyntaxError: Invalid Type. */ +/* @@? 20:23 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 20:23 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 20:34 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 20:34 Error TypeError: Type name 'number' used in the wrong context */ +/* @@? 21:23 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 21:23 Error SyntaxError: Unexpected token ']'. */ +/* @@? 21:26 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/keyof_array_tuple.ets b/ets2panda/test/ast/parser/ets/keyof_array_tuple.ets index f4ffe47cc65d9f16ad447f6345c47c4dfa8e2f42..9284175d61779263c20e9ff49a3dcb6f0ae46f9e 100644 --- a/ets2panda/test/ast/parser/ets/keyof_array_tuple.ets +++ b/ets2panda/test/ast/parser/ets/keyof_array_tuple.ets @@ -33,9 +33,17 @@ function main():void{ let x6:Array<"abcd"|keyofA|number|A> = /* @@ label6 */new Array<"abcd"|keyofA|number|A>("abcd","other field","foo",123,a); } -/* @@@ label1 Error TypeError: Array element at index 1 with type '"field2"' is not compatible with the target array element type '"abcd"|Double|A|"foo"|"field1"' */ -/* @@@ label2 Error TypeError: Array element at index 1 with type '"other field"' is not compatible with the target array element type '"abcd"|Double|A|"foo"|"field1"' */ -/* @@@ label3 Error TypeError: Array initializer's type is not assignable to tuple type at index: 1 */ -/* @@@ label4 Error TypeError: Array initializer's type is not assignable to tuple type at index: 1 */ -/* @@@ label5 Error TypeError: No matching construct signature for escompat.Array("abcd", "field2", "foo", int, A) */ -/* @@@ label6 Error TypeError: No matching construct signature for escompat.Array("abcd", "other field", "foo", int, A) */ +/* @@? 26:62 Error TypeError: Array element at index 1 with type '"field2"' is not compatible with the target array element type '"abcd"|Double|A|"foo"|"field1"' */ +/* @@? 27:62 Error TypeError: Array element at index 1 with type '"other field"' is not compatible with the target array element type '"abcd"|Double|A|"foo"|"field1"' */ +/* @@? 29:60 Error TypeError: Array initializer's type is not assignable to tuple type at index: 1 */ +/* @@? 30:60 Error TypeError: Array initializer's type is not assignable to tuple type at index: 1 */ +/* @@? 32:57 Error TypeError: Expected 1 arguments, got 5. */ +/* @@? 32:57 Error TypeError: Expected 2 arguments, got 5. */ +/* @@? 32:57 Error TypeError: Expected 0 arguments, got 5. */ +/* @@? 32:57 Error TypeError: No matching construct signature for escompat.Array("abcd", "field2", "foo", int, A) */ +/* @@? 32:98 Error TypeError: Type '"field2"' is not compatible with rest parameter type '"abcd"|Double|A|"foo"|"field1"' at index 2 */ +/* @@? 33:57 Error TypeError: Expected 1 arguments, got 5. */ +/* @@? 33:57 Error TypeError: Expected 2 arguments, got 5. */ +/* @@? 33:57 Error TypeError: Expected 0 arguments, got 5. */ +/* @@? 33:57 Error TypeError: No matching construct signature for escompat.Array("abcd", "other field", "foo", int, A) */ +/* @@? 33:98 Error TypeError: Type '"other field"' is not compatible with rest parameter type '"abcd"|Double|A|"foo"|"field1"' at index 2 */ diff --git a/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets b/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets index 4d006cbe6395efa1cdb6c0cf1a95f01efc762672..ca91aaa14d05e138436e4e3e8bb44978d79b2b3e 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 '"$_hashCode"|"add"|"unboxed"|"isGreaterThan"|"compareTo"|"createFromJSONValue"|"isLessEqualThan"|"mul"|"doubleValue"|"toString"|"byteValue"|"isLessThan"|"shortValue"|"sub"|"intValue"|"div"|"floatValue"|"equals"|"longValue"|"isGreaterEqualThan"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ -/* @@@ label2 Error TypeError: Type '"field1"' cannot be assigned to type '"$_hashCode"|"add"|"unboxed"|"isGreaterThan"|"compareTo"|"createFromJSONValue"|"isLessEqualThan"|"mul"|"doubleValue"|"toString"|"byteValue"|"isLessThan"|"shortValue"|"sub"|"intValue"|"div"|"floatValue"|"equals"|"longValue"|"isGreaterEqualThan"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ +/* @@@ label1 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"$_hashCode"|"add"|"toByte"|"unboxed"|"isGreaterThan"|"compareTo"|"toLong"|"createFromJSONValue"|"isLessEqualThan"|"isLessThan"|"toFloat"|"toString"|"mul"|"sub"|"isGreaterEqualThan"|"equals"|"div"|"toInt"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ +/* @@@ label2 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"$_hashCode"|"add"|"toByte"|"unboxed"|"isGreaterThan"|"compareTo"|"toLong"|"createFromJSONValue"|"isLessEqualThan"|"isLessThan"|"toFloat"|"toString"|"mul"|"sub"|"isGreaterEqualThan"|"equals"|"div"|"toInt"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ diff --git a/ets2panda/test/ast/parser/ets/keyword_after_readonly_interface.ets b/ets2panda/test/ast/parser/ets/keyword_after_readonly_interface.ets new file mode 100644 index 0000000000000000000000000000000000000000..48cf3c4993dc03dbd73d8aaaedabb436467ed2b7 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/keyword_after_readonly_interface.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 A { + readonly static a = 45; +} + +/* @@? 17:2 Error SyntaxError: Identifier expected. */ +/* @@? 17:11 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:11 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 17:20 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 17:22 Error SyntaxError: Invalid Type. */ +/* @@? 17:22 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:22 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 17:24 Error SyntaxError: Identifier expected. */ diff --git a/ets2panda/test/ast/parser/ets/lambda-arrow-after-braces.ets b/ets2panda/test/ast/parser/ets/lambda-arrow-after-braces.ets index b800cbbe7c726d1cf305bf761cb93bfd97b21537..03775c1d71b69b24d83d73d98060ee275651af40 100644 --- a/ets2panda/test/ast/parser/ets/lambda-arrow-after-braces.ets +++ b/ets2panda/test/ast/parser/ets/lambda-arrow-after-braces.ets @@ -20,5 +20,5 @@ function main() : void{ /* @@@ label Error SyntaxError: Unexpected token '=>'. */ /* @@@ label1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@@ label2 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label2 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label2 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/lambda-type-inference-bad-arrow.ets b/ets2panda/test/ast/parser/ets/lambda-type-inference-bad-arrow.ets index 283a766b8e9535f9b64efb23e3cbb4a171df62cb..98215468eed7a8e29bda30950ba25eff1fd5ffe0 100644 --- a/ets2panda/test/ast/parser/ets/lambda-type-inference-bad-arrow.ets +++ b/ets2panda/test/ast/parser/ets/lambda-type-inference-bad-arrow.ets @@ -21,7 +21,6 @@ function main(): void { } /* @@? 20:10 Error TypeError: Unresolved reference x */ -/* @@? 28:1 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 28:1 Error SyntaxError: Unexpected token, expected ')'. */ -/* @@? 28:1 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 28:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 27:1 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 27:1 Error SyntaxError: Unexpected token, expected ')'. */ +/* @@? 27:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/lambdaWithWrongOptionalParameter.ets b/ets2panda/test/ast/parser/ets/lambdaWithWrongOptionalParameter.ets index 89ec3e2d13167a1fbcf350293066810dc0392d27..aa61413645ae8fc766f4015100cc9f4535838559 100644 --- a/ets2panda/test/ast/parser/ets/lambdaWithWrongOptionalParameter.ets +++ b/ets2panda/test/ast/parser/ets/lambdaWithWrongOptionalParameter.ets @@ -23,4 +23,3 @@ function main() { /* @@? 17:25 Error TypeError: Expected initializer for parameter b. */ /* @@? 1:1 Error SyntaxError: Required parameter follows default parameter(s). */ -/* @@? 1:1 Error SyntaxError: Required parameter follows default parameter(s). */ diff --git a/ets2panda/test/ast/parser/ets/lambda_function_index_access_neg.ets b/ets2panda/test/ast/parser/ets/lambda_function_index_access_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..d5c80f3524b8eee43443c99f5ea8c4ddbc6c1283 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/lambda_function_index_access_neg.ets @@ -0,0 +1,39 @@ +/* + * 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 = (... ( () => { + +})) = : async () => { + +} [] + +/* @@? 16:9 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 16:9 Error TypeError: No matching call signature for *ERROR_LITERAL*(() => void) */ +/* @@? 16:9 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 16:9 Error TypeError: No matching call signature for *ERROR_LITERAL*(() => void) */ +/* @@? 16:10 Error SyntaxError: Unexpected token '...'. */ +/* @@? 18:5 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 18:7 Error SyntaxError: Unexpected token ':'. */ +/* @@? 18:9 Error SyntaxError: Unexpected token 'async'. */ +/* @@? 18:15 Error SyntaxError: 'async' flags must be used for functions only at top-level. */ +/* @@? 18:16 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 18:16 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 18:16 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 18:18 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 18:18 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 18:18 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 18:18 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 18:21 Error SyntaxError: Unexpected token '{'. */ +/* @@? 20:3 Error TypeError: Can't resolve array type */ diff --git a/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_parameter_neg_1.ets b/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_parameter_neg_1.ets index dc8d99cb1b8c2edb3461b7b5887b2a1fde8290c6..bf482d1aee7ebe81050fa8072f61e0ce82bae084 100644 --- a/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_parameter_neg_1.ets +++ b/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_parameter_neg_1.ets @@ -18,9 +18,6 @@ function func(fn:(x:int)=>void) { } func(x)=>console.log(1)) -/* @@? 19:8 Error SyntaxError: Unexpected token '=>'. */ /* @@? 19:8 Error SyntaxError: Unexpected token '=>'. */ /* @@? 19:8 Error SyntaxError: Unexpected token. */ /* @@? 19:24 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:24 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:24 Error SyntaxError: Unexpected token ')'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_type_alias_neg_1.ets b/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_type_alias_neg_1.ets index 13b37a95ce900f6219dc4bfa41873745877d56cb..2ced9449996adbbaf38fb27bfd4b9bb71e3f763d 100644 --- a/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_type_alias_neg_1.ets +++ b/ets2panda/test/ast/parser/ets/lambda_omit_parentheses_type_alias_neg_1.ets @@ -16,5 +16,4 @@ let a: int => void /* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ -/* @@? 16:12 Error SyntaxError: Unexpected token '=>'. */ \ No newline at end of file +/* @@? 16:15 Error SyntaxError: Unexpected token 'void'. */ 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 bd70f7cd3144d3c1295de2b86f1c3df46a4e9239..966c2505b10ce942f13131132417e56436a48d9e 100644 --- a/ets2panda/test/ast/parser/ets/local_class_already_class.ets +++ b/ets2panda/test/ast/parser/ets/local_class_already_class.ets @@ -22,4 +22,5 @@ function bar(): void { } } -/* @@? 20:9 Error TypeError: Variable 'BC' has already been declared. */ +/* @@? 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! */ 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 d7deaccf10461ce84259c621e2f520c70c6bb36d..9b4408d2911fd330e9822b2cc2ed807f67299a75 100644 --- a/ets2panda/test/ast/parser/ets/local_class_already_interface.ets +++ b/ets2panda/test/ast/parser/ets/local_class_already_interface.ets @@ -22,4 +22,5 @@ function bar(): void { } } -/* @@? 20:9 Error TypeError: Variable 'BC' has already been declared. */ +/* @@? 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! */ 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 f336717b7414f212bb40a3fcdb2d165aa2f634d2..b9523088d00b89e7650b4c7845f40a4673835d83 100644 --- a/ets2panda/test/ast/parser/ets/local_class_already_variable.ets +++ b/ets2panda/test/ast/parser/ets/local_class_already_variable.ets @@ -20,4 +20,5 @@ function bar(): void { } } -/* @@? 18:9 Error TypeError: Variable 'BC' has already been declared. */ +/* @@? 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! */ 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 30b81abff89c8d5f9287a5180cbc9228b4d679bb..92b9a2983afa16657dc82b6ebeb714816548389c 100644 --- a/ets2panda/test/ast/parser/ets/local_interface_already_class.ets +++ b/ets2panda/test/ast/parser/ets/local_interface_already_class.ets @@ -22,4 +22,5 @@ function bar(): void { } } -/* @@? 20:3 Error TypeError: Variable 'BC' has already been declared. */ +/* @@? 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! */ diff --git a/ets2panda/test/ast/parser/ets/local_interface_already_interface.ets b/ets2panda/test/ast/parser/ets/local_interface_already_interface.ets index 083186cec9a393b1b2f2bbc4a3a991a683e9ac00..ad3bd01bac821f3845b1be1536d951e67f75518d 100644 --- a/ets2panda/test/ast/parser/ets/local_interface_already_interface.ets +++ b/ets2panda/test/ast/parser/ets/local_interface_already_interface.ets @@ -22,4 +22,5 @@ function bar(): void { } } -/* @@? 20:3 Error TypeError: Variable 'BC' has already been declared. */ +/* @@? 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! */ diff --git a/ets2panda/test/ast/parser/ets/local_interface_already_variable..ets b/ets2panda/test/ast/parser/ets/local_interface_already_variable..ets index 9b0f2ecae990c592dabbb14b3bfb47873bb31520..0c4c33dce661aa1e9764c957f768cc1f5af07636 100644 --- a/ets2panda/test/ast/parser/ets/local_interface_already_variable..ets +++ b/ets2panda/test/ast/parser/ets/local_interface_already_variable..ets @@ -20,4 +20,5 @@ function bar(): void { } } -/* @@? 18:3 Error TypeError: Variable 'BC' has already been declared. */ +/* @@? 18:3 Error TypeError: Variable 'BC' has already been declared. */ +/* @@? 18:3 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ diff --git a/ets2panda/test/ast/parser/ets/main_entry_point_3.ets b/ets2panda/test/ast/parser/ets/main_entry_point_3.ets index 01fec319929c8faef8040124220f37804266dda0..12aeee11688ca699810b7c40a0366664fa16f1c6 100644 --- a/ets2panda/test/ast/parser/ets/main_entry_point_3.ets +++ b/ets2panda/test/ast/parser/ets/main_entry_point_3.ets @@ -17,4 +17,4 @@ function main(/* @@ label */i : int[]): void { return; } -/* @@@ label Error TypeError: Only 'string[]' type argument is allowed. */ +/* @@@ label Error TypeError: Only 'FixedArray' type argument is allowed. */ diff --git a/ets2panda/test/ast/parser/ets/main_entry_point_5.ets b/ets2panda/test/ast/parser/ets/main_entry_point_5.ets index 3c635da7b07dd73fae60ff5871abd60ff9612ca1..fdca0d522ca929882aff13de5ba24340dcb12099 100644 --- a/ets2panda/test/ast/parser/ets/main_entry_point_5.ets +++ b/ets2panda/test/ast/parser/ets/main_entry_point_5.ets @@ -21,4 +21,5 @@ function /* @@ label */main(i : string[]): void { return; } -/* @@@ label Error TypeError: Main overload is not enabled */ +/* @@? 20:24 Error TypeError: Main overload is not enabled */ +/* @@? 20:29 Error TypeError: Only 'FixedArray' type argument is allowed. */ diff --git a/ets2panda/test/ast/parser/ets/minus_sign_as_index_1.ets b/ets2panda/test/ast/parser/ets/minus_sign_as_index_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..64b36ca55053a67f67347272d8d507de9c521045 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/minus_sign_as_index_1.ets @@ -0,0 +1,24 @@ +/* + * 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 URIError extends WebAssembly {WebAssembly : WeakMap [-6]} + +/* @@? 1:3 Error TypeError: Class 'URIError' is already defined. */ +/* @@? 16:24 Error TypeError: Cannot find type 'WebAssembly'. */ +/* @@? 16:24 Error TypeError: The super type of 'URIError' class is not extensible. */ +/* @@? 16:60 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 16:60 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:61 Error SyntaxError: Unexpected token '6'. */ +/* @@? 16:62 Error SyntaxError: Unexpected token ']'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/n_arrayHoldingNullValue.ets b/ets2panda/test/ast/parser/ets/n_arrayHoldingNullValue.ets index 35a9c180d073445d4a3b808806b576b24a3bb0e7..33ed150ffb0b0683d54d777f9a5c22900aef7c90 100644 --- a/ets2panda/test/ast/parser/ets/n_arrayHoldingNullValue.ets +++ b/ets2panda/test/ast/parser/ets/n_arrayHoldingNullValue.ets @@ -18,5 +18,5 @@ function main(): void { let d: char[] = /* @@ label1 */null; } -/* @@@ label Error TypeError: Type 'null' cannot be assigned to type 'float[]' */ -/* @@@ label1 Error TypeError: Type 'null' cannot be assigned to type 'char[]' */ +/* @@? 17:38 Error TypeError: Type 'null' cannot be assigned to type 'Array' */ +/* @@? 18:36 Error TypeError: Type 'null' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets b/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets index 5f618161da4f65d2d4a1fa5f607c449f83ba1541..f5dd2523aa7cf6bb2ad41a302f47289a40e598ca 100644 --- a/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets +++ b/ets2panda/test/ast/parser/ets/namespace_badtoken04.ets @@ -17,5 +17,4 @@ declare namespace MySpace{ foo():void } /* @@? 17:10 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:10 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:10 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:11 Error SyntaxError: Unexpected token 'void'. */ 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 0b389ebc8c6a133707ce1f47ca4d6aa173628b88..a2ab27116b790369f9c63c526746bc63492b5dc9 100644 --- a/ets2panda/test/ast/parser/ets/non-ambient_call_signature.ets +++ b/ets2panda/test/ast/parser/ets/non-ambient_call_signature.ets @@ -20,4 +20,5 @@ class A{ /* @@@ 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/nonIntegralIndex.ets b/ets2panda/test/ast/parser/ets/nonIntegralIndex.ets index 1d7295d53c26d921d22f94e6613a6f0256535053..99ae69249a09d175981d11fc64d01228597eae4c 100644 --- a/ets2panda/test/ast/parser/ets/nonIntegralIndex.ets +++ b/ets2panda/test/ast/parser/ets/nonIntegralIndex.ets @@ -18,5 +18,3 @@ export class Test { u[/* @@ label */i] = 0.0 } } - -/* @@@ label Error TypeError: Type 'double' cannot be used as an index type. Only primitive or unboxable integral types can be used as index. */ 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 3216e4e82a64370ab8d3592f62ceefa1e0c2807e..7244aeec7e0a90a1f3cc91caf25b0fbb7fe7bebf 100644 --- a/ets2panda/test/ast/parser/ets/non_proper_index_method.ets +++ b/ets2panda/test/ast/parser/ets/non_proper_index_method.ets @@ -22,4 +22,4 @@ function main() { console.log(/* @@ label */a["a"]) } -/* @@@ label Error TypeError: Object type doesn't have proper index access method. */ +/* @@@ label Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ diff --git a/ets2panda/test/ast/parser/ets/object_literal_withfunc.ets b/ets2panda/test/ast/parser/ets/object_literal_withfunc.ets index c18b63da2fed45933efb68d66a5d5eb2dd2262cb..cfd19f7d9934cdc47056cf5167bafa4c79c7ac94 100644 --- a/ets2panda/test/ast/parser/ets/object_literal_withfunc.ets +++ b/ets2panda/test/ast/parser/ets/object_literal_withfunc.ets @@ -19,6 +19,6 @@ const x: A = {foo() {}} /* @@? 17:15 Error TypeError: Method 'foo' cannot be used as a key of object literal. */ /* @@? 17:18 Error SyntaxError: Unexpected token, expected ':'. */ /* @@? 17:19 Error SyntaxError: Unexpected token ')'. */ -/* @@? 17:19 Error SyntaxError: Unexpected token. */ -/* @@? 17:21 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:21 Error SyntaxError: Unexpected token. */ +/* @@? 17:22 Error SyntaxError: Unexpected token '}'. */ /* @@? 17:23 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/parser/ets/optional-chaining-array.ets b/ets2panda/test/ast/parser/ets/optional-chaining-array.ets similarity index 90% rename from ets2panda/test/parser/ets/optional-chaining-array.ets rename to ets2panda/test/ast/parser/ets/optional-chaining-array.ets index c8394c4f7330a4c99707ae8ffb31514acc265a95..fd1f441713577e5d01ba1621480a93c0f5c07440 100644 --- a/ets2panda/test/parser/ets/optional-chaining-array.ets +++ b/ets2panda/test/ast/parser/ets/optional-chaining-array.ets @@ -18,3 +18,5 @@ let test = arr?.[1] ?? "unknown"; let arr2: String[] | null; let test2 = arr2?.[100] ?? "unknown2"; + +/* @@? 20:13 Error TypeError: Variable 'arr2' is used before being assigned. */ diff --git a/ets2panda/test/ast/parser/ets/optional_chaining_invalid_property.ets b/ets2panda/test/ast/parser/ets/optional_chaining_invalid_property.ets index 11d2ffb7eb0882869ccae71f3e9f5106aad6c0fd..70b3e510124f6bd79746b508ef5356073be2ca01 100644 --- a/ets2panda/test/ast/parser/ets/optional_chaining_invalid_property.ets +++ b/ets2panda/test/ast/parser/ets/optional_chaining_invalid_property.ets @@ -26,4 +26,3 @@ let dog: Dog = { let hasSting = dog?.hasSting; /* @@? 26:21 Error TypeError: Property 'hasSting' does not exist on type 'Dog' */ -/* @@? 26:21 Error TypeError: Property 'hasSting' does not exist on type 'Dog' */ diff --git a/ets2panda/test/parser/ets/optional_chaining_nested_property.ets b/ets2panda/test/ast/parser/ets/optional_chaining_nested_property.ets similarity index 100% rename from ets2panda/test/parser/ets/optional_chaining_nested_property.ets rename to ets2panda/test/ast/parser/ets/optional_chaining_nested_property.ets diff --git a/ets2panda/test/parser/ets/optional_chaining_object_property.ets b/ets2panda/test/ast/parser/ets/optional_chaining_object_property.ets similarity index 100% rename from ets2panda/test/parser/ets/optional_chaining_object_property.ets rename to ets2panda/test/ast/parser/ets/optional_chaining_object_property.ets diff --git a/ets2panda/test/parser/ets/optional_field_variable_2.ets b/ets2panda/test/ast/parser/ets/optional_field_variable_2.ets similarity index 100% rename from ets2panda/test/parser/ets/optional_field_variable_2.ets rename to ets2panda/test/ast/parser/ets/optional_field_variable_2.ets diff --git a/ets2panda/test/ast/parser/ets/overloaded_method_as_value_neg.ets b/ets2panda/test/ast/parser/ets/overloaded_method_as_value_neg.ets new file mode 100644 index 0000000000000000000000000000000000000000..2624a849c2912e8b25be517103e94b26e3d1e5c3 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/overloaded_method_as_value_neg.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"actual : " + actual.result[i] + +/* @@? 16:10 Error SyntaxError: Identifier expected, got 'string literal'. */ +/* @@? 16:23 Error SyntaxError: Unexpected token, expected '{'. */ +/* @@? 16:31 Error SyntaxError: Interface fields must have type annotation. */ +/* @@? 16:39 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 16:39 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 16:39 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 16:40 Error SyntaxError: Identifier expected. */ +/* @@? 16:40 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 16:40 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 28:67 Error SyntaxError: Identifier expected. */ +/* @@? 28:67 Error SyntaxError: Unexpected token, expected '}'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/re_export/export.ets b/ets2panda/test/ast/parser/ets/re_export/export.ets index 12112d7fc61f6adcd2823151ae03348ff8f47a55..8d0529a281299e449f8f7441af3bb14cb4d1506e 100644 --- a/ets2panda/test/ast/parser/ets/re_export/export.ets +++ b/ets2panda/test/ast/parser/ets/re_export/export.ets @@ -13,6 +13,6 @@ * limitations under the License. */ -export function foo():void -{ -} +export function foo():void {} + +function bar() :void {} diff --git a/ets2panda/test/ast/parser/ets/re_export/export_5.ets b/ets2panda/test/ast/parser/ets/re_export/export_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..745a950975fb7924475c94bac200e7b35b780212 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/re_export/export_5.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. + */ + +import {test2} from './re_export_16' + +export class test1 {} diff --git a/ets2panda/test/ast/parser/ets/re_export/export_6.ets b/ets2panda/test/ast/parser/ets/re_export/export_6.ets new file mode 100644 index 0000000000000000000000000000000000000000..1628fe5be5d3aae03206746c734c8d2e322068e8 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/re_export/export_6.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. + */ + +import {test1} from './export_5' + +export class test2 {} diff --git a/ets2panda/test/ast/parser/ets/re_export/import_20.ets b/ets2panda/test/ast/parser/ets/re_export/import_20.ets new file mode 100644 index 0000000000000000000000000000000000000000..cdad50d23b0ac71959d06841e863f8543f45b603 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/re_export/import_20.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. + */ + +import { name } from './re_export_16.ets' + +function main() { + name.foo(); + name./* @@ label */bar(); +} + +/* @@@ label Error TypeError: Property 'bar' does not exist on type 'export' */ diff --git a/ets2panda/test/ast/parser/ets/re_export/re_export_16.ets b/ets2panda/test/ast/parser/ets/re_export/re_export_16.ets new file mode 100644 index 0000000000000000000000000000000000000000..b1a52b384dbf900828570cab1846a26daaf836d6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/re_export/re_export_16.ets @@ -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 * as name from './export.ets' +export {test2} from './export_6' diff --git a/ets2panda/test/ast/parser/ets/re_export/re_export_4.ets b/ets2panda/test/ast/parser/ets/re_export/re_export_4.ets index cf271b95faea3ba1ac14a870b34a155b0e972a23..399324e4b7989207edba240d77f1c2145da64717 100644 --- a/ets2panda/test/ast/parser/ets/re_export/re_export_4.ets +++ b/ets2panda/test/ast/parser/ets/re_export/re_export_4.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -export {foo} from "./export" -export /* @@ label */{foo} from "./export_2" +export /* @@ label */{foo} from "./export" +export {foo} from "./export_2" -/* @@@ label Error TypeError: Ambiguous export "foo" */ +/* @@@ label Error TypeError: Ambiguous export 'foo' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test1.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test1.ets index f58ae21fdeac262ae1e75c42a56770f4faabab3d..390023611fb3e1f4954f459df40209a4d7a94979 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test1.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test1.ets @@ -19,5 +19,5 @@ function foo (p: int[]) { let x: Readonly = [] /* @@ label */foo(/* @@ label1 */x) -/* @@@ label1 Error TypeError: Type 'readonly int[]' is not compatible with type 'int[]' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(readonly int[]) */ +/* @@? 20:15 Error TypeError: No matching call signature for foo(Readonly>) */ +/* @@? 20:34 Error TypeError: Type 'Readonly>' is not compatible with type 'Array' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets index 7656872082259533c237005afc004ffbbcc3a816..7fbea40572514d454dd7dd155ae43746e2c46a2e 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets @@ -19,5 +19,5 @@ function foo (p: [int, string]) { let x: Readonly<[int, string]> = [] /* @@ label */foo(/* @@ label1 */x) -/* @@@ label1 Error TypeError: Type 'readonly [Int, String]' is not compatible with type '[Int, String]' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(readonly [Int, String]) */ +/* @@@ label1 Error TypeError: Type 'readonly [int, String]' is not compatible with type '[int, String]' at index 1 */ +/* @@@ label Error TypeError: No matching call signature for foo(readonly [int, String]) */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets index 1d321b90e4c8c89fcfe3c7f036f06e63f0993d80..0953054d474f4d57fee200f49df0951afa76a56d 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets @@ -17,4 +17,4 @@ function foo (x: Readonly<[int, string]>) { let y: [int, string] = /* @@ label */x } -/* @@@ label Error TypeError: Type 'readonly [Int, String]' cannot be assigned to type '[Int, String]' */ +/* @@@ label Error TypeError: Type 'readonly [int, String]' cannot be assigned to type '[int, String]' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test4.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test4.ets index 9a1945910600bc05f30e51394a6863b913b4395c..cf6bf40eb71897b7afec3a55c73fa562d4b1bce0 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test4.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test4.ets @@ -18,4 +18,4 @@ function foo (x: Readonly) { let x1 : int[] x1 = /* @@ label */x } -/* @@@ label Error TypeError: Type 'readonly int[]' cannot be assigned to type 'int[]' */ +/* @@? 19:24 Error TypeError: Type 'Readonly>' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test2.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test2.ets index 28d00ad700c751ecbd93e0ff7c43ef3c22a75367..e6ae30bc89f9baeffac599e4b3ebdb70b49346a2 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test2.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test2.ets @@ -45,9 +45,3 @@ let y2 : Readonly<[int, string]> /* @@@ label3 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ /* @@@ label4 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ /* @@@ label5 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ -/* @@@ label7 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ -/* @@@ label9 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ -/* @@@ label1 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ -/* @@@ label2 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ -/* @@@ label4 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ -/* @@@ label5 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets index 12e4c37feda06db8e2dc233337fc66b095ca17bf..fd6e6d841963f901bc18f99637d0a7901557daaf 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets @@ -18,4 +18,4 @@ function foo (x: readonly [int, string]) { let y: [int, string] = /* @@ label */x } -/* @@@ label Error TypeError: Type 'readonly [Int, String]' cannot be assigned to type '[Int, String]' */ +/* @@@ label Error TypeError: Type 'readonly [int, String]' cannot be assigned to type '[int, String]' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test3.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test3.ets index b99f61d2696f0e6ac41a7a823da731345d9c2503..125bd64c3b67195ebd2032e7cc8f58f564deca0e 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test3.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test3.ets @@ -18,4 +18,4 @@ function foo (x: readonly int[]) { let x1 : int[] x1 = /* @@ label */x } -/* @@@ label Error TypeError: Type 'readonly int[]' cannot be assigned to type 'int[]' */ +/* @@? 19:24 Error TypeError: Type 'Readonly>' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test4.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test4.ets index c8f5c88c2737bc72db08c38b8d4186548d0600e3..56c980492e47fe4448b6d5d2c290457fcf3de056 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test4.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test4.ets @@ -19,5 +19,5 @@ function foo (p: int[]) { let x: readonly int[] = [] /* @@ label */foo(/* @@ label1 */x) -/* @@@ label1 Error TypeError: Type 'readonly int[]' is not compatible with type 'int[]' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(readonly int[]) */ +/* @@? 20:15 Error TypeError: No matching call signature for foo(Readonly>) */ +/* @@? 20:34 Error TypeError: Type 'Readonly>' is not compatible with type 'Array' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets index 5d92154dabb0fe7729185f358e423e7ec9d68066..448f5ebcdb2c075250bdc23c61e164df822a64f9 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets @@ -19,5 +19,5 @@ function foo (p: [int, string]) { let x: readonly [int, string] = [] /* @@ label */foo(/* @@ label1 */x) -/* @@@ label1 Error TypeError: Type 'readonly [Int, String]' is not compatible with type '[Int, String]' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(readonly [Int, String]) */ +/* @@@ label1 Error TypeError: Type 'readonly [int, String]' is not compatible with type '[int, String]' at index 1 */ +/* @@@ label Error TypeError: No matching call signature for foo(readonly [int, String]) */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test6.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test6.ets index 82a9f2688fd601bc5b13525fea2c995a3478eb20..7747ed37497d5c09ab361de2e6b4102a290679cb 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test6.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test6.ets @@ -29,4 +29,3 @@ let tuple = foo2() /* @@@ label Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ /* @@@ label1 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ -/* @@@ label1 Error TypeError: Cannot modify an array or tuple content that has the readonly parameter */ diff --git a/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets b/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..e2fd0dddf4d6e45c2a6d8be2dcecaa7111b2accc --- /dev/null +++ b/ets2panda/test/ast/parser/ets/readonlyFunctionTypeAnnotation.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. + */ + + +func: readonly (Y : object | long [] ) => [ ] + +/* @@? 17:7 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 17:7 Error TypeError: Unresolved reference readonly */ +/* @@? 17:17 Error SyntaxError: Invalid Type. */ +/* @@? 17:20 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:20 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:22 Error SyntaxError: Unexpected token 'object'. */ +/* @@? 17:22 Error TypeError: Type name 'object' used in the wrong context */ +/* @@? 17:22 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 17:39 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:42 Error SyntaxError: Unexpected token '=>'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/readonly_reference_CTE_err_elimilate.ets b/ets2panda/test/ast/parser/ets/readonly_reference_CTE_err_elimilate.ets index 7dd38e559ac50c9456a85ecbe4a27324434c0dfa..7452c971205878f7d592b5a637eda01237f0ed65 100644 --- a/ets2panda/test/ast/parser/ets/readonly_reference_CTE_err_elimilate.ets +++ b/ets2panda/test/ast/parser/ets/readonly_reference_CTE_err_elimilate.ets @@ -22,7 +22,7 @@ let changeAbleVar = new A(); changeAbleVar.x=333 function bar(a:Readonly){ - a.x=111 + /* @@ label2 */a.x=111 console.log(a) } @@ -30,3 +30,4 @@ bar(changeAbleVar) /* @@@ label Error TypeError: Cannot assign to a readonly variable x */ +/* @@@ label2 Error TypeError: The 'Readonly' property cannot be reassigned. */ diff --git a/ets2panda/test/ast/parser/ets/recordIndexing.ets b/ets2panda/test/ast/parser/ets/recordIndexing.ets index 15b3ad58ba68200f6dcee3ae27d871ab20e5335f..ff6f19beaf98965e0d0381d94ba86ca1afd8f1c2 100644 --- a/ets2panda/test/ast/parser/ets/recordIndexing.ets +++ b/ets2panda/test/ast/parser/ets/recordIndexing.ets @@ -22,4 +22,6 @@ console.log(x[/* @@ label */0]) } -/* @@@ label Error TypeError: Cannot find index access method with the required signature. */ +/* @@? 23:17 Error TypeError: No matching indexing signature for $_get(int) */ +/* @@? 23:33 Error TypeError: Type 'int' is not compatible with type 'String' at index 1 */ +/* @@? 23:33 Error TypeError: Cannot find index access method with the required signature. */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_04.ets b/ets2panda/test/ast/parser/ets/rest_parameter_04.ets index 9b08f8851eec41b97e0df8b1c80e7815043f58c8..b175b93357c63158b7e8c9d77a7912d5593fef8a 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_04.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_04.ets @@ -18,6 +18,6 @@ function hehe(...items: number[]/* @@ label */: void /* @@ label1 */{ } /* @@? 16:10 Error TypeError: Only abstract or native methods can't have body. */ -/* @@? 16:47 Error SyntaxError: Rest parameter must be the last formal parameter. */ -/* @@? 16:49 Error TypeError: Unresolved reference void */ -/* @@? 16:69 Error SyntaxError: Unexpected token '{'. */ +/* @@@ label Error SyntaxError: Rest parameter must be the last formal parameter. */ +/* @@? 16:49 Error SyntaxError: Unexpected token 'void'. */ +/* @@@ label1 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_05.ets b/ets2panda/test/ast/parser/ets/rest_parameter_05.ets new file mode 100644 index 0000000000000000000000000000000000000000..53d71208a0886248013a2c68ab4204e05f1e5f78 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_05.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 low 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 sum(...numbers: [number, number, number]): number { + return numbers[0] + numbers[1] + numbers[2] +} + +/* @@ label */sum() + +/* @@@ label Error TypeError: Expected 3 arguments, got 0. */ +/* @@@ label Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_06.ets b/ets2panda/test/ast/parser/ets/rest_parameter_06.ets new file mode 100644 index 0000000000000000000000000000000000000000..7759de0401912ca488db242b55e868581d32f78b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_06.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 low 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 sum(...numbers: [number, number, number]): number { + return numbers[0] + numbers[1] + numbers[2] +} + +/* @@ label */sum(10, 20, 30, 40) + +/* @@@ label Error TypeError: Expected 3 arguments, got 4. */ +/* @@@ label Error TypeError: No matching call signature for sum(int, int, int, int) */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_07.ets b/ets2panda/test/ast/parser/ets/rest_parameter_07.ets new file mode 100644 index 0000000000000000000000000000000000000000..f1373852fb56c61480e240df1f947cc4031adf7e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_07.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 low 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 sum(...numbers: [number, number, number]): number { + return numbers[0] + numbers[1] + numbers[2] +} + +/* @@ label1 */sum(/* @@ label2 */10, 20, "one") + +/* @@@ label1 Error TypeError: No matching call signature for sum(int, int, "one") */ +/* @@@ label2 Error TypeError: Type 'int' is not compatible with type 'double' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_08.ets b/ets2panda/test/ast/parser/ets/rest_parameter_08.ets new file mode 100644 index 0000000000000000000000000000000000000000..9abafc61d90340842ba9af5ce6712ccf06af91fa --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_08.ets @@ -0,0 +1,33 @@ +/* +* 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 low 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 sum(a: int, ...numbers: [number, number, number]): number { + return numbers[0] + numbers[1] + numbers[2] +} + +/* @@ label1 */sum() +/* @@ label2 */sum(11) +/* @@ label3 */sum(11,12,13) +/* @@ label4 */sum(11,12,13,15,16) + +/* @@@ label1 Error TypeError: Expected 1 arguments, got 0. */ +/* @@@ label1 Error TypeError: Expected 4 arguments, got 0. */ +/* @@@ label1 Error TypeError: No matching call signature */ +/* @@@ label2 Error TypeError: Expected 4 arguments, got 1. */ +/* @@@ label2 Error TypeError: No matching call signature for sum(int) */ +/* @@@ label3 Error TypeError: Expected 4 arguments, got 3. */ +/* @@@ label3 Error TypeError: No matching call signature for sum(int, int, int) */ +/* @@@ label4 Error TypeError: Expected 4 arguments, got 5. */ +/* @@@ label4 Error TypeError: No matching call signature for sum(int, int, int, int, int) */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_09.ets b/ets2panda/test/ast/parser/ets/rest_parameter_09.ets new file mode 100644 index 0000000000000000000000000000000000000000..c958b2efe1158870f943ef205ec0ea298cf49f8f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_09.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 low 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 { + foo(...p: [A, B]) {} +} + +/* @@ label */(new C()).foo() + +/* @@@ label Error TypeError: Expected 2 arguments, got 0. */ +/* @@@ label Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_10.ets b/ets2panda/test/ast/parser/ets/rest_parameter_10.ets new file mode 100644 index 0000000000000000000000000000000000000000..db95f4b9b072594eeaef434067e33c86eee8179a --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_10.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 low 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 { + foo(...p: [A, B]) {} +} + +/* @@ label */(new C()).foo(new A) + +/* @@@ label Error TypeError: Expected 2 arguments, got 1. */ +/* @@@ label Error TypeError: No matching call signature for foo(A) */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_11.ets b/ets2panda/test/ast/parser/ets/rest_parameter_11.ets new file mode 100644 index 0000000000000000000000000000000000000000..5750476b45c61d017f30953572399f04db80f51d --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_11.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 low 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 { + foo(...p: [A, B]) {} +} + +/* @@ label */(new C()).foo(new A, new B, new B) + +/* @@@ label Error TypeError: Expected 2 arguments, got 3. */ +/* @@@ label Error TypeError: No matching call signature for foo(A, B, B) */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_12.ets b/ets2panda/test/ast/parser/ets/rest_parameter_12.ets new file mode 100644 index 0000000000000000000000000000000000000000..5b519005961a3ddb39329fe51fa1de4cec476a01 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_12.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable low 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 { + static foo(...p: [A, B]) {} +} + +/* @@ label1 */C.foo() +/* @@ label2 */C.foo(new A) +/* @@ label3 */C.foo(new A, new B, new B) + +/* @@@ label1 Error TypeError: Expected 2 arguments, got 0. */ +/* @@@ label1 Error TypeError: No matching call signature */ +/* @@@ label2 Error TypeError: Expected 2 arguments, got 1. */ +/* @@@ label2 Error TypeError: No matching call signature for foo(A) */ +/* @@@ label3 Error TypeError: Expected 2 arguments, got 3. */ +/* @@@ label3 Error TypeError: No matching call signature for foo(A, B, B) */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_13.ets b/ets2panda/test/ast/parser/ets/rest_parameter_13.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b8c8cdbc278be0553a1451210d4c53ddd8357c8 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_13.ets @@ -0,0 +1,47 @@ +/* +* 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 low 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 { + public field : boolean + + constructor(...p: [A, B]) { + this.field = p[0] == p[1] + } + + constructor(a: int, ...p: [A, B]) { + this.field = p[0] == p[1] + } +} + +function main() { + /* @@ label1 */new C + /* @@ label2 */new C(new A) + /* @@ label3 */new C(new A, new B, new B) +} + +/* @@@ label1 Error TypeError: Expected 1 arguments, got 0. */ +/* @@@ label1 Error TypeError: Expected 2 arguments, got 0. */ +/* @@@ label1 Error TypeError: Expected 3 arguments, got 0. */ +/* @@@ label1 Error TypeError: No matching construct signature */ +/* @@@ label2 Error TypeError: Expected 2 arguments, got 1. */ +/* @@@ label2 Error TypeError: Expected 3 arguments, got 1. */ +/* @@@ label2 Error TypeError: No matching construct signature for rest_parameter_13.C(A) */ +/* @@? 33:37 Error TypeError: Type 'A' is not compatible with type 'int' at index 1 */ +/* @@@ label3 Error TypeError: Expected 2 arguments, got 3. */ +/* @@@ label3 Error TypeError: No matching construct signature for rest_parameter_13.C(A, B, B) */ +/* @@? 34:37 Error TypeError: Type 'A' is not compatible with type 'int' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_14.ets b/ets2panda/test/ast/parser/ets/rest_parameter_14.ets new file mode 100644 index 0000000000000000000000000000000000000000..73bbbb9eb079a4ae9c0701e4ac1a4f98d577a2e1 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/rest_parameter_14.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 low 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 {} + +function foo(/* @@ label1 */...j: A) {} + +class B { + moo(/* @@ label2 */...i: A) {} +} + +/* @@@ label1 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@@ label2 Error SyntaxError: Rest parameter should be either array or tuple type. */ diff --git a/ets2panda/test/ast/parser/ets/launch_non_callable.ets b/ets2panda/test/ast/parser/ets/return_while_warning.ets similarity index 83% rename from ets2panda/test/ast/parser/ets/launch_non_callable.ets rename to ets2panda/test/ast/parser/ets/return_while_warning.ets index 748a265f7a03e6f5275e4cedc2b65f598f6cc481..5c9a15296e79a347f8dad57fdc18238f944c8f3f 100644 --- a/ets2panda/test/ast/parser/ets/launch_non_callable.ets +++ b/ets2panda/test/ast/parser/ets/return_while_warning.ets @@ -14,8 +14,9 @@ */ function main(): void { - let x = 5; - launch /* @@ label */x; + while (false) { + assertTrue( false ); + } } -/* @@@ label Error SyntaxError: Only call expressions are allowed after 'launch'. */ +/* @@? 17:19 Warning Warning: Unreachable statement. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/single_export/single_export_as_n.ets b/ets2panda/test/ast/parser/ets/single_export/single_export_as_n.ets index 783ddd852991d3b747d79346475b91085c363ad4..29a7abba3638de3c247c6b414190fe200e37c018 100644 --- a/ets2panda/test/ast/parser/ets/single_export/single_export_as_n.ets +++ b/ets2panda/test/ast/parser/ets/single_export/single_export_as_n.ets @@ -18,5 +18,5 @@ export a as A let a = 2; /* @@? 16:10 Error SyntaxError: Unexpected token 'as'. */ -/* @@? 16:10 Error SyntaxError: Unexpected token 'as'. */ -/* @@? 16:13 Error TypeError: Cannot find type 'A'. */ +/* @@? 16:13 Error SyntaxError: Unexpected token 'A'. */ +/* @@? 16:13 Error TypeError: Unresolved reference A */ diff --git a/ets2panda/test/ast/parser/ets/single_export/single_export_n.ets b/ets2panda/test/ast/parser/ets/single_export/single_export_n.ets index 44c554036e2259c8df288b15d01932ebbfa5e23c..e25119a5405600f586c47db503e06e933fefec6a 100644 --- a/ets2panda/test/ast/parser/ets/single_export/single_export_n.ets +++ b/ets2panda/test/ast/parser/ets/single_export/single_export_n.ets @@ -19,5 +19,4 @@ let v = 1 let m = 2 /* @@? 16:9 Error SyntaxError: Unexpected token ','. */ -/* @@? 16:9 Error SyntaxError: Unexpected token ','. */ -/* @@? 16:9 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:10 Error SyntaxError: Unexpected token 'm'. */ diff --git a/ets2panda/test/ast/parser/ets/special_signatures.ets b/ets2panda/test/ast/parser/ets/special_signatures.ets index f0037224b4a12499c09e671e39370681efb0a01d..811f62bf38be89ba904fe9279ee87eb225cab517 100644 --- a/ets2panda/test/ast/parser/ets/special_signatures.ets +++ b/ets2panda/test/ast/parser/ets/special_signatures.ets @@ -19,5 +19,4 @@ interface Document { } /* @@@ label Error TypeError: Cannot find type 'HTMLDivElement'. */ /* @@? 18:35 Error TypeError: Cannot find type 'HTMLSpanElement'. */ -/* @@? 18:35 Error TypeError: Cannot find type 'HTMLSpanElement'. */ /* @@? 18:3 Error TypeError: Function createElement with this assembly signature already declared. */ diff --git a/ets2panda/test/ast/parser/ets/spreadArrayInTuple.ets b/ets2panda/test/ast/parser/ets/spreadArrayInTuple.ets index 07fdeb0ab853a5bd5567de477849820349488bd3..597d40da24509d4a5ed9746a12928d6ec6039eb0 100644 --- a/ets2panda/test/ast/parser/ets/spreadArrayInTuple.ets +++ b/ets2panda/test/ast/parser/ets/spreadArrayInTuple.ets @@ -20,7 +20,7 @@ function main() { let y2: [boolean, int, string] = /* @@ label2 */[true, /* @@ label3 */...x2] } -/* @@@ label1 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ -/* @@@ label Error TypeError: Initializer has 1 elements, but tuple requires 2 */ -/* @@@ label3 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ -/* @@@ label2 Error TypeError: Initializer has 2 elements, but tuple requires 3 */ +/* @@? 18:43 Error TypeError: Initializer has 1 elements, but tuple requires 2 */ +/* @@? 18:59 Error TypeError: 'Array' cannot be spread in tuple. */ +/* @@? 20:53 Error TypeError: Initializer has 2 elements, but tuple requires 3 */ +/* @@? 20:75 Error TypeError: 'Array' cannot be spread in tuple. */ diff --git a/ets2panda/test/ast/parser/ets/staticFunctionCallOfObject.ets b/ets2panda/test/ast/parser/ets/staticFunctionCallOfObject.ets index 0df5c32b6ef87057b94468cad83a19d2402da661..987720dcb2d4cb81d5b72bfb314973bd8bce9dea 100644 --- a/ets2panda/test/ast/parser/ets/staticFunctionCallOfObject.ets +++ b/ets2panda/test/ast/parser/ets/staticFunctionCallOfObject.ets @@ -19,7 +19,5 @@ function main() { let c2: int = 4 console.log(Number.toString(c1)) console.log(x.toString(c2)) - console.log(/* @@ label */x.toString(c1)) + console.log(x.toString(c1)) } - -/* @@@ label Error TypeError: No matching call signature for toString(double) */ diff --git a/ets2panda/test/ast/parser/ets/string_literal_const_cast.ets b/ets2panda/test/ast/parser/ets/string_literal_const_cast.ets index 57b184afb756c48026eae2488f6983cb14faaa09..899f906944c3522294dfcdd5cb5f2c9b43feada2 100644 --- a/ets2panda/test/ast/parser/ets/string_literal_const_cast.ets +++ b/ets2panda/test/ast/parser/ets/string_literal_const_cast.ets @@ -17,7 +17,6 @@ let x = "literal str" as const /* @@? 16:26 Error SyntaxError: Invalid Type. */ /* @@? 16:26 Error SyntaxError: Unexpected token 'const'. */ -/* @@? 24:1 Error SyntaxError: Identifier expected, got 'eos'. */ -/* @@? 24:1 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? 24:1 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? 24:1 Error TypeError: Missing initializer in const declaration */ +/* @@? 23:1 Error SyntaxError: Identifier expected, got 'end of stream'. */ +/* @@? 23:1 Error SyntaxError: Variable must be initialized or it's type must be declared. */ +/* @@? 23:1 Error TypeError: Missing initializer in const declaration */ diff --git a/ets2panda/test/ast/parser/ets/struct_in_interface.ets b/ets2panda/test/ast/parser/ets/struct_in_interface.ets index 0520cdcd2d99ad2ed5d82893b8937eb80017af7f..1d6aafc6bfa10e5ec66e613961c152c0631c846a 100644 --- a/ets2panda/test/ast/parser/ets/struct_in_interface.ets +++ b/ets2panda/test/ast/parser/ets/struct_in_interface.ets @@ -24,7 +24,6 @@ interface A { /* @@? 17:18 Error SyntaxError: Unexpected token, expected ','. */ /* @@? 17:18 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ /* @@? 18:12 Error TypeError: Cannot find type 'B'. */ -/* @@? 18:12 Error TypeError: Cannot find type 'B'. */ /* @@? 18:14 Error SyntaxError: Unexpected token, expected ','. */ /* @@? 18:14 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ /* @@? 19:20 Error SyntaxError: Interface member initialization is prohibited. */ @@ -32,4 +31,3 @@ interface A { /* @@? 19:22 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ /* @@? 20:5 Error SyntaxError: Identifier expected. */ /* @@? 21:1 Error SyntaxError: Unexpected token '}'. */ - diff --git a/ets2panda/test/ast/parser/ets/superInConstructor1.ets b/ets2panda/test/ast/parser/ets/superInConstructor1.ets index 68a47c32177cdec13e143425ca659d0bd21d97c9..e1666bd8728ef0771a90ede55a0fa1e953d289c7 100644 --- a/ets2panda/test/ast/parser/ets/superInConstructor1.ets +++ b/ets2panda/test/ast/parser/ets/superInConstructor1.ets @@ -14,9 +14,14 @@ */ class A { - public x: int; + private _x: int; + + get x(): int{ + return this._x; + } + public constructor() { - this.x = 1; + this._x = 1; } } diff --git a/ets2panda/test/ast/parser/ets/superInConstructor2.ets b/ets2panda/test/ast/parser/ets/superInConstructor2.ets index ae773cab404ef52f62eb3b98afa3f7d9f770f8b0..6afa6f51825c42e787270d5382be363da7c0d868 100644 --- a/ets2panda/test/ast/parser/ets/superInConstructor2.ets +++ b/ets2panda/test/ast/parser/ets/superInConstructor2.ets @@ -14,9 +14,14 @@ */ class A { - public x: int; + private _x: int; + + get x(): int{ + return this._x; + } + public constructor() { - this.x = 1; + this._x = 1; } } diff --git a/ets2panda/test/ast/parser/ets/superInConstructor3.ets b/ets2panda/test/ast/parser/ets/superInConstructor3.ets index 518c4ee8d5f49468f7283f53e2d87080210d3b2d..2cbd62e5c48db4d07e3c2fedae0a50d940ff6bda 100644 --- a/ets2panda/test/ast/parser/ets/superInConstructor3.ets +++ b/ets2panda/test/ast/parser/ets/superInConstructor3.ets @@ -14,10 +14,14 @@ */ class A { - public x: int; + private _x: int; + + get x(): int{ + return this._x; + } public constructor() { - this.x = 1; + this._x = 1; } public constructor(arg: boolean) { diff --git a/ets2panda/test/ast/parser/ets/super_field.ets b/ets2panda/test/ast/parser/ets/super_field.ets new file mode 100644 index 0000000000000000000000000000000000000000..680e8dcaf7a0118e22d58bd33092863b57992742 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/super_field.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. + */ + +class A { + value: string = 'A'; +} + +class B extends A { + foo() { + console.log(super./* @@ label */value); + } +} + +/* @@@ label Error TypeError: Class field 'value' defined by the parent class is not accessible in the child class via super. */ diff --git a/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_1.ets b/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_1.ets index 192d1154022dc04e469442696ee24cede0f1c252..8181971b99d128943b15fe971a730ba0db5924ba 100644 --- a/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_1.ets +++ b/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_1.ets @@ -19,5 +19,5 @@ function fn(): void { /* @@ label */v.prop_name = /* @@ label1 */new_prop_value; } -/* @@@ label Warning Warning: Variable 'v' is used before being assigned. */ -/* @@@ label1 Warning Warning: Variable 'new_prop_value' is used before being assigned. */ +/* @@@ label Error TypeError: Variable 'v' is used before being assigned. */ +/* @@@ label1 Error TypeError: Variable 'new_prop_value' is used before being assigned. */ diff --git a/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_2.ets b/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_2.ets index c1d3f0a5cb700a6429918fae9140328e6df25e0d..726dbaf2c7ab0c0855305ac7d75b9fff7a516e65 100644 --- a/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_2.ets +++ b/ets2panda/test/ast/parser/ets/test_jsvalue_set_property_2.ets @@ -18,4 +18,4 @@ function fn(): void { /* @@ label */v.prop_name = 5.6; } -/* @@@ label Warning Warning: Variable 'v' is used before being assigned. */ +/* @@@ label Error TypeError: Variable 'v' is used before being assigned. */ diff --git a/ets2panda/test/ast/parser/ets/test_type_alias1.ets b/ets2panda/test/ast/parser/ets/test_type_alias1.ets index dcc9b800babc1fb78675ac32643bd60f5a0d2e46..e1f3d4cf4fb619ecc62b3308fd715ff117793b38 100644 --- a/ets2panda/test/ast/parser/ets/test_type_alias1.ets +++ b/ets2panda/test/ast/parser/ets/test_type_alias1.ets @@ -13,6 +13,9 @@ * limitations under the License. */ -type /* @@ label */5 = number; +type 5 = number; -/* @@@ label Error SyntaxError: Identifier expected, got 'number literal'. */ +/* @@? 16:1 Error TypeError: Unresolved reference type */ +/* @@? 16:6 Error SyntaxError: Unexpected token '5'. */ +/* @@? 16:6 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 16:8 Error SyntaxError: Invalid left-hand side in assignment expression. */ diff --git a/ets2panda/test/ast/parser/ets/too_many_expression.ets b/ets2panda/test/ast/parser/ets/too_many_expression.ets new file mode 100644 index 0000000000000000000000000000000000000000..e9649de766bc77c7344570f5f227aac15247073f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/too_many_expression.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. + */ + +(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( + +/* @@? 16:1025 Error SyntaxError: Maximum allowed nesting level exceeded. */ +/* @@? 19:67 Error SyntaxError: Unexpected token, expected ')'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/trailing_comma_1.ets b/ets2panda/test/ast/parser/ets/trailing_comma_1.ets index e9576c8261fa9b806f082b283ac34d8b5ce93dc1..3bc32586c949fffa9d73f02178436b3f8757a27d 100644 --- a/ets2panda/test/ast/parser/ets/trailing_comma_1.ets +++ b/ets2panda/test/ast/parser/ets/trailing_comma_1.ets @@ -39,6 +39,10 @@ foo(,) /* @@? 24:15 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 24:15 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 28:12 Error SyntaxError: Unexpected token ','. */ +/* @@? 28:14 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 28:14 Error SyntaxError: Unexpected token '2'. */ +/* @@? 28:15 Error SyntaxError: Unexpected token ','. */ +/* @@? 28:16 Error SyntaxError: Unexpected token ']'. */ /* @@? 30:5 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 31:1 Error TypeError: No matching call signature for foo(a[0], a[1], ...a) */ /* @@? 31:5 Error TypeError: Indexed access is not supported for such expression type. */ @@ -46,16 +50,20 @@ foo(,) /* @@? 31:17 Error TypeError: Spread argument for the rest parameter can be only one. */ /* @@? 32:5 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 32:10 Error SyntaxError: Unexpected token ','. */ +/* @@? 32:11 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 32:11 Error SyntaxError: Unexpected token 'a'. */ /* @@? 32:11 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 32:15 Error SyntaxError: Unexpected token ')'. */ /* @@? 33:5 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 33:10 Error SyntaxError: Unexpected token ','. */ /* @@? 34:5 Error SyntaxError: Unexpected token ','. */ +/* @@? 34:6 Error SyntaxError: Unexpected token 'a'. */ +/* @@? 34:6 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 34:6 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 34:10 Error SyntaxError: Unexpected token ')'. */ /* @@? 35:5 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 35:10 Error SyntaxError: Unexpected token 'a'. */ /* @@? 35:10 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 35:10 Error TypeError: Indexed access is not supported for such expression type. */ /* @@? 35:14 Error SyntaxError: Unexpected token ')'. */ -/* @@? 35:14 Error SyntaxError: Unexpected token ')'. */ -/* @@? 35:14 Error SyntaxError: Unexpected token ')'. */ /* @@? 36:5 Error SyntaxError: Unexpected token ','. */ diff --git a/ets2panda/test/ast/parser/ets/trailing_comma_2.ets b/ets2panda/test/ast/parser/ets/trailing_comma_2.ets index cda9ec19900894f0baa0cc49bef442e006efb93c..bf684f79ab2e860aa28a8a471b1d59dfdc54b058 100644 --- a/ets2panda/test/ast/parser/ets/trailing_comma_2.ets +++ b/ets2panda/test/ast/parser/ets/trailing_comma_2.ets @@ -22,5 +22,3 @@ let a = new C(12,) /* @@@ label1 Error SyntaxError: Unexpected token ','. */ /* @@? 20:9 Error TypeError: Expected 0 arguments, got 1. */ /* @@? 20:9 Error TypeError: No matching construct signature for trailing_comma_2.C(int) */ -/* @@? 20:9 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? 20:9 Error TypeError: No matching construct signature for trailing_comma_2.C(int) */ diff --git a/ets2panda/test/ast/parser/ets/trailing_lambda_tests/double_trailing_lambda_1.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/double_trailing_lambda_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..74e47ee4f4114c6a71d61c266468b9630524a033 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/double_trailing_lambda_1.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. + */ + +function foo(a?:number, b?:()=>void, c?:()=>void){} + +foo(){}{} + +/* @@? 18:8 Error SyntaxError: Unexpected token '{'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/trailing_lambda_tests/empty_vs_nonempty_lambda.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/empty_vs_nonempty_lambda.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7270078e3cb7b4c8d819277e852af07209f1d74 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/empty_vs_nonempty_lambda.ets @@ -0,0 +1,46 @@ +/* + * 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. + */ + +// Test empty lambda handling and parameter binding +class D { + check( + data: string, + onSuccess: (d: string) => void, + onError?: () => void // Optional lambda last + ) { + onSuccess(data.toUpperCase()); + if (onError) onError(); + } +} + +function testEmptyLambda() { + const d = new D(); + + // Case 1: Explicit empty lambda + d.check("test", () => { }, () => { throw new Error() }); + + // Case 2: Trailing empty lambda + d.check("test", (d) => console.log(d)) { + // Empty lambda binds to onError + }; + + // Case 3: Missing required lambda (should error) + d.check("test") { + () => { } + }; +} + +/* @@? 40:5 Error TypeError: Expected 2 arguments, got 1. */ +/* @@? 40:5 Error TypeError: No matching call signature for check("test") */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/trailing_lambda_tests/extra_trailing_lambda_1.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/extra_trailing_lambda_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..12bd43f68cac3ad826e7e907f60f1b50d9641638 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/extra_trailing_lambda_1.ets @@ -0,0 +1,44 @@ +/* + * 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. + */ + +// Test excess trailing lambdas when parameters are full +class C { + process( + required: number, + callback: () => void = () => { }, // Default lambda must be last + optional?: string + ) { } +} + +function testExtraTrailing() { + const c = new C(); + + // Case 1: Normal call with all parameters + c.process(1, () => { }, "ok"); + + // Case 2: Excess trailing lambda (should error) + c.process(1, () => { }, "ok") { + console.log("extra"); + }; + + // Case 3: Lambda parameter position conflict + c.process(1, "ok") { + console.log("error"); + }; +} + +/* @@? 32:5 Error TypeError: No matching call signature with trailing lambda */ +/* @@? 37:5 Error TypeError: No matching call signature for process(int, "ok") */ +/* @@? 37:18 Error TypeError: Type '"ok"' is not compatible with type '() => void|undefined' at index 2 */ diff --git a/ets2panda/test/ast/parser/ets/trailing_lambda_tests/extra_trailing_lambda_2.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/extra_trailing_lambda_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..62cbf9b829972536c2f722c87fcfdc896347ae55 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/extra_trailing_lambda_2.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. + */ + +// Test excess trailing lambdas when parameters are full +class C { + process( + required?: number, + optional?: string, + callback: () => void = () => { }, + ) { } +} + +function testExtraTrailing() { + const c = new C(); + + // Case 1: Normal call with all parameters + c.process(1, "ok", () => { }); + + // Case 2: Excess trailing lambda (should error) + c.process(1, "ok", () => { }) { + console.log("extra"); + }; +} + +/* @@? 32:5 Error TypeError: No matching call signature with trailing lambda */ diff --git a/ets2panda/test/parser/ets/user_defined_2.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_mismatch_lambda_signature_2.ets similarity index 77% rename from ets2panda/test/parser/ets/user_defined_2.ets rename to ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_mismatch_lambda_signature_2.ets index a85d431332a89622fb6f092d47499538ddf539d0..90b3b80d959b2bfe5490e434999877e930b197af 100644 --- a/ets2panda/test/parser/ets/user_defined_2.ets +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_mismatch_lambda_signature_2.ets @@ -13,13 +13,14 @@ * limitations under the License. */ +function f(c?: ()=>void) { + c?.(); +} + function main() { - let float : float; - let boolean : boolean; - let double : double; - let byte : byte; - let short : short; - let int : int; - let char : char; - let long : long; + f() { + return /* @@ label */1 + } } + +/* @@@ label Error TypeError: Unexpected return value, enclosing method return type is void. */ diff --git a/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_10.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_10.ets new file mode 100644 index 0000000000000000000000000000000000000000..295914248459f181e41b669cb37920770fca774b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_10.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. + */ + +class A { + constructor (a0?: () => void){ + + } +} + +function main(): void { + new A() { console.print(2); }; // It is forbidden to extend a class by an anonymous class +} + +/* @@? 23:13 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_6.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_6.ets new file mode 100644 index 0000000000000000000000000000000000000000..9d29273a826bf4e1705c107a90c85b2740f9f8af --- /dev/null +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_6.ets @@ -0,0 +1,26 @@ +/* + * 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(c?: ()=>void) { + c?.(); +} + +/* @@ label */f(()=>{ + +}) { + +} + +/* @@@ label Error TypeError: No matching call signature with trailing lambda */ diff --git a/ets2panda/test/ast/parser/ets/launch_unresolved.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_7.ets similarity index 83% rename from ets2panda/test/ast/parser/ets/launch_unresolved.ets rename to ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_7.ets index 7f687e888e2ca9a9617285dc4e4917ecc7420826..17fcdb4c5028d31447aaac1d9a719451073ea734 100644 --- a/ets2panda/test/ast/parser/ets/launch_unresolved.ets +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_7.ets @@ -13,8 +13,12 @@ * limitations under the License. */ -function main(): void { - launch /* @@ label */foo(5); +function f(c?: ()=>void) { + c?.(); } -/* @@@ label Error TypeError: Unresolved reference foo */ +function main() { + f(); { + console.println("I am call back!") + } +} diff --git a/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_8.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_8.ets new file mode 100644 index 0000000000000000000000000000000000000000..b80f49af56e3aee922324335216786f159c1d086 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_8.ets @@ -0,0 +1,26 @@ +/* + * 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 { + constructor (a0?: () => void){ + + } +} + +function main(): void { + new A() {}; // It is forbidden to extend a class by an anonymous class +} + +/* @@? 23:13 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/launch_super_ctor.ets b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_9.ets similarity index 74% rename from ets2panda/test/ast/parser/ets/launch_super_ctor.ets rename to ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_9.ets index 840455baf973fcb12ffb772512cb05ec89c7aac0..b168957e53cb22071af037a4ae3e4ea00ebc405b 100644 --- a/ets2panda/test/ast/parser/ets/launch_super_ctor.ets +++ b/ets2panda/test/ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_9.ets @@ -13,13 +13,14 @@ * limitations under the License. */ -class Base { +class A { + constructor (a0?: () => void){ + + } } -class Derived extends Base { - constructor() { - launch /* @@ label */super(); - } +function main(): void { + new A {}; // It is forbidden to extend a class by an anonymous class } -/* @@@ label Error TypeError: Call to 'super' must be first statement in constructor */ +/* @@? 23:11 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets index 3ab56c1963cb4e1fc2e97dcad20e3e2280aaedfa..efd161568ce1a49ade7948dc0034b2cc98aff744 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_5.ets @@ -24,4 +24,4 @@ function foo(): int { } } -/* @@@ label Error TypeError: Unreachable statement. */ +/* @@@ label Warning Warning: Unreachable statement. */ diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_6.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_6.ets index 307bae6833d9faa458a6784634afb5c96be8dc40..40fe55f8cca60b657f80b229a2c79d58cefbcd8f 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_6.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_6.ets @@ -25,5 +25,5 @@ function foo(): int { } -/* @@@ label1 Error TypeError: Unreachable statement. */ +/* @@@ label1 Warning Warning: Unreachable statement. */ /* @@@ label Warning Warning: Finally clause cannot complete normally */ diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_8.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_8.ets index 33824549a9b663fa5a949a70407d9cead2a7b4b9..356e8c5c6dabc7930c1b5fd9f1c877d78f240848 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_8.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_8.ets @@ -25,4 +25,4 @@ function foo(): int { } /* @@@ label Warning Warning: Finally clause cannot complete normally */ -/* @@@ label1 Error TypeError: Unreachable statement. */ +/* @@@ label1 Warning Warning: Unreachable statement. */ diff --git a/ets2panda/test/ast/parser/ets/try_catch_alive_9.ets b/ets2panda/test/ast/parser/ets/try_catch_alive_9.ets index 8c4d938a5ac18df3a3f8e4ccb788f93a647b88ed..2b31a764f13361e147457cfa2745f52003d412e9 100644 --- a/ets2panda/test/ast/parser/ets/try_catch_alive_9.ets +++ b/ets2panda/test/ast/parser/ets/try_catch_alive_9.ets @@ -24,5 +24,5 @@ function foo(): int { } } -/* @@@ label Error TypeError: Unreachable statement. */ +/* @@@ label Warning Warning: Unreachable statement. */ /* @@@ label1 Warning Warning: Finally clause cannot complete normally */ diff --git a/ets2panda/test/ast/parser/ets/tuple_trailing_comma.ets b/ets2panda/test/ast/parser/ets/tuple_trailing_comma.ets index b04ad1f28b564d94dd877252463f944bebf220a8..093fa956bef06456fa83008ef6028cf71a8b2ebf 100644 --- a/ets2panda/test/ast/parser/ets/tuple_trailing_comma.ets +++ b/ets2panda/test/ast/parser/ets/tuple_trailing_comma.ets @@ -18,19 +18,13 @@ let a: [number, w: number, number,] = [1, 2, 3,]; let b: [number, /* @@ label */,number, number,] = [1, 2, 3,]; /* @@? 17:17 Error TypeError: Cannot find type 'w'. */ -/* @@? 17:18 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:18 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:18 Error SyntaxError: Unexpected token ':'. */ /* @@? 17:18 Error SyntaxError: Unexpected token, expected ',' or ']'. */ +/* @@? 17:18 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:20 Error SyntaxError: Unexpected token 'number'. */ /* @@? 17:20 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:26 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:26 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:26 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:28 Error SyntaxError: Unexpected token 'number'. */ /* @@? 17:28 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:34 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:34 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:34 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:35 Error SyntaxError: Unexpected token ']'. */ /* @@? 17:35 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:37 Error SyntaxError: Unexpected token '='. */ -/* @@? 18:31 Error SyntaxError: Invalid Type. */ +/* @@@ label Error SyntaxError: Invalid Type. */ diff --git a/ets2panda/test/ast/parser/ets/tuple_type_2_neg.ets b/ets2panda/test/ast/parser/ets/tuple_type_2_neg.ets index ce0fa517a359c5dd3826df771c5049e3dd0764e4..c8033ccf5c2731e0fc1ce837919520b2ec9d7b7b 100644 --- a/ets2panda/test/ast/parser/ets/tuple_type_2_neg.ets +++ b/ets2panda/test/ast/parser/ets/tuple_type_2_neg.ets @@ -19,13 +19,8 @@ let a: [number, ...number[], number] = [1, 2, 3]; /* @@? 17:17 Error SyntaxError: Invalid Type. */ /* @@? 17:17 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 17:17 Error SyntaxError: Unexpected token '...'. */ -/* @@? 17:17 Error SyntaxError: Unexpected token '...'. */ -/* @@? 17:17 Error SyntaxError: Unexpected token '...'. */ -/* @@? 17:28 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:28 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:20 Error SyntaxError: Unexpected token 'number'. */ /* @@? 17:28 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:30 Error SyntaxError: Unexpected token 'number'. */ /* @@? 17:30 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:36 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:36 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:36 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:38 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/test/ast/parser/ets/tuple_type_3_neg.ets b/ets2panda/test/ast/parser/ets/tuple_type_3_neg.ets index f87b439b2284f7f075c4304e739a610edf7ab7d1..2ac71cc79e3b250c2655018f772e55c24be0923a 100644 --- a/ets2panda/test/ast/parser/ets/tuple_type_3_neg.ets +++ b/ets2panda/test/ast/parser/ets/tuple_type_3_neg.ets @@ -20,8 +20,3 @@ let a: [number, number number] = [1, 2, 3]; /* @@? 17:24 Error SyntaxError: Unexpected token 'number'. */ /* @@? 17:24 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:30 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:30 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:30 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:30 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:30 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:32 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/test/ast/parser/ets/tuple_type_4_neg.ets b/ets2panda/test/ast/parser/ets/tuple_type_4_neg.ets index 5d7524e821668a613134ec1d9ecfa0756322c603..47e1f0f24172a1e2f64854f59084bd899f78d0de 100644 --- a/ets2panda/test/ast/parser/ets/tuple_type_4_neg.ets +++ b/ets2panda/test/ast/parser/ets/tuple_type_4_neg.ets @@ -19,13 +19,8 @@ let a: [a0: , a1: number] = [1, 2, 3]; /* @@? 17:9 Error TypeError: Cannot find type 'a0'. */ /* @@? 17:11 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 17:11 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:11 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:11 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:13 Error SyntaxError: Unexpected token ','. */ /* @@? 17:13 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:15 Error SyntaxError: Unexpected token 'a1'. */ /* @@? 17:19 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 17:19 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 17:25 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:25 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:25 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:27 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/test/ast/parser/ets/type_argument_conversion.ets b/ets2panda/test/ast/parser/ets/type_argument_conversion.ets index 0469cda02e2d5458ba3f2124b08776d1b8767b0c..0de608fe9020f50ed3c1580f985d65463e304a91 100644 --- a/ets2panda/test/ast/parser/ets/type_argument_conversion.ets +++ b/ets2panda/test/ast/parser/ets/type_argument_conversion.ets @@ -30,11 +30,8 @@ function main(): int { return 0; } -/* @@? 29:38 Error TypeError: No Matching Parameterless Constructor, parameter count 1 */ -/* @@? 29:38 Error TypeError: No matching parameterless constructor */ -/* @@? 29:38 Error TypeError: Signature is not available here. */ -/* @@? 29:38 Error TypeError: Type 'A[]' is not compatible with type 'A[]' at index 1 */ -/* @@? 29:38 Error TypeError: No Matching Parameterless Constructor, parameter count 1 */ -/* @@? 29:38 Error TypeError: No matching parameterless constructor */ -/* @@? 29:38 Error TypeError: Signature is not available here. */ -/* @@? 29:24 Error TypeError: No matching construct signature for type_argument_conversion.A(A[]) */ +/* @@? 29:24 Error TypeError: No matching construct signature for type_argument_conversion.A(Array>) */ +/* @@? 29:38 Error TypeError: No Matching Parameterless Constructor, parameter count 1 */ +/* @@? 29:38 Error TypeError: No matching parameterless constructor */ +/* @@? 29:38 Error TypeError: Signature is not available here. */ +/* @@? 29:38 Error TypeError: Type 'Array>' is not compatible with type 'Array>' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/type_from_1.ets b/ets2panda/test/ast/parser/ets/type_from_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e10098780338a90595bde28b021e1253aa4d147 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_from_1.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 a = Type.from<>(); + } + + + /* @@? 16:13 Error TypeError: Expected 1 type arguments, got 0 .*/ + /* @@? 16:13 Error TypeError: No matching call signature */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/type_from_generic.ets b/ets2panda/test/ast/parser/ets/type_from_generic.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a37ebe5477f7c4faada61cd74edcf9f439f2871 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_from_generic.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. + */ + +function foo(){ + Type.from(); +} + + /* @@? 17:3 Error TypeError: Unable to resolve type.*/ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/type_from_never_literal_keyof.ets b/ets2panda/test/ast/parser/ets/type_from_never_literal_keyof.ets new file mode 100644 index 0000000000000000000000000000000000000000..954719239bff85b5e33ada6cf49b57176587009e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_from_never_literal_keyof.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 from the specific language governing permissions and + * limitations under the License. + */ + function foo(){ + let neverType = Type.from(); + let literalType = Type.from<"hello">(); + type keyofType = keyof "abc" + let keyOfType = Type.from(); + } + + /* @@? 16:20 Error TypeError: Unable to resolve type. */ + /* @@? 17:22 Error TypeError: Acquiring types for string literal types is not supported. */ + /* @@? 19:20 Error TypeError: Unable to resolve type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/type_from_union_tuple.ets b/ets2panda/test/ast/parser/ets/type_from_union_tuple.ets new file mode 100644 index 0000000000000000000000000000000000000000..6c2a060aa56bdd2f63c1df0801988eb03e391da3 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_from_union_tuple.ets @@ -0,0 +1,24 @@ +/* + * 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(){ + let unionA = Type.from(); + let tupleB = Type.from<[string,number]>(); + let unionTuple = Type.from<[string|number,byte|short|int|long]>(); + } + + /* @@? 17:18 Error TypeError: Acquiring types for union types is not supported. */ + /* @@? 18:18 Error TypeError: Acquiring types for tuple types is not supported. */ + /* @@? 19:22 Error TypeError: Acquiring types for tuple types is not supported. */ diff --git a/ets2panda/test/ast/parser/ets/type_from_utility_type.ets b/ets2panda/test/ast/parser/ets/type_from_utility_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..36718f3d1ed6bfbcaed25e4e62532a2f0bd3c539 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_from_utility_type.ets @@ -0,0 +1,39 @@ + /* + * 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 from the specific language governing permissions and + * limitations under the License. + */ + + function foo(){ + let partialA = Type.from>(); + let partialarrA = Type.from>>(); + let partialarrT = Type.from>>(); + + let requiredA = Type.from>(); + let requiredarrA = Type.from>>(); + let requiredarrT = Type.from>>(); + + let readonlyA = Type.from>(); + let readonlyarrA = Type.from>>(); + let readonlyarrT = Type.from>>(); + + + let recordA = Type.from(); + let recordarrA = Type.from,Array>>(); + let recordarrT = Type.from,Array>>(); + } + /* @@? 17:20 Error TypeError: No matching call signature */ + /* @@? 30:19 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ + /* @@? 30:29 Error TypeError: No static $_invoke method and static $_instantiate method in Record. Record() is not allowed. */ + /* @@? 30:29 Error TypeError: Type 'Record' has no call signatures. */ + /* @@? 31:38 Error TypeError: Type Array is not assignable to constraint type Numeric|String */ + /* @@? 32:38 Error TypeError: Type Array is not assignable to constraint type Numeric|String */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/type_references.ets b/ets2panda/test/ast/parser/ets/type_references.ets index b02b398e0f6154314e44eb33677ad5968785093c..ccd5dcbbdb044e75be1df333b5d19eb5596ebc35 100644 --- a/ets2panda/test/ast/parser/ets/type_references.ets +++ b/ets2panda/test/ast/parser/ets/type_references.ets @@ -20,16 +20,15 @@ let y: G<{a:String}, B> // Error /* @@? 18:8 Error TypeError: Cannot find type 'G'. */ /* @@? 19:8 Error TypeError: Cannot find type 'G'. */ +/* @@? 19:10 Error SyntaxError: Invalid Type. */ /* @@? 19:10 Error SyntaxError: Unexpected token, expected '>'. */ /* @@? 19:10 Error SyntaxError: Unexpected token '>'. */ -/* @@? 19:10 Error SyntaxError: Unexpected token '>'. */ -/* @@? 19:10 Error SyntaxError: Invalid Type. */ -/* @@? 19:11 Error TypeError: Unresolved reference a */ -/* @@? 19:12 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:11 Error SyntaxError: Unexpected token 'a'. */ +/* @@? 19:13 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 19:13 Error TypeError: Class name 'String' used in the wrong context */ /* @@? 19:19 Error SyntaxError: Unexpected token '}'. */ /* @@? 19:20 Error SyntaxError: Unexpected token ','. */ -/* @@? 19:20 Error SyntaxError: Unexpected token ','. */ +/* @@? 19:22 Error SyntaxError: Unexpected token 'B'. */ /* @@? 19:22 Error TypeError: Type name 'B' used in the wrong context */ /* @@? 19:22 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 36:1 Error SyntaxError: Unexpected token 'eos'. */ +/* @@? 35:1 Error SyntaxError: Unexpected token 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_1.ets b/ets2panda/test/ast/parser/ets/unexpected_token_1.ets index 593b68c74f59248cc34ae81f2cebbda160cbacde..475a31b33cba30f94bd5c14eccbe64c0a405dfa8 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_1.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_1.ets @@ -18,4 +18,3 @@ import num from @^& /* @@? 16:17 Error SyntaxError: Unexpected token, expected string literal. */ /* @@? 16:17 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 16:19 Error SyntaxError: Unexpected token '&'. */ -/* @@? 22:1 Error SyntaxError: Unexpected token 'eos'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_14.ets b/ets2panda/test/ast/parser/ets/unexpected_token_14.ets index 91ee89cea3fa57fc0190aed82639415a38b8aadd..8cf75f4f62cb82167ab5e3e9842ce9d6b22db055 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_14.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_14.ets @@ -23,7 +23,5 @@ enum HEHE /* @@? 17:9 Error SyntaxError: Identifier expected, got '='. */ /* @@? 17:11 Error SyntaxError: Unexpected token, expected ',' or '}'. */ /* @@? 17:21 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:21 Error SyntaxError: Unexpected token ','. */ -/* @@? 17:21 Error SyntaxError: Unexpected token ','. */ /* @@? 18:5 Error TypeError: Unresolved reference Green */ /* @@? 19:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_18.ets b/ets2panda/test/ast/parser/ets/unexpected_token_18.ets index 13f623d0590814de37a3aaec2bff3beb4cc2b536..1cfd153d5a913fd8581fd9123d0e34fc6c9651de 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_18.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_18.ets @@ -17,4 +17,3 @@ try {} catch (e: number) /* @@ label */} /* @@? 16:15 Error TypeError: Argument must be an instance of 'Exception' or 'Error' */ /* @@@ label Error SyntaxError: Expected '{', got '}'. */ -/* @@@ label Error SyntaxError: Expected '{', got '}'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_25.ets b/ets2panda/test/ast/parser/ets/unexpected_token_25.ets index 0677f01aa27f47c3ad07fc2c09db48fea2aa06f7..629580bc4ce8d47e158aff21a38af17a223a6f6d 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_25.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_25.ets @@ -17,8 +17,11 @@ let x: int[ = [1,2,3] let y: int = x [0] /* @@? 16:13 Error SyntaxError: Unexpected token, expected ']'. */ -/* @@? 16:13 Error SyntaxError: Variable must be initialized or it's type must be declared. */ -/* @@? 16:13 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:13 Error SyntaxError: Unexpected token ']'. */ /* @@? 16:13 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:13 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:17 Error SyntaxError: Unexpected token, expected ']'. */ +/* @@? 16:18 Error SyntaxError: Unexpected token '2'. */ +/* @@? 16:19 Error SyntaxError: Unexpected token ','. */ +/* @@? 16:20 Error SyntaxError: Unexpected token '3'. */ +/* @@? 16:21 Error SyntaxError: Unexpected token ']'. */ /* @@? 17:14 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_29.ets b/ets2panda/test/ast/parser/ets/unexpected_token_29.ets index 446e37beea8614e6846847b6bc6b9721f8ab59e8..2595e6fdd6f66f78719c4b610d3a6eb57e85553b 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_29.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_29.ets @@ -20,9 +20,10 @@ function main(): void { /*@@ label4 */} /* @@@ label1 Error SyntaxError: Expected ';', got 'identification literal'. */ -/* @@? 17:40 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@@ label1 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@@ label2 Error SyntaxError: Unexpected token, expected ';'. */ /* @@? 17:69 Error TypeError: need to specify target type for class composite */ -/* @@@ label3 Error SyntaxError: Unexpected token, expected ':'. */ -/* @@@ label4 Error SyntaxError: Expected ')', got '}'. */ -/* @@@ label4 Error SyntaxError: Unexpected token '}'. */ \ No newline at end of file +/* @@? 18:30 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 20:15 Error SyntaxError: Expected ')', got '}'. */ +/* @@? 20:15 Error SyntaxError: Unexpected token '}'. */ +/* @@? 30:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_3.ets b/ets2panda/test/ast/parser/ets/unexpected_token_3.ets index e32f16e5e5cad35e4e8b3d47b72e8231ba8fdbc9..9d34f48d53b193ef073afadd2aae0901dbefa485 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_3.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_3.ets @@ -38,5 +38,5 @@ function labeledTest01(): int { /* @@@ label Error SyntaxError: Unexpected token, expected an identifier. */ /* @@@ label1 Error SyntaxError: Unexpected token '^'. */ -/* @@@ label1 Error SyntaxError: Unexpected token '^'. */ +/* @@? 27:57 Error SyntaxError: Unexpected token 'label1'. */ /* @@? 27:57 Error TypeError: Identifier 'label1' is used in wrong context. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_31.ets b/ets2panda/test/ast/parser/ets/unexpected_token_31.ets index 17af310ec18ff4c8a17b77c159ac81cdf242a030..13151518a2956cdb73f3e39e006956154569f56d 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_31.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_31.ets @@ -22,10 +22,8 @@ function foo(...^number: int[]): int { /* @@? 16:18 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 16:18 Error SyntaxError: Rest parameter must be the last formal parameter. */ /* @@? 16:31 Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:31 Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:32 Error SyntaxError: Unexpected token ':'. */ /* @@? 16:32 Error SyntaxError: Unexpected token ':'. */ -/* @@? 16:34 Error TypeError: Unresolved reference int */ +/* @@? 16:34 Error SyntaxError: Unexpected token '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 */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_32.ets b/ets2panda/test/ast/parser/ets/unexpected_token_32.ets index 8266030a337bafcee54f6e01f3551ca8762d5906..001705a3bb6cbe9972183f2a4879b90db113f2c7 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_32.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_32.ets @@ -17,5 +17,5 @@ class G'. */ /* @@@ label1 Error SyntaxError: Expected '{', got '}'. */ -/* @@@ label2 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label2 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@label2 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_35.ets b/ets2panda/test/ast/parser/ets/unexpected_token_35.ets index 92a6f2526e978b24d7b4202409bfd30b84c00fa8..73ba04ece851bd4f2236e83ca791e6729a808f58 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_35.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_35.ets @@ -29,7 +29,5 @@ let sector: float /* @@? 23:19 Error SyntaxError: Unexpected token, expected ')'. */ /* @@? 23:20 Error SyntaxError: Unexpected token. */ /* @@? 23:21 Error SyntaxError: Unexpected token ','. */ -/* @@? 23:21 Error SyntaxError: Unexpected token ','. */ -/* @@? 23:21 Error SyntaxError: Unexpected token ','. */ /* @@? 24:16 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 26:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_36.ets b/ets2panda/test/ast/parser/ets/unexpected_token_36.ets index 453e5cd1e24eba1e03958c2459cea7b0776c6335..e8dc156b5b327c74ec76d73cdfa66daf1d59fe88 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_36.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_36.ets @@ -36,13 +36,8 @@ export class AccessNSieve { /* @@? 29:13 Error TypeError: Unresolved reference i */ /* @@? 29:14 Error SyntaxError: Expected ';', got ':'. */ /* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:14 Error SyntaxError: Expected ')', got ':'. */ -/* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:14 Error SyntaxError: Unexpected token ':'. */ -/* @@? 29:16 Error TypeError: Unresolved reference int */ +/* @@? 29:16 Error SyntaxError: Expected ')', got 'int'. */ +/* @@? 29:16 Error SyntaxError: Unexpected token 'int'. */ /* @@? 29:25 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ -/* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ -/* @@? 29:36 Error SyntaxError: Unexpected token ')'. */ +/* @@? 29:38 Error SyntaxError: Unexpected token '{'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_37.ets b/ets2panda/test/ast/parser/ets/unexpected_token_37.ets index e442b206b1a401e0f712f417c8212b99b4184a54..11db5876c009fc6c5d4e64f380c8e5ca43403e54 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_37.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_37.ets @@ -20,14 +20,12 @@ console.log("h") } -/* @@? 16:15 Error SyntaxError: A try statement should contain either finally clause or at least one catch clause. */ -/* @@? 17:16 Error SyntaxError: Expected '{', got 'identification literal'. */ -/* @@? 17:39 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -/* @@? 17:39 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:39 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:39 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:61 Error SyntaxError: Unexpected token ')'. */ -/* @@? 17:61 Error SyntaxError: Unexpected token ')'. */ -/* @@? 17:61 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:26 Error SyntaxError: Unexpected token '{'. */ -/* @@? 34:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label Error SyntaxError: A try statement should contain either finally clause or at least one catch clause. */ +/* @@@ label1 Error SyntaxError: Expected '{', got 'identification literal'. */ +/* @@@ label2 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@@ label2 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:41 Error SyntaxError: Unexpected token 'Error'. */ +/* @@@ label3 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:63 Error SyntaxError: Unexpected token '{'. */ +/* @@@ label4 Error SyntaxError: Unexpected token '{'. */ +/* @@? 32:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_38.ets b/ets2panda/test/ast/parser/ets/unexpected_token_38.ets index 930b88480474ca44433b69834477e66f841278bd..ca70ddbf8179b5406e7082bc14585f8edcfc0769 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_38.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_38.ets @@ -23,7 +23,6 @@ let func3: (f: (a: number, b: string) => number[]): number[] => (a: number, b: b // let func3: (f: (a: number, b: string) => number[]): number[]) => (a: number, b: boolean) => true; -/* @@? 19:8 Error TypeError: 'void' used as type annotation. */ /* @@? 19:8 Error TypeError: 'void' used as type annotation. */ /* @@? 22:51 Error SyntaxError: Unexpected token, expected '=>'. */ /* @@? 22:51 Error SyntaxError: Unexpected token, expected '('. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_4.ets b/ets2panda/test/ast/parser/ets/unexpected_token_4.ets index d15b17add0e32feff27bbb8f567dcdfcf42c1906..5c8a7e33b0a7cdcffcffad5ae7b1c6733ba5a9bd 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_4.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_4.ets @@ -15,6 +15,6 @@ import {/* @@ label */^} from /* @@ label1 */"./import_tests/modules/module" -/* @@@ label Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@@ label Error SyntaxError: Unexpected token '^'. */ /* @@? 16:26 Error TypeError: Unresolved reference from */ /* @@@ label1 Error SyntaxError: Unexpected token './import_tests/modules/module'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_40.ets b/ets2panda/test/ast/parser/ets/unexpected_token_40.ets index 63a96bec4af6796e784c0bf699d4e62850f90580..f4c93de60bcb1015d8d030e33b073458f658cca0 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_40.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_40.ets @@ -15,7 +15,6 @@ let arr = new Array' is generic but type argument were not provided. */ /* @@? 16:15 Error TypeError: Type 'Array' is generic but type argument were not provided. */ /* @@? 16:41 Error SyntaxError: Unexpected token, expected '>'. */ -/* @@? 22:1 Error SyntaxError: Unexpected token 'eos'. */ +/* @@? 21:1 Error SyntaxError: Unexpected token 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_42.ets b/ets2panda/test/ast/parser/ets/unexpected_token_42.ets index 13d4a9c28345ded93a24b8c70f2f453fb4865017..ece56f4d7e5ee75520451fc501d839f82fde1134 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_42.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_42.ets @@ -15,5 +15,5 @@ // Int[1,2,3,4,5] let a: number = new Int[1 -/* @@? 16:17 Error TypeError: Type 'Int[]' cannot be assigned to type 'double' */ -/* @@? 20:1 Error SyntaxError: Expected ']', got 'eos'. */ +/* @@? 16:17 Error TypeError: Type 'FixedArray' cannot be assigned to type 'double' */ +/* @@? 20:1 Error SyntaxError: Expected ']', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_43.ets b/ets2panda/test/ast/parser/ets/unexpected_token_43.ets index 5b223d199e73a6621af8ecb9f031431718422e8d..750c78b777b810873bbf72d35c4719cf021d5342 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_43.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_43.ets @@ -16,12 +16,8 @@ let v2 = `--- ${y + abc /* @@ label */${y} = ${ n*2 }!`/* @@ label1 */} ---`;` /* @@? 16:17 Error TypeError: Unresolved reference y */ -/* @@? 16:17 Error TypeError: Unresolved reference y */ -/* @@? 16:21 Error TypeError: Unresolved reference abc */ /* @@? 16:21 Error TypeError: Unresolved reference abc */ -/* @@? 16:39 Error SyntaxError: Expected '}', got 'identification literal'. */ -/* @@? 16:49 Error TypeError: Unresolved reference n */ +/* @@@ label Error SyntaxError: Expected '}', got 'identification literal'. */ /* @@? 16:49 Error TypeError: Unresolved reference n */ -/* @@? 16:71 Error SyntaxError: Unexpected token '}'. */ -/* @@? 16:76 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ -/* @@? 28:1 Error SyntaxError: Invalid left-hand side in prefix operation. */ +/* @@@ label1 Error SyntaxError: Unexpected token '}'. */ +/* @@@ label1 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_45.ets b/ets2panda/test/ast/parser/ets/unexpected_token_45.ets index a63ab13c2d941831b499b1c2915405a97adadf67..8ee88559f0d4d7d44166c0aff7163d66b15aa959 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_45.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_45.ets @@ -19,5 +19,5 @@ do { ) } while (true -/* @@@ label Error SyntaxError: Expected ')', got 'eos'. */ +/* @@@ label Error SyntaxError: Expected ')', got 'end of stream'. */ /* @@ label */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_47.ets b/ets2panda/test/ast/parser/ets/unexpected_token_47.ets index 9eda4e7bc99a90ece1953b1832e9c203067bb018..875bd83b5a89bf6866f80faf63bde8eedd8455f8 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_47.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_47.ets @@ -15,7 +15,7 @@ let isPrime: int[] = new int[[]][[] -/* @@? 16:22 Error TypeError: Type 'int[][]' cannot be assigned to type 'int[]' */ +/* @@? 16:22 Error TypeError: Type 'Array>' cannot be assigned to type 'Array' */ /* @@? 16:30 Error TypeError: Can't resolve array type */ /* @@? 16:34 Error TypeError: Can't resolve array type */ -/* @@? 22:1 Error SyntaxError: Expected ']', got 'eos'. */ +/* @@? 22:1 Error SyntaxError: Expected ']', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_48.ets b/ets2panda/test/ast/parser/ets/unexpected_token_48.ets index 1b975dea975017b9f99a007a545eb98596917f09..9193aee2c196dabf4af57223a3dfe15599f718f4 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_48.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_48.ets @@ -15,7 +15,6 @@ export type {B/* @@ label */] -/* @@? 16:14 Error SyntaxError: Can only type export class or interface. */ -/* @@? 16:29 Error SyntaxError: Unexpected token, expected ',' or '}'. */ -/* @@? 16:29 Error SyntaxError: Unexpected token ']'. */ -/* @@? 16:29 Error SyntaxError: Unexpected token ']'. */ +/* @@? 16:14 Error SyntaxError: Cannot find name 'B' to export. */ +/* @@@ label Error SyntaxError: Unexpected token, expected ',' or '}'. */ +/* @@@ label Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_49.ets b/ets2panda/test/ast/parser/ets/unexpected_token_49.ets index 9138c9f88c0ba82442f3f251304bf5abdfa338cc..a08589fe314f4dfdc1383e05db3d7502968d66b1 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_49.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_49.ets @@ -18,9 +18,7 @@ function identity(arg: Type): Type { } let output = identity/* @@ label */"hehe" -/* @@? 19:14 Error TypeError: Expected 1 arguments, got 0. */ -/* @@? 19:14 Error TypeError: No matching call signature */ /* @@? 19:14 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 19:14 Error TypeError: No matching call signature */ /* @@? 19:44 Error SyntaxError: Unexpected token, expected '('. */ -/* @@? 27:1 Error SyntaxError: Expected ')', got 'eos'. */ +/* @@? 25:1 Error SyntaxError: Expected ')', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_50.ets b/ets2panda/test/ast/parser/ets/unexpected_token_50.ets index 1f2156ecc5b4fc9195110019d4db1131b8c69079..d183229f0b8e87e1ba95936112d01c684d3f2688 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_50.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_50.ets @@ -19,9 +19,7 @@ function identity(arg: Type): Type { let output = identity let output1 = identity/* @@ label */"hehe" -/* @@? 20:15 Error TypeError: Expected 1 arguments, got 0. */ -/* @@? 20:15 Error TypeError: No matching call signature */ /* @@? 20:15 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 20:15 Error TypeError: No matching call signature */ /* @@? 20:45 Error SyntaxError: Unexpected token, expected '('. */ -/* @@? 28:1 Error SyntaxError: Expected ')', got 'eos'. */ +/* @@? 26:1 Error SyntaxError: Expected ')', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_53.ets b/ets2panda/test/ast/parser/ets/unexpected_token_53.ets index 70bf658604269b790f7f76e435609ec8659ee11e..8f07621597d68c31c285c6c2590e448595c7d153 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_53.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_53.ets @@ -27,16 +27,11 @@ export class MathSpectralNorm { /* @@? 19:10 Error TypeError: Unresolved reference i */ /* @@? 19:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:22 Error SyntaxError: Expected ')', got ':'. */ /* @@? 19:22 Error SyntaxError: Expected ';', got ':'. */ +/* @@? 19:22 Error SyntaxError: Unexpected token ':'. */ +/* @@? 19:24 Error SyntaxError: Expected ')', got 'identification literal'. */ /* @@? 19:27 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:27 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:27 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:29 Error SyntaxError: Unexpected token '{'. */ /* @@? 20:7 Error TypeError: Unresolved reference vbv */ /* @@? 20:14 Error TypeError: Unresolved reference u */ /* @@? 20:14 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_55.ets b/ets2panda/test/ast/parser/ets/unexpected_token_55.ets index f18667c944b41dfb017d1984899a06fd086660e1..eb0b3d59e6a501bced28866c49699cdb26eb84de 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_55.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_55.ets @@ -30,18 +30,9 @@ export class MathSpectralNorm { /* @@? 19:23 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 19:29 Error SyntaxError: Expected ';', got ':'. */ /* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:29 Error SyntaxError: Expected ')', got ':'. */ -/* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:29 Error SyntaxError: Unexpected token ':'. */ -/* @@? 19:34 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:34 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:34 Error SyntaxError: Unexpected token ')'. */ -/* @@? 19:34 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:31 Error SyntaxError: Expected ')', got 'identification literal'. */ /* @@? 19:34 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:36 Error SyntaxError: Unexpected token '{'. */ /* @@? 20:7 Error TypeError: Unresolved reference vbv */ /* @@? 20:14 Error TypeError: Unresolved reference u */ /* @@? 20:14 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_56.ets b/ets2panda/test/ast/parser/ets/unexpected_token_56.ets index ad0043f46c84b41df4ffc73e5408384d88c0dcf2..a5017ce1b8d99159045bb88bcbed7e28d811438c 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_56.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_56.ets @@ -18,17 +18,14 @@ for await (/* @@ label1 */;/* @@ label2 */;i < count/* @@ label3 */; ++i/* @@ la } for (let i? : Number = 1;;) { break; } -/* @@? 16:27 Error SyntaxError: Unexpected token ';'. */ -/* @@? 16:43 Error SyntaxError: Unexpected token ';'. */ +/* @@@ label1 Error SyntaxError: Unexpected token ';'. */ +/* @@@ label2 Error SyntaxError: Unexpected token ';'. */ /* @@? 16:44 Error TypeError: Unresolved reference i */ -/* @@? 16:48 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 16:44 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 16:68 Error SyntaxError: Expected ')', got ';'. */ -/* @@? 16:87 Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:87 Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:87 Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:87 Error SyntaxError: Unexpected token ')'. */ -/* @@? 16:87 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:48 Error TypeError: Function name 'count' used in the wrong context */ +/* @@@ label3 Error SyntaxError: Expected ')', got ';'. */ +/* @@@ label Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:89 Error SyntaxError: Unexpected token '{'. */ /* @@? 17:5 Error TypeError: Unresolved reference result */ /* @@? 17:23 Error TypeError: Unresolved reference p */ /* @@? 17:23 Error TypeError: Indexed access is not supported for such expression type. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_58.ets b/ets2panda/test/ast/parser/ets/unexpected_token_58.ets index db9194f016287f0c155aa5f2b989b954322afc9e..b6b5d9d26f6768c0d5b7aa8f9e728f06b90d4919 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_58.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_58.ets @@ -17,5 +17,5 @@ function foo(a: int) {} foo(1, -/* @@@ label Error SyntaxError: Expected ')', got 'eos'. */ +/* @@@ label Error SyntaxError: Expected ')', got 'end of stream'. */ /* @@ label */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_59.ets b/ets2panda/test/ast/parser/ets/unexpected_token_59.ets index 1859a8e6a3eeeb903e6f9b0bb6fa0af72ca55c36..b35bc96dee2884ac963395c368587763b895d0b2 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_59.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_59.ets @@ -17,5 +17,5 @@ class A { x: int -/* @@@ label Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_62.ets b/ets2panda/test/ast/parser/ets/unexpected_token_62.ets new file mode 100644 index 0000000000000000000000000000000000000000..b397c9a783511136231c99cfda73e3cb029b229a --- /dev/null +++ b/ets2panda/test/ast/parser/ets/unexpected_token_62.ets @@ -0,0 +1,73 @@ +/* + * 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 extendsA {} + +functioew Nu +nt = 10 A {} + +functioew Nu +nt = 10 +)void {nt = 20, g: s A {} +int = 10 +) => B = (p:+): A6=> { reƒurn _ew B(ô } +|ó + +/* @@? 17:9 Error SyntaxError: Expected '{', got 'identification literal'. */ +/* @@? 17:18 Error SyntaxError: Unexpected token '{'. */ +/* @@? 19:1 Error TypeError: Unresolved reference functioew */ +/* @@? 19:11 Error SyntaxError: Unexpected token 'Nu'. */ +/* @@? 19:11 Error TypeError: Unresolved reference Nu */ +/* @@? 20:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 20:1 Error TypeError: Unresolved reference nt */ +/* @@? 20:10 Error SyntaxError: Unexpected token 'A'. */ +/* @@? 20:10 Error TypeError: Class name 'A' used in the wrong context */ +/* @@? 20:12 Error SyntaxError: Unexpected token '{'. */ +/* @@? 22:11 Error SyntaxError: Unexpected token 'Nu'. */ +/* @@? 23:1 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 24:1 Error SyntaxError: Unexpected token ')'. */ +/* @@? 24:2 Error SyntaxError: Unexpected token 'void'. */ +/* @@? 24:7 Error SyntaxError: Unexpected token '{'. */ +/* @@? 24:8 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 24:8 Error TypeError: Unresolved reference nt */ +/* @@? 24:16 Error SyntaxError: Unexpected token ','. */ +/* @@? 24:18 Error SyntaxError: Unexpected token 'g'. */ +/* @@? 24:21 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 24:21 Error TypeError: Unresolved reference s */ +/* @@? 24:23 Error SyntaxError: Unexpected token 'A'. */ +/* @@? 24:23 Error TypeError: Class name 'A' used in the wrong context */ +/* @@? 24:25 Error SyntaxError: Unexpected token '{'. */ +/* @@? 25:1 Error SyntaxError: Unexpected token 'int'. */ +/* @@? 26:1 Error SyntaxError: Unexpected token ')'. */ +/* @@? 26:3 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 26:13 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 26:13 Error TypeError: Cannot find type ''. */ +/* @@? 26:14 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 26:14 Error SyntaxError: Expected '=>', got '+'. */ +/* @@? 26:15 Error SyntaxError: Unexpected token ')'. */ +/* @@? 26:16 Error SyntaxError: Unexpected token ':'. */ +/* @@? 26:18 Error SyntaxError: Unexpected token 'A6'. */ +/* @@? 26:18 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 26:18 Error TypeError: The type of parameter 'A6' cannot be inferred */ +/* @@? 26:25 Error TypeError: Unresolved reference reƒurn */ +/* @@? 26:32 Error SyntaxError: Unexpected token '_ew'. */ +/* @@? 26:32 Error TypeError: Unresolved reference _ew */ +/* @@? 26:36 Error SyntaxError: Unexpected token 'B'. */ +/* @@? 26:36 Error TypeError: No static $_invoke method and static $_instantiate method in B. B() is not allowed. */ +/* @@? 26:36 Error TypeError: Type 'B' has no call signatures. */ +/* @@? 26:40 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 27:2 Error TypeError: Unresolved reference ó */ +/* @@? 74:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_63.ets b/ets2panda/test/ast/parser/ets/unexpected_token_63.ets new file mode 100644 index 0000000000000000000000000000000000000000..ec6024e988612d96e494bd356eb07334d126a281 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/unexpected_token_63.ets @@ -0,0 +1,56 @@ +/* + * 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 { + func1(list : number, final : number) { + while(true) { + if(false) { + break; + } else { + let endSequence = false + this.func(list, final, endSequence) + } + } + } +} + +/* @@? 17:7 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:23 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:23 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:23 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 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 '('. */ +/* @@? 18:9 Error SyntaxError: Unexpected token 'true'. */ +/* @@? 18:13 Error SyntaxError: Unexpected token ')'. */ +/* @@? 18:15 Error SyntaxError: Unexpected token '{'. */ +/* @@? 19:4 Error SyntaxError: Unexpected token 'if'. */ +/* @@? 19:6 Error SyntaxError: Unexpected token '('. */ +/* @@? 19:7 Error SyntaxError: Unexpected token 'false'. */ +/* @@? 19:12 Error SyntaxError: Unexpected token ')'. */ +/* @@? 19:14 Error SyntaxError: Unexpected token '{'. */ +/* @@? 20:5 Error SyntaxError: Unexpected token 'break'. */ +/* @@? 21:6 Error SyntaxError: Unexpected token 'else'. */ +/* @@? 21:11 Error SyntaxError: Unexpected token '{'. */ +/* @@? 23:5 Error TypeError: Cannot reference 'this' in this context. */ +/* @@? 23:10 Error TypeError: Property 'func' does not exist on type 'Error' */ +/* @@? 23:21 Error SyntaxError: Unexpected token 'final'. */ +/* @@? 25:3 Error SyntaxError: Unexpected token '}'. */ +/* @@? 26:2 Error SyntaxError: Unexpected token '}'. */ +/* @@? 27:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/test/parser/ets/union_generic_field_access.ets b/ets2panda/test/ast/parser/ets/union_generic_field_access.ets similarity index 100% rename from ets2panda/test/parser/ets/union_generic_field_access.ets rename to ets2panda/test/ast/parser/ets/union_generic_field_access.ets diff --git a/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets b/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..43d8b6c6e54e57d4a57de8d0bfa82656cda750f2 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/unreachable_fuzz_error.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + let x = z.meth(foo) + +{ + assert(y[0] == 1) + assert(y[1] == 2) + +classtext: string, reviver: ((key: string, value: NullishType) => NullishType) | undefined, type: Type + +/* @@? 16:13 Error TypeError: Unresolved reference z */ +/* @@? 22:12 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 22:18 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:20 Error SyntaxError: Unexpected token 'reviver'. */ +/* @@? 22:29 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 22:91 Error SyntaxError: Unexpected token ','. */ +/* @@? 22:93 Error SyntaxError: Unexpected token 'type'. */ +/* @@? 22:99 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 33:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_10.ets b/ets2panda/test/ast/parser/ets/user_defined_10.ets index f34b440d7b36653051f52ce048e617d79f8b12ed..3f505ccfbd68ae52d2d2b7db68982b301ecc4375 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_10.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_10.ets @@ -17,6 +17,5 @@ struct number{ a : string = "15"; } -/* @@? 16:8 Error SyntaxError: Cannot be used as user-defined type. */ /* @@? 16:1 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ -/* @@? 1:3 Error TypeError: Variable 'number' is already defined with different type. */ +/* @@? 16:8 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_11.ets b/ets2panda/test/ast/parser/ets/user_defined_11.ets index 685fc998d6bbbf948b2ea7765e0086fbdf96f652..e04f80779fc9e643d032eebf66080cc8055ac2ec 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_11.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_11.ets @@ -17,5 +17,4 @@ class /* @@ label */number{ a : string = "15"; } -/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ -/* @@? 1:3 Error TypeError: Variable 'number' is already defined with different type. */ +/* @@? 16:21 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_14.ets b/ets2panda/test/ast/parser/ets/user_defined_14.ets index 96e8945c06487af37de1e08069a1178a2328f37e..a52c018c9981486973ab3bca26f22271103411b4 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_14.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_14.ets @@ -13,9 +13,6 @@ * limitations under the License. */ -class /* @@ label */typeof{ +class typeof{ a : string = "15"; } - -/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ -/* @@@ label Error SyntaxError: Identifier expected, got 'typeof'. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_19.ets b/ets2panda/test/ast/parser/ets/user_defined_19.ets index 2223fffb2903804c4ef61008bd786caefb87bb99..0da893731848a9ca3ba48665644ac591fe0e1053 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_19.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_19.ets @@ -17,6 +17,4 @@ struct typeof{ a : string = "15"; } -/* @@? 16:8 Error SyntaxError: Cannot be used as user-defined type. */ -/* @@? 16:8 Error SyntaxError: Identifier expected, got 'typeof'. */ /* @@? 16:1 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_26.ets b/ets2panda/test/ast/parser/ets/user_defined_26.ets new file mode 100644 index 0000000000000000000000000000000000000000..19aeb05f0b5911ee21e006696ae7fbd91d55c24d --- /dev/null +++ b/ets2panda/test/ast/parser/ets/user_defined_26.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. + */ + +class instanceof{ + a : string = "15"; +} diff --git a/ets2panda/test/ast/parser/ets/user_defined_27.ets b/ets2panda/test/ast/parser/ets/user_defined_27.ets new file mode 100644 index 0000000000000000000000000000000000000000..73cfa2236bcae2dfc1bc2a9ce90e035ce31852a7 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/user_defined_27.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. + */ + +struct instanceof{ + a : string = "15"; +} + +/* @@? 16:1 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_5.ets b/ets2panda/test/ast/parser/ets/user_defined_5.ets index bfd46c9f78414948cf25721b2c610fc685748f6f..bdf44a3c52233139d5dfcb3a16e90824bcb0b80b 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_5.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_5.ets @@ -17,4 +17,5 @@ enum /* @@ label */double { A, B, C } -/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ +/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ +/* @@@ label Error SyntaxError: Identifier expected, got 'double'. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_7.ets b/ets2panda/test/ast/parser/ets/user_defined_7.ets index d6f9dc12f8a1a961df4f604d6ada9da3613eab36..67c6eec0952f3d56ce21ecaac8914f1f39d2f4bc 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_7.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_7.ets @@ -18,6 +18,7 @@ interface /* @@ label1 */double { /* @@ label4 */} /* @@@ label1 Error SyntaxError: Cannot be used as user-defined type. */ +/* @@@ label1 Error SyntaxError: Identifier expected, got 'double'. */ /* @@@ label2 Error SyntaxError: Interface member initialization is prohibited. */ /* @@@ label3 Error SyntaxError: Unexpected token, expected ','. */ /* @@? 17:51 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ diff --git a/ets2panda/test/ast/parser/ets/while_with_empty_body.ets b/ets2panda/test/ast/parser/ets/while_with_empty_body.ets new file mode 100644 index 0000000000000000000000000000000000000000..3e6ecfbf428e4e16bf84d14524414613a789cd6c --- /dev/null +++ b/ets2panda/test/ast/parser/ets/while_with_empty_body.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. + */ + +while (null) export function foo() {} + +/* @@? 16:14 Error SyntaxError: Unexpected token 'export'. */ +/* @@? 16:14 Error SyntaxError: Missing body in while statement */ diff --git a/ets2panda/test/ast/parser/ets/while_with_empty_condition.ets b/ets2panda/test/ast/parser/ets/while_with_empty_condition.ets new file mode 100644 index 0000000000000000000000000000000000000000..33c96d6b164262d3adec76bed34cc20eb6ce0412 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/while_with_empty_condition.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. + */ + +while () {} + +/* @@? 16:8 Error SyntaxError: Unexpected token ')'. */ +/* @@? 16:10 Error SyntaxError: Expected ')', got '{'. */ +/* @@? 21:1 Error SyntaxError: Missing condition in while statement */ diff --git a/ets2panda/test/ast/parser/ets/wrong-union-array-assignment.ets b/ets2panda/test/ast/parser/ets/wrong-union-array-assignment.ets index ead13d29981992f0cb56191e9ac5a703efae4e14..90dddc19e8d33c1502e969cd577b45decf3e0b9a 100644 --- a/ets2panda/test/ast/parser/ets/wrong-union-array-assignment.ets +++ b/ets2panda/test/ast/parser/ets/wrong-union-array-assignment.ets @@ -24,4 +24,4 @@ function main() array = /* @@ label */new Bad(); } -/* @@@ label Error TypeError: Type 'Bad' cannot be assigned to type '(Int|Double|String)[]' */ +/* @@? 24:27 Error TypeError: Type 'Bad' cannot be assigned to type 'Array' */ 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 97bdb265cec6a98ddfb5aef2a304b8e47abfa311..3af604d858f5423baff2ed5b652ef0c2496a4b0f 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: Class name 'a' used in the wrong context */ -/* @@? 26:5 Error TypeError: Object type doesn't have proper index access method. */ diff --git a/ets2panda/test/ast/parser/js/InvalidExpressions.js b/ets2panda/test/ast/parser/js/InvalidExpressions.js index 0c079851aa525eb5cec3bf4631334ba02f744f0c..110409e0fb929e2e38792f7017fd277d1b1fcac0 100644 --- a/ets2panda/test/ast/parser/js/InvalidExpressions.js +++ b/ets2panda/test/ast/parser/js/InvalidExpressions.js @@ -152,4 +152,4 @@ async (x = await 7) /* @@ label56 */=> expression; /* @@@ label57 Error SyntaxError: Unexpected token ']'. */ /* @@@ label57 Error SyntaxError: Unexpected token ']'. */ /* @@@ label57 Error SyntaxError: Unexpected token ']'. */ -/* @@? 156:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 156:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/js/module/unexpected_token_10.js b/ets2panda/test/ast/parser/js/module/unexpected_token_10.js index c29ecd316ce8779eeceec685930f7c5816007adc..9b30edb06b5001a316de0197b7f0a153c0c50bae 100644 --- a/ets2panda/test/ast/parser/js/module/unexpected_token_10.js +++ b/ets2panda/test/ast/parser/js/module/unexpected_token_10.js @@ -21,4 +21,4 @@ import(import /* @@ label */) /* @@@ label Error SyntaxError: Expected '(', got ')'. */ /* @@@ label Error SyntaxError: Unexpected token ')'. */ -/* @@? 25:1 Error SyntaxError: Expected ')', got 'eos'. */ +/* @@? 25:1 Error SyntaxError: Expected ')', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/js/test-if-2.js b/ets2panda/test/ast/parser/js/test-if-2.js index 2cd12684b9d109c26024728014b716708013f30b..56a941f110607ccd1550bcb82ba9abd6001cd7e7 100644 --- a/ets2panda/test/ast/parser/js/test-if-2.js +++ b/ets2panda/test/ast/parser/js/test-if-2.js @@ -16,4 +16,4 @@ if(/* @@ label */) /* @@@ label Error SyntaxError: Unexpected token ')'. */ -/* @@? 20:1 Error SyntaxError: Unexpected token 'eos'. */ +/* @@? 20:1 Error SyntaxError: Unexpected token 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/js/test-private-field1.js b/ets2panda/test/ast/parser/js/test-private-field1.js index e9b946dc7aa4de87d891d60d95714765f2fc5a26..dd35ab34c96a46598315cb715dde0e89bfe5fe74 100644 --- a/ets2panda/test/ast/parser/js/test-private-field1.js +++ b/ets2panda/test/ast/parser/js/test-private-field1.js @@ -16,4 +16,4 @@ #a /* @@? 20:1 Error SyntaxError: Unexpected private identifier. */ -/* @@? 20:1 Error SyntaxError: Unexpected token 'eos'. */ +/* @@? 20:1 Error SyntaxError: Unexpected token 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/js/test-switch-1.js b/ets2panda/test/ast/parser/js/test-switch-1.js index a5b946e30dc63e4dbf0d6c9047d67f2a9246c1d0..2fb0a42d31e75442ab5d076df90a389195f15b17 100644 --- a/ets2panda/test/ast/parser/js/test-switch-1.js +++ b/ets2panda/test/ast/parser/js/test-switch-1.js @@ -16,9 +16,9 @@ switch -/* @@@ label Error SyntaxError: Expected '(', got 'eos'. */ -/* @@@ label Error SyntaxError: Unexpected token 'eos'. */ -/* @@@ label Error SyntaxError: Expected ')', got 'eos'. */ -/* @@@ label Error SyntaxError: Expected '{', got 'eos'. */ -/* @@@ label Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label Error SyntaxError: Expected '(', got 'end of stream'. */ +/* @@@ label Error SyntaxError: Unexpected token 'end of stream'. */ +/* @@@ label Error SyntaxError: Expected ')', got 'end of stream'. */ +/* @@@ label Error SyntaxError: Expected '{', got 'end of stream'. */ +/* @@@ label Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/js/test-switch-2.js b/ets2panda/test/ast/parser/js/test-switch-2.js index 32a3823b308621e69fe9cc483e1b40725b2dcdc3..626f257980cac5759aab5f778f62b0e1fddff5e3 100644 --- a/ets2panda/test/ast/parser/js/test-switch-2.js +++ b/ets2panda/test/ast/parser/js/test-switch-2.js @@ -19,7 +19,7 @@ switch /* @@ label */{ } /* @@@ label Error SyntaxError: Expected '(', got '{'. */ -/* @@@ label1 Error SyntaxError: Expected ')', got 'eos'. */ -/* @@@ label1 Error SyntaxError: Expected '{', got 'eos'. */ -/* @@@ label1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label1 Error SyntaxError: Expected ')', got 'end of stream'. */ +/* @@@ label1 Error SyntaxError: Expected '{', got 'end of stream'. */ +/* @@@ label1 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label1 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/js/test-wrong-function-decl-1.js b/ets2panda/test/ast/parser/js/test-wrong-function-decl-1.js index 6636ea905179b50a451d387e6055e0cd39908db8..1ea7c667ccd8fe5f2226c4105a9a0626f07ef16d 100644 --- a/ets2panda/test/ast/parser/js/test-wrong-function-decl-1.js +++ b/ets2panda/test/ast/parser/js/test-wrong-function-decl-1.js @@ -20,5 +20,5 @@ function f/* @@ label */{/* @@ label1 */} /* @@@ label1 Error SyntaxError: Unexpected token. */ /* @@@ label1 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@@ label1 Error SyntaxError: Unexpected token, expected '{'. */ -/* @@@ label2 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label2 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label2 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/js/test-wrong-function-decl-2.js b/ets2panda/test/ast/parser/js/test-wrong-function-decl-2.js index 72838f266092521b6b144dff19cb1f41262738ad..34371562577ab5db89f6bfde113f17483f2df9e4 100644 --- a/ets2panda/test/ast/parser/js/test-wrong-function-decl-2.js +++ b/ets2panda/test/ast/parser/js/test-wrong-function-decl-2.js @@ -17,5 +17,5 @@ function f(a,b,c)/* @@ label */; /* @@@ label Error SyntaxError: Unexpected token, expected '{'. */ -/* @@@ label1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label1 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label1 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/js/trailing_comma_1.js b/ets2panda/test/ast/parser/js/trailing_comma_1.js index 9fe9f6167b5f7373013d709d53c9fe8339ee250a..888adab493601c9471360105aa3d3436714c22e4 100644 --- a/ets2panda/test/ast/parser/js/trailing_comma_1.js +++ b/ets2panda/test/ast/parser/js/trailing_comma_1.js @@ -46,5 +46,5 @@ foo(/* @@ label8 */,) /* @@@ label6 Error SyntaxError: Unexpected token 'a'. */ /* @@@ label7 Error SyntaxError: Unexpected token ')'. */ /* @@@ label8 Error SyntaxError: Unexpected token ','. */ -/* @@@ label9 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label9 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label9 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/js/unexpected_token_1.js b/ets2panda/test/ast/parser/js/unexpected_token_1.js index ea6885db3d739e6de7cc8fa3a26fe8dcc9fe2794..d0132c02e2f3c3c0b9166bf21e30e3f79a3fd79d 100644 --- a/ets2panda/test/ast/parser/js/unexpected_token_1.js +++ b/ets2panda/test/ast/parser/js/unexpected_token_1.js @@ -17,5 +17,5 @@ class A /* @@ label */} /* @@@ label Error SyntaxError: Expected '{', got '}'. */ -/* @@@ label1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label1 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label1 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/js/unexpected_token_3.js b/ets2panda/test/ast/parser/js/unexpected_token_3.js index 4d4e9a6cf52ca28b41d540d64adffae5ba22b1c8..59018135dcb77861fbb7669e441e84e065eefad4 100644 --- a/ets2panda/test/ast/parser/js/unexpected_token_3.js +++ b/ets2panda/test/ast/parser/js/unexpected_token_3.js @@ -22,4 +22,4 @@ /* @@? 16:10 Error SyntaxError: Unexpected token ')'. */ /* @@? 16:12 Error SyntaxError: Unterminated RegExp. */ /* @@? 16:18 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 16:18 Error SyntaxError: Unexpected token 'eos'. */ +/* @@? 16:18 Error SyntaxError: Unexpected token 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/js/unexpected_token_5.js b/ets2panda/test/ast/parser/js/unexpected_token_5.js index 4dd12322309be3ef8102c7fc16142316ee3b79ca..277e2391b1e824f4f09f60753c6699a33712387a 100644 --- a/ets2panda/test/ast/parser/js/unexpected_token_5.js +++ b/ets2panda/test/ast/parser/js/unexpected_token_5.js @@ -18,4 +18,4 @@ /* @@? 16:3 Error SyntaxError: Unexpected token, expected '=>'. */ /* @@? 16:5 Error SyntaxError: Unterminated RegExp. */ /* @@? 16:11 Error SyntaxError: Unexpected token, expected an identifier. */ -/* @@? 16:11 Error SyntaxError: Unexpected token 'eos'. */ +/* @@? 16:11 Error SyntaxError: Unexpected token 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/js/unexpected_token_7.js b/ets2panda/test/ast/parser/js/unexpected_token_7.js index bb175ddd8a04c5a8a8b34d4baa42622e0c0c6092..670d0eb8b9b57762fef071953e0c7ce43b23629a 100644 --- a/ets2panda/test/ast/parser/js/unexpected_token_7.js +++ b/ets2panda/test/ast/parser/js/unexpected_token_7.js @@ -22,4 +22,4 @@ class Foo { /* @@? 18:12 Error SyntaxError: Unexpected token, expected ';'. */ /* @@? 19:11 Error SyntaxError: Unexpected token, expected ';'. */ /* @@? 26:1 Error SyntaxError: Private field has already been declared. */ -/* @@? 26:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 26:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ts/InvalidLexer.ts b/ets2panda/test/ast/parser/ts/InvalidLexer.ts index 182300d6142c761b1f2cbe7097fcd39ddd796145..f3c25a0f3be939ca859c0f2235f2306f036cdf7b 100644 --- a/ets2panda/test/ast/parser/ts/InvalidLexer.ts +++ b/ets2panda/test/ast/parser/ts/InvalidLexer.ts @@ -34,7 +34,7 @@ funct\u{0069}on /* @@? 20:5 Error SyntaxError: Unexpected token: 'identification literal'. */ /* @@? 22:1 Error SyntaxError: Unexpected strict mode reserved keyword */ /* @@? 24:1 Error SyntaxError: Escape sequences are not allowed in keywords */ -/* @@? 40:66 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 40:66 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@? 40:66 Error SyntaxError: Unterminated string */ /* @@? 40:66 Error SyntaxError: Unexpected token, expected '${' or '`' */ /* @@? 40:66 Error SyntaxError: Unexpected token, expected '`' */ diff --git a/ets2panda/test/ast/parser/ts/InvalidStatements.ts b/ets2panda/test/ast/parser/ts/InvalidStatements.ts index 873eefcd248c3076528a5ffd897a85ad48cbe727..77b3f7d2edb80ad59003a86ca5ecd2f498a887fd 100644 --- a/ets2panda/test/ast/parser/ts/InvalidStatements.ts +++ b/ets2panda/test/ast/parser/ts/InvalidStatements.ts @@ -161,4 +161,4 @@ module module2 /* @@? 105:8 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 106:5 Error SyntaxError: Unexpected token, expected '{'. */ /* @@? 110:5 Error SyntaxError: Unexpected token, expected '{'. */ -/* @@? 165:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 165:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ts/catch_or_finally_1.ts b/ets2panda/test/ast/parser/ts/catch_or_finally_1.ts index d038313a4c9ccf0e0a23cfc3971d2e43835043bb..8c59f19c69dbb5f8718173aeb690769fad114c38 100644 --- a/ets2panda/test/ast/parser/ts/catch_or_finally_1.ts +++ b/ets2panda/test/ast/parser/ts/catch_or_finally_1.ts @@ -31,5 +31,5 @@ try /* @@ label6 */[] /* @@ label7 */finally {} /* @@? 20:38 Error SyntaxError: Unexpected token 'finally'. */ /* @@? 20:38 Error SyntaxError: Unexpected token 'finally'. */ /* @@? 20:38 Error SyntaxError: Unexpected token 'finally'. */ -/* @@? 36:1 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@? 36:1 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@? 36:1 Error SyntaxError: Missing catch or finally clause. */ diff --git a/ets2panda/test/ast/parser/ts/unexpected_token_8.ts b/ets2panda/test/ast/parser/ts/unexpected_token_8.ts index 1d018cf09f3f24d995c71edf352c0de882ec43f4..61db49560d6c5e43b10570ee07576eb0a22f5efa 100644 --- a/ets2panda/test/ast/parser/ts/unexpected_token_8.ts +++ b/ets2panda/test/ast/parser/ts/unexpected_token_8.ts @@ -17,6 +17,6 @@ class B {} class A extends B -/* @@@ label Error SyntaxError: Expected '{', got 'eos'. */ -/* @@@ label Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label Error SyntaxError: Expected '{', got 'end of stream'. */ +/* @@@ label Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ts/unexpected_token_9.ts b/ets2panda/test/ast/parser/ts/unexpected_token_9.ts index 8c01bc19ac9bcf152a3eb89f49e19c2a603b51de..f3f09596da6a23afa423c78cc140b408cbd3d51e 100644 --- a/ets2panda/test/ast/parser/ts/unexpected_token_9.ts +++ b/ets2panda/test/ast/parser/ts/unexpected_token_9.ts @@ -20,5 +20,5 @@ declare namespace /* @@ label */^/* @@ label1 */a { /* @@@ label Error SyntaxError: Unexpected token, expected an identifier. */ /* @@@ label1 Error SyntaxError: Unexpected token, expected '{'. */ -/* @@@ label2 Error SyntaxError: Expected '}', got 'eos'. */ +/* @@@ label2 Error SyntaxError: Expected '}', got 'end of stream'. */ /* @@ label2 */ \ No newline at end of file diff --git a/ets2panda/test/compiler/ets/116100-expected.txt b/ets2panda/test/compiler/ets/116100-expected.txt index 4d068cdd92a9964b5cf581733022eab59a5e8904..db59083ea570ab4cfed8ed7a0322fb49077447f8 100644 --- a/ets2panda/test/compiler/ets/116100-expected.txt +++ b/ets2panda/test/compiler/ets/116100-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "116100.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "116100.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "116100.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "116100.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/ConditionalExpressionCallVoidNeg-expected.txt b/ets2panda/test/compiler/ets/ConditionalExpressionCallVoidNeg-expected.txt index 500cbfbf6fa573b16f7bc42a443cd3adeeb8e18f..895378e780181bfc17f62039408f498b212a68d5 100644 --- a/ets2panda/test/compiler/ets/ConditionalExpressionCallVoidNeg-expected.txt +++ b/ets2panda/test/compiler/ets/ConditionalExpressionCallVoidNeg-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ConditionalExpressionCallVoidNeg.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ConditionalExpressionCallVoidNeg.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ConditionalExpressionCallVoidNeg.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ConditionalExpressionCallVoidNeg.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/FunctionType2-expected.txt b/ets2panda/test/compiler/ets/FunctionType2-expected.txt index 84cdfaed84ccbf0e18c029a2284a335116dc3676..d38a389d6fc9600f95531fd25df66fab04154ac6 100644 --- a/ets2panda/test/compiler/ets/FunctionType2-expected.txt +++ b/ets2panda/test/compiler/ets/FunctionType2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionType2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionType2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionType2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionType2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -840,4 +806,4 @@ } } } -Warning: Variable 'func' is used before being assigned. [FunctionType2.ets:23:11] +TypeError: Variable 'func' is used before being assigned. [FunctionType2.ets:23:11] diff --git a/ets2panda/test/compiler/ets/FunctionType4-expected.txt b/ets2panda/test/compiler/ets/FunctionType4-expected.txt index 9aa2c3f75a4b18dd64b571b06f3bc4b08af3fd38..025b501c15e0a85ab5daa75465cdc2c95875d529 100644 --- a/ets2panda/test/compiler/ets/FunctionType4-expected.txt +++ b/ets2panda/test/compiler/ets/FunctionType4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionType4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionType4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionType4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionType4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/abstractMethodDeclaredInParentClass-expected.txt b/ets2panda/test/compiler/ets/abstractMethodDeclaredInParentClass-expected.txt index 4662a0623ae45be446c17ddb874450119851a9c9..6864a7a18126bd18541863c56d5eba515e09d49c 100644 --- a/ets2panda/test/compiler/ets/abstractMethodDeclaredInParentClass-expected.txt +++ b/ets2panda/test/compiler/ets/abstractMethodDeclaredInParentClass-expected.txt @@ -3025,40 +3025,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "abstractMethodDeclaredInParentClass.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "abstractMethodDeclaredInParentClass.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "abstractMethodDeclaredInParentClass.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "abstractMethodDeclaredInParentClass.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/abstractNewClassInstanceExpression-expected.txt b/ets2panda/test/compiler/ets/abstractNewClassInstanceExpression-expected.txt index d68af12577e15916a83572f69c902f23cef393d3..7d401ea3ae94487adc738e9d9b80f5ca88cadc5a 100644 --- a/ets2panda/test/compiler/ets/abstractNewClassInstanceExpression-expected.txt +++ b/ets2panda/test/compiler/ets/abstractNewClassInstanceExpression-expected.txt @@ -864,40 +864,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "abstractNewClassInstanceExpression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "abstractNewClassInstanceExpression.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "abstractNewClassInstanceExpression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "abstractNewClassInstanceExpression.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/ambient_declaration-expected.txt b/ets2panda/test/compiler/ets/ambient_declaration-expected.txt index a94eab89864b0dbd413ad4dfdac98f56ef3084fc..441653f31766b461279e9b62b57217c36ffae107 100644 --- a/ets2panda/test/compiler/ets/ambient_declaration-expected.txt +++ b/ets2panda/test/compiler/ets/ambient_declaration-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_declaration.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_declaration.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_declaration.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_declaration.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -356,6 +322,158 @@ } }, "declare": true, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 18, + "program": "ambient_declaration.ets" + }, + "end": { + "line": 16, + "column": 21, + "program": "ambient_declaration.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 18, + "program": "ambient_declaration.ets" + }, + "end": { + "line": 16, + "column": 21, + "program": "ambient_declaration.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 18, + "program": "ambient_declaration.ets" + }, + "end": { + "line": 16, + "column": 21, + "program": "ambient_declaration.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 18, + "program": "ambient_declaration.ets" + }, + "end": { + "line": 16, + "column": 21, + "program": "ambient_declaration.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 18, + "program": "ambient_declaration.ets" + }, + "end": { + "line": 16, + "column": 21, + "program": "ambient_declaration.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 18, + "program": "ambient_declaration.ets" + }, + "end": { + "line": 16, + "column": 21, + "program": "ambient_declaration.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 16, + "column": 18, + "program": "ambient_declaration.ets" + }, + "end": { + "line": 16, + "column": 21, + "program": "ambient_declaration.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 18, + "program": "ambient_declaration.ets" + }, + "end": { + "line": 16, + "column": 21, + "program": "ambient_declaration.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 18, + "program": "ambient_declaration.ets" + }, + "end": { + "line": 16, + "column": 21, + "program": "ambient_declaration.ets" + } + } + } + ], "loc": { "start": { "line": 16, diff --git a/ets2panda/test/compiler/ets/array_indexing_with_chaining_non_nullish-expected.txt b/ets2panda/test/compiler/ets/array_indexing_with_chaining_non_nullish-expected.txt index b3e99411e22e365064e236a624cc22f68bdfd810..adfa47a892da913780bb09b944fc0b2fd2c2924a 100644 --- a/ets2panda/test/compiler/ets/array_indexing_with_chaining_non_nullish-expected.txt +++ b/ets2panda/test/compiler/ets/array_indexing_with_chaining_non_nullish-expected.txt @@ -920,55 +920,103 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 11, - "program": "array_indexing_with_chaining_non_nullish.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_indexing_with_chaining_non_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_non_nullish.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_non_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_non_nullish.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_non_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_non_nullish.ets" + } + } }, - "end": { - "line": 18, - "column": 17, - "program": "array_indexing_with_chaining_non_nullish.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_non_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_non_nullish.ets" + } } } - }, + ], "loc": { "start": { - "line": 18, - "column": 11, + "line": 1, + "column": 3, "program": "array_indexing_with_chaining_non_nullish.ets" }, "end": { - "line": 18, - "column": 18, + "line": 1, + "column": 3, "program": "array_indexing_with_chaining_non_nullish.ets" } } }, "loc": { "start": { - "line": 18, - "column": 11, + "line": 1, + "column": 1, "program": "array_indexing_with_chaining_non_nullish.ets" }, "end": { - "line": 18, - "column": 18, + "line": 1, + "column": 3, "program": "array_indexing_with_chaining_non_nullish.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, diff --git a/ets2panda/test/compiler/ets/array_indexing_with_chaining_nullish-expected.txt b/ets2panda/test/compiler/ets/array_indexing_with_chaining_nullish-expected.txt index c394cc534b93ddc5ef562cef766494449d2e5d8d..9cf3d167a05fcd2872b31e26231a4299971801ff 100644 --- a/ets2panda/test/compiler/ets/array_indexing_with_chaining_nullish-expected.txt +++ b/ets2panda/test/compiler/ets/array_indexing_with_chaining_nullish-expected.txt @@ -923,55 +923,103 @@ "type": "ETSUnionType", "types": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 11, - "program": "array_indexing_with_chaining_nullish.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_indexing_with_chaining_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_nullish.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_nullish.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_nullish.ets" + } + } }, - "end": { - "line": 18, - "column": 17, - "program": "array_indexing_with_chaining_nullish.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_with_chaining_nullish.ets" + } } } - }, + ], "loc": { "start": { - "line": 18, - "column": 11, + "line": 1, + "column": 3, "program": "array_indexing_with_chaining_nullish.ets" }, "end": { - "line": 18, - "column": 18, + "line": 1, + "column": 3, "program": "array_indexing_with_chaining_nullish.ets" } } }, "loc": { "start": { - "line": 18, - "column": 11, + "line": 1, + "column": 1, "program": "array_indexing_with_chaining_nullish.ets" }, "end": { - "line": 18, - "column": 18, + "line": 1, + "column": 3, "program": "array_indexing_with_chaining_nullish.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, diff --git a/ets2panda/test/compiler/ets/array_indexing_without_chaining_non_nullish-expected.txt b/ets2panda/test/compiler/ets/array_indexing_without_chaining_non_nullish-expected.txt index f6f5dfc552418b8c621c83022f26a0a2fbeeb189..ec285695b026d2d5ce9ff5ac52370a12aa58e796 100644 --- a/ets2panda/test/compiler/ets/array_indexing_without_chaining_non_nullish-expected.txt +++ b/ets2panda/test/compiler/ets/array_indexing_without_chaining_non_nullish-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_indexing_without_chaining_non_nullish.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_indexing_without_chaining_non_nullish.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_indexing_without_chaining_non_nullish.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_indexing_without_chaining_non_nullish.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -741,55 +707,103 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 11, - "program": "array_indexing_without_chaining_non_nullish.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_indexing_without_chaining_non_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_without_chaining_non_nullish.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_indexing_without_chaining_non_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_without_chaining_non_nullish.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_indexing_without_chaining_non_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_without_chaining_non_nullish.ets" + } + } }, - "end": { - "line": 18, - "column": 17, - "program": "array_indexing_without_chaining_non_nullish.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_indexing_without_chaining_non_nullish.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_indexing_without_chaining_non_nullish.ets" + } } } - }, + ], "loc": { "start": { - "line": 18, - "column": 11, + "line": 1, + "column": 3, "program": "array_indexing_without_chaining_non_nullish.ets" }, "end": { - "line": 18, - "column": 18, + "line": 1, + "column": 3, "program": "array_indexing_without_chaining_non_nullish.ets" } } }, "loc": { "start": { - "line": 18, - "column": 11, + "line": 1, + "column": 1, "program": "array_indexing_without_chaining_non_nullish.ets" }, "end": { - "line": 18, - "column": 18, + "line": 1, + "column": 3, "program": "array_indexing_without_chaining_non_nullish.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, diff --git a/ets2panda/test/compiler/ets/array_with_null_type-expected.txt b/ets2panda/test/compiler/ets/array_with_null_type-expected.txt index 5dbd906c135e40d3786502f8c37cb8a2517e2689..5381b15030cd504c298d3de96fe581c441424c2a 100644 --- a/ets2panda/test/compiler/ets/array_with_null_type-expected.txt +++ b/ets2panda/test/compiler/ets/array_with_null_type-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_with_null_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_with_null_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_with_null_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_with_null_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -240,23 +206,71 @@ "type": "Identifier", "name": "foo", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSNullType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_with_null_type.ets" + }, + "end": { + "line": 1, + "column": 4, + "program": "array_with_null_type.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSNullType", + "loc": { + "start": { + "line": 1, + "column": 4, + "program": "array_with_null_type.ets" + }, + "end": { + "line": 1, + "column": 4, + "program": "array_with_null_type.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 4, + "program": "array_with_null_type.ets" + }, + "end": { + "line": 1, + "column": 4, + "program": "array_with_null_type.ets" + } + } + }, "loc": { "start": { - "line": 17, - "column": 14, + "line": 1, + "column": 1, "program": "array_with_null_type.ets" }, "end": { - "line": 17, - "column": 18, + "line": 1, + "column": 4, "program": "array_with_null_type.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, diff --git a/ets2panda/test/compiler/ets/array_with_undefined_type-expected.txt b/ets2panda/test/compiler/ets/array_with_undefined_type-expected.txt index 8ab13bc98eebbe6ee5df063c9abecf20e71e0770..97c1d1eacaab20797ad112f5bce5090c34a51df5 100644 --- a/ets2panda/test/compiler/ets/array_with_undefined_type-expected.txt +++ b/ets2panda/test/compiler/ets/array_with_undefined_type-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_with_undefined_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_with_undefined_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_with_undefined_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_with_undefined_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -240,23 +206,71 @@ "type": "Identifier", "name": "foo", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSUndefinedType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_with_undefined_type.ets" + }, + "end": { + "line": 1, + "column": 4, + "program": "array_with_undefined_type.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSUndefinedType", + "loc": { + "start": { + "line": 1, + "column": 4, + "program": "array_with_undefined_type.ets" + }, + "end": { + "line": 1, + "column": 4, + "program": "array_with_undefined_type.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 4, + "program": "array_with_undefined_type.ets" + }, + "end": { + "line": 1, + "column": 4, + "program": "array_with_undefined_type.ets" + } + } + }, "loc": { "start": { - "line": 17, - "column": 14, + "line": 1, + "column": 1, "program": "array_with_undefined_type.ets" }, "end": { - "line": 17, - "column": 23, + "line": 1, + "column": 4, "program": "array_with_undefined_type.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, diff --git a/ets2panda/test/compiler/ets/arrowFunctionCapture-expected.txt b/ets2panda/test/compiler/ets/arrowFunctionCapture-expected.txt index f9bb146e4341c3d24735b0ead9205e2c94bce62e..772965af6fdae55a91d52e9467eda01f844feecb 100644 --- a/ets2panda/test/compiler/ets/arrowFunctionCapture-expected.txt +++ b/ets2panda/test/compiler/ets/arrowFunctionCapture-expected.txt @@ -924,40 +924,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "arrowFunctionCapture.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "arrowFunctionCapture.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "arrowFunctionCapture.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "arrowFunctionCapture.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/boxingConversion10-expected.txt b/ets2panda/test/compiler/ets/boxingConversion10-expected.txt index 84dc78f5eb97a098c1435e2a6a2ec1926ffae87f..3dcfcb569374cb1df7903feb582c0714544be64d 100644 --- a/ets2panda/test/compiler/ets/boxingConversion10-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion10-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion10.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion10.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/boxingConversion2-expected.txt b/ets2panda/test/compiler/ets/boxingConversion2-expected.txt index 95bbcdeda1aa872cbe0658fef2c25fd4d9e5db11..fd853951c7513246bf51d62a1fae3c1ce4d21471 100644 --- a/ets2panda/test/compiler/ets/boxingConversion2-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/boxingConversion3-expected.txt b/ets2panda/test/compiler/ets/boxingConversion3-expected.txt index d8c478ed813d328534097652234224a6832711c5..a8f8673a75af0138e2ca6510f42884e3b8b0f469 100644 --- a/ets2panda/test/compiler/ets/boxingConversion3-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/boxingConversion5-expected.txt b/ets2panda/test/compiler/ets/boxingConversion5-expected.txt index ca8086bf91649b014c3fa72315f6f29cbb102246..52a19571488c0117952d4ff6bc912efb3d81734c 100644 --- a/ets2panda/test/compiler/ets/boxingConversion5-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion5-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/boxingConversion6-expected.txt b/ets2panda/test/compiler/ets/boxingConversion6-expected.txt index c2d838afb181fbc4610963419c0c9b8a5c83277c..88a8b2463965042d15189f2d3515e5bf2205cdd7 100644 --- a/ets2panda/test/compiler/ets/boxingConversion6-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion6-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/boxingConversion7-expected.txt b/ets2panda/test/compiler/ets/boxingConversion7-expected.txt index 4582ff7724f4fbcb9ba093b3fbb570636bb0964e..4ab4be70e0dacc1404f3827b80209f048a2864ae 100644 --- a/ets2panda/test/compiler/ets/boxingConversion7-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion7-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/boxingConversion8-expected.txt b/ets2panda/test/compiler/ets/boxingConversion8-expected.txt index 6e12621e8a02e1ea8bc5b68bf906b1041145e380..081b1f8149dc339cf2be89f1768b2f90136a5212 100644 --- a/ets2panda/test/compiler/ets/boxingConversion8-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion8-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/boxingConversion9-expected.txt b/ets2panda/test/compiler/ets/boxingConversion9-expected.txt index e8c97235dc838f2e3411fcaa638abf32d662af4d..ac430370401c3e91bb1003de194d26378d6adf38 100644 --- a/ets2panda/test/compiler/ets/boxingConversion9-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion9-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingConversion9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingConversion9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt b/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt index 5b7218b4827da7def3e31ac1857fa23da35679b7..253a7e61b976020693d46b8da84276ac4f7a039e 100644 --- a/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt +++ b/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt @@ -8361,40 +8361,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingUnboxingExpressions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingUnboxingExpressions.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boxingUnboxingExpressions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boxingUnboxingExpressions.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/catch-soft-keyword-expected.txt b/ets2panda/test/compiler/ets/catch-soft-keyword-expected.txt index 4d0a4dd016d9512e98e1760934d754b8fcbfc4ef..88f8081fd9b33c71a088f9c90e4eeea4f3059e97 100644 --- a/ets2panda/test/compiler/ets/catch-soft-keyword-expected.txt +++ b/ets2panda/test/compiler/ets/catch-soft-keyword-expected.txt @@ -454,40 +454,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "catch-soft-keyword.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "catch-soft-keyword.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "catch-soft-keyword.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "catch-soft-keyword.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/catchParamScope-expected.txt b/ets2panda/test/compiler/ets/catchParamScope-expected.txt index c7fe753c57f11e692f757484a028d164109ebd89..d0766f9f4774e328b6900697b01abca3ba22dedc 100644 --- a/ets2panda/test/compiler/ets/catchParamScope-expected.txt +++ b/ets2panda/test/compiler/ets/catchParamScope-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "catchParamScope.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "catchParamScope.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "catchParamScope.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "catchParamScope.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/class_def_varargs_1-expected.txt b/ets2panda/test/compiler/ets/class_def_varargs_1-expected.txt index 7ba996f89d00296fc4a23f18b30c37349086ec7d..44f20b1e6cf189486b31df57bdf0fca1bc8ecf4a 100644 --- a/ets2panda/test/compiler/ets/class_def_varargs_1-expected.txt +++ b/ets2panda/test/compiler/ets/class_def_varargs_1-expected.txt @@ -144,55 +144,103 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "class_def_varargs_1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "class_def_varargs_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + } + } }, - "end": { - "line": 17, - "column": 24, - "program": "class_def_varargs_1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 23, + "line": 1, + "column": 3, "program": "class_def_varargs_1.ets" }, "end": { - "line": 17, - "column": 25, + "line": 1, + "column": 3, "program": "class_def_varargs_1.ets" } } }, "loc": { "start": { - "line": 17, - "column": 23, + "line": 1, + "column": 1, "program": "class_def_varargs_1.ets" }, "end": { - "line": 17, - "column": 25, + "line": 1, + "column": 3, "program": "class_def_varargs_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -361,23 +409,71 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "class_def_varargs_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_1.ets" + } + } + }, "loc": { "start": { - "line": 18, - "column": 25, + "line": 1, + "column": 1, "program": "class_def_varargs_1.ets" }, "end": { - "line": 18, - "column": 28, + "line": 1, + "column": 3, "program": "class_def_varargs_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, @@ -894,40 +990,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_def_varargs_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_def_varargs_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_def_varargs_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_def_varargs_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/class_def_varargs_2-expected.txt b/ets2panda/test/compiler/ets/class_def_varargs_2-expected.txt index 51a9e78c64761f51901907fc31d806bfbe47f4f4..ca7e9c33a081c722340b3ba8dfe1aeaffbd13c5d 100644 --- a/ets2panda/test/compiler/ets/class_def_varargs_2-expected.txt +++ b/ets2panda/test/compiler/ets/class_def_varargs_2-expected.txt @@ -95,55 +95,103 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 28, - "program": "class_def_varargs_2.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "class_def_varargs_2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_2.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "class_def_varargs_2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_2.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "class_def_varargs_2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_2.ets" + } + } }, - "end": { - "line": 17, - "column": 34, - "program": "class_def_varargs_2.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "class_def_varargs_2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "class_def_varargs_2.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 28, + "line": 1, + "column": 3, "program": "class_def_varargs_2.ets" }, "end": { - "line": 17, - "column": 35, + "line": 1, + "column": 3, "program": "class_def_varargs_2.ets" } } }, "loc": { "start": { - "line": 17, - "column": 28, + "line": 1, + "column": 1, "program": "class_def_varargs_2.ets" }, "end": { - "line": 17, - "column": 35, + "line": 1, + "column": 3, "program": "class_def_varargs_2.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -290,40 +338,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_def_varargs_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_def_varargs_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_def_varargs_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_def_varargs_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt b/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt index 31ce9f044799f117ee6919626b27d7c23aaad18c..e77bd7128750c71b08404a0018d74de762fc921e 100644 --- a/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt +++ b/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "conversion-w-ASExpr.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/conversion_w_functions-expected.txt b/ets2panda/test/compiler/ets/conversion_w_functions-expected.txt index 17d8bd8d982914acfaec761193a4c51e40a4642c..af3444cb50f2d749ddc9c6836d7c16855a24c43c 100644 --- a/ets2panda/test/compiler/ets/conversion_w_functions-expected.txt +++ b/ets2panda/test/compiler/ets/conversion_w_functions-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "conversion_w_functions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "conversion_w_functions.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "conversion_w_functions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "conversion_w_functions.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/delete-non-keyword-expected.txt b/ets2panda/test/compiler/ets/delete-non-keyword-expected.txt index b20ce9188bb3037760d3a3842a116aaceaf1b391..61c9e3875264d92d500e8cd597187c9e40e7beb8 100644 --- a/ets2panda/test/compiler/ets/delete-non-keyword-expected.txt +++ b/ets2panda/test/compiler/ets/delete-non-keyword-expected.txt @@ -366,40 +366,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "delete-non-keyword.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "delete-non-keyword.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "delete-non-keyword.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "delete-non-keyword.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/dynamic-equality-expected.txt b/ets2panda/test/compiler/ets/dynamic-equality-expected.txt index eae396b7e665260d37f76523b52192eaec1f2e71..a50490cf321bbaa3f924e97e284df03298218982 100644 --- a/ets2panda/test/compiler/ets/dynamic-equality-expected.txt +++ b/ets2panda/test/compiler/ets/dynamic-equality-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic-equality.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic-equality.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic-equality.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic-equality.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1241,482 +1207,6 @@ "program": null } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/dynamicJsImport-expected.txt b/ets2panda/test/compiler/ets/dynamicJsImport-expected.txt index cbc3cf965f1d6ad71fa1846812872d5718f7a018..d9df1cf37b19192efc519cf326cf7c3f3a4d0b9c 100644 --- a/ets2panda/test/compiler/ets/dynamicJsImport-expected.txt +++ b/ets2panda/test/compiler/ets/dynamicJsImport-expected.txt @@ -187,40 +187,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicJsImport.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicJsImport.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicJsImport.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicJsImport.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -2692,704 +2658,6 @@ "program": null } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests1", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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 - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests1", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/dynamicLambda-expected.txt b/ets2panda/test/compiler/ets/dynamicLambda-expected.txt index 60f92592f2419a794b0dabaa206bf869602cc2ca..4ebad3eed1b1e6d366309baf1a14e6d1a729ea01 100644 --- a/ets2panda/test/compiler/ets/dynamicLambda-expected.txt +++ b/ets2panda/test/compiler/ets/dynamicLambda-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicLambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicLambda.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicLambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicLambda.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -2185,482 +2151,6 @@ "program": null } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt b/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt index 438ffaf4467281d74d5dff84b25b63e005e33479..31f9c613849da97a49afd18c4f25d81d42980d6a 100644 --- a/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt +++ b/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicLambdaJSValue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicLambdaJSValue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicLambdaJSValue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicLambdaJSValue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -2410,482 +2376,6 @@ "program": null } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/dynamicLambdaJSValueCast-expected.txt b/ets2panda/test/compiler/ets/dynamicLambdaJSValueCast-expected.txt index 8decab2d582437512b53e58b65bc9f63be47071f..bb11d9f297a225f819f5fb7e558aaa604e3651df 100644 --- a/ets2panda/test/compiler/ets/dynamicLambdaJSValueCast-expected.txt +++ b/ets2panda/test/compiler/ets/dynamicLambdaJSValueCast-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicLambdaJSValueCast.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicLambdaJSValueCast.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicLambdaJSValueCast.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicLambdaJSValueCast.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/dynamicObjectLiteral-expected.txt b/ets2panda/test/compiler/ets/dynamicObjectLiteral-expected.txt index 26d6681b1b90ee2066b023d953d263eb67cc4efe..1df9ddfce6c5ffa8fe7a1833e1dfd880624d3027 100644 --- a/ets2panda/test/compiler/ets/dynamicObjectLiteral-expected.txt +++ b/ets2panda/test/compiler/ets/dynamicObjectLiteral-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicObjectLiteral.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicObjectLiteral.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamicObjectLiteral.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamicObjectLiteral.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -664,482 +630,6 @@ "program": "dynamicObjectLiteral.ets" } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/dynamic_call-expected.txt b/ets2panda/test/compiler/ets/dynamic_call-expected.txt index 831001cfbcd5503519f2f27307019ef8f2e6a46f..17a0e7d88a1cda3e61122e33287232d1b99102e0 100644 --- a/ets2panda/test/compiler/ets/dynamic_call-expected.txt +++ b/ets2panda/test/compiler/ets/dynamic_call-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_call.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_call.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_call.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_call.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -2453,482 +2419,6 @@ "program": null } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt b/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt index 2af0bdd77c0bf1deed89aa56cbb416bb8ece4f0a..5c094ae9aa2f0b24bad7930904f0cc5fde20aacf 100644 --- a/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt +++ b/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_instanceof_error.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_instanceof_error.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_instanceof_error.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_instanceof_error.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -696,482 +662,6 @@ "program": "dynamic_instanceof_error.ets" } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { @@ -1187,4 +677,5 @@ } } } -TypeError: Bad operand type, the types of the operands must be same type. [dynamic_instanceof_error.ets:24:11] +TypeError: Using the 'instance of' operator with non-object type 'a' [dynamic_instanceof_error.ets:24:11] +TypeError: Right-hand side of instanceof expression must represent a type. [dynamic_instanceof_error.ets:24:11] diff --git a/ets2panda/test/compiler/ets/ensureNotNullArgNotNullable-expected.txt b/ets2panda/test/compiler/ets/ensureNotNullArgNotNullable-expected.txt index 8ed32227d7f266139928ef347e20f798b64f1990..e8bdf6bfde51035a3f77af216967798c353f8e79 100644 --- a/ets2panda/test/compiler/ets/ensureNotNullArgNotNullable-expected.txt +++ b/ets2panda/test/compiler/ets/ensureNotNullArgNotNullable-expected.txt @@ -134,40 +134,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ensureNotNullArgNotNullable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ensureNotNullArgNotNullable.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ensureNotNullArgNotNullable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ensureNotNullArgNotNullable.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/ensureNotNullLocalNotNullable-expected.txt b/ets2panda/test/compiler/ets/ensureNotNullLocalNotNullable-expected.txt index 050987b1b1c7ac2e98f7f8d1320ff35c9f04b544..6baa69fe8457d72ffb0602f2e2c2d03c511fef90 100644 --- a/ets2panda/test/compiler/ets/ensureNotNullLocalNotNullable-expected.txt +++ b/ets2panda/test/compiler/ets/ensureNotNullLocalNotNullable-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ensureNotNullLocalNotNullable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ensureNotNullLocalNotNullable.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ensureNotNullLocalNotNullable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ensureNotNullLocalNotNullable.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/ensureNotNullReturnNotNullable-expected.txt b/ets2panda/test/compiler/ets/ensureNotNullReturnNotNullable-expected.txt index 83978008cf2014052ba5f060ad8659e53cc2d5fc..28be07a026784a52f23bf9d94c78ac2550a905a9 100644 --- a/ets2panda/test/compiler/ets/ensureNotNullReturnNotNullable-expected.txt +++ b/ets2panda/test/compiler/ets/ensureNotNullReturnNotNullable-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ensureNotNullReturnNotNullable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ensureNotNullReturnNotNullable.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ensureNotNullReturnNotNullable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ensureNotNullReturnNotNullable.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt b/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt index 27cf62006c7a0cbf95cd16e4f005dc0b11253cc9..2fd33256389be81ecbd2e47ed733173af8fbc566 100644 --- a/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt +++ b/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt @@ -21,7 +21,85 @@ } } }, - "superClass": null, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "BaseEnum", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, "implements": [], "body": [ { @@ -280,11 +358,123 @@ "program": "enum_as_class_member_getValue_call.ets" } } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } } ], "body": { "type": "BlockStatement", "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Super", + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, { "type": "ExpressionStatement", "expression": { @@ -506,6 +696,22 @@ } }, "arguments": [ + { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, { "type": "NumberLiteral", "value": 0, @@ -673,6 +879,22 @@ } }, "arguments": [ + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, { "type": "NumberLiteral", "value": 1, @@ -840,6 +1062,22 @@ } }, "arguments": [ + { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, { "type": "NumberLiteral", "value": 2, @@ -4881,47 +5119,157 @@ "column": 1, "program": "enum_as_class_member_getValue_call.ets" }, - "end": { - "line": 20, - "column": 1, - "program": "enum_as_class_member_getValue_call.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "Shape", - "decorators": [], + "end": { + "line": 20, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Shape", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 6, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 11, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "BaseEnum", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, "loc": { "start": { "line": 26, - "column": 6, + "column": 1, "program": "enum_as_class_member_getValue_call.ets" }, "end": { "line": 26, - "column": 11, + "column": 1, "program": "enum_as_class_member_getValue_call.ets" } } }, - "superClass": null, "implements": [], "body": [ { @@ -5180,11 +5528,155 @@ "program": "enum_as_class_member_getValue_call.ets" } } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } } ], "body": { "type": "BlockStatement", "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Super", + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } + }, { "type": "ExpressionStatement", "expression": { @@ -5421,6 +5913,22 @@ "program": "enum_as_class_member_getValue_call.ets" } } + }, + { + "type": "StringLiteral", + "value": "CIRCLE", + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } } ], "loc": { @@ -5588,6 +6096,22 @@ "program": "enum_as_class_member_getValue_call.ets" } } + }, + { + "type": "StringLiteral", + "value": "SQUARE", + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } } ], "loc": { @@ -5755,6 +6279,22 @@ "program": "enum_as_class_member_getValue_call.ets" } } + }, + { + "type": "StringLiteral", + "value": "TRIANGLE", + "loc": { + "start": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + }, + "end": { + "line": 26, + "column": 1, + "program": "enum_as_class_member_getValue_call.ets" + } + } } ], "loc": { @@ -10842,40 +11382,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "enum_as_class_member_getValue_call.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "enum_as_class_member_getValue_call.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "enum_as_class_member_getValue_call.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "enum_as_class_member_getValue_call.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/export_type-expected.txt b/ets2panda/test/compiler/ets/export_type-expected.txt index dd4b65847e460442dfe0f901d024f92b7b0c28dd..cd258876a3e1531ab116b2b352f82777d9d20ef7 100644 --- a/ets2panda/test/compiler/ets/export_type-expected.txt +++ b/ets2panda/test/compiler/ets/export_type-expected.txt @@ -537,40 +537,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/extended_conditional_expression_not-expected.txt b/ets2panda/test/compiler/ets/extended_conditional_expression_not-expected.txt index b933c78d0c7dadf554251ea6a0bb5a7adb636d03..ff6a2de361487c19fab2cc41fdd454aa6ab41813 100644 --- a/ets2panda/test/compiler/ets/extended_conditional_expression_not-expected.txt +++ b/ets2panda/test/compiler/ets/extended_conditional_expression_not-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "extended_conditional_expression_not.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "extended_conditional_expression_not.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "extended_conditional_expression_not.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "extended_conditional_expression_not.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/extended_conditional_expression_not_return_type-expected.txt b/ets2panda/test/compiler/ets/extended_conditional_expression_not_return_type-expected.txt index a4ffdaad6c5782c305207e29c9fe4d15919b7af7..aa0afff24d0b8c18152a3ab60710afd85a728532 100644 --- a/ets2panda/test/compiler/ets/extended_conditional_expression_not_return_type-expected.txt +++ b/ets2panda/test/compiler/ets/extended_conditional_expression_not_return_type-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "extended_conditional_expression_not_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "extended_conditional_expression_not_return_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "extended_conditional_expression_not_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "extended_conditional_expression_not_return_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/forUpdate-expected.txt b/ets2panda/test/compiler/ets/forUpdate-expected.txt index 453ddd4f1956122ac019ed984d529c9dd6efa806..e5bcb79a17f15688badd6f4cb95927416abcbafb 100644 --- a/ets2panda/test/compiler/ets/forUpdate-expected.txt +++ b/ets2panda/test/compiler/ets/forUpdate-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "forUpdate.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "forUpdate.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "forUpdate.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "forUpdate.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/forUpdateCharType-expected.txt b/ets2panda/test/compiler/ets/forUpdateCharType-expected.txt index bc8512b02611dc771e26c553a68d0d0770964c77..6d585cce522fb584353a93175d42cf6590188323 100644 --- a/ets2panda/test/compiler/ets/forUpdateCharType-expected.txt +++ b/ets2panda/test/compiler/ets/forUpdateCharType-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "forUpdateCharType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "forUpdateCharType.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "forUpdateCharType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "forUpdateCharType.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/from-soft-keyword-0-expected.txt b/ets2panda/test/compiler/ets/from-soft-keyword-0-expected.txt index 6a9edc303fc9f0a2ff877ce11eb26bed4d40f5aa..04b2dfe4ae84adf737554a7b2d02be6b9095b02c 100644 --- a/ets2panda/test/compiler/ets/from-soft-keyword-0-expected.txt +++ b/ets2panda/test/compiler/ets/from-soft-keyword-0-expected.txt @@ -574,40 +574,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-0.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-0.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-0.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-0.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/from-soft-keyword-1-expected.txt b/ets2panda/test/compiler/ets/from-soft-keyword-1-expected.txt index 08494f9e6b8ed82554fc1e6f5e3721f6a1ad1466..a72b40f301d2138a28d5352eb245ba468073d2d1 100644 --- a/ets2panda/test/compiler/ets/from-soft-keyword-1-expected.txt +++ b/ets2panda/test/compiler/ets/from-soft-keyword-1-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/from-soft-keyword-2-expected.txt b/ets2panda/test/compiler/ets/from-soft-keyword-2-expected.txt index 7faf56eba1d23931fffd90318d2f7bace91b0be3..3e6e2e5a19dd453834a152c9800f5a80aaa76f66 100644 --- a/ets2panda/test/compiler/ets/from-soft-keyword-2-expected.txt +++ b/ets2panda/test/compiler/ets/from-soft-keyword-2-expected.txt @@ -291,40 +291,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "from-soft-keyword-2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/func-ref-private-expected.txt b/ets2panda/test/compiler/ets/func-ref-private-expected.txt index 84ee581d085e2ae7abc97379d7bacd29ffae2c2e..42e551d9da3d8670cb40dce850fd9549142ab580 100644 --- a/ets2panda/test/compiler/ets/func-ref-private-expected.txt +++ b/ets2panda/test/compiler/ets/func-ref-private-expected.txt @@ -538,40 +538,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "func-ref-private.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "func-ref-private.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "func-ref-private.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "func-ref-private.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/functionPointerArray-expected.txt b/ets2panda/test/compiler/ets/functionPointerArray-expected.txt index 32d0456f4f448f2033512621f4dda70f53769110..8d17c39ba76aca72fb2b084443f5d07f555b1f6d 100644 --- a/ets2panda/test/compiler/ets/functionPointerArray-expected.txt +++ b/ets2panda/test/compiler/ets/functionPointerArray-expected.txt @@ -86,40 +86,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functionPointerArray.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functionPointerArray.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functionPointerArray.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functionPointerArray.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -478,55 +444,103 @@ } ], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "func_type", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 37, - "program": "functionPointerArray.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "func_type", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } + } }, - "end": { - "line": 20, - "column": 46, - "program": "functionPointerArray.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } } } - }, + ], "loc": { "start": { - "line": 20, - "column": 37, + "line": 1, + "column": 3, "program": "functionPointerArray.ets" }, "end": { - "line": 20, - "column": 47, + "line": 1, + "column": 3, "program": "functionPointerArray.ets" } } }, "loc": { "start": { - "line": 20, - "column": 37, + "line": 1, + "column": 1, "program": "functionPointerArray.ets" }, "end": { - "line": 20, - "column": 47, + "line": 1, + "column": 3, "program": "functionPointerArray.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, @@ -723,55 +737,103 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "func_type", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 12, - "program": "functionPointerArray.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "func_type", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } + } }, - "end": { - "line": 25, - "column": 21, - "program": "functionPointerArray.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } } } - }, + ], "loc": { "start": { - "line": 25, - "column": 12, + "line": 1, + "column": 3, "program": "functionPointerArray.ets" }, "end": { - "line": 25, - "column": 22, + "line": 1, + "column": 3, "program": "functionPointerArray.ets" } } }, "loc": { "start": { - "line": 25, - "column": 12, + "line": 1, + "column": 1, "program": "functionPointerArray.ets" }, "end": { - "line": 25, - "column": 22, + "line": 1, + "column": 3, "program": "functionPointerArray.ets" } } }, - "annotations": [], "loc": { "start": { "line": 25, @@ -984,55 +1046,103 @@ "type": "Identifier", "name": "array", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "func_type", - "decorators": [], - "loc": { - "start": { - "line": 28, - "column": 14, - "program": "functionPointerArray.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "func_type", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } + } }, - "end": { - "line": 28, - "column": 23, - "program": "functionPointerArray.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functionPointerArray.ets" + } } } - }, + ], "loc": { "start": { - "line": 28, - "column": 14, + "line": 1, + "column": 3, "program": "functionPointerArray.ets" }, "end": { - "line": 28, - "column": 24, + "line": 1, + "column": 3, "program": "functionPointerArray.ets" } } }, "loc": { "start": { - "line": 28, - "column": 14, + "line": 1, + "column": 1, "program": "functionPointerArray.ets" }, "end": { - "line": 28, - "column": 24, + "line": 1, + "column": 3, "program": "functionPointerArray.ets" } } }, - "annotations": [], "loc": { "start": { "line": 28, diff --git a/ets2panda/test/compiler/ets/functionTypeToObject-expected.txt b/ets2panda/test/compiler/ets/functionTypeToObject-expected.txt index 4cc2d41a0891d408740a5ab4d2d0877949fcee2a..bb46138b3aef68fb94848508bbb1314c16e3a45b 100644 --- a/ets2panda/test/compiler/ets/functionTypeToObject-expected.txt +++ b/ets2panda/test/compiler/ets/functionTypeToObject-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functionTypeToObject.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functionTypeToObject.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functionTypeToObject.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functionTypeToObject.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/function_subtyping_1-expected.txt b/ets2panda/test/compiler/ets/function_subtyping_1-expected.txt index 6fa68d08ed6127fd3f54b7a70ac30194eb3cba30..6773ef4311ec9aaea7f37c88be2e8d596e8d63d3 100644 --- a/ets2panda/test/compiler/ets/function_subtyping_1-expected.txt +++ b/ets2panda/test/compiler/ets/function_subtyping_1-expected.txt @@ -379,40 +379,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_subtyping_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_subtyping_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_subtyping_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_subtyping_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/functions_with_ambiguous_rest_parameter-expected.txt b/ets2panda/test/compiler/ets/functions_with_ambiguous_rest_parameter-expected.txt index eb423dcd90cdedeee3a2596e9369578f8f6e7ed2..74d45b5f1b321a4f27da1dc122b113efe013422a 100644 --- a/ets2panda/test/compiler/ets/functions_with_ambiguous_rest_parameter-expected.txt +++ b/ets2panda/test/compiler/ets/functions_with_ambiguous_rest_parameter-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functions_with_ambiguous_rest_parameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functions_with_ambiguous_rest_parameter.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functions_with_ambiguous_rest_parameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functions_with_ambiguous_rest_parameter.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -235,55 +201,103 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "number", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 20, - "program": "functions_with_ambiguous_rest_parameter.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "functions_with_ambiguous_rest_parameter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + } + } }, - "end": { - "line": 16, - "column": 26, - "program": "functions_with_ambiguous_rest_parameter.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + } } } - }, + ], "loc": { "start": { - "line": 16, - "column": 20, + "line": 1, + "column": 3, "program": "functions_with_ambiguous_rest_parameter.ets" }, "end": { - "line": 16, - "column": 27, + "line": 1, + "column": 3, "program": "functions_with_ambiguous_rest_parameter.ets" } } }, "loc": { "start": { - "line": 16, - "column": 20, + "line": 1, + "column": 1, "program": "functions_with_ambiguous_rest_parameter.ets" }, "end": { - "line": 16, - "column": 27, + "line": 1, + "column": 3, "program": "functions_with_ambiguous_rest_parameter.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -453,55 +467,103 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 20, - "program": "functions_with_ambiguous_rest_parameter.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "functions_with_ambiguous_rest_parameter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + } + } }, - "end": { - "line": 20, - "column": 26, - "program": "functions_with_ambiguous_rest_parameter.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "functions_with_ambiguous_rest_parameter.ets" + } } } - }, + ], "loc": { "start": { - "line": 20, - "column": 20, + "line": 1, + "column": 3, "program": "functions_with_ambiguous_rest_parameter.ets" }, "end": { - "line": 20, - "column": 27, + "line": 1, + "column": 3, "program": "functions_with_ambiguous_rest_parameter.ets" } } }, "loc": { "start": { - "line": 20, - "column": 20, + "line": 1, + "column": 1, "program": "functions_with_ambiguous_rest_parameter.ets" }, "end": { - "line": 20, - "column": 27, + "line": 1, + "column": 3, "program": "functions_with_ambiguous_rest_parameter.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, @@ -841,5 +903,6 @@ } } } +TypeError: Function foo with this assembly signature already declared. [functions_with_ambiguous_rest_parameter.ets:20:1] TypeError: Call to `foo` is ambiguous [functions_with_ambiguous_rest_parameter.ets:25:5] TypeError: Reference to foo is ambiguous [functions_with_ambiguous_rest_parameter.ets:25:5] diff --git a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt index c9373edffea15b5eaf93d0db4790a2b9c56ddb0e..8e5a6dcacbd8dfc13960654f74a634da669383bd 100644 --- a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt +++ b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt @@ -7794,11 +7794,45 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { + "type": "TSAsExpression", + "expression": { "type": "MemberExpression", "object": { - "type": "ThisExpression", + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 82, + "column": 59, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 82, + "column": 63, + "program": "generic_arrayaslist.ets" + } + } + }, + "property": { + "type": "Identifier", + "name": "data", + "decorators": [], + "loc": { + "start": { + "line": 82, + "column": 64, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 82, + "column": 68, + "program": "generic_arrayaslist.ets" + } + } + }, + "computed": false, + "optional": false, "loc": { "start": { "line": 82, @@ -7807,24 +7841,24 @@ }, "end": { "line": 82, - "column": 63, + "column": 68, "program": "generic_arrayaslist.ets" } } }, "property": { "type": "Identifier", - "name": "data", + "name": "length", "decorators": [], "loc": { "start": { "line": 82, - "column": 64, + "column": 69, "program": "generic_arrayaslist.ets" }, "end": { "line": 82, - "column": 68, + "column": 75, "program": "generic_arrayaslist.ets" } } @@ -7839,30 +7873,26 @@ }, "end": { "line": 82, - "column": 68, + "column": 75, "program": "generic_arrayaslist.ets" } } }, - "property": { - "type": "Identifier", - "name": "length", - "decorators": [], + "typeAnnotation": { + "type": "ETSPrimitiveType", "loc": { "start": { "line": 82, - "column": 69, + "column": 79, "program": "generic_arrayaslist.ets" }, "end": { "line": 82, - "column": 75, + "column": 82, "program": "generic_arrayaslist.ets" } } }, - "computed": false, - "optional": false, "loc": { "start": { "line": 82, @@ -7886,7 +7916,7 @@ }, "end": { "line": 82, - "column": 76, + "column": 83, "program": "generic_arrayaslist.ets" } } @@ -7899,7 +7929,7 @@ }, "end": { "line": 82, - "column": 77, + "column": 84, "program": "generic_arrayaslist.ets" } } @@ -7912,7 +7942,7 @@ }, "end": { "line": 82, - "column": 77, + "column": 84, "program": "generic_arrayaslist.ets" } } @@ -7925,7 +7955,7 @@ }, "end": { "line": 82, - "column": 78, + "column": 85, "program": "generic_arrayaslist.ets" } } @@ -10270,11 +10300,45 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { + "type": "TSAsExpression", + "expression": { "type": "MemberExpression", "object": { - "type": "ThisExpression", + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 104, + "column": 67, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 104, + "column": 71, + "program": "generic_arrayaslist.ets" + } + } + }, + "property": { + "type": "Identifier", + "name": "data", + "decorators": [], + "loc": { + "start": { + "line": 104, + "column": 72, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 104, + "column": 76, + "program": "generic_arrayaslist.ets" + } + } + }, + "computed": false, + "optional": false, "loc": { "start": { "line": 104, @@ -10283,24 +10347,24 @@ }, "end": { "line": 104, - "column": 71, + "column": 76, "program": "generic_arrayaslist.ets" } } }, "property": { "type": "Identifier", - "name": "data", + "name": "length", "decorators": [], "loc": { "start": { "line": 104, - "column": 72, + "column": 77, "program": "generic_arrayaslist.ets" }, "end": { "line": 104, - "column": 76, + "column": 83, "program": "generic_arrayaslist.ets" } } @@ -10315,30 +10379,26 @@ }, "end": { "line": 104, - "column": 76, + "column": 83, "program": "generic_arrayaslist.ets" } } }, - "property": { - "type": "Identifier", - "name": "length", - "decorators": [], + "typeAnnotation": { + "type": "ETSPrimitiveType", "loc": { "start": { "line": 104, - "column": 77, + "column": 87, "program": "generic_arrayaslist.ets" }, "end": { "line": 104, - "column": 83, + "column": 90, "program": "generic_arrayaslist.ets" } } }, - "computed": false, - "optional": false, "loc": { "start": { "line": 104, @@ -10362,7 +10422,7 @@ }, "end": { "line": 104, - "column": 84, + "column": 91, "program": "generic_arrayaslist.ets" } } @@ -10375,7 +10435,7 @@ }, "end": { "line": 104, - "column": 85, + "column": 92, "program": "generic_arrayaslist.ets" } } @@ -10388,7 +10448,7 @@ }, "end": { "line": 104, - "column": 85, + "column": 92, "program": "generic_arrayaslist.ets" } } @@ -10403,7 +10463,7 @@ }, "end": { "line": 104, - "column": 86, + "column": 93, "program": "generic_arrayaslist.ets" } } @@ -20504,87 +20564,135 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 203, - "column": 28, - "program": "generic_arrayaslist.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } }, - "end": { - "line": 203, - "column": 29, - "program": "generic_arrayaslist.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + { + "type": "ETSUndefinedType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } } } - }, + ], "loc": { "start": { - "line": 203, - "column": 28, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" }, "end": { - "line": 203, - "column": 31, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" } } - }, - "loc": { - "start": { - "line": 203, - "column": 28, - "program": "generic_arrayaslist.ets" - }, - "end": { - "line": 203, - "column": 31, - "program": "generic_arrayaslist.ets" - } } - }, - { - "type": "ETSUndefinedType", - "loc": { - "start": { - "line": 203, - "column": 32, - "program": "generic_arrayaslist.ets" - }, - "end": { - "line": 203, - "column": 41, - "program": "generic_arrayaslist.ets" - } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" } } - ], + }, "loc": { "start": { - "line": 203, - "column": 27, + "line": 1, + "column": 1, "program": "generic_arrayaslist.ets" }, "end": { - "line": 203, - "column": 41, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" } } }, - "annotations": [], "loc": { "start": { "line": 203, @@ -21069,55 +21177,103 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 207, - "column": 35, - "program": "generic_arrayaslist.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } }, - "end": { - "line": 207, - "column": 36, - "program": "generic_arrayaslist.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } } } - }, + ], "loc": { "start": { - "line": 207, - "column": 35, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" }, "end": { - "line": 207, - "column": 37, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" } } }, "loc": { "start": { - "line": 207, - "column": 35, + "line": 1, + "column": 1, "program": "generic_arrayaslist.ets" }, "end": { - "line": 207, - "column": 37, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" } } }, - "annotations": [], "loc": { "start": { "line": 207, @@ -23064,55 +23220,103 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 225, - "column": 36, - "program": "generic_arrayaslist.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } }, - "end": { - "line": 225, - "column": 37, - "program": "generic_arrayaslist.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } } } - }, + ], "loc": { "start": { - "line": 225, - "column": 36, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" }, "end": { - "line": 225, - "column": 38, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" } } }, "loc": { "start": { - "line": 225, - "column": 36, + "line": 1, + "column": 1, "program": "generic_arrayaslist.ets" }, "end": { - "line": 225, - "column": 38, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" } } }, - "annotations": [], "loc": { "start": { "line": 225, @@ -24583,87 +24787,135 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 238, - "column": 20, - "program": "generic_arrayaslist.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } }, - "end": { - "line": 238, - "column": 21, - "program": "generic_arrayaslist.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } + } + }, + { + "type": "ETSUndefinedType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + } } } - }, + ], "loc": { "start": { - "line": 238, - "column": 20, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" }, "end": { - "line": 238, - "column": 23, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" } } - }, - "loc": { - "start": { - "line": 238, - "column": 20, - "program": "generic_arrayaslist.ets" - }, - "end": { - "line": 238, - "column": 23, - "program": "generic_arrayaslist.ets" - } } - }, - { - "type": "ETSUndefinedType", - "loc": { - "start": { - "line": 238, - "column": 24, - "program": "generic_arrayaslist.ets" - }, - "end": { - "line": 238, - "column": 33, - "program": "generic_arrayaslist.ets" - } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_arrayaslist.ets" } } - ], + }, "loc": { "start": { - "line": 238, - "column": 19, + "line": 1, + "column": 1, "program": "generic_arrayaslist.ets" }, "end": { - "line": 238, - "column": 33, + "line": 1, + "column": 3, "program": "generic_arrayaslist.ets" } } }, - "annotations": [], "loc": { "start": { "line": 238, @@ -24796,40 +25048,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_arrayaslist.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_arrayaslist.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_arrayaslist.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_arrayaslist.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_arrayaslist.ets b/ets2panda/test/compiler/ets/generic_arrayaslist.ets index 10d0a9d119cb0848f1f5608fb605319cb91c4692..22de891fc37989db27984bc51878bd6d951c1610 100644 --- a/ets2panda/test/compiler/ets/generic_arrayaslist.ets +++ b/ets2panda/test/compiler/ets/generic_arrayaslist.ets @@ -79,7 +79,7 @@ class ArrayAsListt implements Listt { public override pushFront(e: T): void { let dst = this.data; if (this.curSize == this.data.length) { - dst = new (T | undefined)[this.getNewCapacity(this.data.length)]; + dst = new (T | undefined)[this.getNewCapacity(this.data.length as int)]; } for (let i = this.curSize; i != 0; --i) { dst[i] = this.data[i-1]; @@ -101,7 +101,7 @@ class ArrayAsListt implements Listt { public override pushBack(e: T): void { if (this.curSize == this.data.length) { - let newData = new (T | undefined)[this.getNewCapacity(this.data.length)]; + let newData = new (T | undefined)[this.getNewCapacity(this.data.length as int)]; for (let i = 0; i < this.curSize; ++i) { newData[i] = this.data[i]; } diff --git a/ets2panda/test/compiler/ets/generic_class_getter_setter-expected.txt b/ets2panda/test/compiler/ets/generic_class_getter_setter-expected.txt index 3a3def4877b4260cb3f3df2476763db00cdc67f9..fb6cf3a2db824837cc46cf3c598825bef0b63297 100644 --- a/ets2panda/test/compiler/ets/generic_class_getter_setter-expected.txt +++ b/ets2panda/test/compiler/ets/generic_class_getter_setter-expected.txt @@ -599,40 +599,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_class_getter_setter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_class_getter_setter.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_class_getter_setter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_class_getter_setter.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_deadlock-expected.txt b/ets2panda/test/compiler/ets/generic_deadlock-expected.txt index 3d4363a3ed241f78b0e26b0292ca6db5235c696b..8892d6af0dc83981a49a68f1e8fc9270fdeef49b 100644 --- a/ets2panda/test/compiler/ets/generic_deadlock-expected.txt +++ b/ets2panda/test/compiler/ets/generic_deadlock-expected.txt @@ -878,40 +878,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_deadlock.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_deadlock.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_deadlock.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_deadlock.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_func_rest_param_spread_infer-expected.txt b/ets2panda/test/compiler/ets/generic_func_rest_param_spread_infer-expected.txt index d6db2d6b93e3644132504b46828278d6d39f1940..d5764ab4a6bb10db6c0d6b0aca2b7292e0c86326 100644 --- a/ets2panda/test/compiler/ets/generic_func_rest_param_spread_infer-expected.txt +++ b/ets2panda/test/compiler/ets/generic_func_rest_param_spread_infer-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_func_rest_param_spread_infer.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_func_rest_param_spread_infer.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_func_rest_param_spread_infer.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_func_rest_param_spread_infer.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -362,55 +328,103 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 42, - "program": "generic_func_rest_param_spread_infer.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } + } }, - "end": { - "line": 17, - "column": 45, - "program": "generic_func_rest_param_spread_infer.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 42, + "line": 1, + "column": 3, "program": "generic_func_rest_param_spread_infer.ets" }, "end": { - "line": 17, - "column": 46, + "line": 1, + "column": 3, "program": "generic_func_rest_param_spread_infer.ets" } } }, "loc": { "start": { - "line": 17, - "column": 42, + "line": 1, + "column": 1, "program": "generic_func_rest_param_spread_infer.ets" }, "end": { - "line": 17, - "column": 46, + "line": 1, + "column": 3, "program": "generic_func_rest_param_spread_infer.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -639,55 +653,103 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Double", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 42, - "program": "generic_func_rest_param_spread_infer.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } + } }, - "end": { - "line": 18, - "column": 48, - "program": "generic_func_rest_param_spread_infer.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } } } - }, + ], "loc": { "start": { - "line": 18, - "column": 42, + "line": 1, + "column": 3, "program": "generic_func_rest_param_spread_infer.ets" }, "end": { - "line": 18, - "column": 49, + "line": 1, + "column": 3, "program": "generic_func_rest_param_spread_infer.ets" } } }, "loc": { "start": { - "line": 18, - "column": 42, + "line": 1, + "column": 1, "program": "generic_func_rest_param_spread_infer.ets" }, "end": { - "line": 18, - "column": 49, + "line": 1, + "column": 3, "program": "generic_func_rest_param_spread_infer.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, @@ -916,55 +978,103 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 42, - "program": "generic_func_rest_param_spread_infer.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } + } }, - "end": { - "line": 19, - "column": 48, - "program": "generic_func_rest_param_spread_infer.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generic_func_rest_param_spread_infer.ets" + } } } - }, + ], "loc": { "start": { - "line": 19, - "column": 42, + "line": 1, + "column": 3, "program": "generic_func_rest_param_spread_infer.ets" }, "end": { - "line": 19, - "column": 49, + "line": 1, + "column": 3, "program": "generic_func_rest_param_spread_infer.ets" } } }, "loc": { "start": { - "line": 19, - "column": 42, + "line": 1, + "column": 1, "program": "generic_func_rest_param_spread_infer.ets" }, "end": { - "line": 19, - "column": 49, + "line": 1, + "column": 3, "program": "generic_func_rest_param_spread_infer.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, diff --git a/ets2panda/test/compiler/ets/generic_function_call_1-expected.txt b/ets2panda/test/compiler/ets/generic_function_call_1-expected.txt index 18b8344f9c652601c72ed92fba1d6b41b0e52e60..103caf2507089853ef61c20e174c0fcb560286fd 100644 --- a/ets2panda/test/compiler/ets/generic_function_call_1-expected.txt +++ b/ets2panda/test/compiler/ets/generic_function_call_1-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_function_call_3-expected.txt b/ets2panda/test/compiler/ets/generic_function_call_3-expected.txt index 74307327e2b1e26ec4b42f134bc13b4567ae7cef..38a6336d530433f4c4c03e9f3ecf0368e45e5ff7 100644 --- a/ets2panda/test/compiler/ets/generic_function_call_3-expected.txt +++ b/ets2panda/test/compiler/ets/generic_function_call_3-expected.txt @@ -379,40 +379,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_function_call_4-expected.txt b/ets2panda/test/compiler/ets/generic_function_call_4-expected.txt index 1b7ce0eddb5f3c36819257204d2bba4398e76b5a..59b93fd89368498428e371e5a363b0ee8d976391 100644 --- a/ets2panda/test/compiler/ets/generic_function_call_4-expected.txt +++ b/ets2panda/test/compiler/ets/generic_function_call_4-expected.txt @@ -382,40 +382,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_function_call_5-expected.txt b/ets2panda/test/compiler/ets/generic_function_call_5-expected.txt index 9b2c40df243d4d45e5632adc2817afc70686dc7e..419f8fd9d558759b4bb3ffbef840088860b5fac2 100644 --- a/ets2panda/test/compiler/ets/generic_function_call_5-expected.txt +++ b/ets2panda/test/compiler/ets/generic_function_call_5-expected.txt @@ -587,40 +587,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_function_call_7-expected.txt b/ets2panda/test/compiler/ets/generic_function_call_7-expected.txt index f172839f1ba7738e40837a305a40cdba7e220ff4..f9f6b3bff3547383654c31febd5e89f5771961ea 100644 --- a/ets2panda/test/compiler/ets/generic_function_call_7-expected.txt +++ b/ets2panda/test/compiler/ets/generic_function_call_7-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function_call_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function_call_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_override_1-expected.txt b/ets2panda/test/compiler/ets/generic_override_1-expected.txt index b3df20b763223eec34b0011ee6de0e33361551cd..4a34e9a646b7bc3bcbaf60b9208a807be49f381b 100644 --- a/ets2panda/test/compiler/ets/generic_override_1-expected.txt +++ b/ets2panda/test/compiler/ets/generic_override_1-expected.txt @@ -931,6 +931,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "generic_override_1.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "generic_override_1.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "generic_override_1.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "generic_override_1.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "generic_override_1.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "generic_override_1.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "generic_override_1.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "generic_override_1.ets" + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "generic_override_1.ets" + } + } + } + ], "loc": { "start": { "line": 21, @@ -1856,6 +2008,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 29, + "column": 6, + "program": "generic_override_1.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 29, + "column": 6, + "program": "generic_override_1.ets" + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 29, + "column": 6, + "program": "generic_override_1.ets" + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 29, + "column": 6, + "program": "generic_override_1.ets" + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 29, + "column": 6, + "program": "generic_override_1.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 29, + "column": 6, + "program": "generic_override_1.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 27, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 29, + "column": 6, + "program": "generic_override_1.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 29, + "column": 6, + "program": "generic_override_1.ets" + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 8, + "program": "generic_override_1.ets" + }, + "end": { + "line": 29, + "column": 6, + "program": "generic_override_1.ets" + } + } + } + ], "loc": { "start": { "line": 27, @@ -2051,40 +2355,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_override_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_override_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_override_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_override_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_override_2-expected.txt b/ets2panda/test/compiler/ets/generic_override_2-expected.txt index bfea00998e002d61c04ce8e6f0ffaf22499b6359..c2dbfd36a3dadcf15ce403e3d5a15f3051f18044 100644 --- a/ets2panda/test/compiler/ets/generic_override_2-expected.txt +++ b/ets2panda/test/compiler/ets/generic_override_2-expected.txt @@ -967,6 +967,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 18, + "column": 75, + "program": "generic_override_2.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 18, + "column": 75, + "program": "generic_override_2.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 18, + "column": 75, + "program": "generic_override_2.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 18, + "column": 75, + "program": "generic_override_2.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 18, + "column": 75, + "program": "generic_override_2.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 18, + "column": 75, + "program": "generic_override_2.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 18, + "column": 75, + "program": "generic_override_2.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 18, + "column": 75, + "program": "generic_override_2.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 18, + "column": 75, + "program": "generic_override_2.ets" + } + } + } + ], "loc": { "start": { "line": 17, @@ -2485,6 +2637,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "generic_override_2.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "generic_override_2.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "generic_override_2.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "generic_override_2.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "generic_override_2.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "generic_override_2.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 22, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "generic_override_2.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "generic_override_2.ets" + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 9, + "program": "generic_override_2.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "generic_override_2.ets" + } + } + } + ], "loc": { "start": { "line": 22, @@ -2680,40 +2984,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_override_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_override_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_override_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_override_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_override_3-expected.txt b/ets2panda/test/compiler/ets/generic_override_3-expected.txt index 6cfc4ea0e71f2aa3ed988214a790de9262627a0c..2d4cfb7f0bb1741d961793bb15a369fa00390f24 100644 --- a/ets2panda/test/compiler/ets/generic_override_3-expected.txt +++ b/ets2panda/test/compiler/ets/generic_override_3-expected.txt @@ -1081,6 +1081,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_3.ets" + }, + "end": { + "line": 21, + "column": 37, + "program": "generic_override_3.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_3.ets" + }, + "end": { + "line": 21, + "column": 37, + "program": "generic_override_3.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_3.ets" + }, + "end": { + "line": 21, + "column": 37, + "program": "generic_override_3.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_3.ets" + }, + "end": { + "line": 21, + "column": 37, + "program": "generic_override_3.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_3.ets" + }, + "end": { + "line": 21, + "column": 37, + "program": "generic_override_3.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_3.ets" + }, + "end": { + "line": 21, + "column": 37, + "program": "generic_override_3.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_3.ets" + }, + "end": { + "line": 21, + "column": 37, + "program": "generic_override_3.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_3.ets" + }, + "end": { + "line": 21, + "column": 37, + "program": "generic_override_3.ets" + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 8, + "program": "generic_override_3.ets" + }, + "end": { + "line": 21, + "column": 37, + "program": "generic_override_3.ets" + } + } + } + ], "loc": { "start": { "line": 21, @@ -1765,6 +1917,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 24, + "program": "generic_override_3.ets" + }, + "end": { + "line": 27, + "column": 6, + "program": "generic_override_3.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 24, + "program": "generic_override_3.ets" + }, + "end": { + "line": 27, + "column": 6, + "program": "generic_override_3.ets" + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 24, + "program": "generic_override_3.ets" + }, + "end": { + "line": 27, + "column": 6, + "program": "generic_override_3.ets" + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 24, + "program": "generic_override_3.ets" + }, + "end": { + "line": 27, + "column": 6, + "program": "generic_override_3.ets" + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 24, + "program": "generic_override_3.ets" + }, + "end": { + "line": 27, + "column": 6, + "program": "generic_override_3.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 24, + "program": "generic_override_3.ets" + }, + "end": { + "line": 27, + "column": 6, + "program": "generic_override_3.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 25, + "column": 24, + "program": "generic_override_3.ets" + }, + "end": { + "line": 27, + "column": 6, + "program": "generic_override_3.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 24, + "program": "generic_override_3.ets" + }, + "end": { + "line": 27, + "column": 6, + "program": "generic_override_3.ets" + } + } + } + ], + "loc": { + "start": { + "line": 25, + "column": 24, + "program": "generic_override_3.ets" + }, + "end": { + "line": 27, + "column": 6, + "program": "generic_override_3.ets" + } + } + } + ], "loc": { "start": { "line": 25, @@ -1960,40 +2264,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_override_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_override_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_override_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_override_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_typealias_1-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_1-expected.txt index c7de946078c481ea64574c1d4feb65c27b2ec34f..bb55e4fe01345a08908aa41fbba6b4bd8dc8b77d 100644 --- a/ets2panda/test/compiler/ets/generic_typealias_1-expected.txt +++ b/ets2panda/test/compiler/ets/generic_typealias_1-expected.txt @@ -626,40 +626,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_typealias_6-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_6-expected.txt index cc6a6cfb0b03a7353df411f6193421293c8a89a8..b48772350b801c100c30950b51ead16f1cc9ad21 100644 --- a/ets2panda/test/compiler/ets/generic_typealias_6-expected.txt +++ b/ets2panda/test/compiler/ets/generic_typealias_6-expected.txt @@ -530,40 +530,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_typealias_7_neg-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_7_neg-expected.txt index e5345a409f4385457bf6703c613fb7526669e4d5..8f6727aa4f0ec60a0356a3efae720a3b9b2fe29b 100644 --- a/ets2panda/test/compiler/ets/generic_typealias_7_neg-expected.txt +++ b/ets2panda/test/compiler/ets/generic_typealias_7_neg-expected.txt @@ -151,40 +151,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_7_neg.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_7_neg.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_7_neg.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_7_neg.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_typealias_8-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_8-expected.txt index 2adc2e12dc7050ce4733f16889f670839f73fcdd..fc2c7877a256c456f6fbbf7f209e01e0067d32f1 100644 --- a/ets2panda/test/compiler/ets/generic_typealias_8-expected.txt +++ b/ets2panda/test/compiler/ets/generic_typealias_8-expected.txt @@ -306,40 +306,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_typealias_9-expected.txt b/ets2panda/test/compiler/ets/generic_typealias_9-expected.txt index 5c784109bfb0afcd764ea9543097c6cb3221439a..ee67f2d5ef702513708da7a90a46236a8defacc7 100644 --- a/ets2panda/test/compiler/ets/generic_typealias_9-expected.txt +++ b/ets2panda/test/compiler/ets/generic_typealias_9-expected.txt @@ -215,40 +215,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generic_variance_1-expected.txt b/ets2panda/test/compiler/ets/generic_variance_1-expected.txt index 042329e59a998c9c35509838b8b3fd7e0c3f4d81..3fd3bc29062df9caf27e1dee04d8885976325c83 100644 --- a/ets2panda/test/compiler/ets/generic_variance_1-expected.txt +++ b/ets2panda/test/compiler/ets/generic_variance_1-expected.txt @@ -789,40 +789,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_variance_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_variance_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_variance_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_variance_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generics_class_recursive_type_1-expected.txt b/ets2panda/test/compiler/ets/generics_class_recursive_type_1-expected.txt index f9625fdaa457c98be9f56785dab87be047aed720..15455cf8ca3a66ec726b01b84b5859c47cdc9f31 100644 --- a/ets2panda/test/compiler/ets/generics_class_recursive_type_1-expected.txt +++ b/ets2panda/test/compiler/ets/generics_class_recursive_type_1-expected.txt @@ -8269,40 +8269,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_class_recursive_type_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_class_recursive_type_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_class_recursive_type_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_class_recursive_type_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generics_implicit_lambda1-expected.txt b/ets2panda/test/compiler/ets/generics_implicit_lambda1-expected.txt index 26630d53332437d0df4efac55262d633cb904a70..8aad3e19bf3e72714e3b52cf498805bfd6b5669b 100644 --- a/ets2panda/test/compiler/ets/generics_implicit_lambda1-expected.txt +++ b/ets2panda/test/compiler/ets/generics_implicit_lambda1-expected.txt @@ -1232,40 +1232,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_implicit_lambda1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_implicit_lambda1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_implicit_lambda1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_implicit_lambda1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generics_instantiation_1-expected.txt b/ets2panda/test/compiler/ets/generics_instantiation_1-expected.txt index 1d82b43d1e0c6faec769f0f4c94c5b32716fd850..311c0e2a9d56553cf7dc99b152f98d23e840a1fe 100644 --- a/ets2panda/test/compiler/ets/generics_instantiation_1-expected.txt +++ b/ets2panda/test/compiler/ets/generics_instantiation_1-expected.txt @@ -2307,40 +2307,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_instantiation_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_instantiation_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_instantiation_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_instantiation_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generics_instantiation_2-expected.txt b/ets2panda/test/compiler/ets/generics_instantiation_2-expected.txt index 85e5c1fe1bbf904eaa7b0253444f8eca52d0b14f..43a0768251ec5f45409d249804efe7287e0a2708 100644 --- a/ets2panda/test/compiler/ets/generics_instantiation_2-expected.txt +++ b/ets2panda/test/compiler/ets/generics_instantiation_2-expected.txt @@ -1410,40 +1410,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_instantiation_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_instantiation_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_instantiation_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_instantiation_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt b/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt index f711954b5a59ed0dd916f1c903f2c4bc28ab6e97..ce99ae1ff27a9000c342fb881a35c2bebee9251a 100644 --- a/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt +++ b/ets2panda/test/compiler/ets/generics_instantiation_3-expected.txt @@ -494,55 +494,103 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 19, - "program": "generics_instantiation_3.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "generics_instantiation_3.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generics_instantiation_3.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generics_instantiation_3.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generics_instantiation_3.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generics_instantiation_3.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generics_instantiation_3.ets" + } + } }, - "end": { - "line": 21, - "column": 20, - "program": "generics_instantiation_3.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "generics_instantiation_3.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "generics_instantiation_3.ets" + } } } - }, + ], "loc": { "start": { - "line": 21, - "column": 19, + "line": 1, + "column": 3, "program": "generics_instantiation_3.ets" }, "end": { - "line": 21, - "column": 21, + "line": 1, + "column": 3, "program": "generics_instantiation_3.ets" } } }, "loc": { "start": { - "line": 21, - "column": 19, + "line": 1, + "column": 1, "program": "generics_instantiation_3.ets" }, "end": { - "line": 21, - "column": 21, + "line": 1, + "column": 3, "program": "generics_instantiation_3.ets" } } }, - "annotations": [], "loc": { "start": { "line": 21, @@ -725,40 +773,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_instantiation_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_instantiation_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_instantiation_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_instantiation_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generics_instantiation_4-expected.txt b/ets2panda/test/compiler/ets/generics_instantiation_4-expected.txt index 3faeaa5a0b72956c7f09ef52355cba3016d94e4c..88921ffe6d040f8f9b9c92d22333bfcdc9e0a691 100644 --- a/ets2panda/test/compiler/ets/generics_instantiation_4-expected.txt +++ b/ets2panda/test/compiler/ets/generics_instantiation_4-expected.txt @@ -2447,40 +2447,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_instantiation_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_instantiation_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_instantiation_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_instantiation_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generics_interface_bounds_1-expected.txt b/ets2panda/test/compiler/ets/generics_interface_bounds_1-expected.txt index 2422bd8e30d025115e27a7f4f4ccd1fa769c4fc0..41648a6b9e24645cbde4e60aca46485d484e0a15 100644 --- a/ets2panda/test/compiler/ets/generics_interface_bounds_1-expected.txt +++ b/ets2panda/test/compiler/ets/generics_interface_bounds_1-expected.txt @@ -1156,40 +1156,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_interface_bounds_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_interface_bounds_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_interface_bounds_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_interface_bounds_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generics_interface_bounds_2-expected.txt b/ets2panda/test/compiler/ets/generics_interface_bounds_2-expected.txt index beaa2a0730e5332dbd48d37a5df3a56d31f3b5b8..07b6fb741b91cd4a0c0daa8ee12b2a3c95168db5 100644 --- a/ets2panda/test/compiler/ets/generics_interface_bounds_2-expected.txt +++ b/ets2panda/test/compiler/ets/generics_interface_bounds_2-expected.txt @@ -328,40 +328,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_interface_bounds_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_interface_bounds_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_interface_bounds_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_interface_bounds_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/generics_primitive_type_param_1-expected.txt b/ets2panda/test/compiler/ets/generics_primitive_type_param_1-expected.txt index 3247972ed2d761fd8c54ae695bd7ce9c067d428d..bb1de932281d64c5fe80f789a8cf9218fbac4cc8 100644 --- a/ets2panda/test/compiler/ets/generics_primitive_type_param_1-expected.txt +++ b/ets2panda/test/compiler/ets/generics_primitive_type_param_1-expected.txt @@ -385,40 +385,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_primitive_type_param_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_primitive_type_param_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_primitive_type_param_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_primitive_type_param_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/identifierReference14-expected.txt b/ets2panda/test/compiler/ets/identifierReference14-expected.txt index 10f8607c4bbf484f3d2f1b6b9bcd85fc99e4ca96..f0b7ebecc135a3b17db9ced81509ef269440d583 100644 --- a/ets2panda/test/compiler/ets/identifierReference14-expected.txt +++ b/ets2panda/test/compiler/ets/identifierReference14-expected.txt @@ -904,40 +904,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "identifierReference14.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "identifierReference14.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "identifierReference14.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "identifierReference14.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/identifierReference4-expected.txt b/ets2panda/test/compiler/ets/identifierReference4-expected.txt index f492e8eb7899cdbb0d782412b61afd1eea97866e..5ca765a6cc06095881c2de9b8c1268ee7e820555 100644 --- a/ets2panda/test/compiler/ets/identifierReference4-expected.txt +++ b/ets2panda/test/compiler/ets/identifierReference4-expected.txt @@ -668,40 +668,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "identifierReference4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "identifierReference4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "identifierReference4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "identifierReference4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/implicit-conversion-expected.txt b/ets2panda/test/compiler/ets/implicit-conversion-expected.txt index c33545e1f5b0aa5db0bc431aa62c691c17d952c0..9c26969875912c82348538395eb802f53cc679b7 100644 --- a/ets2panda/test/compiler/ets/implicit-conversion-expected.txt +++ b/ets2panda/test/compiler/ets/implicit-conversion-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "implicit-conversion.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "implicit-conversion.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "implicit-conversion.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "implicit-conversion.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/package_module_1-expected.txt b/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/package_module_1-expected.txt index 6286bb82d80cc8ecbbe4798b4cf67125ab18e23c..221888de539e7cce685efb1d7a145f9c4b6f1244 100644 --- a/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/package_module_1-expected.txt +++ b/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/package_module_1-expected.txt @@ -395,40 +395,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/package_module_2-expected.txt b/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/package_module_2-expected.txt index 31ddd2d9c0e6daef2b312a56a57e90d05ff7a678..798f662e62189646fc86b7fffb315eab1c304c92 100644 --- a/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/package_module_2-expected.txt +++ b/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/package_module_2-expected.txt @@ -395,40 +395,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/separate_module_1-expected.txt b/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/separate_module_1-expected.txt index d9adfd2f3a8d457863c5e1889ba7487350df966b..3468422f016988a13888933895cca0e8bf849264 100644 --- a/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/separate_module_1-expected.txt +++ b/ets2panda/test/compiler/ets/implicit_package_import/package_test_1/separate_module_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "separate_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "separate_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "separate_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "separate_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_1-expected.txt b/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_1-expected.txt index ef4aac9edce2ff3c26d5613f8aefc7f1fed5c888..57744f20aca04039bb31f7372c008d9fa08c6d91 100644 --- a/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_1-expected.txt +++ b/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_1-expected.txt @@ -137,46 +137,12 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", "key": { "type": "Identifier", - "name": "_$init$_", + "name": "_$initializerBlockInit$_mypackage", "decorators": [], "loc": { "start": { @@ -202,7 +168,7 @@ "type": "ScriptFunction", "id": { "type": "Identifier", - "name": "_$init$_", + "name": "_$initializerBlockInit$_mypackage", "decorators": [], "loc": { "start": { @@ -225,181 +191,198 @@ "type": "BlockStatement", "statements": [ { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" - }, - "end": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" - } - } - }, - "right": { - "type": "ArrowFunctionExpression", - "function": { - "type": "ScriptFunction", - "id": null, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "number", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" - }, - "end": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" - }, - "end": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" - } - } - }, + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "foo", + "decorators": [], "loc": { "start": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" } } }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ReturnStatement", - "argument": { - "type": "Identifier", - "name": "myvar", - "decorators": [], + "right": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 2, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 2, + "program": "package_module_2.ets" + } + } + }, "loc": { "start": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" } } }, "loc": { "start": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, + "program": "package_module_2.ets" + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "myvar", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 2, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 2, + "program": "package_module_2.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 2, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 2, + "program": "package_module_2.ets" + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 2, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 2, "program": "package_module_2.ets" } } + }, + "loc": { + "start": { + "line": 21, + "column": 2, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 2, + "program": "package_module_2.ets" + } } - ], + }, "loc": { "start": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" } } }, "loc": { "start": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" } } }, "loc": { "start": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 27, + "line": 21, + "column": 2, "program": "package_module_2.ets" } } - }, - "loc": { - "start": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" - }, - "end": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" - } } - }, + ], "loc": { "start": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" + "line": 1, + "column": 1, + "program": null }, "end": { - "line": 19, - "column": 27, - "program": "package_module_2.ets" + "line": 1, + "column": 1, + "program": null } } } @@ -458,6 +441,112 @@ } } }, + { + "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": 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 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "package_module_1.ets" + }, + "end": { + "line": 1, + "column": 1, + "program": "package_module_1.ets" + } + } + }, { "type": "MethodDefinition", "key": { diff --git a/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_2-expected.txt b/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_2-expected.txt index f9ef1c8d9ea1d9765113f648a0f99a9fa99e2d5a..28e77ee934291bb7c4c7e7321f8613e2452157b7 100644 --- a/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_2-expected.txt +++ b/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_2-expected.txt @@ -137,46 +137,12 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", "key": { "type": "Identifier", - "name": "_$init$_", + "name": "_$initializerBlockInit$_mypackage", "decorators": [], "loc": { "start": { @@ -202,7 +168,7 @@ "type": "ScriptFunction", "id": { "type": "Identifier", - "name": "_$init$_", + "name": "_$initializerBlockInit$_mypackage", "decorators": [], "loc": { "start": { @@ -225,181 +191,198 @@ "type": "BlockStatement", "statements": [ { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "package_module_2.ets" - }, - "end": { - "line": 19, - "column": 8, - "program": "package_module_2.ets" - } - } - }, - "right": { - "type": "ArrowFunctionExpression", - "function": { - "type": "ScriptFunction", - "id": null, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "number", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 29, - "program": "package_module_2.ets" - }, - "end": { - "line": 19, - "column": 35, - "program": "package_module_2.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 29, - "program": "package_module_2.ets" - }, - "end": { - "line": 19, - "column": 38, - "program": "package_module_2.ets" - } - } - }, + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "foo", + "decorators": [], "loc": { "start": { - "line": 19, - "column": 29, + "line": 21, + "column": 5, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 38, + "line": 21, + "column": 8, "program": "package_module_2.ets" } } }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ReturnStatement", - "argument": { - "type": "Identifier", - "name": "myvar", - "decorators": [], + "right": { + "type": "ArrowFunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 15, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 21, + "program": "package_module_2.ets" + } + } + }, "loc": { "start": { - "line": 19, - "column": 48, + "line": 21, + "column": 15, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 53, + "line": 21, + "column": 24, "program": "package_module_2.ets" } } }, "loc": { "start": { - "line": 19, - "column": 41, + "line": 21, + "column": 15, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 54, + "line": 21, + "column": 24, + "program": "package_module_2.ets" + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "myvar", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 34, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 39, + "program": "package_module_2.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 27, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 40, + "program": "package_module_2.ets" + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 25, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 42, "program": "package_module_2.ets" } } + }, + "loc": { + "start": { + "line": 21, + "column": 11, + "program": "package_module_2.ets" + }, + "end": { + "line": 21, + "column": 42, + "program": "package_module_2.ets" + } } - ], + }, "loc": { "start": { - "line": 19, - "column": 39, + "line": 21, + "column": 11, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 56, + "line": 21, + "column": 42, "program": "package_module_2.ets" } } }, "loc": { "start": { - "line": 19, - "column": 25, + "line": 21, + "column": 5, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 56, + "line": 21, + "column": 42, "program": "package_module_2.ets" } } }, "loc": { "start": { - "line": 19, - "column": 25, + "line": 21, + "column": 5, "program": "package_module_2.ets" }, "end": { - "line": 19, - "column": 56, + "line": 21, + "column": 43, "program": "package_module_2.ets" } } - }, - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "package_module_2.ets" - }, - "end": { - "line": 19, - "column": 56, - "program": "package_module_2.ets" - } } - }, + ], "loc": { "start": { - "line": 19, - "column": 5, - "program": "package_module_2.ets" + "line": 1, + "column": 1, + "program": null }, "end": { - "line": 19, - "column": 56, - "program": "package_module_2.ets" + "line": 1, + "column": 1, + "program": null } } } @@ -458,6 +441,112 @@ } } }, + { + "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": 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 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "package_module_2.ets" + }, + "end": { + "line": 1, + "column": 1, + "program": "package_module_2.ets" + } + } + }, { "type": "ClassProperty", "key": { @@ -515,7 +604,7 @@ }, "end": { "line": 19, - "column": 24, + "column": 23, "program": "package_module_2.ets" } } @@ -528,7 +617,7 @@ }, "end": { "line": 19, - "column": 24, + "column": 23, "program": "package_module_2.ets" } } @@ -541,7 +630,7 @@ }, "end": { "line": 19, - "column": 24, + "column": 23, "program": "package_module_2.ets" } } @@ -556,7 +645,7 @@ }, "end": { "line": 19, - "column": 56, + "column": 8, "program": "package_module_2.ets" } } @@ -632,12 +721,12 @@ "loc": { "start": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" }, "end": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" } } @@ -645,12 +734,12 @@ "loc": { "start": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" }, "end": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" } } @@ -658,12 +747,12 @@ "loc": { "start": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" }, "end": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" } } @@ -672,12 +761,12 @@ "loc": { "start": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" }, "end": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" } } @@ -691,12 +780,12 @@ "loc": { "start": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" }, "end": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" } } @@ -706,12 +795,12 @@ "loc": { "start": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" }, "end": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" } } @@ -719,12 +808,12 @@ "loc": { "start": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" }, "end": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" } } @@ -734,12 +823,12 @@ "loc": { "start": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" }, "end": { "line": 19, - "column": 57, + "column": 24, "program": "package_module_1.ets" } } @@ -763,12 +852,12 @@ "loc": { "start": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" }, "end": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" } } @@ -776,12 +865,12 @@ "loc": { "start": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" }, "end": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" } } @@ -789,12 +878,12 @@ "loc": { "start": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" }, "end": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" } } @@ -803,12 +892,12 @@ "loc": { "start": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" }, "end": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" } } @@ -820,12 +909,12 @@ "loc": { "start": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" }, "end": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" } } @@ -833,12 +922,12 @@ "loc": { "start": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" }, "end": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" } } @@ -848,12 +937,12 @@ "loc": { "start": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" }, "end": { "line": 20, - "column": 1, + "column": 9, "program": "package_module_1.ets" } } @@ -866,8 +955,8 @@ "program": "package_module_1.ets" }, "end": { - "line": 20, - "column": 1, + "line": 21, + "column": 43, "program": "package_module_1.ets" } } @@ -879,8 +968,8 @@ "program": "package_module_1.ets" }, "end": { - "line": 20, - "column": 1, + "line": 21, + "column": 43, "program": "package_module_1.ets" } } @@ -892,8 +981,8 @@ "program": "package_module_1.ets" }, "end": { - "line": 20, - "column": 1, + "line": 21, + "column": 43, "program": "package_module_1.ets" } } @@ -907,8 +996,8 @@ "program": "package_module_1.ets" }, "end": { - "line": 20, - "column": 1, + "line": 21, + "column": 43, "program": "package_module_1.ets" } } @@ -948,7 +1037,7 @@ "program": "package_module_2.ets" }, "end": { - "line": 20, + "line": 24, "column": 1, "program": "package_module_2.ets" } diff --git a/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_2.ets b/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_2.ets index da31365575ea5d7a197e46af0787f48f2b1ec843..95c5de017a91a6d1feafa3a4179c7a0ac77ff9ad 100644 --- a/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_2.ets +++ b/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_1/package_module_2.ets @@ -16,4 +16,8 @@ package mypackage; import {myvar} from "./../subpackage_2/separate_module_1" -let foo: () => number = (): number => { return myvar; }; +let foo: () => number; +static { + foo = (): number => { return myvar; }; +} + diff --git a/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_2/separate_module_1-expected.txt b/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_2/separate_module_1-expected.txt index 867a2e51331983d0df2a9c9a83f63e684df8b5d9..baacd60da4d9b0f4e119e4cf3f8aebc1b978df71 100644 --- a/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_2/separate_module_1-expected.txt +++ b/ets2panda/test/compiler/ets/implicit_package_import/package_test_2/subpackage_2/separate_module_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "separate_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "separate_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "separate_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "separate_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/asyncfun_lambda_lib-expected.txt b/ets2panda/test/compiler/ets/import_tests/asyncfun_lambda_lib-expected.txt index 062817aca79ed5571dcf898e7f4366a198a94b48..61cf0f61530f04681fcfcad871f0f1521f44374e 100644 --- a/ets2panda/test/compiler/ets/import_tests/asyncfun_lambda_lib-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/asyncfun_lambda_lib-expected.txt @@ -1448,40 +1448,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "asyncfun_lambda_lib.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "asyncfun_lambda_lib.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "asyncfun_lambda_lib.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "asyncfun_lambda_lib.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/asyncfunc_lambda_main-expected.txt b/ets2panda/test/compiler/ets/import_tests/asyncfunc_lambda_main-expected.txt index 09ce6068fdd070e6fe20e8418f49133c6cc7d85a..1a6536528c1294a93fda16763d12bc7ee807042f 100644 --- a/ets2panda/test/compiler/ets/import_tests/asyncfunc_lambda_main-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/asyncfunc_lambda_main-expected.txt @@ -351,40 +351,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "asyncfunc_lambda_main.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "asyncfunc_lambda_main.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "asyncfunc_lambda_main.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "asyncfunc_lambda_main.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -799,7 +765,7 @@ }, "end": { "line": 24, - "column": 24, + "column": 23, "program": "asyncfunc_lambda_main.ets" } } diff --git a/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt b/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt index 26730a19019f52d435120462920521622803747e..4cc17d40520afeb3afb1b065851814a133276897 100644 --- a/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt @@ -21,7 +21,85 @@ } } }, - "superClass": null, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "BaseEnum", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + }, + "end": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + }, + "end": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + }, + "end": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + }, + "end": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + }, + "end": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + } + } + }, "implements": [], "body": [ { @@ -174,82 +252,14 @@ "program": "enum_export.ets" } } - } - ], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "ThisExpression", - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "enum_export.ets" - }, - "end": { - "line": 20, - "column": 9, - "program": "enum_export.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "#ordinal", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "enum_export.ets" - }, - "end": { - "line": 20, - "column": 9, - "program": "enum_export.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "enum_export.ets" - }, - "end": { - "line": 20, - "column": 9, - "program": "enum_export.ets" - } - } - }, - "right": { - "type": "Identifier", - "name": "ordinal", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "enum_export.ets" - }, - "end": { - "line": 20, - "column": 9, - "program": "enum_export.ets" - } - } - }, + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSPrimitiveType", "loc": { "start": { "line": 20, @@ -263,6 +273,7 @@ } } }, + "decorators": [], "loc": { "start": { "line": 20, @@ -275,8 +286,24 @@ "program": "enum_export.ets" } } + }, + "loc": { + "start": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + }, + "end": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + } } - ], + } + ], + "body": { + "type": "BlockStatement", + "statements": [], "loc": { "start": { "line": 20, @@ -400,6 +427,22 @@ } }, "arguments": [ + { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + }, + "end": { + "line": 20, + "column": 9, + "program": "enum_export.ets" + } + } + }, { "type": "NumberLiteral", "value": 0, @@ -2356,7 +2399,85 @@ } } }, - "superClass": null, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "BaseEnum", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, "implements": [], "body": [ { @@ -2573,7 +2694,54 @@ "type": "ETSParameterExpression", "name": { "type": "Identifier", - "name": "ordinal", + "name": "ordinal", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", "typeAnnotation": { "type": "ETSPrimitiveType", "loc": { @@ -2620,6 +2788,71 @@ "body": { "type": "BlockStatement", "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Super", + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, { "type": "ExpressionStatement", "expression": { @@ -2841,6 +3074,22 @@ } }, "arguments": [ + { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, { "type": "NumberLiteral", "value": 0, @@ -3023,6 +3272,22 @@ "program": "enum_export.ets" } } + }, + { + "type": "NumberLiteral", + "value": 42, + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } } ], "loc": { @@ -3190,6 +3455,22 @@ "program": "enum_export.ets" } } + }, + { + "type": "NumberLiteral", + "value": 43, + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } } ], "loc": { @@ -7180,83 +7461,193 @@ "program": "enum_export.ets" } } - }, + }, + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 22, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Commands", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 13, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 21, + "program": "enum_export.ets" + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "BaseEnum", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + } + ], "loc": { "start": { - "line": 22, + "line": 26, "column": 8, "program": "enum_export.ets" }, "end": { - "line": 22, + "line": 26, "column": 8, "program": "enum_export.ets" } } }, - "overloads": [], - "decorators": [], "loc": { "start": { - "line": 22, + "line": 26, "column": 8, "program": "enum_export.ets" }, "end": { - "line": 22, + "line": 26, "column": 8, "program": "enum_export.ets" } } - } - ], - "loc": { - "start": { - "line": 22, - "column": 8, - "program": "enum_export.ets" }, - "end": { - "line": 22, - "column": 8, - "program": "enum_export.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "Commands", - "decorators": [], "loc": { "start": { "line": 26, - "column": 13, + "column": 8, "program": "enum_export.ets" }, "end": { "line": 26, - "column": 21, + "column": 8, "program": "enum_export.ets" } } }, - "superClass": null, "implements": [], "body": [ { @@ -7515,11 +7906,155 @@ "program": "enum_export.ets" } } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } } ], "body": { "type": "BlockStatement", "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Super", + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } + }, { "type": "ExpressionStatement", "expression": { @@ -7756,6 +8291,22 @@ "program": "enum_export.ets" } } + }, + { + "type": "StringLiteral", + "value": "fopen", + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } } ], "loc": { @@ -7923,6 +8474,22 @@ "program": "enum_export.ets" } } + }, + { + "type": "StringLiteral", + "value": "fclose", + "loc": { + "start": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + }, + "end": { + "line": 26, + "column": 8, + "program": "enum_export.ets" + } + } } ], "loc": { @@ -12129,40 +12696,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "enum_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "enum_export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "enum_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "enum_export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/enum_import-expected.txt b/ets2panda/test/compiler/ets/import_tests/enum_import-expected.txt index 0ce22ce3f5c2a648974a25efbcb0de40170a631f..234229fd33cec4ae5f30cbb86f105b60ca4a0892 100644 --- a/ets2panda/test/compiler/ets/import_tests/enum_import-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/enum_import-expected.txt @@ -203,40 +203,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "enum_import.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "enum_import.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "enum_import.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "enum_import.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/export_class_with_getters_setters-expected.txt b/ets2panda/test/compiler/ets/import_tests/export_class_with_getters_setters-expected.txt index 093152b169d6825cded0721a88a7609718dee0f9..0ff68cff92731842dbc89da894bba97f44c8dae6 100644 --- a/ets2panda/test/compiler/ets/import_tests/export_class_with_getters_setters-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/export_class_with_getters_setters-expected.txt @@ -904,40 +904,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_class_with_getters_setters.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_class_with_getters_setters.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_class_with_getters_setters.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_class_with_getters_setters.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type-expected.txt b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type-expected.txt index d23e979afe997107d772bd6a48a5b786d63d618a..67e4ebce208dd160c3f3f592b7eb61d90170a286 100644 --- a/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_func_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_func_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_func_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_func_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib-expected.txt b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib-expected.txt index c519e69ecdd2c38e36e21781010b4f24a7f82349..4c0d8a449b37b6f6fea711d8ab393473ba0f26d4 100644 --- a/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/generic_typealias_func_type_lib-expected.txt @@ -279,40 +279,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_func_type_lib.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_func_type_lib.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_typealias_func_type_lib.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_typealias_func_type_lib.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/import_class_with_getters_setters-expected.txt b/ets2panda/test/compiler/ets/import_tests/import_class_with_getters_setters-expected.txt index e65d65947b7df5729a915389b118e8edafb312df..20e7f0350557751a9255c5e98e9291bf01a7f335 100644 --- a/ets2panda/test/compiler/ets/import_tests/import_class_with_getters_setters-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/import_class_with_getters_setters-expected.txt @@ -154,40 +154,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_class_with_getters_setters.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_class_with_getters_setters.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_class_with_getters_setters.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_class_with_getters_setters.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type-expected.txt b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type-expected.txt index 3fc8b6445433c63e6d6a799777f54e61a624bfc4..b13fb9afe6e4bbd8c003c81baa21b176f2de3432 100644 --- a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "infer_imported_function_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "infer_imported_function_return_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "infer_imported_function_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "infer_imported_function_return_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt index 140e3f88bec6089a5962c929634d55b7386db3b8..d04e570c0f22c272d885d9e64de8c7ae17874a55 100644 --- a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "infer_imported_function_return_type_lib.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "infer_imported_function_return_type_lib.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "infer_imported_function_return_type_lib.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "infer_imported_function_return_type_lib.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export-expected.txt b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export-expected.txt index e850da7c29c64b64a046527e234c96eed775c631..937539ce2a6a180dd7da03a1b988286a7ecacd38 100644 --- a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/export-expected.txt @@ -400,40 +400,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export-expected.txt b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export-expected.txt index fc4e872819cfe0d65f571e8f0d3d272ee2225624..0748020cdb8643e09bdb1d30b29a5b14989646dc 100644 --- a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/import_aliased_re-export-expected.txt @@ -236,40 +236,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_aliased_re-export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_aliased_re-export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_aliased_re-export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_aliased_re-export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias-expected.txt b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias-expected.txt index b0e0804dffb257c36de487ccc94288ad657eeee2..edfd5063db03b6ec7a7b45ba7eac6db1ee6405eb 100644 --- a/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/re-export_with_alias/re-export_with_alias-expected.txt @@ -266,40 +266,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re-export_with_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re-export_with_alias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re-export_with_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re-export_with_alias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface-expected.txt index ba7227003fc8c1337efa80c7d1e4a53935f01a82..99b6763f23dd3cd0bf2e3aab3f6bff632d067311 100644 --- a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_interface-expected.txt @@ -590,40 +590,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_interface.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_interface.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported-expected.txt index 2c970792d916edb959770fd79d8e5e314e667f7c..503604c72bedc1c63a63c346d8ad4e561e15f6ee 100644 --- a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/import_selective_exported-expected.txt @@ -170,40 +170,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_selective_exported.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_selective_exported.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_selective_exported.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_selective_exported.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export-expected.txt index 95c0c5a9d65c07e10b560edaddfe7ae9c816da6a..8f2595b4503d6cc16cb906329a9ecee3ece26ac1 100644 --- a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export-expected.txt @@ -811,40 +811,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function-expected.txt index 594915351450a8a710156f261356caf263b9b897..191cade283c8c62a7acdeca3e5d8901ccdc92f14 100644 --- a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_function-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_function.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_function.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface-expected.txt index 0d1753e12429471e477c8a4ba6d46485861226a4..2793feea082d5646b14a0633e86a3c2753e375e9 100644 --- a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_interface-expected.txt @@ -121,40 +121,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_interface.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_interface.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias-expected.txt index 6bf763f3bf2aadec2418b7d6c50e503b5fbf58a2..61b96e29def6a09c678c44b3c54f78972d5319a8 100644 --- a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_export_with_alias-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_with_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_with_alias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_with_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_with_alias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1-expected.txt index 234ff78b36ef72068d69d0889ed441b0104d1cd1..5b31ff5f4d6a58912c76aad18633212ed2f9286e 100644 --- a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_1-expected.txt @@ -323,40 +323,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_import_with_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_import_with_alias_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_import_with_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_import_with_alias_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2-expected.txt b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2-expected.txt index 2386e88d13c17216f77e9b34ae722f53f4f6ca2f..88a32d015673ab186b025c67213a1f5b214e5b4e 100644 --- a/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/selective_export_tests/selective_import_with_alias_2-expected.txt @@ -323,40 +323,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_import_with_alias_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_import_with_alias_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_import_with_alias_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_import_with_alias_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/import_type-expected.txt b/ets2panda/test/compiler/ets/import_type-expected.txt index c304037aa645de86afe40f2165f4e26e33cf76e4..4624e649f53f29f9501b85835959ff7d7d41923c 100644 --- a/ets2panda/test/compiler/ets/import_type-expected.txt +++ b/ets2panda/test/compiler/ets/import_type-expected.txt @@ -421,40 +421,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/inferTypeOfArray-expected.txt b/ets2panda/test/compiler/ets/inferTypeOfArray-expected.txt index 52ce42f965ba175d1252de23bb49a7cd47e7f149..760183394c72cfc72f60a15adf4ce811237c4708 100644 --- a/ets2panda/test/compiler/ets/inferTypeOfArray-expected.txt +++ b/ets2panda/test/compiler/ets/inferTypeOfArray-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "inferTypeOfArray.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "inferTypeOfArray.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "inferTypeOfArray.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "inferTypeOfArray.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/instanceof_dyndecl_dynvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_dyndecl_dynvalue-expected.txt index 6397f04d33dc556b92655e26aa20918f51b54323..295ef18e626f77944b116b50099fbbf640543bb4 100644 --- a/ets2panda/test/compiler/ets/instanceof_dyndecl_dynvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_dyndecl_dynvalue-expected.txt @@ -14,7 +14,7 @@ }, "end": { "line": 20, - "column": 44, + "column": 41, "program": "instanceof_dyndecl_dynvalue.ets" } } @@ -78,7 +78,7 @@ }, "end": { "line": 20, - "column": 44, + "column": 41, "program": "instanceof_dyndecl_dynvalue.ets" } } @@ -187,40 +187,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_dyndecl_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_dyndecl_dynvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_dyndecl_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_dyndecl_dynvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -836,6 +802,61 @@ } } }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof1", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "accessibility": "public", + "static": true, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, { "type": "ClassStaticBlock", "value": { @@ -1032,6 +1053,173 @@ "program": null } } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof1", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "JSRuntime", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "loadModule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "/home/anya/panda_reps/standalone_new/arkcompiler/runtime_core/static_core/tools/es2panda/test/parser/ets/dynamic_import_tests/modules/instanceof.ets", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "optional": false, + "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": { diff --git a/ets2panda/test/compiler/ets/instanceof_dyndecl_jsvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_dyndecl_jsvalue-expected.txt index 2ec901bcb74a736bae8b9ae14bf99db27f558814..7bfcf12d596e7c405c596b180131a3dc5c8fb8d2 100644 --- a/ets2panda/test/compiler/ets/instanceof_dyndecl_jsvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_dyndecl_jsvalue-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_dyndecl_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_dyndecl_jsvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_dyndecl_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_dyndecl_jsvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -675,6 +641,482 @@ "program": "instanceof_dyndecl_jsvalue.ets" } } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof0", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "accessibility": "public", + "static": true, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "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": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof0", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "JSRuntime", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "loadModule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "/home/anya/panda_reps/standalone_new/arkcompiler/runtime_core/static_core/tools/es2panda/test/parser/ets/dynamic_import_tests/modules/instanceof.ets", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "optional": false, + "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": 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": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "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": [], + "returnType": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "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 + } + } + }, + "overloads": [], + "decorators": [], + "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": { diff --git a/ets2panda/test/compiler/ets/instanceof_dynvalue_dynvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_dynvalue_dynvalue-expected.txt index 5d4706c78e841d75e73ae69c087265e2a5d6c211..e3bad427a2c75c88dfb215f6e273ae2e4bfa63f5 100644 --- a/ets2panda/test/compiler/ets/instanceof_dynvalue_dynvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_dynvalue_dynvalue-expected.txt @@ -154,40 +154,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_dynvalue_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_dynvalue_dynvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_dynvalue_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_dynvalue_dynvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -724,482 +690,6 @@ "program": "instanceof_dynvalue_dynvalue.ets" } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/instanceof_dynvalue_jsvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_dynvalue_jsvalue-expected.txt index ca744db92cef86c3d9848b1822def8ae1ec01e01..67aab49975a30e8daaed26ee97ac02eaad89dc97 100644 --- a/ets2panda/test/compiler/ets/instanceof_dynvalue_jsvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_dynvalue_jsvalue-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_dynvalue_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_dynvalue_jsvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_dynvalue_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_dynvalue_jsvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -675,482 +641,6 @@ "program": "instanceof_dynvalue_jsvalue.ets" } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/instanceof_etsobject_dynvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_etsobject_dynvalue-expected.txt index 8d4202c4c50ce4274419fc9ea91ba344acb6e031..c5057fedc3eaeb9c5be3139546f5ed14bd510f01 100644 --- a/ets2panda/test/compiler/ets/instanceof_etsobject_dynvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_etsobject_dynvalue-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_etsobject_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_etsobject_dynvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_etsobject_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_etsobject_dynvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -830,482 +796,6 @@ "program": "instanceof_etsobject_dynvalue.ets" } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/instanceof_etsobject_jsvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_etsobject_jsvalue-expected.txt index 11297e5d7b574a3d63d1ec23e94c72cd5cddbf01..58cc1902d33dc8a680a8cb9b84b6d5bd31e9cebc 100644 --- a/ets2panda/test/compiler/ets/instanceof_etsobject_jsvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_etsobject_jsvalue-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_etsobject_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_etsobject_jsvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_etsobject_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_etsobject_jsvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/instanceof_jsvalue_dynvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_jsvalue_dynvalue-expected.txt index ea0f73eb336c7ae4fc15059bdd1d0dc93796c821..6d53282c4ed55e390336be900a569ad95b30d3a0 100644 --- a/ets2panda/test/compiler/ets/instanceof_jsvalue_dynvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_jsvalue_dynvalue-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_jsvalue_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_jsvalue_dynvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_jsvalue_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_jsvalue_dynvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -675,482 +641,6 @@ "program": "instanceof_jsvalue_dynvalue.ets" } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/instanceof_jsvalue_jsvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_jsvalue_jsvalue-expected.txt index 0302f47669086e0161cd093832f9bf641a85c518..ace3481dfca8be34c2beff9b61bc7d45a0ea483b 100644 --- a/ets2panda/test/compiler/ets/instanceof_jsvalue_jsvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_jsvalue_jsvalue-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_jsvalue_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_jsvalue_jsvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_jsvalue_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_jsvalue_jsvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/instanceof_object_dynvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_object_dynvalue-expected.txt index 16902d759d410bc18047d49c1fe0f077cfe5c7a7..c27c1bf6338474bf5bffa9046e3bf9b0c1002e24 100644 --- a/ets2panda/test/compiler/ets/instanceof_object_dynvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_object_dynvalue-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_object_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_object_dynvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_object_dynvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_object_dynvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -675,482 +641,6 @@ "program": "instanceof_object_dynvalue.ets" } } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "accessibility": "public", - "static": true, - "readonly": true, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "$dynmodule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "dynamic_import_tests0", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "right": { - "type": "CallExpression", - "callee": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "JSRuntime", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "property": { - "type": "Identifier", - "name": "loadModule", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "arguments": [ - { - "type": "StringLiteral", - "value": "dynamic_import_tests", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "optional": false, - "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": 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": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - { - "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": [], - "returnType": { - "type": "OpaqueType", - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [], - "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 - } - } - }, - "overloads": [], - "decorators": [], - "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": { diff --git a/ets2panda/test/compiler/ets/instanceof_object_jsvalue-expected.txt b/ets2panda/test/compiler/ets/instanceof_object_jsvalue-expected.txt index 27d1e5fcea4057869d5360d1c6edefd924ddde27..420f8a4d23a46b8a565d7f0397c696ecf1373786 100644 --- a/ets2panda/test/compiler/ets/instanceof_object_jsvalue-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_object_jsvalue-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_object_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_object_jsvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_object_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_object_jsvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt b/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt index c910038c802ceb16a5103d6662add19d1642f113..bab47a98ee73d43c735f1a0fca4390952b2af36c 100644 --- a/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_object_long.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_object_long.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_object_long.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_object_long.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/instanceof_x_dyndecl-expected.txt b/ets2panda/test/compiler/ets/instanceof_x_dyndecl-expected.txt index f587c6f1ce6454f917c08a60884136e4c6285ce0..d44902f55113f845acaff564b5ce0f2d729d5446 100644 --- a/ets2panda/test/compiler/ets/instanceof_x_dyndecl-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_x_dyndecl-expected.txt @@ -14,7 +14,7 @@ }, "end": { "line": 20, - "column": 49, + "column": 46, "program": "instanceof_x_dyndecl.ets" } } @@ -78,7 +78,7 @@ }, "end": { "line": 20, - "column": 49, + "column": 46, "program": "instanceof_x_dyndecl.ets" } } @@ -236,40 +236,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_x_dyndecl.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_x_dyndecl.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_x_dyndecl.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_x_dyndecl.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -2228,6 +2194,61 @@ } } }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof1", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "accessibility": "public", + "static": true, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, { "type": "ClassStaticBlock", "value": { @@ -2424,6 +2445,173 @@ "program": null } } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof1", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "JSRuntime", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "loadModule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "/home/anya/panda_reps/standalone_new/arkcompiler/runtime_core/static_core/tools/es2panda/test/parser/ets/dynamic_import_tests/modules/instanceof.ets", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "optional": false, + "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": { diff --git a/ets2panda/test/compiler/ets/instanceof_x_etstype-expected.txt b/ets2panda/test/compiler/ets/instanceof_x_etstype-expected.txt index 28cb84a32d5a6dcfc7be00d165f3e2d12117a846..6a58368378b6eac813963edf8bfcabfabfa2debe 100644 --- a/ets2panda/test/compiler/ets/instanceof_x_etstype-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_x_etstype-expected.txt @@ -14,7 +14,7 @@ }, "end": { "line": 20, - "column": 49, + "column": 46, "program": "instanceof_x_etstype.ets" } } @@ -78,7 +78,7 @@ }, "end": { "line": 20, - "column": 49, + "column": 46, "program": "instanceof_x_etstype.ets" } } @@ -187,40 +187,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_x_etstype.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_x_etstype.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_x_etstype.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_x_etstype.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -2334,6 +2300,61 @@ } } }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof1", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "accessibility": "public", + "static": true, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, { "type": "ClassStaticBlock", "value": { @@ -2530,6 +2551,173 @@ "program": null } } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof1", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "JSRuntime", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "loadModule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "/home/anya/panda_reps/standalone_new/arkcompiler/runtime_core/static_core/tools/es2panda/test/parser/ets/dynamic_import_tests/modules/instanceof.ets", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "optional": false, + "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": { diff --git a/ets2panda/test/compiler/ets/instanceof_x_object-expected.txt b/ets2panda/test/compiler/ets/instanceof_x_object-expected.txt index c7771f79ddc8a207b07d34df5f9547f18c1e6d6d..2f04808c10a1295625a4ccfea74ccfc764b60e74 100644 --- a/ets2panda/test/compiler/ets/instanceof_x_object-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_x_object-expected.txt @@ -14,7 +14,7 @@ }, "end": { "line": 20, - "column": 49, + "column": 46, "program": "instanceof_x_object.ets" } } @@ -78,7 +78,7 @@ }, "end": { "line": 20, - "column": 49, + "column": 46, "program": "instanceof_x_object.ets" } } @@ -187,40 +187,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_x_object.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_x_object.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof_x_object.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof_x_object.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -2179,6 +2145,61 @@ } } }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof1", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "accessibility": "public", + "static": true, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, { "type": "ClassStaticBlock", "value": { @@ -2375,6 +2396,173 @@ "program": null } } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_instanceof1", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "JSRuntime", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "loadModule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "/home/anya/panda_reps/standalone_new/arkcompiler/runtime_core/static_core/tools/es2panda/test/parser/ets/dynamic_import_tests/modules/instanceof.ets", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "optional": false, + "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": { diff --git a/ets2panda/test/compiler/ets/interface_noreturn_type_function-expected.txt b/ets2panda/test/compiler/ets/interface_noreturn_type_function-expected.txt index b0bdfeb34dcd88109ff3eedda3144b07b5fc6482..1bc910d1e70bfa0b2dbb22a6f5fb842ac38084bd 100644 --- a/ets2panda/test/compiler/ets/interface_noreturn_type_function-expected.txt +++ b/ets2panda/test/compiler/ets/interface_noreturn_type_function-expected.txt @@ -429,40 +429,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interface_noreturn_type_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interface_noreturn_type_function.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interface_noreturn_type_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interface_noreturn_type_function.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/invalidCallInstruction-expected.txt b/ets2panda/test/compiler/ets/invalidCallInstruction-expected.txt index efc1f4f6d24169fba794d90f854a98895cdf674d..618c51090b0c3c65547b4396202e36651232874a 100644 --- a/ets2panda/test/compiler/ets/invalidCallInstruction-expected.txt +++ b/ets2panda/test/compiler/ets/invalidCallInstruction-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "invalidCallInstruction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "invalidCallInstruction.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "invalidCallInstruction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "invalidCallInstruction.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/invalidInheritance3-expected.txt b/ets2panda/test/compiler/ets/invalidInheritance3-expected.txt index 1d89f0d132265210b6088f984470fdbc2ea1698e..89d140de9fba3fd0ec99e838748ce8c04f672cdd 100644 --- a/ets2panda/test/compiler/ets/invalidInheritance3-expected.txt +++ b/ets2panda/test/compiler/ets/invalidInheritance3-expected.txt @@ -779,40 +779,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "invalidInheritance3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "invalidInheritance3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "invalidInheritance3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "invalidInheritance3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambdaFunction1-expected.txt b/ets2panda/test/compiler/ets/lambdaFunction1-expected.txt index 8ee8b70f5abcc521d5cba1425b61066c9e610fff..79e03cb456033bead7348c9bd6cbea5e0186853f 100644 --- a/ets2panda/test/compiler/ets/lambdaFunction1-expected.txt +++ b/ets2panda/test/compiler/ets/lambdaFunction1-expected.txt @@ -792,40 +792,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaFunction1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaFunction1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaFunction1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaFunction1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambdaFunctionArrayDeclaration-expected.txt b/ets2panda/test/compiler/ets/lambdaFunctionArrayDeclaration-expected.txt index 17ceb1ce191d7cd56691c60be52bceaab6516773..8653854d808d9e67f116d5c13fdd07e761d93ebd 100644 --- a/ets2panda/test/compiler/ets/lambdaFunctionArrayDeclaration-expected.txt +++ b/ets2panda/test/compiler/ets/lambdaFunctionArrayDeclaration-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaFunctionArrayDeclaration.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaFunctionArrayDeclaration.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaFunctionArrayDeclaration.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaFunctionArrayDeclaration.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -240,119 +206,167 @@ "type": "Identifier", "name": "src14", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSFunctionType", - "params": [ - { - "type": "ETSParameterExpression", - "name": { - "type": "Identifier", - "name": "x", - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "lambdaFunctionArrayDeclaration.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambdaFunctionArrayDeclaration.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", "name": { "type": "Identifier", - "name": "Char", + "name": "x", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Char", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambdaFunctionArrayDeclaration.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambdaFunctionArrayDeclaration.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambdaFunctionArrayDeclaration.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambdaFunctionArrayDeclaration.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambdaFunctionArrayDeclaration.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambdaFunctionArrayDeclaration.ets" + } + } + }, "decorators": [], "loc": { "start": { - "line": 17, - "column": 19, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" }, "end": { - "line": 17, - "column": 23, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" } } }, "loc": { "start": { - "line": 17, - "column": 19, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" }, "end": { - "line": 17, - "column": 24, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" } } - }, + } + ], + "returnType": { + "type": "ETSPrimitiveType", "loc": { "start": { - "line": 17, - "column": 19, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" }, "end": { - "line": 17, - "column": 24, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" } } }, - "decorators": [], "loc": { "start": { - "line": 17, - "column": 16, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" }, "end": { - "line": 17, - "column": 24, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" } } - }, - "loc": { - "start": { - "line": 17, - "column": 16, - "program": "lambdaFunctionArrayDeclaration.ets" - }, - "end": { - "line": 17, - "column": 24, - "program": "lambdaFunctionArrayDeclaration.ets" - } } - } - ], - "returnType": { - "type": "ETSPrimitiveType", + ], "loc": { "start": { - "line": 17, - "column": 28, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" }, "end": { - "line": 17, - "column": 32, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" } } }, "loc": { "start": { - "line": 17, - "column": 14, + "line": 1, + "column": 1, "program": "lambdaFunctionArrayDeclaration.ets" }, "end": { - "line": 17, - "column": 32, + "line": 1, + "column": 3, "program": "lambdaFunctionArrayDeclaration.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, diff --git a/ets2panda/test/compiler/ets/lambda_capturing-expected.txt b/ets2panda/test/compiler/ets/lambda_capturing-expected.txt index 23f0b13a46e400765269a699095f96d138396b3c..95324f7bff43bdf1a709e2f20a9c5a8718fae8d1 100644 --- a/ets2panda/test/compiler/ets/lambda_capturing-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_capturing-expected.txt @@ -134,40 +134,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_capturing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_capturing.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_capturing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_capturing.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt index 52df06988afccb502df1a0c93b8bc2bca975e61e..c7634b64c25ed2139693d95416e02fac3b196a09 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing-expected.txt @@ -396,9 +396,55 @@ { "type": "ReturnStatement", "argument": { - "type": "Identifier", - "name": "a", - "decorators": [], + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 41, + "program": "lambda_cast_infer_type_narrowing.ets" + }, + "end": { + "line": 22, + "column": 42, + "program": "lambda_cast_infer_type_narrowing.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 41, + "program": "lambda_cast_infer_type_narrowing.ets" + }, + "end": { + "line": 22, + "column": 43, + "program": "lambda_cast_infer_type_narrowing.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 41, + "program": "lambda_cast_infer_type_narrowing.ets" + }, + "end": { + "line": 22, + "column": 43, + "program": "lambda_cast_infer_type_narrowing.ets" + } + } + }, + "arguments": [], "loc": { "start": { "line": 22, @@ -407,7 +453,7 @@ }, "end": { "line": 22, - "column": 38, + "column": 46, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -420,7 +466,7 @@ }, "end": { "line": 22, - "column": 38, + "column": 46, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -434,7 +480,7 @@ }, "end": { "line": 22, - "column": 39, + "column": 46, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -447,7 +493,7 @@ }, "end": { "line": 22, - "column": 39, + "column": 46, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -460,7 +506,7 @@ }, "end": { "line": 22, - "column": 39, + "column": 46, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -472,7 +518,7 @@ "type": "ETSParameterExpression", "name": { "type": "Identifier", - "name": "a", + "name": "b", "typeAnnotation": { "type": "ETSTypeReference", "part": { @@ -484,12 +530,12 @@ "loc": { "start": { "line": 22, - "column": 48, + "column": 55, "program": "lambda_cast_infer_type_narrowing.ets" }, "end": { "line": 22, - "column": 49, + "column": 56, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -497,12 +543,12 @@ "loc": { "start": { "line": 22, - "column": 48, + "column": 55, "program": "lambda_cast_infer_type_narrowing.ets" }, "end": { "line": 22, - "column": 50, + "column": 57, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -510,12 +556,12 @@ "loc": { "start": { "line": 22, - "column": 48, + "column": 55, "program": "lambda_cast_infer_type_narrowing.ets" }, "end": { "line": 22, - "column": 50, + "column": 57, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -524,12 +570,12 @@ "loc": { "start": { "line": 22, - "column": 44, + "column": 51, "program": "lambda_cast_infer_type_narrowing.ets" }, "end": { "line": 22, - "column": 50, + "column": 57, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -537,12 +583,12 @@ "loc": { "start": { "line": 22, - "column": 44, + "column": 51, "program": "lambda_cast_infer_type_narrowing.ets" }, "end": { "line": 22, - "column": 50, + "column": 57, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -559,12 +605,12 @@ "loc": { "start": { "line": 22, - "column": 54, + "column": 61, "program": "lambda_cast_infer_type_narrowing.ets" }, "end": { "line": 22, - "column": 55, + "column": 62, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -572,7 +618,7 @@ "loc": { "start": { "line": 22, - "column": 54, + "column": 61, "program": "lambda_cast_infer_type_narrowing.ets" }, "end": { @@ -585,7 +631,7 @@ "loc": { "start": { "line": 22, - "column": 54, + "column": 61, "program": "lambda_cast_infer_type_narrowing.ets" }, "end": { @@ -598,7 +644,7 @@ "loc": { "start": { "line": 22, - "column": 43, + "column": 50, "program": "lambda_cast_infer_type_narrowing.ets" }, "end": { @@ -616,7 +662,7 @@ }, "end": { "line": 22, - "column": 39, + "column": 46, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -629,7 +675,7 @@ }, "end": { "line": 22, - "column": 39, + "column": 46, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -644,7 +690,7 @@ }, "end": { "line": 22, - "column": 39, + "column": 46, "program": "lambda_cast_infer_type_narrowing.ets" } } @@ -746,7 +792,7 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "B", + "name": "A", "decorators": [], "loc": { "start": { @@ -1068,40 +1114,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_narrowing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_narrowing.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_narrowing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_narrowing.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets index 4b2d64b18927a20c1d370e6d9419602d72f6193c..688046af24bdce30be476a57d0d42f5ed654e8e8 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_narrowing.ets @@ -19,7 +19,7 @@ class A { class B extends A { main () { - let a = (a : A) => { return a} as (a : B) => B - let expected : (a : B) => B = a + let a = (a : A) => { return new B() } as (b : B) => B + let expected : (a : B) => A = a } } diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt index 2fdc5d0da324c65997b31b5b2bc0d42ee8e37059..e0b68b4ea0a2a12d0955073b93c0de0984c3485f 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_void-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_void.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_void.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_void.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_void.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt index 463406cfeaff6967c0b5e4639c74f3e0c0008379..9d0c4a664cceb2ad48da77e2fa6a7777cd092749 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_infer_type_widening-expected.txt @@ -1114,40 +1114,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_widening.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_widening.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_widening.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_cast_infer_type_widening.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt index 69efc6221b577fe27e8546da5fb9f16f92a6fbf7..52981c41e98462517f3e51d51d3c91f32be757d3 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_cast_type_has_pramas-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_cast_type_has_pramas.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_cast_type_has_pramas.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_cast_type_has_pramas.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_cast_type_has_pramas.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type-expected.txt index 7a2f2fa09f4a32dbae59d3c48109bb343748b4ef..50a8f9b7df578f12cbe63dd1c7c06f0105c06d7f 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt index aa8aa1b8c4a554bed4de4e0bfbb2929a2177657b..d76dc0af96bce487b3af86c086c736dc2e4b18e9 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression-expected.txt @@ -595,40 +595,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_arrow_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_arrow_expression.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_arrow_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_arrow_expression.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt index cc70598f001c4ede9262431cf5668b6a6ee36a65..acb76e09d478cb6beed064d986509ebe08126e4a 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_arrow_expression_literal-expected.txt @@ -548,40 +548,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_arrow_expression_literal.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_arrow_expression_literal.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_arrow_expression_literal.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_arrow_expression_literal.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt index e380e7a29783823514afd8709f2e8547fe8b762d..27526a0561bb1c189841436ad3fde807b7e2da84 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_has_return-expected.txt @@ -709,40 +709,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_has_return.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_has_return.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_has_return.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_has_return.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt index a6b62d2c4c95b93411bc223adbb4571bcdbd3949..39e640a0ff170b1aea3641b6fbd238b339f39126 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_param2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_param2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_param2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_param2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt index e1603e74addc154a6c0bf4b2dbc03a9f1d445d07..436191e910c4604f95f9a6693e0f11ab08cf4d5c 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_array-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_array.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_array.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_array.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_array.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -225,55 +191,103 @@ "type": "Identifier", "name": "y", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "number", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 11, - "program": "lambda_infer_type_return_array.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "lambda_infer_type_return_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + } + } }, - "end": { - "line": 17, - "column": 17, - "program": "lambda_infer_type_return_array.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 11, + "line": 1, + "column": 3, "program": "lambda_infer_type_return_array.ets" }, "end": { - "line": 17, - "column": 18, + "line": 1, + "column": 3, "program": "lambda_infer_type_return_array.ets" } } }, "loc": { "start": { - "line": 17, - "column": 11, + "line": 1, + "column": 1, "program": "lambda_infer_type_return_array.ets" }, "end": { - "line": 17, - "column": 18, + "line": 1, + "column": 3, "program": "lambda_infer_type_return_array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -540,55 +554,103 @@ "type": "ETSFunctionType", "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "number", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 24, - "program": "lambda_infer_type_return_array.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "lambda_infer_type_return_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + } + } }, - "end": { - "line": 19, - "column": 30, - "program": "lambda_infer_type_return_array.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_infer_type_return_array.ets" + } } } - }, + ], "loc": { "start": { - "line": 19, - "column": 24, + "line": 1, + "column": 3, "program": "lambda_infer_type_return_array.ets" }, "end": { - "line": 19, - "column": 31, + "line": 1, + "column": 3, "program": "lambda_infer_type_return_array.ets" } } }, "loc": { "start": { - "line": 19, - "column": 24, + "line": 1, + "column": 1, "program": "lambda_infer_type_return_array.ets" }, "end": { - "line": 19, - "column": 31, + "line": 1, + "column": 3, "program": "lambda_infer_type_return_array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt index 98f25b34d42ae8d4fb1d6eebe456deaf56b13c44..0e150addfb5da78bceb35ccf3e9f9ae359ce30e4 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt index b4177187ab0b3fbeaa91e9c3e4b5d303f65a87b8..026159d3ce182a843639e64a1f966ce1efd17a70 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt index e330504bae7bc77e513a7c957e9bf3533b625add..54f0403fca716cd4d389666feead3e80b442056f 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_lambda_expression-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda_expression.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_lambda_expression.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt index f445df641edb27292fcd4f5f9db942a6531c7388..573e5311585498a2982f69ca6b082ef5be173374 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_literal-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_literal.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_literal.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_literal.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_literal.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt index 8f5814fba93c21eebc9c1672617a82c94b511056..389e4d15b35ba4f17448e4470ad67dae07edb531 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_return_union-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_union.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_union.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_union.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_return_union.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope-expected.txt index dd9ae6b96433b2d02cd069b724bf55fcace6c279..cf65a444be5ce78de5a3e60473e06389e6c6d74f 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_scope-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_scope.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_scope.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_scope.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_infer_type_scope.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lambda_unresolved_ref_1-expected.txt b/ets2panda/test/compiler/ets/lambda_unresolved_ref_1-expected.txt index 0a83d7d0dfb6932ffb60f506b590129c80ad56c6..a2c1ec433988affa5f2ae2385a900a1b3a38a172 100644 --- a/ets2panda/test/compiler/ets/lambda_unresolved_ref_1-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_unresolved_ref_1-expected.txt @@ -741,40 +741,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_unresolved_ref_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_unresolved_ref_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_unresolved_ref_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_unresolved_ref_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -937,55 +903,103 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 19, - "program": "lambda_unresolved_ref_1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } }, - "end": { - "line": 23, - "column": 25, - "program": "lambda_unresolved_ref_1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } } } - }, + ], "loc": { "start": { - "line": 23, - "column": 19, + "line": 1, + "column": 3, "program": "lambda_unresolved_ref_1.ets" }, "end": { - "line": 23, - "column": 26, + "line": 1, + "column": 3, "program": "lambda_unresolved_ref_1.ets" } } }, "loc": { "start": { - "line": 23, - "column": 19, + "line": 1, + "column": 1, "program": "lambda_unresolved_ref_1.ets" }, "end": { - "line": 23, - "column": 26, + "line": 1, + "column": 3, "program": "lambda_unresolved_ref_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 23, @@ -1584,55 +1598,103 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 30, - "column": 20, - "program": "lambda_unresolved_ref_1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } }, - "end": { - "line": 30, - "column": 26, - "program": "lambda_unresolved_ref_1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } } } - }, + ], "loc": { "start": { - "line": 30, - "column": 20, + "line": 1, + "column": 3, "program": "lambda_unresolved_ref_1.ets" }, "end": { - "line": 30, - "column": 27, + "line": 1, + "column": 3, "program": "lambda_unresolved_ref_1.ets" } } }, "loc": { "start": { - "line": 30, - "column": 20, + "line": 1, + "column": 1, "program": "lambda_unresolved_ref_1.ets" }, "end": { - "line": 30, - "column": 27, + "line": 1, + "column": 3, "program": "lambda_unresolved_ref_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 30, @@ -2318,23 +2380,71 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + }, "loc": { "start": { - "line": 40, - "column": 11, + "line": 1, + "column": 1, "program": "lambda_unresolved_ref_1.ets" }, "end": { - "line": 40, - "column": 16, + "line": 1, + "column": 3, "program": "lambda_unresolved_ref_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 40, @@ -3252,23 +3362,71 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lambda_unresolved_ref_1.ets" + } + } + }, "loc": { "start": { - "line": 51, - "column": 14, + "line": 1, + "column": 1, "program": "lambda_unresolved_ref_1.ets" }, "end": { - "line": 51, - "column": 19, + "line": 1, + "column": 3, "program": "lambda_unresolved_ref_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 51, diff --git a/ets2panda/test/compiler/ets/launch_expression-expected.txt b/ets2panda/test/compiler/ets/launch_expression-expected.txt index cd89afa987196cc48c981f287723d1105450ee46..8c8e6cf95172948c5faee77b8330f5ce4c5dccdd 100644 --- a/ets2panda/test/compiler/ets/launch_expression-expected.txt +++ b/ets2panda/test/compiler/ets/launch_expression-expected.txt @@ -1,6 +1,88 @@ { "type": "Program", "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/concurrency", + "loc": { + "start": { + "line": 16, + "column": 22, + "program": "launch_expression.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_expression.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_expression.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_expression.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_expression.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_expression.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_expression.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1, + "program": "launch_expression.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_expression.ets" + } + } + }, { "type": "TSTypeAliasDeclaration", "id": { @@ -9,12 +91,12 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 22, "column": 6, "program": "launch_expression.ets" }, "end": { - "line": 20, + "line": 22, "column": 7, "program": "launch_expression.ets" } @@ -29,17 +111,17 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "Promise", + "name": "Job", "decorators": [], "loc": { "start": { - "line": 20, + "line": 22, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 20, - "column": 17, + "line": 22, + "column": 13, "program": "launch_expression.ets" } } @@ -57,39 +139,39 @@ "decorators": [], "loc": { "start": { - "line": 20, - "column": 18, + "line": 22, + "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 20, - "column": 21, + "line": 22, + "column": 17, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 20, - "column": 18, + "line": 22, + "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 20, - "column": 22, + "line": 22, + "column": 18, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 20, - "column": 18, + "line": 22, + "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 20, - "column": 22, + "line": 22, + "column": 18, "program": "launch_expression.ets" } } @@ -97,39 +179,39 @@ ], "loc": { "start": { - "line": 20, - "column": 17, + "line": 22, + "column": 13, "program": "launch_expression.ets" }, "end": { - "line": 20, - "column": 22, + "line": 22, + "column": 18, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 20, + "line": 22, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 20, - "column": 24, + "line": 22, + "column": 20, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 20, + "line": 22, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 20, - "column": 24, + "line": 22, + "column": 20, "program": "launch_expression.ets" } } @@ -138,13 +220,13 @@ "type": "ETSUndefinedType", "loc": { "start": { - "line": 20, - "column": 25, + "line": 22, + "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 20, - "column": 34, + "line": 22, + "column": 30, "program": "launch_expression.ets" } } @@ -152,25 +234,25 @@ ], "loc": { "start": { - "line": 20, + "line": 22, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 20, - "column": 34, + "line": 22, + "column": 30, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 20, + "line": 22, "column": 1, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 9, "program": "launch_expression.ets" } @@ -198,40 +280,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_expression.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_expression.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -296,12 +344,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 18, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 16, + "line": 18, "column": 10, "program": "launch_expression.ets" } @@ -312,12 +360,12 @@ "value": 2, "loc": { "start": { - "line": 16, + "line": 18, "column": 13, "program": "launch_expression.ets" }, "end": { - "line": 16, + "line": 18, "column": 14, "program": "launch_expression.ets" } @@ -325,12 +373,12 @@ }, "loc": { "start": { - "line": 16, + "line": 18, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 16, + "line": 18, "column": 14, "program": "launch_expression.ets" } @@ -338,12 +386,12 @@ }, "loc": { "start": { - "line": 16, + "line": 18, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 16, + "line": 18, "column": 14, "program": "launch_expression.ets" } @@ -360,12 +408,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 19, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 17, + "line": 19, "column": 6, "program": "launch_expression.ets" } @@ -376,12 +424,12 @@ "value": 9, "loc": { "start": { - "line": 17, + "line": 19, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 17, + "line": 19, "column": 10, "program": "launch_expression.ets" } @@ -389,12 +437,12 @@ }, "loc": { "start": { - "line": 17, + "line": 19, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 17, + "line": 19, "column": 10, "program": "launch_expression.ets" } @@ -402,12 +450,12 @@ }, "loc": { "start": { - "line": 17, + "line": 19, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 17, + "line": 19, "column": 10, "program": "launch_expression.ets" } @@ -424,12 +472,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 20, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 18, + "line": 20, "column": 6, "program": "launch_expression.ets" } @@ -441,12 +489,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 18, + "line": 20, "column": 20, "program": "launch_expression.ets" }, "end": { - "line": 18, + "line": 20, "column": 23, "program": "launch_expression.ets" } @@ -458,12 +506,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 20, "column": 24, "program": "launch_expression.ets" }, "end": { - "line": 18, + "line": 20, "column": 29, "program": "launch_expression.ets" } @@ -471,12 +519,12 @@ }, "loc": { "start": { - "line": 18, + "line": 20, "column": 16, "program": "launch_expression.ets" }, "end": { - "line": 18, + "line": 20, "column": 30, "program": "launch_expression.ets" } @@ -484,12 +532,12 @@ }, "loc": { "start": { - "line": 18, + "line": 20, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 18, + "line": 20, "column": 30, "program": "launch_expression.ets" } @@ -497,12 +545,12 @@ }, "loc": { "start": { - "line": 18, + "line": 20, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 18, + "line": 20, "column": 30, "program": "launch_expression.ets" } @@ -519,12 +567,12 @@ "decorators": [], "loc": { "start": { - "line": 19, + "line": 21, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 19, + "line": 21, "column": 6, "program": "launch_expression.ets" } @@ -536,12 +584,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 19, + "line": 21, "column": 20, "program": "launch_expression.ets" }, "end": { - "line": 19, + "line": 21, "column": 23, "program": "launch_expression.ets" } @@ -553,12 +601,12 @@ "decorators": [], "loc": { "start": { - "line": 19, + "line": 21, "column": 24, "program": "launch_expression.ets" }, "end": { - "line": 19, + "line": 21, "column": 29, "program": "launch_expression.ets" } @@ -566,12 +614,12 @@ }, "loc": { "start": { - "line": 19, + "line": 21, "column": 16, "program": "launch_expression.ets" }, "end": { - "line": 19, + "line": 21, "column": 30, "program": "launch_expression.ets" } @@ -579,12 +627,12 @@ }, "loc": { "start": { - "line": 19, + "line": 21, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 19, + "line": 21, "column": 30, "program": "launch_expression.ets" } @@ -592,12 +640,12 @@ }, "loc": { "start": { - "line": 19, + "line": 21, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 19, + "line": 21, "column": 30, "program": "launch_expression.ets" } @@ -666,12 +714,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 18, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 16, + "line": 18, "column": 10, "program": "launch_expression.ets" } @@ -682,12 +730,12 @@ "value": 2, "loc": { "start": { - "line": 16, + "line": 18, "column": 13, "program": "launch_expression.ets" }, "end": { - "line": 16, + "line": 18, "column": 14, "program": "launch_expression.ets" } @@ -703,12 +751,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 18, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 16, + "line": 18, "column": 14, "program": "launch_expression.ets" } @@ -722,12 +770,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 19, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 17, + "line": 19, "column": 6, "program": "launch_expression.ets" } @@ -738,12 +786,12 @@ "value": 9, "loc": { "start": { - "line": 17, + "line": 19, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 17, + "line": 19, "column": 10, "program": "launch_expression.ets" } @@ -759,12 +807,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 19, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 17, + "line": 19, "column": 10, "program": "launch_expression.ets" } @@ -778,12 +826,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 20, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 18, + "line": 20, "column": 6, "program": "launch_expression.ets" } @@ -796,31 +844,79 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } + } + }, "loc": { "start": { - "line": 18, - "column": 8, + "line": 1, + "column": 1, "program": "launch_expression.ets" }, "end": { - "line": 18, - "column": 11, + "line": 1, + "column": 3, "program": "launch_expression.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 18, + "line": 20, "column": 11, "program": "launch_expression.ets" }, "end": { - "line": 18, + "line": 20, "column": 13, "program": "launch_expression.ets" } @@ -830,12 +926,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 20, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 18, + "line": 20, "column": 30, "program": "launch_expression.ets" } @@ -849,12 +945,12 @@ "decorators": [], "loc": { "start": { - "line": 19, + "line": 21, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 19, + "line": 21, "column": 6, "program": "launch_expression.ets" } @@ -867,31 +963,79 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } + } + }, "loc": { "start": { - "line": 19, - "column": 8, + "line": 1, + "column": 1, "program": "launch_expression.ets" }, "end": { - "line": 19, - "column": 11, + "line": 1, + "column": 3, "program": "launch_expression.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 19, + "line": 21, "column": 11, "program": "launch_expression.ets" }, "end": { - "line": 19, + "line": 21, "column": 13, "program": "launch_expression.ets" } @@ -901,12 +1045,12 @@ "decorators": [], "loc": { "start": { - "line": 19, + "line": 21, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 19, + "line": 21, "column": 30, "program": "launch_expression.ets" } @@ -920,12 +1064,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 23, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 19, "program": "launch_expression.ets" } @@ -946,12 +1090,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 23, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 19, "program": "launch_expression.ets" } @@ -970,12 +1114,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 21, + "line": 23, "column": 28, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 31, "program": "launch_expression.ets" } @@ -984,12 +1128,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 23, "column": 20, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 31, "program": "launch_expression.ets" } @@ -997,12 +1141,12 @@ }, "loc": { "start": { - "line": 21, + "line": 23, "column": 20, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 31, "program": "launch_expression.ets" } @@ -1017,12 +1161,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 21, + "line": 23, "column": 41, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 44, "program": "launch_expression.ets" } @@ -1031,12 +1175,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 23, "column": 33, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 44, "program": "launch_expression.ets" } @@ -1044,12 +1188,12 @@ }, "loc": { "start": { - "line": 21, + "line": 23, "column": 33, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 44, "program": "launch_expression.ets" } @@ -1060,12 +1204,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 21, + "line": 23, "column": 47, "program": "launch_expression.ets" }, "end": { - "line": 21, + "line": 23, "column": 51, "program": "launch_expression.ets" } @@ -1085,12 +1229,12 @@ "decorators": [], "loc": { "start": { - "line": 22, + "line": 24, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 22, + "line": 24, "column": 15, "program": "launch_expression.ets" } @@ -1102,12 +1246,12 @@ "decorators": [], "loc": { "start": { - "line": 22, + "line": 24, "column": 19, "program": "launch_expression.ets" }, "end": { - "line": 22, + "line": 24, "column": 25, "program": "launch_expression.ets" } @@ -1115,12 +1259,12 @@ }, "loc": { "start": { - "line": 22, + "line": 24, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 22, + "line": 24, "column": 25, "program": "launch_expression.ets" } @@ -1134,12 +1278,12 @@ "argument": null, "loc": { "start": { - "line": 23, + "line": 25, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 23, + "line": 25, "column": 16, "program": "launch_expression.ets" } @@ -1148,12 +1292,12 @@ ], "loc": { "start": { - "line": 22, + "line": 24, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 24, + "line": 26, "column": 6, "program": "launch_expression.ets" } @@ -1162,12 +1306,12 @@ "alternate": null, "loc": { "start": { - "line": 22, + "line": 24, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 24, + "line": 26, "column": 6, "program": "launch_expression.ets" } @@ -1185,12 +1329,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 27, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 12, "program": "launch_expression.ets" } @@ -1202,12 +1346,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 27, "column": 13, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 20, "program": "launch_expression.ets" } @@ -1217,12 +1361,12 @@ "optional": false, "loc": { "start": { - "line": 25, + "line": 27, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 20, "program": "launch_expression.ets" } @@ -1243,12 +1387,12 @@ "value": "Values of type int are not equal: ", "loc": { "start": { - "line": 25, + "line": 27, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 57, "program": "launch_expression.ets" } @@ -1260,12 +1404,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 27, "column": 60, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 66, "program": "launch_expression.ets" } @@ -1273,12 +1417,12 @@ }, "loc": { "start": { - "line": 25, + "line": 27, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 66, "program": "launch_expression.ets" } @@ -1289,12 +1433,12 @@ "value": " != ", "loc": { "start": { - "line": 25, + "line": 27, "column": 69, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 75, "program": "launch_expression.ets" } @@ -1302,12 +1446,12 @@ }, "loc": { "start": { - "line": 25, + "line": 27, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 75, "program": "launch_expression.ets" } @@ -1319,12 +1463,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 27, "column": 78, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 84, "program": "launch_expression.ets" } @@ -1332,12 +1476,12 @@ }, "loc": { "start": { - "line": 25, + "line": 27, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 84, "program": "launch_expression.ets" } @@ -1347,12 +1491,12 @@ "optional": false, "loc": { "start": { - "line": 25, + "line": 27, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 85, "program": "launch_expression.ets" } @@ -1360,12 +1504,12 @@ }, "loc": { "start": { - "line": 25, + "line": 27, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 25, + "line": 27, "column": 86, "program": "launch_expression.ets" } @@ -1385,12 +1529,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 28, "column": 15, "program": "launch_expression.ets" }, "end": { - "line": 26, + "line": 28, "column": 20, "program": "launch_expression.ets" } @@ -1398,12 +1542,12 @@ }, "loc": { "start": { - "line": 26, + "line": 28, "column": 15, "program": "launch_expression.ets" }, "end": { - "line": 26, + "line": 28, "column": 21, "program": "launch_expression.ets" } @@ -1411,12 +1555,12 @@ }, "loc": { "start": { - "line": 26, + "line": 28, "column": 15, "program": "launch_expression.ets" }, "end": { - "line": 26, + "line": 28, "column": 21, "program": "launch_expression.ets" } @@ -1425,12 +1569,12 @@ "arguments": [], "loc": { "start": { - "line": 26, + "line": 28, "column": 11, "program": "launch_expression.ets" }, "end": { - "line": 26, + "line": 28, "column": 23, "program": "launch_expression.ets" } @@ -1438,12 +1582,12 @@ }, "loc": { "start": { - "line": 26, + "line": 28, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 26, + "line": 28, "column": 23, "program": "launch_expression.ets" } @@ -1452,12 +1596,12 @@ ], "loc": { "start": { - "line": 21, + "line": 23, "column": 52, "program": "launch_expression.ets" }, "end": { - "line": 27, + "line": 29, "column": 2, "program": "launch_expression.ets" } @@ -1465,12 +1609,12 @@ }, "loc": { "start": { - "line": 21, + "line": 23, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 27, + "line": 29, "column": 2, "program": "launch_expression.ets" } @@ -1478,12 +1622,12 @@ }, "loc": { "start": { - "line": 21, + "line": 23, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 27, + "line": 29, "column": 2, "program": "launch_expression.ets" } @@ -1493,12 +1637,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 23, "column": 1, "program": "launch_expression.ets" }, "end": { - "line": 27, + "line": 29, "column": 2, "program": "launch_expression.ets" } @@ -1512,12 +1656,12 @@ "decorators": [], "loc": { "start": { - "line": 28, + "line": 30, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 28, + "line": 30, "column": 14, "program": "launch_expression.ets" } @@ -1538,12 +1682,12 @@ "decorators": [], "loc": { "start": { - "line": 28, + "line": 30, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 28, + "line": 30, "column": 14, "program": "launch_expression.ets" } @@ -1562,12 +1706,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 28, + "line": 30, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 28, + "line": 30, "column": 21, "program": "launch_expression.ets" } @@ -1576,12 +1720,12 @@ "decorators": [], "loc": { "start": { - "line": 28, + "line": 30, "column": 15, "program": "launch_expression.ets" }, "end": { - "line": 28, + "line": 30, "column": 21, "program": "launch_expression.ets" } @@ -1589,12 +1733,12 @@ }, "loc": { "start": { - "line": 28, + "line": 30, "column": 15, "program": "launch_expression.ets" }, "end": { - "line": 28, + "line": 30, "column": 21, "program": "launch_expression.ets" } @@ -1611,12 +1755,12 @@ "decorators": [], "loc": { "start": { - "line": 28, + "line": 30, "column": 25, "program": "launch_expression.ets" }, "end": { - "line": 28, + "line": 30, "column": 28, "program": "launch_expression.ets" } @@ -1624,12 +1768,12 @@ }, "loc": { "start": { - "line": 28, + "line": 30, "column": 25, "program": "launch_expression.ets" }, "end": { - "line": 28, + "line": 30, "column": 30, "program": "launch_expression.ets" } @@ -1637,12 +1781,12 @@ }, "loc": { "start": { - "line": 28, + "line": 30, "column": 25, "program": "launch_expression.ets" }, "end": { - "line": 28, + "line": 30, "column": 30, "program": "launch_expression.ets" } @@ -1665,12 +1809,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 31, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 29, + "line": 31, "column": 10, "program": "launch_expression.ets" } @@ -1681,12 +1825,12 @@ "value": 0, "loc": { "start": { - "line": 29, + "line": 31, "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 29, + "line": 31, "column": 15, "program": "launch_expression.ets" } @@ -1694,12 +1838,12 @@ }, "loc": { "start": { - "line": 29, + "line": 31, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 29, + "line": 31, "column": 15, "program": "launch_expression.ets" } @@ -1714,12 +1858,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 31, "column": 19, "program": "launch_expression.ets" }, "end": { - "line": 29, + "line": 31, "column": 20, "program": "launch_expression.ets" } @@ -1731,12 +1875,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 31, "column": 23, "program": "launch_expression.ets" }, "end": { - "line": 29, + "line": 31, "column": 28, "program": "launch_expression.ets" } @@ -1744,12 +1888,12 @@ }, "loc": { "start": { - "line": 29, + "line": 31, "column": 19, "program": "launch_expression.ets" }, "end": { - "line": 29, + "line": 31, "column": 28, "program": "launch_expression.ets" } @@ -1757,12 +1901,12 @@ }, "loc": { "start": { - "line": 29, + "line": 31, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 29, + "line": 31, "column": 28, "program": "launch_expression.ets" } @@ -1781,12 +1925,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 32, "column": 16, "program": "launch_expression.ets" }, "end": { - "line": 30, + "line": 32, "column": 17, "program": "launch_expression.ets" } @@ -1798,12 +1942,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 32, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 30, + "line": 32, "column": 19, "program": "launch_expression.ets" } @@ -1813,12 +1957,12 @@ "optional": false, "loc": { "start": { - "line": 30, + "line": 32, "column": 16, "program": "launch_expression.ets" }, "end": { - "line": 30, + "line": 32, "column": 20, "program": "launch_expression.ets" } @@ -1826,12 +1970,12 @@ }, "loc": { "start": { - "line": 30, + "line": 32, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 30, + "line": 32, "column": 21, "program": "launch_expression.ets" } @@ -1840,12 +1984,12 @@ ], "loc": { "start": { - "line": 29, + "line": 31, "column": 30, "program": "launch_expression.ets" }, "end": { - "line": 31, + "line": 33, "column": 6, "program": "launch_expression.ets" } @@ -1854,12 +1998,12 @@ "alternate": null, "loc": { "start": { - "line": 29, + "line": 31, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 31, + "line": 33, "column": 6, "program": "launch_expression.ets" } @@ -1874,63 +2018,111 @@ "type": "Identifier", "name": "p", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "P", - "decorators": [], - "loc": { - "start": { - "line": 32, - "column": 12, - "program": "launch_expression.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "P", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } + } }, - "end": { - "line": 32, - "column": 13, - "program": "launch_expression.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "launch_expression.ets" + } } } - }, + ], "loc": { "start": { - "line": 32, - "column": 12, + "line": 1, + "column": 3, "program": "launch_expression.ets" }, "end": { - "line": 32, - "column": 14, + "line": 1, + "column": 3, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 32, - "column": 12, + "line": 1, + "column": 1, "program": "launch_expression.ets" }, "end": { - "line": 32, - "column": 14, + "line": 1, + "column": 3, "program": "launch_expression.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 32, + "line": 34, "column": 13, "program": "launch_expression.ets" }, "end": { - "line": 32, + "line": 34, "column": 15, "program": "launch_expression.ets" } @@ -1939,12 +2131,12 @@ "decorators": [], "loc": { "start": { - "line": 32, + "line": 34, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 32, + "line": 34, "column": 10, "program": "launch_expression.ets" } @@ -1962,12 +2154,12 @@ "decorators": [], "loc": { "start": { - "line": 32, + "line": 34, "column": 22, "program": "launch_expression.ets" }, "end": { - "line": 32, + "line": 34, "column": 23, "program": "launch_expression.ets" } @@ -1975,12 +2167,12 @@ }, "loc": { "start": { - "line": 32, + "line": 34, "column": 22, "program": "launch_expression.ets" }, "end": { - "line": 32, + "line": 34, "column": 24, "program": "launch_expression.ets" } @@ -1988,12 +2180,12 @@ }, "loc": { "start": { - "line": 32, + "line": 34, "column": 22, "program": "launch_expression.ets" }, "end": { - "line": 32, + "line": 34, "column": 24, "program": "launch_expression.ets" } @@ -2005,12 +2197,12 @@ "decorators": [], "loc": { "start": { - "line": 32, + "line": 34, "column": 24, "program": "launch_expression.ets" }, "end": { - "line": 32, + "line": 34, "column": 29, "program": "launch_expression.ets" } @@ -2018,12 +2210,12 @@ }, "loc": { "start": { - "line": 32, + "line": 34, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 32, + "line": 34, "column": 30, "program": "launch_expression.ets" } @@ -2031,12 +2223,12 @@ }, "loc": { "start": { - "line": 32, + "line": 34, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 32, + "line": 34, "column": 30, "program": "launch_expression.ets" } @@ -2046,12 +2238,12 @@ "kind": "let", "loc": { "start": { - "line": 32, + "line": 34, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 32, + "line": 34, "column": 30, "program": "launch_expression.ets" } @@ -2070,12 +2262,12 @@ "decorators": [], "loc": { "start": { - "line": 33, + "line": 35, "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 33, + "line": 35, "column": 15, "program": "launch_expression.ets" } @@ -2086,12 +2278,12 @@ "value": 0, "loc": { "start": { - "line": 33, + "line": 35, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 33, + "line": 35, "column": 19, "program": "launch_expression.ets" } @@ -2099,12 +2291,12 @@ }, "loc": { "start": { - "line": 33, + "line": 35, "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 33, + "line": 35, "column": 19, "program": "launch_expression.ets" } @@ -2114,12 +2306,12 @@ "kind": "let", "loc": { "start": { - "line": 33, + "line": 35, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 33, + "line": 35, "column": 19, "program": "launch_expression.ets" } @@ -2134,12 +2326,12 @@ "decorators": [], "loc": { "start": { - "line": 33, + "line": 35, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 33, + "line": 35, "column": 22, "program": "launch_expression.ets" } @@ -2151,12 +2343,12 @@ "decorators": [], "loc": { "start": { - "line": 33, + "line": 35, "column": 25, "program": "launch_expression.ets" }, "end": { - "line": 33, + "line": 35, "column": 30, "program": "launch_expression.ets" } @@ -2164,12 +2356,12 @@ }, "loc": { "start": { - "line": 33, + "line": 35, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 33, + "line": 35, "column": 30, "program": "launch_expression.ets" } @@ -2185,12 +2377,12 @@ "decorators": [], "loc": { "start": { - "line": 33, + "line": 35, "column": 34, "program": "launch_expression.ets" }, "end": { - "line": 33, + "line": 35, "column": 35, "program": "launch_expression.ets" } @@ -2198,12 +2390,12 @@ }, "loc": { "start": { - "line": 33, + "line": 35, "column": 32, "program": "launch_expression.ets" }, "end": { - "line": 33, + "line": 35, "column": 35, "program": "launch_expression.ets" } @@ -2225,12 +2417,12 @@ "decorators": [], "loc": { "start": { - "line": 34, + "line": 36, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 34, + "line": 36, "column": 10, "program": "launch_expression.ets" } @@ -2242,12 +2434,12 @@ "decorators": [], "loc": { "start": { - "line": 34, + "line": 36, "column": 11, "program": "launch_expression.ets" }, "end": { - "line": 34, + "line": 36, "column": 12, "program": "launch_expression.ets" } @@ -2257,171 +2449,348 @@ "optional": false, "loc": { "start": { - "line": 34, + "line": 36, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 34, + "line": 36, "column": 13, "program": "launch_expression.ets" } } }, "right": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 16, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 22, + "program": "launch_expression.ets" + } + } + }, + "arguments": [ + { "type": "Identifier", "name": "ufib", "decorators": [], "loc": { "start": { - "line": 34, - "column": 23, + "line": 36, + "column": 45, "program": "launch_expression.ets" }, "end": { - "line": 34, - "column": 27, + "line": 36, + "column": 49, "program": "launch_expression.ets" } } }, - "arguments": [ - { + { + "type": "BinaryExpression", + "operator": "-", + "left": { "type": "BinaryExpression", "operator": "-", "left": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "Identifier", - "name": "n", - "decorators": [], - "loc": { - "start": { - "line": 34, - "column": 28, - "program": "launch_expression.ets" - }, - "end": { - "line": 34, - "column": 29, - "program": "launch_expression.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 34, - "column": 30, - "program": "launch_expression.ets" - }, - "end": { - "line": 34, - "column": 31, - "program": "launch_expression.ets" - } - } - }, + "type": "Identifier", + "name": "n", + "decorators": [], "loc": { "start": { - "line": 34, - "column": 28, + "line": 36, + "column": 51, "program": "launch_expression.ets" }, "end": { - "line": 34, - "column": 31, + "line": 36, + "column": 52, "program": "launch_expression.ets" } } }, "right": { - "type": "Identifier", - "name": "i", - "decorators": [], + "type": "NumberLiteral", + "value": 1, "loc": { "start": { - "line": 34, - "column": 32, + "line": 36, + "column": 53, "program": "launch_expression.ets" }, "end": { - "line": 34, - "column": 33, + "line": 36, + "column": 54, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 34, - "column": 28, + "line": 36, + "column": 51, "program": "launch_expression.ets" }, "end": { - "line": 34, - "column": 33, + "line": 36, + "column": 54, "program": "launch_expression.ets" } } - } - ], - "optional": false, - "loc": { - "start": { - "line": 34, - "column": 23, - "program": "launch_expression.ets" }, - "end": { - "line": 34, - "column": 34, - "program": "launch_expression.ets" + "right": { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 55, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 56, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 51, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 56, + "program": "launch_expression.ets" + } } } - }, - "loc": { - "start": { - "line": 34, - "column": 16, - "program": "launch_expression.ets" + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 23, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 26, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 23, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 27, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 23, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 27, + "program": "launch_expression.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "i", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 36, + "column": 32, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 35, + "program": "launch_expression.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 29, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 35, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 29, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 35, + "program": "launch_expression.ets" + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 40, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 43, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 40, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 44, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 40, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 44, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 28, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 44, + "program": "launch_expression.ets" + } + } + } + ], + "loc": { + "start": { + "line": 36, + "column": 22, + "program": "launch_expression.ets" + }, + "end": { + "line": 36, + "column": 44, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 16, + "program": "launch_expression.ets" }, "end": { - "line": 34, - "column": 34, + "line": 36, + "column": 57, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 34, + "line": 36, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 34, - "column": 34, + "line": 36, + "column": 57, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 34, + "line": 36, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 34, - "column": 35, + "line": 36, + "column": 58, "program": "launch_expression.ets" } } @@ -2429,12 +2798,12 @@ ], "loc": { "start": { - "line": 33, + "line": 35, "column": 37, "program": "launch_expression.ets" }, "end": { - "line": 35, + "line": 37, "column": 6, "program": "launch_expression.ets" } @@ -2442,12 +2811,12 @@ }, "loc": { "start": { - "line": 33, + "line": 35, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 35, + "line": 37, "column": 6, "program": "launch_expression.ets" } @@ -2464,12 +2833,12 @@ "decorators": [], "loc": { "start": { - "line": 36, + "line": 38, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 36, + "line": 38, "column": 15, "program": "launch_expression.ets" } @@ -2480,12 +2849,12 @@ "value": 0, "loc": { "start": { - "line": 36, + "line": 38, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 36, + "line": 38, "column": 19, "program": "launch_expression.ets" } @@ -2493,12 +2862,12 @@ }, "loc": { "start": { - "line": 36, + "line": 38, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 36, + "line": 38, "column": 19, "program": "launch_expression.ets" } @@ -2508,12 +2877,12 @@ "kind": "let", "loc": { "start": { - "line": 36, + "line": 38, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 36, + "line": 38, "column": 19, "program": "launch_expression.ets" } @@ -2532,12 +2901,12 @@ "decorators": [], "loc": { "start": { - "line": 37, + "line": 39, "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 37, + "line": 39, "column": 15, "program": "launch_expression.ets" } @@ -2548,12 +2917,12 @@ "value": 0, "loc": { "start": { - "line": 37, + "line": 39, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 37, + "line": 39, "column": 19, "program": "launch_expression.ets" } @@ -2561,12 +2930,12 @@ }, "loc": { "start": { - "line": 37, + "line": 39, "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 37, + "line": 39, "column": 19, "program": "launch_expression.ets" } @@ -2576,12 +2945,12 @@ "kind": "let", "loc": { "start": { - "line": 37, + "line": 39, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 37, + "line": 39, "column": 19, "program": "launch_expression.ets" } @@ -2596,12 +2965,12 @@ "decorators": [], "loc": { "start": { - "line": 37, + "line": 39, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 37, + "line": 39, "column": 22, "program": "launch_expression.ets" } @@ -2613,12 +2982,12 @@ "decorators": [], "loc": { "start": { - "line": 37, + "line": 39, "column": 25, "program": "launch_expression.ets" }, "end": { - "line": 37, + "line": 39, "column": 30, "program": "launch_expression.ets" } @@ -2626,12 +2995,12 @@ }, "loc": { "start": { - "line": 37, + "line": 39, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 37, + "line": 39, "column": 30, "program": "launch_expression.ets" } @@ -2647,12 +3016,12 @@ "decorators": [], "loc": { "start": { - "line": 37, + "line": 39, "column": 34, "program": "launch_expression.ets" }, "end": { - "line": 37, + "line": 39, "column": 35, "program": "launch_expression.ets" } @@ -2660,12 +3029,12 @@ }, "loc": { "start": { - "line": 37, + "line": 39, "column": 32, "program": "launch_expression.ets" }, "end": { - "line": 37, + "line": 39, "column": 35, "program": "launch_expression.ets" } @@ -2685,12 +3054,12 @@ "decorators": [], "loc": { "start": { - "line": 38, + "line": 40, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 38, + "line": 40, "column": 15, "program": "launch_expression.ets" } @@ -2705,12 +3074,12 @@ "decorators": [], "loc": { "start": { - "line": 38, + "line": 40, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 38, + "line": 40, "column": 24, "program": "launch_expression.ets" } @@ -2733,12 +3102,12 @@ "decorators": [], "loc": { "start": { - "line": 38, + "line": 40, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 38, + "line": 40, "column": 28, "program": "launch_expression.ets" } @@ -2750,12 +3119,12 @@ "decorators": [], "loc": { "start": { - "line": 38, + "line": 40, "column": 29, "program": "launch_expression.ets" }, "end": { - "line": 38, + "line": 40, "column": 30, "program": "launch_expression.ets" } @@ -2765,12 +3134,12 @@ "optional": false, "loc": { "start": { - "line": 38, + "line": 40, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 38, + "line": 40, "column": 31, "program": "launch_expression.ets" } @@ -2778,12 +3147,12 @@ }, "loc": { "start": { - "line": 38, + "line": 40, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 38, + "line": 40, "column": 32, "program": "launch_expression.ets" } @@ -2791,17 +3160,17 @@ }, "property": { "type": "Identifier", - "name": "awaitResolution", + "name": "Await", "decorators": [], "loc": { "start": { - "line": 38, + "line": 40, "column": 33, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 48, + "line": 40, + "column": 38, "program": "launch_expression.ets" } } @@ -2810,13 +3179,13 @@ "optional": false, "loc": { "start": { - "line": 38, + "line": 40, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 48, + "line": 40, + "column": 38, "program": "launch_expression.ets" } } @@ -2825,13 +3194,13 @@ "optional": false, "loc": { "start": { - "line": 38, + "line": 40, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 50, + "line": 40, + "column": 40, "program": "launch_expression.ets" } } @@ -2844,13 +3213,13 @@ "decorators": [], "loc": { "start": { - "line": 38, - "column": 53, + "line": 40, + "column": 43, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 54, + "line": 40, + "column": 44, "program": "launch_expression.ets" } } @@ -2861,13 +3230,13 @@ "decorators": [], "loc": { "start": { - "line": 38, - "column": 55, + "line": 40, + "column": 45, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 56, + "line": 40, + "column": 46, "program": "launch_expression.ets" } } @@ -2876,65 +3245,65 @@ "optional": false, "loc": { "start": { - "line": 38, - "column": 53, + "line": 40, + "column": 43, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 57, + "line": 40, + "column": 47, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 38, + "line": 40, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 57, + "line": 40, + "column": 47, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 38, + "line": 40, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 57, + "line": 40, + "column": 47, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 38, + "line": 40, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 57, + "line": 40, + "column": 47, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 38, + "line": 40, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 38, - "column": 58, + "line": 40, + "column": 48, "program": "launch_expression.ets" } } @@ -2942,12 +3311,12 @@ ], "loc": { "start": { - "line": 37, + "line": 39, "column": 37, "program": "launch_expression.ets" }, "end": { - "line": 39, + "line": 41, "column": 6, "program": "launch_expression.ets" } @@ -2955,12 +3324,12 @@ }, "loc": { "start": { - "line": 37, + "line": 39, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 39, + "line": 41, "column": 6, "program": "launch_expression.ets" } @@ -2974,12 +3343,12 @@ "decorators": [], "loc": { "start": { - "line": 40, + "line": 42, "column": 12, "program": "launch_expression.ets" }, "end": { - "line": 40, + "line": 42, "column": 18, "program": "launch_expression.ets" } @@ -2987,12 +3356,12 @@ }, "loc": { "start": { - "line": 40, + "line": 42, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 40, + "line": 42, "column": 19, "program": "launch_expression.ets" } @@ -3001,12 +3370,12 @@ ], "loc": { "start": { - "line": 28, + "line": 30, "column": 29, "program": "launch_expression.ets" }, "end": { - "line": 41, + "line": 43, "column": 2, "program": "launch_expression.ets" } @@ -3014,12 +3383,12 @@ }, "loc": { "start": { - "line": 28, + "line": 30, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 41, + "line": 43, "column": 2, "program": "launch_expression.ets" } @@ -3027,12 +3396,12 @@ }, "loc": { "start": { - "line": 28, + "line": 30, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 41, + "line": 43, "column": 2, "program": "launch_expression.ets" } @@ -3042,12 +3411,12 @@ "decorators": [], "loc": { "start": { - "line": 28, + "line": 30, "column": 1, "program": "launch_expression.ets" }, "end": { - "line": 41, + "line": 43, "column": 2, "program": "launch_expression.ets" } @@ -3061,12 +3430,12 @@ "decorators": [], "loc": { "start": { - "line": 42, + "line": 44, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 42, + "line": 44, "column": 18, "program": "launch_expression.ets" } @@ -3087,12 +3456,12 @@ "decorators": [], "loc": { "start": { - "line": 42, + "line": 44, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 42, + "line": 44, "column": 18, "program": "launch_expression.ets" } @@ -3111,12 +3480,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 42, + "line": 44, "column": 22, "program": "launch_expression.ets" }, "end": { - "line": 42, + "line": 44, "column": 25, "program": "launch_expression.ets" } @@ -3125,12 +3494,12 @@ "decorators": [], "loc": { "start": { - "line": 42, + "line": 44, "column": 19, "program": "launch_expression.ets" }, "end": { - "line": 42, + "line": 44, "column": 25, "program": "launch_expression.ets" } @@ -3138,12 +3507,12 @@ }, "loc": { "start": { - "line": 42, + "line": 44, "column": 19, "program": "launch_expression.ets" }, "end": { - "line": 42, + "line": 44, "column": 25, "program": "launch_expression.ets" } @@ -3154,12 +3523,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 42, + "line": 44, "column": 29, "program": "launch_expression.ets" }, "end": { - "line": 42, + "line": 44, "column": 32, "program": "launch_expression.ets" } @@ -3182,12 +3551,12 @@ "decorators": [], "loc": { "start": { - "line": 43, + "line": 45, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 43, + "line": 45, "column": 10, "program": "launch_expression.ets" } @@ -3198,12 +3567,12 @@ "value": 0, "loc": { "start": { - "line": 43, + "line": 45, "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 43, + "line": 45, "column": 15, "program": "launch_expression.ets" } @@ -3211,12 +3580,12 @@ }, "loc": { "start": { - "line": 43, + "line": 45, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 43, + "line": 45, "column": 15, "program": "launch_expression.ets" } @@ -3231,12 +3600,12 @@ "decorators": [], "loc": { "start": { - "line": 43, + "line": 45, "column": 19, "program": "launch_expression.ets" }, "end": { - "line": 43, + "line": 45, "column": 20, "program": "launch_expression.ets" } @@ -3248,12 +3617,12 @@ "decorators": [], "loc": { "start": { - "line": 43, + "line": 45, "column": 23, "program": "launch_expression.ets" }, "end": { - "line": 43, + "line": 45, "column": 28, "program": "launch_expression.ets" } @@ -3261,12 +3630,12 @@ }, "loc": { "start": { - "line": 43, + "line": 45, "column": 19, "program": "launch_expression.ets" }, "end": { - "line": 43, + "line": 45, "column": 28, "program": "launch_expression.ets" } @@ -3274,12 +3643,12 @@ }, "loc": { "start": { - "line": 43, + "line": 45, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 43, + "line": 45, "column": 28, "program": "launch_expression.ets" } @@ -3298,12 +3667,12 @@ "decorators": [], "loc": { "start": { - "line": 44, + "line": 46, "column": 16, "program": "launch_expression.ets" }, "end": { - "line": 44, + "line": 46, "column": 17, "program": "launch_expression.ets" } @@ -3315,12 +3684,12 @@ "decorators": [], "loc": { "start": { - "line": 44, + "line": 46, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 44, + "line": 46, "column": 19, "program": "launch_expression.ets" } @@ -3330,12 +3699,12 @@ "optional": false, "loc": { "start": { - "line": 44, + "line": 46, "column": 16, "program": "launch_expression.ets" }, "end": { - "line": 44, + "line": 46, "column": 20, "program": "launch_expression.ets" } @@ -3343,12 +3712,12 @@ }, "loc": { "start": { - "line": 44, + "line": 46, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 44, + "line": 46, "column": 21, "program": "launch_expression.ets" } @@ -3357,12 +3726,12 @@ ], "loc": { "start": { - "line": 43, + "line": 45, "column": 30, "program": "launch_expression.ets" }, "end": { - "line": 45, + "line": 47, "column": 6, "program": "launch_expression.ets" } @@ -3371,12 +3740,12 @@ "alternate": null, "loc": { "start": { - "line": 43, + "line": 45, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 45, + "line": 47, "column": 6, "program": "launch_expression.ets" } @@ -3393,12 +3762,12 @@ "decorators": [], "loc": { "start": { - "line": 46, + "line": 48, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 46, + "line": 48, "column": 15, "program": "launch_expression.ets" } @@ -3409,12 +3778,12 @@ "value": 0, "loc": { "start": { - "line": 46, + "line": 48, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 46, + "line": 48, "column": 19, "program": "launch_expression.ets" } @@ -3422,12 +3791,12 @@ }, "loc": { "start": { - "line": 46, + "line": 48, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 46, + "line": 48, "column": 19, "program": "launch_expression.ets" } @@ -3437,12 +3806,12 @@ "kind": "let", "loc": { "start": { - "line": 46, + "line": 48, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 46, + "line": 48, "column": 19, "program": "launch_expression.ets" } @@ -3461,12 +3830,12 @@ "decorators": [], "loc": { "start": { - "line": 47, + "line": 49, "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 47, + "line": 49, "column": 15, "program": "launch_expression.ets" } @@ -3477,12 +3846,12 @@ "value": 0, "loc": { "start": { - "line": 47, + "line": 49, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 47, + "line": 49, "column": 19, "program": "launch_expression.ets" } @@ -3490,12 +3859,12 @@ }, "loc": { "start": { - "line": 47, + "line": 49, "column": 14, "program": "launch_expression.ets" }, "end": { - "line": 47, + "line": 49, "column": 19, "program": "launch_expression.ets" } @@ -3505,12 +3874,12 @@ "kind": "let", "loc": { "start": { - "line": 47, + "line": 49, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 47, + "line": 49, "column": 19, "program": "launch_expression.ets" } @@ -3525,12 +3894,12 @@ "decorators": [], "loc": { "start": { - "line": 47, + "line": 49, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 47, + "line": 49, "column": 22, "program": "launch_expression.ets" } @@ -3542,12 +3911,12 @@ "decorators": [], "loc": { "start": { - "line": 47, + "line": 49, "column": 25, "program": "launch_expression.ets" }, "end": { - "line": 47, + "line": 49, "column": 30, "program": "launch_expression.ets" } @@ -3555,12 +3924,12 @@ }, "loc": { "start": { - "line": 47, + "line": 49, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 47, + "line": 49, "column": 30, "program": "launch_expression.ets" } @@ -3576,12 +3945,12 @@ "decorators": [], "loc": { "start": { - "line": 47, + "line": 49, "column": 34, "program": "launch_expression.ets" }, "end": { - "line": 47, + "line": 49, "column": 35, "program": "launch_expression.ets" } @@ -3589,12 +3958,12 @@ }, "loc": { "start": { - "line": 47, + "line": 49, "column": 32, "program": "launch_expression.ets" }, "end": { - "line": 47, + "line": 49, "column": 35, "program": "launch_expression.ets" } @@ -3614,12 +3983,12 @@ "decorators": [], "loc": { "start": { - "line": 48, + "line": 50, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 15, "program": "launch_expression.ets" } @@ -3634,12 +4003,12 @@ "decorators": [], "loc": { "start": { - "line": 48, + "line": 50, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 24, "program": "launch_expression.ets" } @@ -3656,12 +4025,12 @@ "decorators": [], "loc": { "start": { - "line": 48, + "line": 50, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 35, "program": "launch_expression.ets" } @@ -3680,12 +4049,12 @@ "decorators": [], "loc": { "start": { - "line": 48, + "line": 50, "column": 36, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 37, "program": "launch_expression.ets" } @@ -3696,12 +4065,12 @@ "value": 1, "loc": { "start": { - "line": 48, + "line": 50, "column": 38, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 39, "program": "launch_expression.ets" } @@ -3709,12 +4078,12 @@ }, "loc": { "start": { - "line": 48, + "line": 50, "column": 36, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 39, "program": "launch_expression.ets" } @@ -3726,12 +4095,12 @@ "decorators": [], "loc": { "start": { - "line": 48, + "line": 50, "column": 40, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 41, "program": "launch_expression.ets" } @@ -3739,12 +4108,12 @@ }, "loc": { "start": { - "line": 48, + "line": 50, "column": 36, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 41, "program": "launch_expression.ets" } @@ -3754,12 +4123,12 @@ "optional": false, "loc": { "start": { - "line": 48, + "line": 50, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 42, "program": "launch_expression.ets" } @@ -3773,12 +4142,12 @@ "decorators": [], "loc": { "start": { - "line": 48, + "line": 50, "column": 45, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 46, "program": "launch_expression.ets" } @@ -3790,12 +4159,12 @@ "decorators": [], "loc": { "start": { - "line": 48, + "line": 50, "column": 47, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 48, "program": "launch_expression.ets" } @@ -3805,12 +4174,12 @@ "optional": false, "loc": { "start": { - "line": 48, + "line": 50, "column": 45, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 49, "program": "launch_expression.ets" } @@ -3818,12 +4187,12 @@ }, "loc": { "start": { - "line": 48, + "line": 50, "column": 27, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 49, "program": "launch_expression.ets" } @@ -3831,12 +4200,12 @@ }, "loc": { "start": { - "line": 48, + "line": 50, "column": 18, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 49, "program": "launch_expression.ets" } @@ -3844,12 +4213,12 @@ }, "loc": { "start": { - "line": 48, + "line": 50, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 49, "program": "launch_expression.ets" } @@ -3857,12 +4226,12 @@ }, "loc": { "start": { - "line": 48, + "line": 50, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 48, + "line": 50, "column": 50, "program": "launch_expression.ets" } @@ -3871,12 +4240,12 @@ ], "loc": { "start": { - "line": 47, + "line": 49, "column": 37, "program": "launch_expression.ets" }, "end": { - "line": 49, + "line": 51, "column": 6, "program": "launch_expression.ets" } @@ -3884,12 +4253,12 @@ }, "loc": { "start": { - "line": 47, + "line": 49, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 49, + "line": 51, "column": 6, "program": "launch_expression.ets" } @@ -3903,12 +4272,12 @@ "decorators": [], "loc": { "start": { - "line": 50, + "line": 52, "column": 12, "program": "launch_expression.ets" }, "end": { - "line": 50, + "line": 52, "column": 18, "program": "launch_expression.ets" } @@ -3916,12 +4285,12 @@ }, "loc": { "start": { - "line": 50, + "line": 52, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 50, + "line": 52, "column": 19, "program": "launch_expression.ets" } @@ -3930,12 +4299,12 @@ ], "loc": { "start": { - "line": 42, + "line": 44, "column": 33, "program": "launch_expression.ets" }, "end": { - "line": 51, + "line": 53, "column": 2, "program": "launch_expression.ets" } @@ -3943,12 +4312,12 @@ }, "loc": { "start": { - "line": 42, + "line": 44, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 51, + "line": 53, "column": 2, "program": "launch_expression.ets" } @@ -3956,12 +4325,12 @@ }, "loc": { "start": { - "line": 42, + "line": 44, "column": 10, "program": "launch_expression.ets" }, "end": { - "line": 51, + "line": 53, "column": 2, "program": "launch_expression.ets" } @@ -3971,12 +4340,12 @@ "decorators": [], "loc": { "start": { - "line": 42, + "line": 44, "column": 1, "program": "launch_expression.ets" }, "end": { - "line": 51, + "line": 53, "column": 2, "program": "launch_expression.ets" } @@ -3990,12 +4359,12 @@ "decorators": [], "loc": { "start": { - "line": 52, + "line": 54, "column": 17, "program": "launch_expression.ets" }, "end": { - "line": 52, + "line": 54, "column": 21, "program": "launch_expression.ets" } @@ -4016,12 +4385,12 @@ "decorators": [], "loc": { "start": { - "line": 52, + "line": 54, "column": 17, "program": "launch_expression.ets" }, "end": { - "line": 52, + "line": 54, "column": 21, "program": "launch_expression.ets" } @@ -4035,12 +4404,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 52, + "line": 54, "column": 25, "program": "launch_expression.ets" }, "end": { - "line": 52, + "line": 54, "column": 28, "program": "launch_expression.ets" } @@ -4062,12 +4431,12 @@ "decorators": [], "loc": { "start": { - "line": 53, + "line": 55, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 53, + "line": 55, "column": 6, "program": "launch_expression.ets" } @@ -4078,12 +4447,12 @@ "value": 0, "loc": { "start": { - "line": 53, + "line": 55, "column": 7, "program": "launch_expression.ets" }, "end": { - "line": 53, + "line": 55, "column": 8, "program": "launch_expression.ets" } @@ -4093,12 +4462,12 @@ "optional": false, "loc": { "start": { - "line": 53, + "line": 55, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 53, + "line": 55, "column": 9, "program": "launch_expression.ets" } @@ -4109,12 +4478,12 @@ "value": 2, "loc": { "start": { - "line": 53, + "line": 55, "column": 12, "program": "launch_expression.ets" }, "end": { - "line": 53, + "line": 55, "column": 13, "program": "launch_expression.ets" } @@ -4122,12 +4491,12 @@ }, "loc": { "start": { - "line": 53, + "line": 55, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 53, + "line": 55, "column": 13, "program": "launch_expression.ets" } @@ -4135,12 +4504,12 @@ }, "loc": { "start": { - "line": 53, + "line": 55, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 53, + "line": 55, "column": 14, "program": "launch_expression.ets" } @@ -4159,12 +4528,12 @@ "decorators": [], "loc": { "start": { - "line": 54, + "line": 56, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 54, + "line": 56, "column": 6, "program": "launch_expression.ets" } @@ -4175,12 +4544,12 @@ "value": 0, "loc": { "start": { - "line": 54, + "line": 56, "column": 7, "program": "launch_expression.ets" }, "end": { - "line": 54, + "line": 56, "column": 8, "program": "launch_expression.ets" } @@ -4190,12 +4559,12 @@ "optional": false, "loc": { "start": { - "line": 54, + "line": 56, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 54, + "line": 56, "column": 9, "program": "launch_expression.ets" } @@ -4206,12 +4575,12 @@ "value": 6, "loc": { "start": { - "line": 54, + "line": 56, "column": 12, "program": "launch_expression.ets" }, "end": { - "line": 54, + "line": 56, "column": 13, "program": "launch_expression.ets" } @@ -4219,12 +4588,12 @@ }, "loc": { "start": { - "line": 54, + "line": 56, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 54, + "line": 56, "column": 13, "program": "launch_expression.ets" } @@ -4232,12 +4601,12 @@ }, "loc": { "start": { - "line": 54, + "line": 56, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 54, + "line": 56, "column": 14, "program": "launch_expression.ets" } @@ -4256,12 +4625,12 @@ "decorators": [], "loc": { "start": { - "line": 55, + "line": 57, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 55, + "line": 57, "column": 6, "program": "launch_expression.ets" } @@ -4272,12 +4641,12 @@ "value": 1, "loc": { "start": { - "line": 55, + "line": 57, "column": 7, "program": "launch_expression.ets" }, "end": { - "line": 55, + "line": 57, "column": 8, "program": "launch_expression.ets" } @@ -4287,12 +4656,12 @@ "optional": false, "loc": { "start": { - "line": 55, + "line": 57, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 55, + "line": 57, "column": 9, "program": "launch_expression.ets" } @@ -4303,12 +4672,12 @@ "value": 2, "loc": { "start": { - "line": 55, + "line": 57, "column": 12, "program": "launch_expression.ets" }, "end": { - "line": 55, + "line": 57, "column": 13, "program": "launch_expression.ets" } @@ -4316,12 +4685,12 @@ }, "loc": { "start": { - "line": 55, + "line": 57, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 55, + "line": 57, "column": 13, "program": "launch_expression.ets" } @@ -4329,12 +4698,12 @@ }, "loc": { "start": { - "line": 55, + "line": 57, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 55, + "line": 57, "column": 14, "program": "launch_expression.ets" } @@ -4353,12 +4722,12 @@ "decorators": [], "loc": { "start": { - "line": 56, + "line": 58, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 56, + "line": 58, "column": 6, "program": "launch_expression.ets" } @@ -4369,12 +4738,12 @@ "value": 1, "loc": { "start": { - "line": 56, + "line": 58, "column": 7, "program": "launch_expression.ets" }, "end": { - "line": 56, + "line": 58, "column": 8, "program": "launch_expression.ets" } @@ -4384,12 +4753,12 @@ "optional": false, "loc": { "start": { - "line": 56, + "line": 58, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 56, + "line": 58, "column": 9, "program": "launch_expression.ets" } @@ -4400,12 +4769,12 @@ "value": 7, "loc": { "start": { - "line": 56, + "line": 58, "column": 12, "program": "launch_expression.ets" }, "end": { - "line": 56, + "line": 58, "column": 13, "program": "launch_expression.ets" } @@ -4413,12 +4782,12 @@ }, "loc": { "start": { - "line": 56, + "line": 58, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 56, + "line": 58, "column": 13, "program": "launch_expression.ets" } @@ -4426,12 +4795,12 @@ }, "loc": { "start": { - "line": 56, + "line": 58, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 56, + "line": 58, "column": 14, "program": "launch_expression.ets" } @@ -4448,12 +4817,12 @@ "decorators": [], "loc": { "start": { - "line": 57, + "line": 59, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 57, + "line": 59, "column": 19, "program": "launch_expression.ets" } @@ -4467,12 +4836,12 @@ "decorators": [], "loc": { "start": { - "line": 57, + "line": 59, "column": 22, "program": "launch_expression.ets" }, "end": { - "line": 57, + "line": 59, "column": 30, "program": "launch_expression.ets" } @@ -4485,12 +4854,12 @@ "decorators": [], "loc": { "start": { - "line": 57, + "line": 59, "column": 31, "program": "launch_expression.ets" }, "end": { - "line": 57, + "line": 59, "column": 32, "program": "launch_expression.ets" } @@ -4500,12 +4869,12 @@ "optional": false, "loc": { "start": { - "line": 57, + "line": 59, "column": 22, "program": "launch_expression.ets" }, "end": { - "line": 57, + "line": 59, "column": 33, "program": "launch_expression.ets" } @@ -4513,12 +4882,12 @@ }, "loc": { "start": { - "line": 57, + "line": 59, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 57, + "line": 59, "column": 33, "program": "launch_expression.ets" } @@ -4528,12 +4897,12 @@ "kind": "let", "loc": { "start": { - "line": 57, + "line": 59, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 57, + "line": 59, "column": 34, "program": "launch_expression.ets" } @@ -4550,93 +4919,270 @@ "decorators": [], "loc": { "start": { - "line": 58, + "line": 60, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 58, + "line": 60, "column": 10, "program": "launch_expression.ets" } } }, "init": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 60, + "column": 13, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 19, + "program": "launch_expression.ets" + } + } + }, + "arguments": [ + { "type": "Identifier", "name": "ufib", "decorators": [], "loc": { "start": { - "line": 58, - "column": 20, + "line": 60, + "column": 42, "program": "launch_expression.ets" }, "end": { - "line": 58, - "column": 24, + "line": 60, + "column": 46, "program": "launch_expression.ets" } } }, - "arguments": [ + { + "type": "Identifier", + "name": "n", + "decorators": [], + "loc": { + "start": { + "line": 60, + "column": 48, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 49, + "program": "launch_expression.ets" + } + } + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ { - "type": "Identifier", - "name": "n", - "decorators": [], + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 60, + "column": 20, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 23, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 60, + "column": 20, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 24, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 60, + "column": 20, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 24, + "program": "launch_expression.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "i", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 60, + "column": 29, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 32, + "program": "launch_expression.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 60, + "column": 26, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 32, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 60, + "column": 26, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 32, + "program": "launch_expression.ets" + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 60, + "column": 37, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 40, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 60, + "column": 37, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 41, + "program": "launch_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 60, + "column": 37, + "program": "launch_expression.ets" + }, + "end": { + "line": 60, + "column": 41, + "program": "launch_expression.ets" + } + } + }, "loc": { "start": { - "line": 58, + "line": 60, "column": 25, "program": "launch_expression.ets" }, "end": { - "line": 58, - "column": 26, + "line": 60, + "column": 41, "program": "launch_expression.ets" } } } ], - "optional": false, "loc": { "start": { - "line": 58, - "column": 20, + "line": 60, + "column": 19, "program": "launch_expression.ets" }, "end": { - "line": 58, - "column": 27, + "line": 60, + "column": 41, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 58, + "line": 60, "column": 13, "program": "launch_expression.ets" }, "end": { - "line": 58, - "column": 27, + "line": 60, + "column": 50, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 58, + "line": 60, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 58, - "column": 27, + "line": 60, + "column": 50, "program": "launch_expression.ets" } } @@ -4645,13 +5191,13 @@ "kind": "let", "loc": { "start": { - "line": 58, + "line": 60, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 58, - "column": 28, + "line": 60, + "column": 51, "program": "launch_expression.ets" } } @@ -4667,12 +5213,12 @@ "decorators": [], "loc": { "start": { - "line": 59, + "line": 61, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 59, + "line": 61, "column": 18, "program": "launch_expression.ets" } @@ -4688,12 +5234,12 @@ "decorators": [], "loc": { "start": { - "line": 59, + "line": 61, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 59, + "line": 61, "column": 22, "program": "launch_expression.ets" } @@ -4701,17 +5247,17 @@ }, "property": { "type": "Identifier", - "name": "awaitResolution", + "name": "Await", "decorators": [], "loc": { "start": { - "line": 59, + "line": 61, "column": 23, "program": "launch_expression.ets" }, "end": { - "line": 59, - "column": 38, + "line": 61, + "column": 28, "program": "launch_expression.ets" } } @@ -4720,13 +5266,13 @@ "optional": false, "loc": { "start": { - "line": 59, + "line": 61, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 59, - "column": 38, + "line": 61, + "column": 28, "program": "launch_expression.ets" } } @@ -4735,26 +5281,26 @@ "optional": false, "loc": { "start": { - "line": 59, + "line": 61, "column": 21, "program": "launch_expression.ets" }, "end": { - "line": 59, - "column": 40, + "line": 61, + "column": 30, "program": "launch_expression.ets" } } }, "loc": { "start": { - "line": 59, + "line": 61, "column": 9, "program": "launch_expression.ets" }, "end": { - "line": 59, - "column": 40, + "line": 61, + "column": 30, "program": "launch_expression.ets" } } @@ -4763,13 +5309,13 @@ "kind": "let", "loc": { "start": { - "line": 59, + "line": 61, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 59, - "column": 41, + "line": 61, + "column": 31, "program": "launch_expression.ets" } } @@ -4784,12 +5330,12 @@ "decorators": [], "loc": { "start": { - "line": 60, + "line": 62, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 60, + "line": 62, "column": 14, "program": "launch_expression.ets" } @@ -4804,12 +5350,12 @@ "decorators": [], "loc": { "start": { - "line": 60, + "line": 62, "column": 15, "program": "launch_expression.ets" }, "end": { - "line": 60, + "line": 62, "column": 24, "program": "launch_expression.ets" } @@ -4819,12 +5365,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 60, + "line": 62, "column": 28, "program": "launch_expression.ets" }, "end": { - "line": 60, + "line": 62, "column": 31, "program": "launch_expression.ets" } @@ -4832,12 +5378,12 @@ }, "loc": { "start": { - "line": 60, + "line": 62, "column": 15, "program": "launch_expression.ets" }, "end": { - "line": 60, + "line": 62, "column": 24, "program": "launch_expression.ets" } @@ -4849,12 +5395,12 @@ "decorators": [], "loc": { "start": { - "line": 60, + "line": 62, "column": 33, "program": "launch_expression.ets" }, "end": { - "line": 60, + "line": 62, "column": 43, "program": "launch_expression.ets" } @@ -4864,12 +5410,12 @@ "optional": false, "loc": { "start": { - "line": 60, + "line": 62, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 60, + "line": 62, "column": 44, "program": "launch_expression.ets" } @@ -4877,12 +5423,12 @@ }, "loc": { "start": { - "line": 60, + "line": 62, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 60, + "line": 62, "column": 45, "program": "launch_expression.ets" } @@ -4895,12 +5441,12 @@ "value": 0, "loc": { "start": { - "line": 61, + "line": 63, "column": 12, "program": "launch_expression.ets" }, "end": { - "line": 61, + "line": 63, "column": 13, "program": "launch_expression.ets" } @@ -4908,12 +5454,12 @@ }, "loc": { "start": { - "line": 61, + "line": 63, "column": 5, "program": "launch_expression.ets" }, "end": { - "line": 61, + "line": 63, "column": 14, "program": "launch_expression.ets" } @@ -4922,12 +5468,12 @@ ], "loc": { "start": { - "line": 52, + "line": 54, "column": 29, "program": "launch_expression.ets" }, "end": { - "line": 62, + "line": 64, "column": 2, "program": "launch_expression.ets" } @@ -4935,12 +5481,12 @@ }, "loc": { "start": { - "line": 52, + "line": 54, "column": 17, "program": "launch_expression.ets" }, "end": { - "line": 62, + "line": 64, "column": 2, "program": "launch_expression.ets" } @@ -4948,12 +5494,12 @@ }, "loc": { "start": { - "line": 52, + "line": 54, "column": 17, "program": "launch_expression.ets" }, "end": { - "line": 62, + "line": 64, "column": 2, "program": "launch_expression.ets" } @@ -4963,12 +5509,12 @@ "decorators": [], "loc": { "start": { - "line": 52, + "line": 54, "column": 8, "program": "launch_expression.ets" }, "end": { - "line": 62, + "line": 64, "column": 2, "program": "launch_expression.ets" } @@ -5009,7 +5555,7 @@ "program": "launch_expression.ets" }, "end": { - "line": 63, + "line": 65, "column": 1, "program": "launch_expression.ets" } diff --git a/ets2panda/test/compiler/ets/launch_expression.ets b/ets2panda/test/compiler/ets/launch_expression.ets index 5058e42f6b666bb8a01102b820a4fac718247795..d9435d56fe034f1045f24bb7c5ab81c76cdac6e6 100644 --- a/ets2panda/test/compiler/ets/launch_expression.ets +++ b/ets2panda/test/compiler/ets/launch_expression.ets @@ -13,11 +13,13 @@ * limitations under the License. */ +import {launch} from "std/concurrency" + let count = 2 let n = 9 let a: int[] = new int[count]; let v: int[] = new int[count]; -type P = Promise | undefined +type P = Job | undefined function assert_eq(value1: int, value2: int): void { if (value1 == value2) { return; @@ -31,11 +33,11 @@ function ufib(n: int) : Int { } let p: P[] = new P[count] for (let i = 0; i < count; ++i) { - p[i] = launch ufib(n-1-i); + p[i] = launch Int>(ufib, n-1-i); } let result = 0 for (let i = 0; i < count; ++i) { - result = result + p[i]!.awaitResolution() * a[i]; + result = result + p[i]!.Await() * a[i]; } return result; } @@ -55,8 +57,8 @@ export function main(): int { a[1] = 2; v[1] = 7; let seq_result = ufib_seq(n); - let p = launch ufib(n); - let co_result = p.awaitResolution(); + let p = launch Int>(ufib, n); + let co_result = p.Await(); assert_eq(co_result as int, seq_result); return 0; } diff --git a/ets2panda/test/compiler/ets/loopWithinLambda-expected.txt b/ets2panda/test/compiler/ets/loopWithinLambda-expected.txt index 339b3c8131201760c5639dd6cc4a16a3631d5e51..2dffdc1e5b14a857ef23b7538d1cad30ea8be2e7 100644 --- a/ets2panda/test/compiler/ets/loopWithinLambda-expected.txt +++ b/ets2panda/test/compiler/ets/loopWithinLambda-expected.txt @@ -467,40 +467,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "loopWithinLambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "loopWithinLambda.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "loopWithinLambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "loopWithinLambda.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/lowering-interaction-expected.txt b/ets2panda/test/compiler/ets/lowering-interaction-expected.txt index 325b197a15e3230cd354dcbe7d480bd71c470fca..1da047d07692e789cc334ba9b5bfb2bdcc64c451 100644 --- a/ets2panda/test/compiler/ets/lowering-interaction-expected.txt +++ b/ets2panda/test/compiler/ets/lowering-interaction-expected.txt @@ -581,55 +581,103 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "C", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 18, - "program": "lowering-interaction.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "lowering-interaction.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + } + } }, - "end": { - "line": 25, - "column": 19, - "program": "lowering-interaction.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + } } } - }, + ], "loc": { "start": { - "line": 25, - "column": 18, + "line": 1, + "column": 3, "program": "lowering-interaction.ets" }, "end": { - "line": 25, - "column": 20, + "line": 1, + "column": 3, "program": "lowering-interaction.ets" } } }, "loc": { "start": { - "line": 25, - "column": 18, + "line": 1, + "column": 1, "program": "lowering-interaction.ets" }, "end": { - "line": 25, - "column": 20, + "line": 1, + "column": 3, "program": "lowering-interaction.ets" } } }, - "annotations": [], "loc": { "start": { "line": 25, @@ -713,55 +761,103 @@ "type": "Identifier", "name": "base", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "C", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 22, - "program": "lowering-interaction.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "lowering-interaction.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + } + } }, - "end": { - "line": 27, - "column": 23, - "program": "lowering-interaction.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "lowering-interaction.ets" + } } } - }, + ], "loc": { "start": { - "line": 27, - "column": 22, + "line": 1, + "column": 3, "program": "lowering-interaction.ets" }, "end": { - "line": 27, - "column": 24, + "line": 1, + "column": 3, "program": "lowering-interaction.ets" } } }, "loc": { "start": { - "line": 27, - "column": 22, + "line": 1, + "column": 1, "program": "lowering-interaction.ets" }, "end": { - "line": 27, - "column": 24, + "line": 1, + "column": 3, "program": "lowering-interaction.ets" } } }, - "annotations": [], "loc": { "start": { "line": 27, @@ -1376,40 +1472,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lowering-interaction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lowering-interaction.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lowering-interaction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lowering-interaction.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/manyLocalsParamRegUsage-expected.txt b/ets2panda/test/compiler/ets/manyLocalsParamRegUsage-expected.txt index 974a41b880d6a3c567e275f23141046a20fec0e6..368b383ee18d7a11f2a7f76e39524119382d65b0 100644 --- a/ets2panda/test/compiler/ets/manyLocalsParamRegUsage-expected.txt +++ b/ets2panda/test/compiler/ets/manyLocalsParamRegUsage-expected.txt @@ -35325,40 +35325,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "manyLocalsParamRegUsage.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "manyLocalsParamRegUsage.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "manyLocalsParamRegUsage.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "manyLocalsParamRegUsage.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/memberExprInLambda-expected.txt b/ets2panda/test/compiler/ets/memberExprInLambda-expected.txt index c162e9d8a07f63fb01395c89e44f0abced7c7af4..1e77ccc4d0a05a8c54b950691d8fa72da7ca6962 100644 --- a/ets2panda/test/compiler/ets/memberExprInLambda-expected.txt +++ b/ets2panda/test/compiler/ets/memberExprInLambda-expected.txt @@ -86,40 +86,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "memberExprInLambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "memberExprInLambda.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "memberExprInLambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "memberExprInLambda.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -409,55 +375,103 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "number", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 16, - "program": "memberExprInLambda.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "memberExprInLambda.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "memberExprInLambda.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "memberExprInLambda.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "memberExprInLambda.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "memberExprInLambda.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "memberExprInLambda.ets" + } + } }, - "end": { - "line": 19, - "column": 22, - "program": "memberExprInLambda.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "memberExprInLambda.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "memberExprInLambda.ets" + } } } - }, + ], "loc": { "start": { - "line": 19, - "column": 16, + "line": 1, + "column": 3, "program": "memberExprInLambda.ets" }, "end": { - "line": 19, - "column": 23, + "line": 1, + "column": 3, "program": "memberExprInLambda.ets" } } }, "loc": { "start": { - "line": 19, - "column": 16, + "line": 1, + "column": 1, "program": "memberExprInLambda.ets" }, "end": { - "line": 19, - "column": 23, + "line": 1, + "column": 3, "program": "memberExprInLambda.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, diff --git a/ets2panda/test/compiler/ets/memberExpressionFromStaticContext-expected.txt b/ets2panda/test/compiler/ets/memberExpressionFromStaticContext-expected.txt index 729d5e66afcabdcd828815ec2ce8e8d0f1982382..77e24d212576ed930dd068f47cc83f2abec45f07 100644 --- a/ets2panda/test/compiler/ets/memberExpressionFromStaticContext-expected.txt +++ b/ets2panda/test/compiler/ets/memberExpressionFromStaticContext-expected.txt @@ -3005,40 +3005,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "memberExpressionFromStaticContext.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "memberExpressionFromStaticContext.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "memberExpressionFromStaticContext.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "memberExpressionFromStaticContext.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/method-resolution-class-and-interface-in-signatures_5-expected.txt b/ets2panda/test/compiler/ets/method-resolution-class-and-interface-in-signatures_5-expected.txt index 4a7c723f61fefa9212f84d098b6185a64c477484..31d7c0bbe3debea489ea3ee705e02e4c4fb39ea0 100644 --- a/ets2panda/test/compiler/ets/method-resolution-class-and-interface-in-signatures_5-expected.txt +++ b/ets2panda/test/compiler/ets/method-resolution-class-and-interface-in-signatures_5-expected.txt @@ -803,40 +803,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method-resolution-class-and-interface-in-signatures_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method-resolution-class-and-interface-in-signatures_5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method-resolution-class-and-interface-in-signatures_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method-resolution-class-and-interface-in-signatures_5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/methodOverrideAsyncMethod-expected.txt b/ets2panda/test/compiler/ets/methodOverrideAsyncMethod-expected.txt index c6b646f112a37b2f5527afdccde9b4565b72a16c..a3889c32e118b57c07973df1c82a2ed63a70773d 100644 --- a/ets2panda/test/compiler/ets/methodOverrideAsyncMethod-expected.txt +++ b/ets2panda/test/compiler/ets/methodOverrideAsyncMethod-expected.txt @@ -1250,40 +1250,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodOverrideAsyncMethod.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodOverrideAsyncMethod.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodOverrideAsyncMethod.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodOverrideAsyncMethod.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/methodOverrideCovariantReturnType-expected.txt b/ets2panda/test/compiler/ets/methodOverrideCovariantReturnType-expected.txt index 615d5713e96b0555118ca52f050fed8f79c3c377..cd642fce8c8c4890a7b1a86a6ac76cb59fea2ee5 100644 --- a/ets2panda/test/compiler/ets/methodOverrideCovariantReturnType-expected.txt +++ b/ets2panda/test/compiler/ets/methodOverrideCovariantReturnType-expected.txt @@ -2153,40 +2153,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodOverrideCovariantReturnType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodOverrideCovariantReturnType.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodOverrideCovariantReturnType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodOverrideCovariantReturnType.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/methodOverrideDifferentSignature-expected.txt b/ets2panda/test/compiler/ets/methodOverrideDifferentSignature-expected.txt index 098152e778147ce739f084769fcdf24135243394..2f6c7b678c68ac7e75ebf91facddfaadbed69775 100644 --- a/ets2panda/test/compiler/ets/methodOverrideDifferentSignature-expected.txt +++ b/ets2panda/test/compiler/ets/methodOverrideDifferentSignature-expected.txt @@ -1437,40 +1437,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodOverrideDifferentSignature.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodOverrideDifferentSignature.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodOverrideDifferentSignature.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodOverrideDifferentSignature.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/methodOverrideWithoutModifier-expected.txt b/ets2panda/test/compiler/ets/methodOverrideWithoutModifier-expected.txt index 5e50f1ffe1b61801148ef609a1052143f09752f5..864cd808e4d9beb685126951a64ef990ed2d86f1 100644 --- a/ets2panda/test/compiler/ets/methodOverrideWithoutModifier-expected.txt +++ b/ets2panda/test/compiler/ets/methodOverrideWithoutModifier-expected.txt @@ -621,40 +621,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodOverrideWithoutModifier.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodOverrideWithoutModifier.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodOverrideWithoutModifier.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodOverrideWithoutModifier.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/multipleMethodOverride-expected.txt b/ets2panda/test/compiler/ets/multipleMethodOverride-expected.txt index 75b30d118d75789743510d6659c68a39f8f13f42..1a388bd32d5c8c2afae364e455752fb4b43ab3a9 100644 --- a/ets2panda/test/compiler/ets/multipleMethodOverride-expected.txt +++ b/ets2panda/test/compiler/ets/multipleMethodOverride-expected.txt @@ -1144,40 +1144,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "multipleMethodOverride.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "multipleMethodOverride.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "multipleMethodOverride.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "multipleMethodOverride.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/n_nullableTypeInArgNotRef-expected.txt b/ets2panda/test/compiler/ets/n_nullableTypeInArgNotRef-expected.txt index af25de422fbd01e3d478bc78e5de78890ea9219f..d751217bc9bebcf7c60caed86d3e76741a69e11a 100644 --- a/ets2panda/test/compiler/ets/n_nullableTypeInArgNotRef-expected.txt +++ b/ets2panda/test/compiler/ets/n_nullableTypeInArgNotRef-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "n_nullableTypeInArgNotRef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "n_nullableTypeInArgNotRef.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "n_nullableTypeInArgNotRef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "n_nullableTypeInArgNotRef.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/n_nullableTypeInReturnNotRef-expected.txt b/ets2panda/test/compiler/ets/n_nullableTypeInReturnNotRef-expected.txt index 3d33bda0cbd20c17f624f3f2f894f24bc864deeb..43fc249667e32f75b6d78e1288d692e22d301231 100644 --- a/ets2panda/test/compiler/ets/n_nullableTypeInReturnNotRef-expected.txt +++ b/ets2panda/test/compiler/ets/n_nullableTypeInReturnNotRef-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "n_nullableTypeInReturnNotRef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "n_nullableTypeInReturnNotRef.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "n_nullableTypeInReturnNotRef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "n_nullableTypeInReturnNotRef.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/n_nullableTypeNotRef-expected.txt b/ets2panda/test/compiler/ets/n_nullableTypeNotRef-expected.txt index ed32720e87213a49a154bb85b51539ea3aec9b53..34b399bb68b5a18f96a6387d2aeb6f3628941c91 100644 --- a/ets2panda/test/compiler/ets/n_nullableTypeNotRef-expected.txt +++ b/ets2panda/test/compiler/ets/n_nullableTypeNotRef-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "n_nullableTypeNotRef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "n_nullableTypeNotRef.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "n_nullableTypeNotRef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "n_nullableTypeNotRef.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/native_toplevel-expected.txt b/ets2panda/test/compiler/ets/native_toplevel-expected.txt index 113f76813553e3de76e60c117cf51cfe4141d84f..88d918fd566810df8d4e530c06bac9e3e06fc9da 100644 --- a/ets2panda/test/compiler/ets/native_toplevel-expected.txt +++ b/ets2panda/test/compiler/ets/native_toplevel-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "native_toplevel.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "native_toplevel.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "native_toplevel.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "native_toplevel.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/non-const-lambda-with-scopes-expected.txt b/ets2panda/test/compiler/ets/non-const-lambda-with-scopes-expected.txt index da32b6e0d2977bb845a8c6e3f65b6351110ca780..6c210630f99a75236d6d2966be830034f6ef5a54 100644 --- a/ets2panda/test/compiler/ets/non-const-lambda-with-scopes-expected.txt +++ b/ets2panda/test/compiler/ets/non-const-lambda-with-scopes-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "non-const-lambda-with-scopes.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "non-const-lambda-with-scopes.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "non-const-lambda-with-scopes.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "non-const-lambda-with-scopes.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/null_coalescing_generic_1-expected.txt b/ets2panda/test/compiler/ets/null_coalescing_generic_1-expected.txt index cd1a78604c2abcef10d10714062a868b14b7472b..e129c87f44e7621b689097531a0a55454b0822d7 100644 --- a/ets2panda/test/compiler/ets/null_coalescing_generic_1-expected.txt +++ b/ets2panda/test/compiler/ets/null_coalescing_generic_1-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "null_coalescing_generic_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "null_coalescing_generic_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "null_coalescing_generic_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "null_coalescing_generic_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/nullableTuple-expected.txt b/ets2panda/test/compiler/ets/nullableTuple-expected.txt index 4e41a2e5c7e6df9436597f5a8edb6833902244c6..1b5b431a73100719270f019dbff6b8f5bee79d57 100644 --- a/ets2panda/test/compiler/ets/nullableTuple-expected.txt +++ b/ets2panda/test/compiler/ets/nullableTuple-expected.txt @@ -277,40 +277,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullableTuple.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullableTuple.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullableTuple.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullableTuple.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/nullable_type_in_arithmeticdiv-expected.txt b/ets2panda/test/compiler/ets/nullable_type_in_arithmeticdiv-expected.txt index f15287d77195d80017155970d65d6c67ec982d0c..15d582ab6516007d602b37eebf10eebf7c27b28f 100644 --- a/ets2panda/test/compiler/ets/nullable_type_in_arithmeticdiv-expected.txt +++ b/ets2panda/test/compiler/ets/nullable_type_in_arithmeticdiv-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullable_type_in_arithmeticdiv.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullable_type_in_arithmeticdiv.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullable_type_in_arithmeticdiv.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullable_type_in_arithmeticdiv.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/nullable_type_in_arithmeticplus-expected.txt b/ets2panda/test/compiler/ets/nullable_type_in_arithmeticplus-expected.txt index 19187a07dad9ba52b71c9e76f9dd11455dda6b7a..8ea7dac534daaf2085da4d86174d1892db464c35 100644 --- a/ets2panda/test/compiler/ets/nullable_type_in_arithmeticplus-expected.txt +++ b/ets2panda/test/compiler/ets/nullable_type_in_arithmeticplus-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullable_type_in_arithmeticplus.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullable_type_in_arithmeticplus.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullable_type_in_arithmeticplus.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullable_type_in_arithmeticplus.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/objectLiteralInterface-expected.txt b/ets2panda/test/compiler/ets/objectLiteralInterface-expected.txt index 23920fd5d7737a6364c2e806129440440cc34345..b801c2567644a1d3f8962d6a9fc6fcdb1a3d93f3 100644 --- a/ets2panda/test/compiler/ets/objectLiteralInterface-expected.txt +++ b/ets2panda/test/compiler/ets/objectLiteralInterface-expected.txt @@ -72,40 +72,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "objectLiteralInterface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "objectLiteralInterface.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "objectLiteralInterface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "objectLiteralInterface.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/objectLiteralReadonlyKey-expected.txt b/ets2panda/test/compiler/ets/objectLiteralReadonlyKey-expected.txt index c847674a8e3b18846d8547c575109cb7b61e57f7..21e8d6b6f59353c9677a94e186f030a0bb4f4486 100644 --- a/ets2panda/test/compiler/ets/objectLiteralReadonlyKey-expected.txt +++ b/ets2panda/test/compiler/ets/objectLiteralReadonlyKey-expected.txt @@ -233,40 +233,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "objectLiteralReadonlyKey.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "objectLiteralReadonlyKey.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "objectLiteralReadonlyKey.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "objectLiteralReadonlyKey.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/optionalLambdaParameter-expected.txt b/ets2panda/test/compiler/ets/optionalLambdaParameter-expected.txt deleted file mode 100644 index c7da1cf35320dd114decb9a5a006e06fbb607bd5..0000000000000000000000000000000000000000 --- a/ets2panda/test/compiler/ets/optionalLambdaParameter-expected.txt +++ /dev/null @@ -1,932 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - } - } - }, - "superClass": null, - "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - } - } - } - ], - "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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 16, - "column": 13, - "program": "optionalLambdaParameter.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 16, - "column": 13, - "program": "optionalLambdaParameter.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [ - { - "type": "ETSParameterExpression", - "name": { - "type": "Identifier", - "name": "exec", - "typeAnnotation": { - "type": "ETSFunctionType", - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 16, - "column": 27, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 16, - "column": 31, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 21, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 16, - "column": 31, - "program": "optionalLambdaParameter.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 14, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 16, - "column": 31, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 14, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 16, - "column": 31, - "program": "optionalLambdaParameter.ets" - } - } - } - ], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 16, - "column": 34, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 16, - "column": 38, - "program": "optionalLambdaParameter.ets" - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - } - } - }, - "init": { - "type": "Identifier", - "name": "exec", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 17, - "column": 9, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 17, - "column": 13, - "program": "optionalLambdaParameter.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - } - } - }, - "alternate": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 17, - "column": 13, - "program": "optionalLambdaParameter.ets" - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 17, - "column": 13, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optionalLambdaParameter.ets" - } - } - } - ], - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 17, - "column": 13, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 17, - "column": 13, - "program": "optionalLambdaParameter.ets" - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 39, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 18, - "column": 2, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 18, - "column": 2, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 18, - "column": 2, - "program": "optionalLambdaParameter.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 18, - "column": 2, - "program": "optionalLambdaParameter.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "bar", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 10, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 20, - "column": 13, - "program": "optionalLambdaParameter.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "bar", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 10, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 20, - "column": 13, - "program": "optionalLambdaParameter.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 21, - "column": 8, - "program": "optionalLambdaParameter.ets" - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 21, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 21, - "column": 10, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 21, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 21, - "column": 10, - "program": "optionalLambdaParameter.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 27, - "column": 8, - "program": "optionalLambdaParameter.ets" - } - } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 27, - "column": 10, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 27, - "column": 10, - "program": "optionalLambdaParameter.ets" - } - } - } - ], - "loc": { - "start": { - "line": 20, - "column": 16, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 28, - "column": 2, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 10, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 28, - "column": 2, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 10, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 28, - "column": 2, - "program": "optionalLambdaParameter.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 28, - "column": 2, - "program": "optionalLambdaParameter.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optionalLambdaParameter.ets" - }, - "end": { - "line": 29, - "column": 1, - "program": "optionalLambdaParameter.ets" - } - } -} diff --git a/ets2panda/test/compiler/ets/overload_with_generics-expected.txt b/ets2panda/test/compiler/ets/overload_with_generics-expected.txt index be2033e620b79809193a1409f462264435928ee3..f5ca8d7c55f32d540643a71c6c39e9b6aa3a4dbd 100644 --- a/ets2panda/test/compiler/ets/overload_with_generics-expected.txt +++ b/ets2panda/test/compiler/ets/overload_with_generics-expected.txt @@ -790,40 +790,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "overload_with_generics.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "overload_with_generics.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "overload_with_generics.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "overload_with_generics.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override-expected.txt b/ets2panda/test/compiler/ets/override-expected.txt index c0030aadee74c0c2487290fec38f66dcb3f5a189..f8a1434f1892bb919c5ed823e92a65e893bcac53 100644 --- a/ets2panda/test/compiler/ets/override-expected.txt +++ b/ets2panda/test/compiler/ets/override-expected.txt @@ -467,37 +467,86 @@ "expression": false, "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 10, - "program": "override.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 20, + "program": "override.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 21, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 27, + "program": "override.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 21, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 28, + "program": "override.ets" + } + } }, - "end": { - "line": 20, - "column": 16, - "program": "override.ets" + "loc": { + "start": { + "line": 20, + "column": 21, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 28, + "program": "override.ets" + } } } - }, + ], "loc": { "start": { "line": 20, - "column": 10, + "column": 20, "program": "override.ets" }, "end": { "line": 20, - "column": 17, + "column": 28, "program": "override.ets" } } @@ -510,21 +559,20 @@ }, "end": { "line": 20, - "column": 17, + "column": 29, "program": "override.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, - "column": 16, + "column": 10, "program": "override.ets" }, "end": { "line": 20, - "column": 18, + "column": 29, "program": "override.ets" } } @@ -537,7 +585,7 @@ }, "end": { "line": 20, - "column": 18, + "column": 29, "program": "override.ets" } } @@ -550,7 +598,7 @@ }, "end": { "line": 20, - "column": 18, + "column": 29, "program": "override.ets" } } @@ -565,7 +613,7 @@ }, "end": { "line": 20, - "column": 19, + "column": 29, "program": "override.ets" } } @@ -936,37 +984,86 @@ "expression": false, "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 19, - "program": "override.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 19, + "program": "override.ets" + }, + "end": { + "line": 25, + "column": 29, + "program": "override.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 30, + "program": "override.ets" + }, + "end": { + "line": 25, + "column": 36, + "program": "override.ets" + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 30, + "program": "override.ets" + }, + "end": { + "line": 25, + "column": 37, + "program": "override.ets" + } + } }, - "end": { - "line": 25, - "column": 25, - "program": "override.ets" + "loc": { + "start": { + "line": 25, + "column": 30, + "program": "override.ets" + }, + "end": { + "line": 25, + "column": 37, + "program": "override.ets" + } } } - }, + ], "loc": { "start": { "line": 25, - "column": 19, + "column": 29, "program": "override.ets" }, "end": { "line": 25, - "column": 26, + "column": 37, "program": "override.ets" } } @@ -979,21 +1076,20 @@ }, "end": { "line": 25, - "column": 26, + "column": 39, "program": "override.ets" } } }, - "annotations": [], "loc": { "start": { "line": 25, - "column": 25, + "column": 19, "program": "override.ets" }, "end": { "line": 25, - "column": 27, + "column": 39, "program": "override.ets" } } @@ -1019,12 +1115,12 @@ "loc": { "start": { "line": 25, - "column": 42, + "column": 52, "program": "override.ets" }, "end": { "line": 25, - "column": 48, + "column": 58, "program": "override.ets" } } @@ -1032,12 +1128,12 @@ "loc": { "start": { "line": 25, - "column": 42, + "column": 52, "program": "override.ets" }, "end": { "line": 25, - "column": 49, + "column": 59, "program": "override.ets" } } @@ -1045,12 +1141,12 @@ "loc": { "start": { "line": 25, - "column": 42, + "column": 52, "program": "override.ets" }, "end": { "line": 25, - "column": 49, + "column": 59, "program": "override.ets" } } @@ -1059,12 +1155,12 @@ "loc": { "start": { "line": 25, - "column": 38, + "column": 48, "program": "override.ets" }, "end": { "line": 25, - "column": 51, + "column": 61, "program": "override.ets" } } @@ -1073,12 +1169,12 @@ "loc": { "start": { "line": 25, - "column": 37, + "column": 47, "program": "override.ets" }, "end": { "line": 25, - "column": 51, + "column": 61, "program": "override.ets" } } @@ -1086,12 +1182,12 @@ "loc": { "start": { "line": 25, - "column": 30, + "column": 40, "program": "override.ets" }, "end": { "line": 25, - "column": 52, + "column": 62, "program": "override.ets" } } @@ -1100,12 +1196,12 @@ "loc": { "start": { "line": 25, - "column": 28, + "column": 38, "program": "override.ets" }, "end": { "line": 25, - "column": 54, + "column": 64, "program": "override.ets" } } @@ -1118,7 +1214,7 @@ }, "end": { "line": 25, - "column": 54, + "column": 64, "program": "override.ets" } } @@ -1131,7 +1227,7 @@ }, "end": { "line": 25, - "column": 54, + "column": 64, "program": "override.ets" } } @@ -1146,7 +1242,7 @@ }, "end": { "line": 25, - "column": 54, + "column": 64, "program": "override.ets" } } @@ -1201,9 +1297,58 @@ "expression": false, "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 19, + "program": "override.ets" + }, + "end": { + "line": 26, + "column": 29, + "program": "override.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 26, + "column": 30, + "program": "override.ets" + }, + "end": { + "line": 26, + "column": 33, + "program": "override.ets" + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 29, + "program": "override.ets" + }, + "end": { + "line": 26, + "column": 34, + "program": "override.ets" + } + } + }, "loc": { "start": { "line": 26, @@ -1212,21 +1357,20 @@ }, "end": { "line": 26, - "column": 22, + "column": 36, "program": "override.ets" } } }, - "annotations": [], "loc": { "start": { "line": 26, - "column": 22, + "column": 19, "program": "override.ets" }, "end": { "line": 26, - "column": 24, + "column": 36, "program": "override.ets" } } @@ -1245,12 +1389,12 @@ "loc": { "start": { "line": 26, - "column": 35, + "column": 45, "program": "override.ets" }, "end": { "line": 26, - "column": 36, + "column": 46, "program": "override.ets" } } @@ -1259,12 +1403,12 @@ "loc": { "start": { "line": 26, - "column": 34, + "column": 44, "program": "override.ets" }, "end": { "line": 26, - "column": 37, + "column": 47, "program": "override.ets" } } @@ -1272,12 +1416,12 @@ "loc": { "start": { "line": 26, - "column": 27, + "column": 37, "program": "override.ets" }, "end": { "line": 26, - "column": 38, + "column": 48, "program": "override.ets" } } @@ -1286,12 +1430,12 @@ "loc": { "start": { "line": 26, - "column": 25, + "column": 35, "program": "override.ets" }, "end": { "line": 26, - "column": 40, + "column": 50, "program": "override.ets" } } @@ -1304,7 +1448,7 @@ }, "end": { "line": 26, - "column": 40, + "column": 50, "program": "override.ets" } } @@ -1317,7 +1461,7 @@ }, "end": { "line": 26, - "column": 40, + "column": 50, "program": "override.ets" } } @@ -1332,7 +1476,7 @@ }, "end": { "line": 26, - "column": 40, + "column": 50, "program": "override.ets" } } @@ -1387,37 +1531,86 @@ "expression": false, "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "String", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 19, - "program": "override.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 19, + "program": "override.ets" + }, + "end": { + "line": 27, + "column": 29, + "program": "override.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 30, + "program": "override.ets" + }, + "end": { + "line": 27, + "column": 36, + "program": "override.ets" + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 30, + "program": "override.ets" + }, + "end": { + "line": 27, + "column": 37, + "program": "override.ets" + } + } }, - "end": { - "line": 27, - "column": 25, - "program": "override.ets" + "loc": { + "start": { + "line": 27, + "column": 30, + "program": "override.ets" + }, + "end": { + "line": 27, + "column": 37, + "program": "override.ets" + } } } - }, + ], "loc": { "start": { "line": 27, - "column": 19, + "column": 29, "program": "override.ets" }, "end": { "line": 27, - "column": 26, + "column": 37, "program": "override.ets" } } @@ -1430,21 +1623,20 @@ }, "end": { "line": 27, - "column": 26, + "column": 39, "program": "override.ets" } } }, - "annotations": [], "loc": { "start": { "line": 27, - "column": 25, + "column": 19, "program": "override.ets" }, "end": { "line": 27, - "column": 27, + "column": 39, "program": "override.ets" } } @@ -1463,12 +1655,12 @@ "loc": { "start": { "line": 27, - "column": 38, + "column": 48, "program": "override.ets" }, "end": { "line": 27, - "column": 40, + "column": 50, "program": "override.ets" } } @@ -1477,12 +1669,12 @@ "loc": { "start": { "line": 27, - "column": 37, + "column": 47, "program": "override.ets" }, "end": { "line": 27, - "column": 41, + "column": 51, "program": "override.ets" } } @@ -1490,12 +1682,12 @@ "loc": { "start": { "line": 27, - "column": 30, + "column": 40, "program": "override.ets" }, "end": { "line": 27, - "column": 42, + "column": 52, "program": "override.ets" } } @@ -1504,12 +1696,12 @@ "loc": { "start": { "line": 27, - "column": 28, + "column": 38, "program": "override.ets" }, "end": { "line": 27, - "column": 44, + "column": 54, "program": "override.ets" } } @@ -1522,7 +1714,7 @@ }, "end": { "line": 27, - "column": 44, + "column": 54, "program": "override.ets" } } @@ -1535,7 +1727,7 @@ }, "end": { "line": 27, - "column": 44, + "column": 54, "program": "override.ets" } } @@ -1550,7 +1742,7 @@ }, "end": { "line": 27, - "column": 44, + "column": 54, "program": "override.ets" } } @@ -1709,40 +1901,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override.ets b/ets2panda/test/compiler/ets/override.ets index 02751d79bd622769222da422a87cceddd6519f33..b02fb4e657843d7d37f293432ed4cc935384cb21 100644 --- a/ets2panda/test/compiler/ets/override.ets +++ b/ets2panda/test/compiler/ets/override.ets @@ -17,14 +17,14 @@ interface I { fn(): Object; fn2(): Object; fn3(): Object; - fn4(): Object[]; + fn4(): FixedArray; } class A implements I { override fn(): String { return ""; } - override fn2(): Object[] { return [new Object()]; } - override fn3(): int[] { return [0]; } - override fn4(): String[] { return [""]; } + override fn2(): FixedArray { return [new Object()]; } + override fn3(): FixedArray { return [0]; } + override fn4(): FixedArray { return [""]; } } function main(): void {} diff --git a/ets2panda/test/compiler/ets/override10-expected.txt b/ets2panda/test/compiler/ets/override10-expected.txt index c7200a9ee7942ceb8a0234a00f530bffbc679682..538955d3afdd25bd51f60b7f383808925f105c15 100644 --- a/ets2panda/test/compiler/ets/override10-expected.txt +++ b/ets2panda/test/compiler/ets/override10-expected.txt @@ -896,40 +896,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override10.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override10.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override12-expected.txt b/ets2panda/test/compiler/ets/override12-expected.txt index d44d8a352d002a846dd06eb20b7d63ae3fb1377d..b36a9566bd0e65b2ead1736ea23975f6d77cd962 100644 --- a/ets2panda/test/compiler/ets/override12-expected.txt +++ b/ets2panda/test/compiler/ets/override12-expected.txt @@ -1607,40 +1607,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override12.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override12.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override13-expected.txt b/ets2panda/test/compiler/ets/override13-expected.txt index 364b686a7a8684e4c0559e4bc109ab2a2b2ef4f3..5b4c925f6b2f0f574f26efbd5f8824170fb7b4f2 100644 --- a/ets2panda/test/compiler/ets/override13-expected.txt +++ b/ets2panda/test/compiler/ets/override13-expected.txt @@ -1009,40 +1009,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override13.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override13.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override13.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override13.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override16-expected.txt b/ets2panda/test/compiler/ets/override16-expected.txt index 080c32e941d55c82a5332f2e47da3350c46b10e1..5947eedf223d866e65b73c2079992200fc0bfeec 100644 --- a/ets2panda/test/compiler/ets/override16-expected.txt +++ b/ets2panda/test/compiler/ets/override16-expected.txt @@ -685,40 +685,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override16.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override16.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override16.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override16.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override17-expected.txt b/ets2panda/test/compiler/ets/override17-expected.txt index f3cfcd088eaf594392f5a6c32b4c5f09c1ee9ad5..fd757fd65555e44ce435fb917aa63bd85412b98b 100644 --- a/ets2panda/test/compiler/ets/override17-expected.txt +++ b/ets2panda/test/compiler/ets/override17-expected.txt @@ -685,40 +685,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override17.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override17.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override17.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override17.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override19-expected.txt b/ets2panda/test/compiler/ets/override19-expected.txt index a046419071fc7eb984a42e3e181f8365e2c6956b..2ae88e9df9213e59006c9fa8bd72bc99839dc366 100644 --- a/ets2panda/test/compiler/ets/override19-expected.txt +++ b/ets2panda/test/compiler/ets/override19-expected.txt @@ -717,40 +717,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override19.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override19.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override19.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override19.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override2-expected.txt b/ets2panda/test/compiler/ets/override2-expected.txt index ba72ed1d358f601fd48888930392e709fa11db22..d38e7aa40fd25ad5690e8a49f83cbd3924b0fde1 100644 --- a/ets2panda/test/compiler/ets/override2-expected.txt +++ b/ets2panda/test/compiler/ets/override2-expected.txt @@ -750,40 +750,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override4-expected.txt b/ets2panda/test/compiler/ets/override4-expected.txt index d5d4ddf663157669e77a948fce89f6d5d1fea52c..2948b976cb35a21c73c49fc846b54e243d353b25 100644 --- a/ets2panda/test/compiler/ets/override4-expected.txt +++ b/ets2panda/test/compiler/ets/override4-expected.txt @@ -798,40 +798,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override5-expected.txt b/ets2panda/test/compiler/ets/override5-expected.txt index fcda6ff94f34e8a3745ac4422721771a460ba8fc..35b7a674de0571ad33fa3c54e7e350b1f77a5319 100644 --- a/ets2panda/test/compiler/ets/override5-expected.txt +++ b/ets2panda/test/compiler/ets/override5-expected.txt @@ -685,40 +685,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override6-expected.txt b/ets2panda/test/compiler/ets/override6-expected.txt index 3eb1449bf2e64f77d75881cf99ca74ed5dbd0f90..030401332dd96e6e31b69d97ac38bdbcf72d273a 100644 --- a/ets2panda/test/compiler/ets/override6-expected.txt +++ b/ets2panda/test/compiler/ets/override6-expected.txt @@ -661,40 +661,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override8-expected.txt b/ets2panda/test/compiler/ets/override8-expected.txt index a5bc8882b4664c8e2a050aeb38f80a3677d14a04..81577b0a0a368f60bec5d4e2d26932f89a51d6d8 100644 --- a/ets2panda/test/compiler/ets/override8-expected.txt +++ b/ets2panda/test/compiler/ets/override8-expected.txt @@ -612,40 +612,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/override9-expected.txt b/ets2panda/test/compiler/ets/override9-expected.txt index face0ae9171eba06970bc3b0ca734b2b0fc07b60..006de229cbefe88d4003da1d0567a6e85e8fa401 100644 --- a/ets2panda/test/compiler/ets/override9-expected.txt +++ b/ets2panda/test/compiler/ets/override9-expected.txt @@ -724,40 +724,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/parenthesizedType-expected.txt b/ets2panda/test/compiler/ets/parenthesizedType-expected.txt index a38a064445bf37387eb1ed99dd0b054d015a0438..e28bad53eb222bb39258c262230e27d5add600c5 100644 --- a/ets2panda/test/compiler/ets/parenthesizedType-expected.txt +++ b/ets2panda/test/compiler/ets/parenthesizedType-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "parenthesizedType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "parenthesizedType.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "parenthesizedType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "parenthesizedType.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/requiredType_1-expected.txt b/ets2panda/test/compiler/ets/requiredType_1-expected.txt index 61bfd17692978b98b6e5ef604c0822811a6bf25a..02e43c739e5b665db05101cbb58ad40815038ca2 100644 --- a/ets2panda/test/compiler/ets/requiredType_1-expected.txt +++ b/ets2panda/test/compiler/ets/requiredType_1-expected.txt @@ -313,40 +313,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/requiredType_11-expected.txt b/ets2panda/test/compiler/ets/requiredType_11-expected.txt index 732f158b71f918cdba6b495ea424cff95144ed81..90d3b08f0649f1e6fe0b14cdf6b1b37c2d50e375 100644 --- a/ets2panda/test/compiler/ets/requiredType_11-expected.txt +++ b/ets2panda/test/compiler/ets/requiredType_11-expected.txt @@ -652,40 +652,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_11.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_11.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_11.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_11.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/requiredType_4-expected.txt b/ets2panda/test/compiler/ets/requiredType_4-expected.txt index 41b63b0ce7b787f3e64a8246610861238b6de734..a6e74b9ae0aa4c58067a310055b7435511fabd5f 100644 --- a/ets2panda/test/compiler/ets/requiredType_4-expected.txt +++ b/ets2panda/test/compiler/ets/requiredType_4-expected.txt @@ -313,40 +313,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/requiredType_5-expected.txt b/ets2panda/test/compiler/ets/requiredType_5-expected.txt index d210fe0bec74a8e20c03e07f5ee9d00d2556aa2e..95c93ffdd8bef94ff1f605bc20f5fdaff19516a8 100644 --- a/ets2panda/test/compiler/ets/requiredType_5-expected.txt +++ b/ets2panda/test/compiler/ets/requiredType_5-expected.txt @@ -463,40 +463,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/requiredType_9-expected.txt b/ets2panda/test/compiler/ets/requiredType_9-expected.txt index 849a8dd4f24b5eaa970c6304cdc62efd95971b60..578e4d7ad2da9b989d2802b156f8be94dd962e87 100644 --- a/ets2panda/test/compiler/ets/requiredType_9-expected.txt +++ b/ets2panda/test/compiler/ets/requiredType_9-expected.txt @@ -922,40 +922,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "requiredType_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "requiredType_9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/rethrowingCheck1-expected.txt b/ets2panda/test/compiler/ets/rethrowingCheck1-expected.txt index 915ac9c329aa723ce02326b0830c1cc2ee379337..c971b8965f88cc9b6f7bcce7c6e4367ca2db13be 100644 --- a/ets2panda/test/compiler/ets/rethrowingCheck1-expected.txt +++ b/ets2panda/test/compiler/ets/rethrowingCheck1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingCheck1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingCheck1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingCheck1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingCheck1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/rethrowingCheck4-expected.txt b/ets2panda/test/compiler/ets/rethrowingCheck4-expected.txt index a326711571bbd58bd1994bc1455f918fe0cf3472..ffd83cec5b9c5f998fa009ec3a2e05f8cf8620d6 100644 --- a/ets2panda/test/compiler/ets/rethrowingCheck4-expected.txt +++ b/ets2panda/test/compiler/ets/rethrowingCheck4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingCheck4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingCheck4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingCheck4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingCheck4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/rethrowingConstructorCheck3-expected.txt b/ets2panda/test/compiler/ets/rethrowingConstructorCheck3-expected.txt index 2067391a08d5fd12a9ddc9e47236057361d05152..1a0939cc0cf5ae5d42f94d29f0249fa4ad361098 100644 --- a/ets2panda/test/compiler/ets/rethrowingConstructorCheck3-expected.txt +++ b/ets2panda/test/compiler/ets/rethrowingConstructorCheck3-expected.txt @@ -245,40 +245,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingConstructorCheck3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingConstructorCheck3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingConstructorCheck3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingConstructorCheck3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/rethrowingFunctionCheck3-expected.txt b/ets2panda/test/compiler/ets/rethrowingFunctionCheck3-expected.txt index 9bb871666bd6a7a70cc2b19db494503139be576d..811fac12b9c8b46a33195195d34e1bd9f9b17928 100644 --- a/ets2panda/test/compiler/ets/rethrowingFunctionCheck3-expected.txt +++ b/ets2panda/test/compiler/ets/rethrowingFunctionCheck3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingFunctionCheck3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingFunctionCheck3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingFunctionCheck3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingFunctionCheck3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/rethrowingMethodCheck3-expected.txt b/ets2panda/test/compiler/ets/rethrowingMethodCheck3-expected.txt index 52e6bea7852c0b7fb27db39a9baf569ef09e56f0..270f5b70663e1208732eb8528dae02d8a6ff60d0 100644 --- a/ets2panda/test/compiler/ets/rethrowingMethodCheck3-expected.txt +++ b/ets2panda/test/compiler/ets/rethrowingMethodCheck3-expected.txt @@ -365,40 +365,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingMethodCheck3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingMethodCheck3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrowingMethodCheck3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrowingMethodCheck3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/returnTypeGenericArray-expected.txt b/ets2panda/test/compiler/ets/returnTypeGenericArray-expected.txt index 1d99a5eb0631ca36a51cbbccab6a67125addc398..ec04fccc6c056780ead551c59bc93280f2dfb76a 100644 --- a/ets2panda/test/compiler/ets/returnTypeGenericArray-expected.txt +++ b/ets2panda/test/compiler/ets/returnTypeGenericArray-expected.txt @@ -56,87 +56,135 @@ "expression": false, "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 28, - "program": "returnTypeGenericArray.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } + } }, - "end": { - "line": 17, - "column": 29, - "program": "returnTypeGenericArray.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } + } + }, + { + "type": "ETSUndefinedType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 28, + "line": 1, + "column": 3, "program": "returnTypeGenericArray.ets" }, "end": { - "line": 17, - "column": 31, + "line": 1, + "column": 3, "program": "returnTypeGenericArray.ets" } } - }, - "loc": { - "start": { - "line": 17, - "column": 28, - "program": "returnTypeGenericArray.ets" - }, - "end": { - "line": 17, - "column": 31, - "program": "returnTypeGenericArray.ets" - } } - }, - { - "type": "ETSUndefinedType", - "loc": { - "start": { - "line": 17, - "column": 32, - "program": "returnTypeGenericArray.ets" - }, - "end": { - "line": 17, - "column": 41, - "program": "returnTypeGenericArray.ets" - } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" } } - ], + }, "loc": { "start": { - "line": 17, - "column": 27, + "line": 1, + "column": 1, "program": "returnTypeGenericArray.ets" }, "end": { - "line": 17, - "column": 41, + "line": 1, + "column": 3, "program": "returnTypeGenericArray.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -534,87 +582,135 @@ "expression": false, "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 37, - "program": "returnTypeGenericArray.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } + } }, - "end": { - "line": 21, - "column": 38, - "program": "returnTypeGenericArray.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } + } + }, + { + "type": "ETSUndefinedType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + } } } - }, + ], "loc": { "start": { - "line": 21, - "column": 37, + "line": 1, + "column": 3, "program": "returnTypeGenericArray.ets" }, "end": { - "line": 21, - "column": 40, + "line": 1, + "column": 3, "program": "returnTypeGenericArray.ets" } } - }, - "loc": { - "start": { - "line": 21, - "column": 37, - "program": "returnTypeGenericArray.ets" - }, - "end": { - "line": 21, - "column": 40, - "program": "returnTypeGenericArray.ets" - } } - }, - { - "type": "ETSUndefinedType", - "loc": { - "start": { - "line": 21, - "column": 41, - "program": "returnTypeGenericArray.ets" - }, - "end": { - "line": 21, - "column": 50, - "program": "returnTypeGenericArray.ets" - } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "returnTypeGenericArray.ets" } } - ], + }, "loc": { "start": { - "line": 21, - "column": 36, + "line": 1, + "column": 1, "program": "returnTypeGenericArray.ets" }, "end": { - "line": 21, - "column": 50, + "line": 1, + "column": 3, "program": "returnTypeGenericArray.ets" } } }, - "annotations": [], "loc": { "start": { "line": 21, @@ -965,40 +1061,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "returnTypeGenericArray.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "returnTypeGenericArray.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "returnTypeGenericArray.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "returnTypeGenericArray.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt b/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt index 516f90ed32c78256d13a9db7158cb1c68a6f6c23..2b5107c89e012103608e617fd8b517b028ac4655 100644 --- a/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt +++ b/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt @@ -610,40 +610,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switchStatementBoxing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switchStatementBoxing.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switchStatementBoxing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switchStatementBoxing.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt b/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt index d0694d6504f14ba02421b25ddfc2089d2a1fcb93..9fff8c798dc60d63dc03f5fcf03682cd84b80652 100644 --- a/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt +++ b/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt @@ -987,40 +987,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switchStatementCorrectConversion.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switchStatementCorrectConversion.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switchStatementCorrectConversion.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switchStatementCorrectConversion.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/this_type_valid_return_type-expected.txt b/ets2panda/test/compiler/ets/this_type_valid_return_type-expected.txt index 7452144a1d77a39adb0396214aeab0fbf3f6ffb1..a0b005774d1bab8877be0ad70796bf571d7c72c8 100644 --- a/ets2panda/test/compiler/ets/this_type_valid_return_type-expected.txt +++ b/ets2panda/test/compiler/ets/this_type_valid_return_type-expected.txt @@ -330,40 +330,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_type_valid_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_type_valid_return_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_type_valid_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_type_valid_return_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwInCatchClause3-expected.txt b/ets2panda/test/compiler/ets/throwInCatchClause3-expected.txt index 4adb806e51412bc2dfbd9c920fd900647aa940e4..ddcae8fdbf2414daeddf6d52e894530dba328e92 100644 --- a/ets2panda/test/compiler/ets/throwInCatchClause3-expected.txt +++ b/ets2panda/test/compiler/ets/throwInCatchClause3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInCatchClause3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInCatchClause3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInCatchClause3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInCatchClause3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwInFinallyBlock1-expected.txt b/ets2panda/test/compiler/ets/throwInFinallyBlock1-expected.txt index 4ec770c68265a0ab263aede4bba831da431f09b2..4ec5b9214dea10eb91d02536e055fed9a875324b 100644 --- a/ets2panda/test/compiler/ets/throwInFinallyBlock1-expected.txt +++ b/ets2panda/test/compiler/ets/throwInFinallyBlock1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInFinallyBlock1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInFinallyBlock1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInFinallyBlock1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInFinallyBlock1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwInRethrowingFunction2-expected.txt b/ets2panda/test/compiler/ets/throwInRethrowingFunction2-expected.txt index c0c5532cf4a9bd4d240a9ab0bccc8ff4bfca4215..0206339f3231dcfc682db447febd9932e448d7a1 100644 --- a/ets2panda/test/compiler/ets/throwInRethrowingFunction2-expected.txt +++ b/ets2panda/test/compiler/ets/throwInRethrowingFunction2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInRethrowingFunction2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInRethrowingFunction2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInRethrowingFunction2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInRethrowingFunction2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwInThrowingFunction-expected.txt b/ets2panda/test/compiler/ets/throwInThrowingFunction-expected.txt index 7f6ea6a0607beeadffe2ee510e54b731378284d6..a677bd13a0d0115eb42be6cbec8093c7d3af0e7b 100644 --- a/ets2panda/test/compiler/ets/throwInThrowingFunction-expected.txt +++ b/ets2panda/test/compiler/ets/throwInThrowingFunction-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInThrowingFunction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInThrowingFunction.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInThrowingFunction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInThrowingFunction.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwInTryStatement-expected.txt b/ets2panda/test/compiler/ets/throwInTryStatement-expected.txt index d56f831977f451d41e01364109e9d68af5753fea..5b455dceb86e300dd62df867b00a8d980f45e3e5 100644 --- a/ets2panda/test/compiler/ets/throwInTryStatement-expected.txt +++ b/ets2panda/test/compiler/ets/throwInTryStatement-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInTryStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInTryStatement.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwInTryStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwInTryStatement.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwingFunctionAsParameter1-expected.txt b/ets2panda/test/compiler/ets/throwingFunctionAsParameter1-expected.txt index 3f2b8726731e6534682b3f2d90b67c8b1760d687..1b05a374db3c1e40b2f483e642796e69dc3aa168 100644 --- a/ets2panda/test/compiler/ets/throwingFunctionAsParameter1-expected.txt +++ b/ets2panda/test/compiler/ets/throwingFunctionAsParameter1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionAsParameter1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionAsParameter1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionAsParameter1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionAsParameter1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwingFunctionCheck2-expected.txt b/ets2panda/test/compiler/ets/throwingFunctionCheck2-expected.txt index 145591dfc4d1b1a6cd49c5cc922cdc4bb059335b..cc12ad55a965cbdff86e12a70b4763982f9ea998 100644 --- a/ets2panda/test/compiler/ets/throwingFunctionCheck2-expected.txt +++ b/ets2panda/test/compiler/ets/throwingFunctionCheck2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwingFunctionCheck3-expected.txt b/ets2panda/test/compiler/ets/throwingFunctionCheck3-expected.txt index 90d0e9fa34dcffa3bf26522faf6ac9239f605c7e..d9f11899d8a68c7752d0369b34b85b99f09e8598 100644 --- a/ets2panda/test/compiler/ets/throwingFunctionCheck3-expected.txt +++ b/ets2panda/test/compiler/ets/throwingFunctionCheck3-expected.txt @@ -301,40 +301,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwingFunctionCheck6-expected.txt b/ets2panda/test/compiler/ets/throwingFunctionCheck6-expected.txt index 528751460190f7b9ad81e2d3e5dae34192bdee32..767d95af4817b9d2eb576dc977c91bab7a2680c8 100644 --- a/ets2panda/test/compiler/ets/throwingFunctionCheck6-expected.txt +++ b/ets2panda/test/compiler/ets/throwingFunctionCheck6-expected.txt @@ -379,40 +379,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionCheck6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/throwingFunctionType1-expected.txt b/ets2panda/test/compiler/ets/throwingFunctionType1-expected.txt index 6326ffbd5436993c584fe65da0eb5358da937724..123a8379e06381a25eb6cfade032502deeba74c2 100644 --- a/ets2panda/test/compiler/ets/throwingFunctionType1-expected.txt +++ b/ets2panda/test/compiler/ets/throwingFunctionType1-expected.txt @@ -87,40 +87,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionType1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionType1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwingFunctionType1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwingFunctionType1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/tryCatchErrorMissingParamType-expected.txt b/ets2panda/test/compiler/ets/tryCatchErrorMissingParamType-expected.txt index 6778942c163c260d864b798eef569036cc633492..7baee8c0dd31de1e9bad50fd27e286e5590416cb 100644 --- a/ets2panda/test/compiler/ets/tryCatchErrorMissingParamType-expected.txt +++ b/ets2panda/test/compiler/ets/tryCatchErrorMissingParamType-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tryCatchErrorMissingParamType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tryCatchErrorMissingParamType.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tryCatchErrorMissingParamType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tryCatchErrorMissingParamType.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/tryCatchMissingParamType-expected.txt b/ets2panda/test/compiler/ets/tryCatchMissingParamType-expected.txt index 5395ba6eacc3a3c43d96f7955af54b3843db8da5..8738b6624240cacc4b14654b7d80d3cb6bbc511f 100644 --- a/ets2panda/test/compiler/ets/tryCatchMissingParamType-expected.txt +++ b/ets2panda/test/compiler/ets/tryCatchMissingParamType-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tryCatchMissingParamType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tryCatchMissingParamType.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tryCatchMissingParamType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tryCatchMissingParamType.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/tryDefaultCatches-expected.txt b/ets2panda/test/compiler/ets/tryDefaultCatches-expected.txt index 496ae5525537c71f2836b1df9dd064b53ccd8c7a..0e37bee20ec9c558ed8009b204fdb0dd8c855f76 100644 --- a/ets2panda/test/compiler/ets/tryDefaultCatches-expected.txt +++ b/ets2panda/test/compiler/ets/tryDefaultCatches-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tryDefaultCatches.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tryDefaultCatches.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tryDefaultCatches.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tryDefaultCatches.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/tuple_types_1-expected.txt b/ets2panda/test/compiler/ets/tuple_types_1-expected.txt index b3c0d6aa207d3ca543d478a1a2ebb5431454d2b2..d7a76bc74072e2eaf68df34bac654366785d8db8 100644 --- a/ets2panda/test/compiler/ets/tuple_types_1-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_1-expected.txt @@ -829,55 +829,103 @@ } }, { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "number", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 50, - "program": "tuple_types_1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } }, - "end": { - "line": 20, - "column": 56, - "program": "tuple_types_1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } } } - }, + ], "loc": { "start": { - "line": 20, - "column": 50, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" }, "end": { - "line": 20, - "column": 57, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" } } }, "loc": { "start": { - "line": 20, - "column": 50, + "line": 1, + "column": 1, "program": "tuple_types_1.ets" }, "end": { - "line": 20, - "column": 57, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, @@ -940,40 +988,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1157,55 +1171,103 @@ "type": "Identifier", "name": "tup_arr_1", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "num_str_str_type", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 22, - "program": "tuple_types_1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "num_str_str_type", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } }, - "end": { - "line": 23, - "column": 38, - "program": "tuple_types_1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } } } - }, + ], "loc": { "start": { - "line": 23, - "column": 22, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" }, "end": { - "line": 23, - "column": 39, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" } } }, "loc": { "start": { - "line": 23, - "column": 22, + "line": 1, + "column": 1, "program": "tuple_types_1.ets" }, "end": { - "line": 23, - "column": 39, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 23, @@ -1482,55 +1544,103 @@ "type": "Identifier", "name": "tup_arr_2", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "num_str_str_with_array", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 22, - "program": "tuple_types_1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "num_str_str_with_array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } }, - "end": { - "line": 29, - "column": 44, - "program": "tuple_types_1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } } } - }, + ], "loc": { "start": { - "line": 29, - "column": 22, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" }, "end": { - "line": 29, - "column": 45, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" } } }, "loc": { "start": { - "line": 29, - "column": 22, + "line": 1, + "column": 1, "program": "tuple_types_1.ets" }, "end": { - "line": 29, - "column": 45, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 29, @@ -3721,119 +3831,167 @@ "type": "Identifier", "name": "g_var", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTuple", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "number", - "decorators": [], - "loc": { - "start": { - "line": 44, - "column": 17, - "program": "tuple_types_1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTuple", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } }, - "end": { - "line": 44, - "column": 23, - "program": "tuple_types_1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } } - } - }, - "loc": { - "start": { - "line": 44, - "column": 17, - "program": "tuple_types_1.ets" }, - "end": { - "line": 44, - "column": 24, - "program": "tuple_types_1.ets" - } - } - }, - "loc": { - "start": { - "line": 44, - "column": 17, - "program": "tuple_types_1.ets" - }, - "end": { - "line": 44, - "column": 24, - "program": "tuple_types_1.ets" - } - } - }, - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 44, - "column": 25, - "program": "tuple_types_1.ets" + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } + } }, - "end": { - "line": 44, - "column": 31, - "program": "tuple_types_1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" + } } } - }, + ], "loc": { "start": { - "line": 44, - "column": 25, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" }, "end": { - "line": 44, - "column": 32, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" } } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" }, - "loc": { - "start": { - "line": 44, - "column": 25, - "program": "tuple_types_1.ets" - }, - "end": { - "line": 44, - "column": 32, - "program": "tuple_types_1.ets" - } + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_1.ets" } } - ], + }, "loc": { "start": { - "line": 44, - "column": 16, + "line": 1, + "column": 1, "program": "tuple_types_1.ets" }, "end": { - "line": 44, - "column": 32, + "line": 1, + "column": 3, "program": "tuple_types_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 44, diff --git a/ets2panda/test/compiler/ets/tuple_types_12-expected.txt b/ets2panda/test/compiler/ets/tuple_types_12-expected.txt index 28c3758a12c5f3bc00e16ee9fd8643aac21af84c..10c09fb4074840d9b03fa4b9470ec34bec5ae2ae 100644 --- a/ets2panda/test/compiler/ets/tuple_types_12-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_12-expected.txt @@ -702,40 +702,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_12.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_12.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1176,55 +1142,103 @@ } }, { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "custom_tuple_type", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 61, - "program": "tuple_types_12.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tuple_types_12.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_12.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "custom_tuple_type", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_12.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_12.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_12.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_12.ets" + } + } }, - "end": { - "line": 22, - "column": 78, - "program": "tuple_types_12.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_12.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_12.ets" + } } } - }, + ], "loc": { "start": { - "line": 22, - "column": 61, + "line": 1, + "column": 3, "program": "tuple_types_12.ets" }, "end": { - "line": 22, - "column": 79, + "line": 1, + "column": 3, "program": "tuple_types_12.ets" } } }, "loc": { "start": { - "line": 22, - "column": 61, + "line": 1, + "column": 1, "program": "tuple_types_12.ets" }, "end": { - "line": 22, - "column": 79, + "line": 1, + "column": 3, "program": "tuple_types_12.ets" } } }, - "annotations": [], "loc": { "start": { "line": 22, diff --git a/ets2panda/test/compiler/ets/tuple_types_13-expected.txt b/ets2panda/test/compiler/ets/tuple_types_13-expected.txt index 69bf100c2661951899f49ff459d5d26d455af02c..014a48229801a92b2001315036164b18d0c74ee6 100644 --- a/ets2panda/test/compiler/ets/tuple_types_13-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_13-expected.txt @@ -213,40 +213,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_13.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_13.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_13.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_13.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -568,55 +534,103 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "num_str_str", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 14, - "program": "tuple_types_13.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tuple_types_13.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_13.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "num_str_str", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_13.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_13.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_13.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_13.ets" + } + } }, - "end": { - "line": 19, - "column": 25, - "program": "tuple_types_13.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_13.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_13.ets" + } } } - }, + ], "loc": { "start": { - "line": 19, - "column": 14, + "line": 1, + "column": 3, "program": "tuple_types_13.ets" }, "end": { - "line": 19, - "column": 26, + "line": 1, + "column": 3, "program": "tuple_types_13.ets" } } }, "loc": { "start": { - "line": 19, - "column": 14, + "line": 1, + "column": 1, "program": "tuple_types_13.ets" }, "end": { - "line": 19, - "column": 26, + "line": 1, + "column": 3, "program": "tuple_types_13.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, diff --git a/ets2panda/test/compiler/ets/tuple_types_14-expected.txt b/ets2panda/test/compiler/ets/tuple_types_14-expected.txt index d471f35ec5f9b4e0270ffa668fd917d72f2c1a4a..f3a64301f4672793bebd3abf30ae36ab20213683 100644 --- a/ets2panda/test/compiler/ets/tuple_types_14-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_14-expected.txt @@ -733,40 +733,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_14.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_14.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_14.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_14.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/tuple_types_15-expected.txt b/ets2panda/test/compiler/ets/tuple_types_15-expected.txt index dd6d9362ae507760a750b1fe27a1f54ddf4b8c46..410a69863909bd412f6d502ac3c2d834ce5a49bf 100644 --- a/ets2panda/test/compiler/ets/tuple_types_15-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_15-expected.txt @@ -134,40 +134,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_15.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_15.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_15.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_15.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1556,55 +1522,103 @@ "type": "Identifier", "name": "array", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "array_tuple", - "decorators": [], - "loc": { - "start": { - "line": 32, - "column": 16, - "program": "tuple_types_15.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tuple_types_15.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_15.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "array_tuple", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_15.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_15.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_15.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_15.ets" + } + } }, - "end": { - "line": 32, - "column": 27, - "program": "tuple_types_15.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tuple_types_15.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tuple_types_15.ets" + } } } - }, + ], "loc": { "start": { - "line": 32, - "column": 16, + "line": 1, + "column": 3, "program": "tuple_types_15.ets" }, "end": { - "line": 32, - "column": 28, + "line": 1, + "column": 3, "program": "tuple_types_15.ets" } } }, "loc": { "start": { - "line": 32, - "column": 16, + "line": 1, + "column": 1, "program": "tuple_types_15.ets" }, "end": { - "line": 32, - "column": 28, + "line": 1, + "column": 3, "program": "tuple_types_15.ets" } } }, - "annotations": [], "loc": { "start": { "line": 32, diff --git a/ets2panda/test/compiler/ets/tuple_types_16-expected.txt b/ets2panda/test/compiler/ets/tuple_types_16-expected.txt index 37e21b771f93a8039ed8104b4b76b4fe8269bae9..5d5e3315b16dbf426009829195deab4402129151 100644 --- a/ets2panda/test/compiler/ets/tuple_types_16-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_16-expected.txt @@ -562,40 +562,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_16.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_16.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_16.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_16.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/tuple_types_17-expected.txt b/ets2panda/test/compiler/ets/tuple_types_17-expected.txt index cdba099378178a82ca1e809877ba5e15a722a524..ac7cf64b2eb6416b9283b61072ac3f930d4bc232 100644 --- a/ets2panda/test/compiler/ets/tuple_types_17-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_17-expected.txt @@ -198,40 +198,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_17.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_17.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_17.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_17.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/tuple_types_18-expected.txt b/ets2panda/test/compiler/ets/tuple_types_18-expected.txt index 11777335041cb083b631abaf843211113d47844e..7c58b43190439a44c2c1730c2e9fdeb29c5ddd33 100644 --- a/ets2panda/test/compiler/ets/tuple_types_18-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_18-expected.txt @@ -245,40 +245,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_18.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_18.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_18.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_18.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/tuple_types_19-expected.txt b/ets2panda/test/compiler/ets/tuple_types_19-expected.txt index 6de694f10d6bf92d80e3a69287f0895965d3bb69..17e090cb81435ea9f74cb6c98c10e96e6573fdcb 100644 --- a/ets2panda/test/compiler/ets/tuple_types_19-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_19-expected.txt @@ -1815,40 +1815,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_19.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_19.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_19.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_19.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/tuple_types_7-expected.txt b/ets2panda/test/compiler/ets/tuple_types_7-expected.txt index 3d4f0dfc0254cc419f19f245c10bca429463bca8..f4972d8ceac0d83410afd6765383f9e392793c28 100644 --- a/ets2panda/test/compiler/ets/tuple_types_7-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_7-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_types_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_types_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/typeAlias-expected.txt b/ets2panda/test/compiler/ets/typeAlias-expected.txt index 4683c6ea695f791b0c4021ef321f8a5d24e8f623..ed6e1c5f5ab7767dd2dd8d4cf61220a6b69af21e 100644 --- a/ets2panda/test/compiler/ets/typeAlias-expected.txt +++ b/ets2panda/test/compiler/ets/typeAlias-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "typeAlias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "typeAlias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "typeAlias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "typeAlias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/typeVarReferenceFromStaticContext2-expected.txt b/ets2panda/test/compiler/ets/typeVarReferenceFromStaticContext2-expected.txt index be172fdbe9e17812775bc850f55165ad5441003c..6c94e48e8328581c6b36efeb852e8990ace9b5fa 100644 --- a/ets2panda/test/compiler/ets/typeVarReferenceFromStaticContext2-expected.txt +++ b/ets2panda/test/compiler/ets/typeVarReferenceFromStaticContext2-expected.txt @@ -636,40 +636,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "typeVarReferenceFromStaticContext2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "typeVarReferenceFromStaticContext2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "typeVarReferenceFromStaticContext2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "typeVarReferenceFromStaticContext2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/union_types_1-expected.txt b/ets2panda/test/compiler/ets/union_types_1-expected.txt index 827791f9a529555cbae0aaacccd8db6a11ad346e..f1d4160763d5f330443abd6a4a08760ccfe42d9e 100644 --- a/ets2panda/test/compiler/ets/union_types_1-expected.txt +++ b/ets2panda/test/compiler/ets/union_types_1-expected.txt @@ -1034,40 +1034,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_types_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_types_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_types_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_types_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/union_types_3-expected.txt b/ets2panda/test/compiler/ets/union_types_3-expected.txt index 0b6e70401978b7dc53e0570d1dcf12b9a5acf5c4..05a22f480526ad6ccd7d3ff730388cb583e97351 100644 --- a/ets2panda/test/compiler/ets/union_types_3-expected.txt +++ b/ets2panda/test/compiler/ets/union_types_3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_types_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_types_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_types_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_types_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/union_types_5-expected.txt b/ets2panda/test/compiler/ets/union_types_5-expected.txt index 069a5c85ac42dbd647a88e22cfb195cdc3e5df7d..b41bdcb77ca8cd2b7d316573a216503181be5739 100644 --- a/ets2panda/test/compiler/ets/union_types_5-expected.txt +++ b/ets2panda/test/compiler/ets/union_types_5-expected.txt @@ -992,40 +992,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_types_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_types_5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_types_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_types_5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/compiler/ets/union_types_merging-expected.txt b/ets2panda/test/compiler/ets/union_types_merging-expected.txt index d0a258d40d823d08448de3de6e84949449a7360f..614396b8aeacb065a55ce902ca4d10f2e18aad1c 100644 --- a/ets2panda/test/compiler/ets/union_types_merging-expected.txt +++ b/ets2panda/test/compiler/ets/union_types_merging-expected.txt @@ -1941,40 +1941,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_types_merging.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_types_merging.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_types_merging.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_types_merging.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/declgen/class-expected.txt b/ets2panda/test/declgen/class-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..74dcb08e917a38ad5ee9709cd98b6dc34336fc84 --- /dev/null +++ b/ets2panda/test/declgen/class-expected.txt @@ -0,0 +1,42 @@ +/** + * 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 declare interface I0 { + I0Method(a: string): String; + +} + +export declare interface I1 { + I1Method(a: double): double; + +} + +export declare class Base { + public a: double; + + public constructor(a: double); + +} + +export declare class Derived extends Base implements I0, I1 { + public I0Method(a: string): String; + + public I1Method(a: double): double; + + public b: double; + + public constructor(a: double, b: double); + +} \ No newline at end of file diff --git a/ets2panda/test/declgen/class.ets b/ets2panda/test/declgen/class.ets new file mode 100644 index 0000000000000000000000000000000000000000..c35fec53999aea7bfa29f92b86b02c7fb73e3d77 --- /dev/null +++ b/ets2panda/test/declgen/class.ets @@ -0,0 +1,33 @@ +/** + * 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 I0 { + I0Method(a: string): string { return a; }; +} + +export interface I1 { + I1Method(a: double): double { return a; }; +} + +export class Base { + a: double = 1; + constructor(a: double) {this.a = a;} +} + +export class Derived extends Base implements I0, I1 { + I0Method(a: string): string { return a; }; + I1Method(a: double): double { return a; }; + b: double = 2; + constructor(a: double, b: double) {super(a); this.b = b;} +} \ No newline at end of file diff --git a/ets2panda/test/declgen/enum-expected.txt b/ets2panda/test/declgen/enum-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..0bff710d1fc55fa48285afee2e3f26bd08101f80 --- /dev/null +++ b/ets2panda/test/declgen/enum-expected.txt @@ -0,0 +1,79 @@ +/** + * 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 declare final class Direction extends BaseEnum { + + + public constructor(ordinal: int, value: int); + + public static readonly Up: Direction; + + public static readonly Down: Direction; + + public static readonly Left: Direction; + + public static readonly Right: Direction; + + + + + + public getName(): String; + + public static getValueOf(name: String): Direction; + + public static fromValue(value: int): Direction; + + public valueOf(): int; + + public toString(): String; + + public static values(): FixedArray; + + public getOrdinal(): int; + + +} + +export declare final class Message extends BaseEnum { + + + public constructor(ordinal: int, value: String); + + public static readonly Success: Message; + + public static readonly Failure: Message; + + public static readonly Pending: Message; + + + + + public getName(): String; + + public static getValueOf(name: String): Message; + + public static fromValue(value: String): Message; + + public valueOf(): String; + + public toString(): String; + + public static values(): FixedArray; + + public getOrdinal(): int; + + +} \ No newline at end of file diff --git a/ets2panda/test/declgen/enum.ets b/ets2panda/test/declgen/enum.ets new file mode 100644 index 0000000000000000000000000000000000000000..045fe8db94925de3f107f39aa8a4acb5bd607788 --- /dev/null +++ b/ets2panda/test/declgen/enum.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. + */ +export enum Direction { + Up, + Down, + Left, + Right +} + +export enum Message { + Success = "SUCCESS", + Failure = "FAILURE", + Pending = "PENDING" +} \ No newline at end of file diff --git a/ets2panda/test/declgen/export-expected.txt b/ets2panda/test/declgen/export-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..487a95e02fe2fc78e3903c4e59084d8684439aef --- /dev/null +++ b/ets2panda/test/declgen/export-expected.txt @@ -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. + */ + +export { union as union1 } from "./var"; \ No newline at end of file diff --git a/ets2panda/test/declgen/export.ets b/ets2panda/test/declgen/export.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a5c3b6e472845e90d74b974ec5e32d2b6785554 --- /dev/null +++ b/ets2panda/test/declgen/export.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. + */ +'use static' +export { union as union1 } from "./var"; \ No newline at end of file diff --git a/ets2panda/test/declgen/function-expected.txt b/ets2panda/test/declgen/function-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..6212d507e84ca0e9ba6e83505d4a2935ce81c0f1 --- /dev/null +++ b/ets2panda/test/declgen/function-expected.txt @@ -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. + */ +export declare function add(x: number, y: number): double; + +export declare function greet(name: string, age?: number): String; + +export declare function multiply(x: number, gensym%%_1?: number): double; + +export declare function formatInput(input: number): double; + +export declare function formatInput(input: string): String; + +export declare function identity(arg: T): T; + +export declare function hello(): String; \ No newline at end of file diff --git a/ets2panda/test/declgen/function.ets b/ets2panda/test/declgen/function.ets new file mode 100644 index 0000000000000000000000000000000000000000..a642db7db079a46c4e23dac715382fae553b4fca --- /dev/null +++ b/ets2panda/test/declgen/function.ets @@ -0,0 +1,36 @@ +/** + * 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 function add(x: number, y: number): number { + return x + y; +} + +export function greet(name: string, age?: number): string { + return age ? `Hello ${name}, you are ${age} years old.` : `Hello ${name}.`; +} + +export function multiply(x: number, y: number = 2): number { + return x * y; +} + +export function formatInput(input: string): string {return input;}; +export function formatInput(input: number): number {return input;}; + +export function identity(arg: T): T { + return arg; +} + +export function hello() { + return "hello"; +} \ No newline at end of file diff --git a/ets2panda/test/declgen/import-expected.txt b/ets2panda/test/declgen/import-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..daaa85018d09067318156a99d38c956a2deba25a --- /dev/null +++ b/ets2panda/test/declgen/import-expected.txt @@ -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. + */ + +import * as AllType from "./var"; + +import { union as union1 } from "./var"; \ No newline at end of file diff --git a/ets2panda/test/declgen/import.ets b/ets2panda/test/declgen/import.ets new file mode 100644 index 0000000000000000000000000000000000000000..27329183dffe16471b8dbc34d292cff4947201e2 --- /dev/null +++ b/ets2panda/test/declgen/import.ets @@ -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. + */ +import { union as union1 } from "./var" + +import * as AllType from "./var" \ No newline at end of file diff --git a/ets2panda/test/declgen/indirect_dependence-expected.txt b/ets2panda/test/declgen/indirect_dependence-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..0889fa1c7cd1296ad074ade8daa94f6b181b96c6 --- /dev/null +++ b/ets2panda/test/declgen/indirect_dependence-expected.txt @@ -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. + */ + +export declare function foo(c: C): int; + +export declare function foo1(): D; + + + + + +export declare class B { + public a: A; + + public constructor(); + +} + +export type Point3 = Point2; + + + + +declare class C { + public constructor(); + +} +declare class D { + public constructor(); + +} +declare class A { + public constructor(); + +} +type Point2 = Point1; +type Point1 = Point; +declare class Point { + public x: double; + + public y: double; + + public constructor(); + +} \ No newline at end of file diff --git a/ets2panda/test/declgen/indirect_dependence.ets b/ets2panda/test/declgen/indirect_dependence.ets new file mode 100644 index 0000000000000000000000000000000000000000..248a541710b9d7d2adc93721a7d0cfd9c8399f56 --- /dev/null +++ b/ets2panda/test/declgen/indirect_dependence.ets @@ -0,0 +1,42 @@ +/** + * 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 C {} +class D {} + +export class B { + a: A = new A(); +} + +export function foo(c: C) { + return 123; +} + +export function foo1() { + return new D(); +} + +export type Point3 = Point2; + +type Point2 = Point1; +type Point1 = Point; +declare class Point { + public x: double; + + public y: double; + + public constructor(); + +} \ No newline at end of file diff --git a/ets2panda/test/declgen/interface-expected.txt b/ets2panda/test/declgen/interface-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..0e45342f0c8f82f14888d0a26a68fe3a1301ce03 --- /dev/null +++ b/ets2panda/test/declgen/interface-expected.txt @@ -0,0 +1,36 @@ +/** + * 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 declare interface User { + abstract set id(id: number): void; + + abstract get id(): double; + abstract set name(name: string): void; + + abstract get name(): String; + abstract set age(age: number | undefined): void; + + abstract get age(): Double|undefined; + abstract get apiUrl(): String; + +} + +export declare interface Animal { + abstract set name(name: string): void; + + abstract get name(): String; + makeSound(): void; + +} \ No newline at end of file diff --git a/ets2panda/test/declgen/interface.ets b/ets2panda/test/declgen/interface.ets new file mode 100644 index 0000000000000000000000000000000000000000..57132ca620ea1768a2be7ae7c4d7537d956b9f65 --- /dev/null +++ b/ets2panda/test/declgen/interface.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. + */ +export interface User { + id: number; + name: string; + age?: number; + readonly apiUrl: string; +} + +export interface Animal { + name: string; + makeSound(): void; +} \ No newline at end of file diff --git a/ets2panda/test/declgen/namespace-expected.txt b/ets2panda/test/declgen/namespace-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..8089251f18d803230d4730ab93563acb857c7932 --- /dev/null +++ b/ets2panda/test/declgen/namespace-expected.txt @@ -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. + */ + +export declare namespace MathOperations { + + let PI: double; + + function add(a: number, b: number): double; + + function subtract(a: number, b: number): double; + + +} \ No newline at end of file diff --git a/ets2panda/test/declgen/namespace.ets b/ets2panda/test/declgen/namespace.ets new file mode 100644 index 0000000000000000000000000000000000000000..5db717be01caf92afb459efddd6e037a1e81a776 --- /dev/null +++ b/ets2panda/test/declgen/namespace.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. + */ +export namespace MathOperations { + const PI = 3.14; + export function add(a: number, b: number): number { + return a + b; + } + export function subtract(a: number, b: number): number { + return a - b; + } +} \ No newline at end of file diff --git a/ets2panda/test/declgen/var-expected.txt b/ets2panda/test/declgen/var-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..2a92bb7cf43e592c558a4fa4ef5ce53e70998e71 --- /dev/null +++ b/ets2panda/test/declgen/var-expected.txt @@ -0,0 +1,39 @@ +/** + * 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 declare let n: double; + +export declare let o: Object; + +export declare let a: Array; + +export declare let t: [double, double]; + +export declare let f: () => Double; + +export declare let u: Double|String; + +export declare let l: "xyz"; + +export declare const b: float; + +export declare const c: double; + +export declare const d: "world"; + + + + +export type union = number | byte | short | int | long | float | double | char | boolean | string | bigint; \ No newline at end of file diff --git a/ets2panda/test/declgen/var.ets b/ets2panda/test/declgen/var.ets new file mode 100644 index 0000000000000000000000000000000000000000..64b91bc4b4a83b8bf58712fbcf3f14f9f16c58e2 --- /dev/null +++ b/ets2panda/test/declgen/var.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. + */ +export type union = number | byte | short | int | long | float | double | char | boolean | string | bigint; + +export let n: number +export let o: Object +export let a: number[] +export let t: [number, double] +export let f: ()=>number +export let u: number|string +export let l: "xyz" +export const b: float = 3.1 +export const c = 3.14 +export const d = "world" \ No newline at end of file diff --git a/ets2panda/test/depanalyzer/path_getter.h.erb b/ets2panda/test/depanalyzer/path_getter.h.erb index dc331fe9fdc8dad2548a5ba36681ea0e16884627..245be2c3a9be01287f3dd65e1cebc8b8453d42ad 100644 --- a/ets2panda/test/depanalyzer/path_getter.h.erb +++ b/ets2panda/test/depanalyzer/path_getter.h.erb @@ -29,9 +29,9 @@ inline std::string DepAnalyzerTestsBinPathGet() inline std::string DepAnalyzerTestsPathGet(size_t testFolderNum, size_t testFileNum) { - return std::string("<%= TESTS_FOLDER %>") + std::to_string(testFolderNum) + + return std::string(std::filesystem::canonical(std::string("<%= TESTS_FOLDER %>") + std::to_string(testFolderNum) + ark::es2panda::util::Path::GetPathDelimiter() + std::string("file") + - std::to_string(testFileNum) + std::string(".ets"); + std::to_string(testFileNum) + std::string(".ets"))); } } // namespace test::utils diff --git a/ets2panda/test/depanalyzer/test.cpp b/ets2panda/test/depanalyzer/test.cpp index 348ace2adb51825796ebc93d3a45f60ab946d817..e3bfa34aac3803d9a34052179ef26bf1aa4f3b90 100644 --- a/ets2panda/test/depanalyzer/test.cpp +++ b/ets2panda/test/depanalyzer/test.cpp @@ -21,6 +21,8 @@ #include "path_getter.h" #include "os/filesystem.h" +namespace { + class DepAnalyzerTest : public testing::Test { public: DepAnalyzerTest() = default; @@ -50,6 +52,16 @@ public: return depAnalyzer_.GetSourcePaths(); } + std::unordered_map> &GetTestFileDirectDependencies() + { + return depAnalyzer_.GetFileDirectDependencies(); + } + + std::unordered_map> &GetTestFileDirectDependants() + { + return depAnalyzer_.GetFileDirectDependants(); + } + private: DepAnalyzer depAnalyzer_; @@ -60,39 +72,66 @@ private: TEST_F(DepAnalyzerTest, Subtestv1) { size_t testFolderNum = 1; - size_t testFileCounter = 1; RunDepAnalyzer(testFolderNum); - std::vector expected; - GetExpectedAns(expected, testFolderNum, testFileCounter); - ASSERT(GetTestSourcePaths() == expected); + std::unordered_map> dependenciesExpected; + std::unordered_map> dependentsExpected; + std::string file1 = test::utils::DepAnalyzerTestsPathGet(1, 1); + dependenciesExpected[file1] = {}; + dependentsExpected[file1] = {}; + ASSERT(GetTestFileDirectDependencies() == dependenciesExpected); + ASSERT(GetTestFileDirectDependants() == dependentsExpected); } TEST_F(DepAnalyzerTest, Subtestv2) { size_t testFolderNum = 2; - size_t testFileCounter = 4; RunDepAnalyzer(testFolderNum); - std::vector expected; - GetExpectedAns(expected, testFolderNum, testFileCounter); - ASSERT(GetTestSourcePaths() == expected); + std::unordered_map> dependenciesExpected; + std::unordered_map> dependentsExpected; + std::string file1 = test::utils::DepAnalyzerTestsPathGet(2, 1); + std::string file2 = test::utils::DepAnalyzerTestsPathGet(2, 2); + std::string file3 = test::utils::DepAnalyzerTestsPathGet(2, 3); + std::string file4 = test::utils::DepAnalyzerTestsPathGet(2, 4); + dependenciesExpected[file1] = {file2}; + dependenciesExpected[file2] = {file3}; + dependenciesExpected[file3] = {file2, file4}; + dependenciesExpected[file4] = {file2}; + dependentsExpected[file1] = {}; + dependentsExpected[file2] = {file3, file4, file1}; + dependentsExpected[file3] = {file2}; + dependentsExpected[file4] = {file3}; + ASSERT(GetTestFileDirectDependencies() == dependenciesExpected); + ASSERT(GetTestFileDirectDependants() == dependentsExpected); } TEST_F(DepAnalyzerTest, Subtestv3) { size_t testFolderNum = 3; - size_t testFileCounter = 2; RunDepAnalyzer(testFolderNum); - std::vector expected; - GetExpectedAns(expected, testFolderNum, testFileCounter); - ASSERT(GetTestSourcePaths() == expected); + std::unordered_map> dependenciesExpected; + std::unordered_map> dependentsExpected; + std::string file1 = test::utils::DepAnalyzerTestsPathGet(3, 1); + std::string file2 = test::utils::DepAnalyzerTestsPathGet(3, 2); + dependenciesExpected[file1] = {file2}; + dependentsExpected[file1] = {}; + dependentsExpected[file2] = {file1}; + ASSERT(GetTestFileDirectDependencies() == dependenciesExpected); + ASSERT(GetTestFileDirectDependants() == dependentsExpected); } TEST_F(DepAnalyzerTest, Subtestv4) { size_t testFolderNum = 4; - size_t testFileCounter = 2; RunDepAnalyzer(testFolderNum); - std::vector expected; - GetExpectedAns(expected, testFolderNum, testFileCounter); - ASSERT(GetTestSourcePaths() == expected); + std::unordered_map> dependenciesExpected; + std::unordered_map> dependentsExpected; + std::string file1 = test::utils::DepAnalyzerTestsPathGet(4, 1); + std::string file2 = test::utils::DepAnalyzerTestsPathGet(4, 2); + dependenciesExpected[file1] = {file2}; + dependentsExpected[file1] = {}; + dependentsExpected[file2] = {file1}; + ASSERT(GetTestFileDirectDependencies() == dependenciesExpected); + ASSERT(GetTestFileDirectDependants() == dependentsExpected); } + +} // namespace diff --git a/ets2panda/test/isolated_declgen/infer_function_return_type_with_import_symbol-expected.txt b/ets2panda/test/isolated_declgen/infer_function_return_type_with_import_symbol-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..1804ab1e7b0d015bede8f8e8a61ec68c5830e100 --- /dev/null +++ b/ets2panda/test/isolated_declgen/infer_function_return_type_with_import_symbol-expected.txt @@ -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 A from "./infer_function_return_type_with_literal.ets"; + +import B from "./infer_function_return_type_with_literal.ets"; + +import C from "./infer_function_return_type_with_literal.ets"; + +export declare let b: A; + +export default declare let d: int; + +export declare function foo(a: int, c: C): A | Array | Array | Array | B | Number | String; \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/infer_function_return_type_with_import_symbol.ets b/ets2panda/test/isolated_declgen/infer_function_return_type_with_import_symbol.ets new file mode 100644 index 0000000000000000000000000000000000000000..6acccddadf48097094f19d1f36d565ccd37d2b16 --- /dev/null +++ b/ets2panda/test/isolated_declgen/infer_function_return_type_with_import_symbol.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. + */ + +import A from "./infer_function_return_type_with_literal.ets" +import B from "./infer_function_return_type_with_literal.ets" +import C from "./infer_function_return_type_with_literal.ets" + +export let b: A = new A + +export default let d: int = 1 + +export function foo(a: int, c: C) +{ + if (a < 0) { + return 1; + } + if (a == 0) { + return b; + } + if (a == 1) { + return new B; + } + if (a == 2) { + return ["hello", "arkts"]; + } + if (a == 3) { + return [0, 1, 2]; + } + if (a == 4) { + return [true, false, false, true]; + } + + return "hello"; +} + + + + diff --git a/ets2panda/test/isolated_declgen/infer_function_return_type_with_literal-expected.txt b/ets2panda/test/isolated_declgen/infer_function_return_type_with_literal-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..05805385471adb6e052b1feb486d7bdf830517ad --- /dev/null +++ b/ets2panda/test/isolated_declgen/infer_function_return_type_with_literal-expected.txt @@ -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. + */ + + export declare function foo(a: int): Int|Boolean|String; \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/infer_function_return_type_with_literal.ets b/ets2panda/test/isolated_declgen/infer_function_return_type_with_literal.ets new file mode 100644 index 0000000000000000000000000000000000000000..00375f7d6e4c9b5dc9bdd75fcac3659305e702b4 --- /dev/null +++ b/ets2panda/test/isolated_declgen/infer_function_return_type_with_literal.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. + */ + +export function foo(a: int) +{ + if (a < 0) { + return 1; + } + if (a == 0) { + return "hello"; + } + if (a > 0) { + return true; + } + + return 0; +} \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/infer_function_return_type_with_variable-expected.txt b/ets2panda/test/isolated_declgen/infer_function_return_type_with_variable-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..6eced866112266e6fc719f40a73bfa8ce070d9a3 --- /dev/null +++ b/ets2panda/test/isolated_declgen/infer_function_return_type_with_variable-expected.txt @@ -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. + */ + + export declare function foo(a: int): String|B|Int|A; \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/infer_function_return_type_with_variable.ets b/ets2panda/test/isolated_declgen/infer_function_return_type_with_variable.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a19a2de337f3d47e3f48e3886f6269b06a6b799 --- /dev/null +++ b/ets2panda/test/isolated_declgen/infer_function_return_type_with_variable.ets @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A {} +class B {} + +export function foo(a: int) +{ + if (a < 0) { + return 1; + } + if (a == 0) { + return new A; + } + if (a > 0) { + return new B; + } + + return "hello"; +} \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/isolated_class-expected.txt b/ets2panda/test/isolated_declgen/isolated_class-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..5ee4f2678560c8517eae0cdc3ad898888c9f20b6 --- /dev/null +++ b/ets2panda/test/isolated_declgen/isolated_class-expected.txt @@ -0,0 +1,42 @@ +/** + * 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 declare interface I0 { + I0Method(a: string): String; + +} + +export declare interface I1 { + I1Method(a: double): double; + +} + +export declare class Base { + public a: double; + + public constructor(a: double); + +} + +export declare class Derived extends Base implements I0, I1 { + public I0Method(a: string): String; + + public I1Method(a: double): double; + + public b: double; + + public constructor(a: double, b: double); + +} \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/isolated_class.ets b/ets2panda/test/isolated_declgen/isolated_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb074a409f2a2726f22a0d92d7c940563f48fc90 --- /dev/null +++ b/ets2panda/test/isolated_declgen/isolated_class.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. + */ + +export interface I0 { + I0Method(a: string): string { return a; }; +} + +export interface I1 { + I1Method(a: double): double { return a; }; +} + +export class Base { + a: double = 1; + constructor(a: double) {this.a = a;} +} + +export class Derived extends Base implements I0, I1 { + I0Method(a: string): string { return a; }; + I1Method(a: double): double { return a; }; + b: double = 2; + constructor(a: double, b: double) {super(a); this.b = b;} +} \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/isolated_function_with_optional_parameter-expected.txt b/ets2panda/test/isolated_declgen/isolated_function_with_optional_parameter-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..5276a1c1bdc1e8292851d58d4bf38cf6bba15789 --- /dev/null +++ b/ets2panda/test/isolated_declgen/isolated_function_with_optional_parameter-expected.txt @@ -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 declare function greet(name: string, age?: number): String; + +export declare function multiply(x: number, gensym%%_1?: number): double; \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/isolated_function_with_optional_parameter.ets b/ets2panda/test/isolated_declgen/isolated_function_with_optional_parameter.ets new file mode 100644 index 0000000000000000000000000000000000000000..ee707643a8a8b768616ff15405e696379216c3b4 --- /dev/null +++ b/ets2panda/test/isolated_declgen/isolated_function_with_optional_parameter.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. + */ + +export function greet(name: string, age?: number): string { + return age ? `Hello ${name}, you are ${age} years old.` : `Hello ${name}.`; +} + +export function multiply(x: number, y: number = 2): number { + return x * y; +} \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/isolated_interface-expected.txt b/ets2panda/test/isolated_declgen/isolated_interface-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..029658ebdd12244c5efb3adf5d96601b7ff912b5 --- /dev/null +++ b/ets2panda/test/isolated_declgen/isolated_interface-expected.txt @@ -0,0 +1,36 @@ +/** + * 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 declare interface User { + set id(id: number): void; + + get id(): double; + set name(name: string): void; + + get name(): String; + set age(age: number | undefined): void; + + get age(): Double|undefined; + get apiUrl(): String; + +} + +export declare interface Animal { + set name(name: string): void; + + get name(): String; + makeSound(): void; + +} \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/isolated_interface.ets b/ets2panda/test/isolated_declgen/isolated_interface.ets new file mode 100644 index 0000000000000000000000000000000000000000..828c67738536ae8091df3593418c2d7cdf383c17 --- /dev/null +++ b/ets2panda/test/isolated_declgen/isolated_interface.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. + */ + +export interface User { + id: number; + name: string; + age?: number; + readonly apiUrl: string; +} + +export interface Animal { + name: string; + makeSound(): void; +} \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/isolated_namespace-expected.txt b/ets2panda/test/isolated_declgen/isolated_namespace-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..c5d5aa7784db7a9b4c7d84f40f27a12db0a668bf --- /dev/null +++ b/ets2panda/test/isolated_declgen/isolated_namespace-expected.txt @@ -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. + */ + + export declare namespace MathOperations { + + let PI: double; + + function add(a: number, b: number): double; + + function subtract(a: number, b: number): double; + + +} \ No newline at end of file diff --git a/ets2panda/test/isolated_declgen/isolated_namespace.ets b/ets2panda/test/isolated_declgen/isolated_namespace.ets new file mode 100644 index 0000000000000000000000000000000000000000..909b5f31858fca960b9d5386fe6ab3240a50955f --- /dev/null +++ b/ets2panda/test/isolated_declgen/isolated_namespace.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. + */ + +export namespace MathOperations { + const PI:double = 3.14; + export function add(a: number, b: number): number { + return a + b; + } + export function subtract(a: number, b: number): number { + return a - b; + } +} \ No newline at end of file diff --git a/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt b/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt index a74777149ea0b69b0b513d346cff158be168b8d8..59013f92d3b4ffa22e7584eefa2e88c830e1a642 100644 --- a/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt +++ b/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt @@ -5431,40 +5431,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "AccessBinaryTrees.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "AccessBinaryTrees.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/AccessFannkuch-expected.txt b/ets2panda/test/parser/ets/AccessFannkuch-expected.txt index 871a9c126acbbfbf0e69452ba2c8124b18e23d66..51ba649b625c078ed445c4c2a34c3676e97b070f 100644 --- a/ets2panda/test/parser/ets/AccessFannkuch-expected.txt +++ b/ets2panda/test/parser/ets/AccessFannkuch-expected.txt @@ -477,23 +477,71 @@ "type": "Identifier", "name": "perm", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + }, "loc": { "start": { - "line": 26, - "column": 19, + "line": 1, + "column": 1, "program": "AccessFannkuch.ets" }, "end": { - "line": 26, - "column": 22, + "line": 1, + "column": 3, "program": "AccessFannkuch.ets" } } }, - "annotations": [], "loc": { "start": { "line": 26, @@ -637,23 +685,71 @@ "type": "Identifier", "name": "perm1", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + }, "loc": { "start": { - "line": 28, - "column": 20, + "line": 1, + "column": 1, "program": "AccessFannkuch.ets" }, "end": { - "line": 28, - "column": 23, + "line": 1, + "column": 3, "program": "AccessFannkuch.ets" } } }, - "annotations": [], "loc": { "start": { "line": 28, @@ -797,23 +893,71 @@ "type": "Identifier", "name": "count", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + }, "loc": { "start": { - "line": 30, - "column": 20, + "line": 1, + "column": 1, "program": "AccessFannkuch.ets" }, "end": { - "line": 30, - "column": 23, + "line": 1, + "column": 3, "program": "AccessFannkuch.ets" } } }, - "annotations": [], "loc": { "start": { "line": 30, @@ -957,23 +1101,71 @@ "type": "Identifier", "name": "maxPerm", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessFannkuch.ets" + } + } + }, "loc": { "start": { - "line": 32, - "column": 22, + "line": 1, + "column": 1, "program": "AccessFannkuch.ets" }, "end": { - "line": 32, - "column": 25, + "line": 1, + "column": 3, "program": "AccessFannkuch.ets" } } }, - "annotations": [], "loc": { "start": { "line": 32, @@ -5916,40 +6108,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "AccessFannkuch.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "AccessFannkuch.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "AccessFannkuch.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "AccessFannkuch.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/AccessNBody-expected.txt b/ets2panda/test/parser/ets/AccessNBody-expected.txt index 722f9f50747109d08a860728bf5c7f617702af1c..83097faa8d788de48670e7a59d4dedb58288ff84 100644 --- a/ets2panda/test/parser/ets/AccessNBody-expected.txt +++ b/ets2panda/test/parser/ets/AccessNBody-expected.txt @@ -2683,55 +2683,103 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Body", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 15, - "program": "AccessNBody.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "AccessNBody.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Body", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + } + } }, - "end": { - "line": 47, - "column": 19, - "program": "AccessNBody.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + } } } - }, + ], "loc": { "start": { - "line": 47, - "column": 15, + "line": 1, + "column": 3, "program": "AccessNBody.ets" }, "end": { - "line": 47, - "column": 20, + "line": 1, + "column": 3, "program": "AccessNBody.ets" } } }, "loc": { "start": { - "line": 47, - "column": 15, + "line": 1, + "column": 1, "program": "AccessNBody.ets" }, "end": { - "line": 47, - "column": 20, + "line": 1, + "column": 3, "program": "AccessNBody.ets" } } }, - "annotations": [], "loc": { "start": { "line": 47, @@ -2815,55 +2863,103 @@ "type": "Identifier", "name": "bodies", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Body", - "decorators": [], - "loc": { - "start": { - "line": 48, - "column": 34, - "program": "AccessNBody.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "AccessNBody.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Body", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + } + } }, - "end": { - "line": 48, - "column": 38, - "program": "AccessNBody.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNBody.ets" + } } } - }, + ], "loc": { "start": { - "line": 48, - "column": 34, + "line": 1, + "column": 3, "program": "AccessNBody.ets" }, "end": { - "line": 48, - "column": 39, + "line": 1, + "column": 3, "program": "AccessNBody.ets" } } }, "loc": { "start": { - "line": 48, - "column": 34, + "line": 1, + "column": 1, "program": "AccessNBody.ets" }, "end": { - "line": 48, - "column": 39, + "line": 1, + "column": 3, "program": "AccessNBody.ets" } } }, - "annotations": [], "loc": { "start": { "line": 48, @@ -3286,11 +3382,45 @@ } }, "init": { - "type": "MemberExpression", - "object": { + "type": "TSAsExpression", + "expression": { "type": "MemberExpression", "object": { - "type": "ThisExpression", + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 53, + "column": 27, + "program": "AccessNBody.ets" + }, + "end": { + "line": 53, + "column": 31, + "program": "AccessNBody.ets" + } + } + }, + "property": { + "type": "Identifier", + "name": "bodies", + "decorators": [], + "loc": { + "start": { + "line": 53, + "column": 32, + "program": "AccessNBody.ets" + }, + "end": { + "line": 53, + "column": 38, + "program": "AccessNBody.ets" + } + } + }, + "computed": false, + "optional": false, "loc": { "start": { "line": 53, @@ -3299,24 +3429,24 @@ }, "end": { "line": 53, - "column": 31, + "column": 38, "program": "AccessNBody.ets" } } }, "property": { "type": "Identifier", - "name": "bodies", + "name": "length", "decorators": [], "loc": { "start": { "line": 53, - "column": 32, + "column": 39, "program": "AccessNBody.ets" }, "end": { "line": 53, - "column": 38, + "column": 45, "program": "AccessNBody.ets" } } @@ -3331,30 +3461,26 @@ }, "end": { "line": 53, - "column": 38, + "column": 45, "program": "AccessNBody.ets" } } }, - "property": { - "type": "Identifier", - "name": "length", - "decorators": [], + "typeAnnotation": { + "type": "ETSPrimitiveType", "loc": { "start": { "line": 53, - "column": 39, + "column": 49, "program": "AccessNBody.ets" }, "end": { "line": 53, - "column": 45, + "column": 52, "program": "AccessNBody.ets" } } }, - "computed": false, - "optional": false, "loc": { "start": { "line": 53, @@ -3391,7 +3517,7 @@ }, "end": { "line": 53, - "column": 46, + "column": 53, "program": "AccessNBody.ets" } } @@ -5023,11 +5149,45 @@ } }, "init": { - "type": "MemberExpression", - "object": { + "type": "TSAsExpression", + "expression": { "type": "MemberExpression", "object": { - "type": "ThisExpression", + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 70, + "column": 27, + "program": "AccessNBody.ets" + }, + "end": { + "line": 70, + "column": 31, + "program": "AccessNBody.ets" + } + } + }, + "property": { + "type": "Identifier", + "name": "bodies", + "decorators": [], + "loc": { + "start": { + "line": 70, + "column": 32, + "program": "AccessNBody.ets" + }, + "end": { + "line": 70, + "column": 38, + "program": "AccessNBody.ets" + } + } + }, + "computed": false, + "optional": false, "loc": { "start": { "line": 70, @@ -5036,24 +5196,24 @@ }, "end": { "line": 70, - "column": 31, + "column": 38, "program": "AccessNBody.ets" } } }, "property": { "type": "Identifier", - "name": "bodies", + "name": "length", "decorators": [], "loc": { "start": { "line": 70, - "column": 32, + "column": 39, "program": "AccessNBody.ets" }, "end": { "line": 70, - "column": 38, + "column": 45, "program": "AccessNBody.ets" } } @@ -5068,30 +5228,26 @@ }, "end": { "line": 70, - "column": 38, + "column": 45, "program": "AccessNBody.ets" } } }, - "property": { - "type": "Identifier", - "name": "length", - "decorators": [], + "typeAnnotation": { + "type": "ETSPrimitiveType", "loc": { "start": { "line": 70, - "column": 39, + "column": 49, "program": "AccessNBody.ets" }, "end": { "line": 70, - "column": 45, + "column": 52, "program": "AccessNBody.ets" } } }, - "computed": false, - "optional": false, "loc": { "start": { "line": 70, @@ -5128,7 +5284,7 @@ }, "end": { "line": 70, - "column": 46, + "column": 53, "program": "AccessNBody.ets" } } @@ -9421,11 +9577,45 @@ } }, "init": { - "type": "MemberExpression", - "object": { + "type": "TSAsExpression", + "expression": { "type": "MemberExpression", "object": { - "type": "ThisExpression", + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 101, + "column": 27, + "program": "AccessNBody.ets" + }, + "end": { + "line": 101, + "column": 31, + "program": "AccessNBody.ets" + } + } + }, + "property": { + "type": "Identifier", + "name": "bodies", + "decorators": [], + "loc": { + "start": { + "line": 101, + "column": 32, + "program": "AccessNBody.ets" + }, + "end": { + "line": 101, + "column": 38, + "program": "AccessNBody.ets" + } + } + }, + "computed": false, + "optional": false, "loc": { "start": { "line": 101, @@ -9434,24 +9624,24 @@ }, "end": { "line": 101, - "column": 31, + "column": 38, "program": "AccessNBody.ets" } } }, "property": { "type": "Identifier", - "name": "bodies", + "name": "length", "decorators": [], "loc": { "start": { "line": 101, - "column": 32, + "column": 39, "program": "AccessNBody.ets" }, "end": { "line": 101, - "column": 38, + "column": 45, "program": "AccessNBody.ets" } } @@ -9466,30 +9656,26 @@ }, "end": { "line": 101, - "column": 38, + "column": 45, "program": "AccessNBody.ets" } } }, - "property": { - "type": "Identifier", - "name": "length", - "decorators": [], + "typeAnnotation": { + "type": "ETSPrimitiveType", "loc": { "start": { "line": 101, - "column": 39, + "column": 49, "program": "AccessNBody.ets" }, "end": { "line": 101, - "column": 45, + "column": 52, "program": "AccessNBody.ets" } } }, - "computed": false, - "optional": false, "loc": { "start": { "line": 101, @@ -9526,7 +9712,7 @@ }, "end": { "line": 101, - "column": 46, + "column": 53, "program": "AccessNBody.ets" } } @@ -17130,40 +17316,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "AccessNBody.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "AccessNBody.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "AccessNBody.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "AccessNBody.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/AccessNBody.ets b/ets2panda/test/parser/ets/AccessNBody.ets index 85d303226d4d4d896d58b7e59b657e85ea88ae01..8a8f4db207439314f7cb1478ea3ed8780202614f 100644 --- a/ets2panda/test/parser/ets/AccessNBody.ets +++ b/ets2panda/test/parser/ets/AccessNBody.ets @@ -50,7 +50,7 @@ class NBodySystem { let px : double = 0.0; let py : double = 0.0; let pz : double = 0.0; - let size : int = this.bodies.length; + let size : int = this.bodies.length as int; for (let i : int = 0; i < size; i++) { let b : Body = this.bodies[i]; let m : double = b.mass; @@ -67,7 +67,7 @@ class NBodySystem { let dz : double ; let distance : double ; let mag : double ; - let size : int = this.bodies.length; + let size : int = this.bodies.length as int; for (let i : int = 0; i < size; i++) { let bodyi : Body = this.bodies[i]; for (let j : int = i + 1; j < size; j++) { @@ -98,7 +98,7 @@ class NBodySystem { let dz : double ; let distance : double ; let e : double = 0.0; - let size : int = this.bodies.length; + let size : int = this.bodies.length as int; for (let i : int = 0; i < size; i++) { let bodyi : Body = this.bodies[i]; e += 0.5 * bodyi.mass * (bodyi.vx * bodyi.vx + bodyi.vy * bodyi.vy + bodyi.vz * bodyi.vz); diff --git a/ets2panda/test/parser/ets/AccessNSieve-expected.txt b/ets2panda/test/parser/ets/AccessNSieve-expected.txt index c327d0af67906a528584ff817cf2d8b78ce03506..bf181a0b4ab79328b210bed58e564af13a828bec 100644 --- a/ets2panda/test/parser/ets/AccessNSieve-expected.txt +++ b/ets2panda/test/parser/ets/AccessNSieve-expected.txt @@ -279,23 +279,71 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "AccessNSieve.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNSieve.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessNSieve.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNSieve.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "AccessNSieve.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "AccessNSieve.ets" + } + } + }, "loc": { "start": { - "line": 20, - "column": 19, + "line": 1, + "column": 1, "program": "AccessNSieve.ets" }, "end": { - "line": 20, - "column": 26, + "line": 1, + "column": 3, "program": "AccessNSieve.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, @@ -3419,40 +3467,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "AccessNSieve.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "AccessNSieve.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt b/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt index f471a30da12202f986223646043644794b0d70ef..978b8c3d6e60529b779b6b056c0c2972d7b85c59 100644 --- a/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt +++ b/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt @@ -2251,40 +2251,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Bitops3BitBitsInByte.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Bitops3BitBitsInByte.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Bitops3BitBitsInByte.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Bitops3BitBitsInByte.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt b/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt index 6542adc6cb4f6c838859761f950795a2fc438cb4..19b23b72af01cfa027065d232afa22d9fd5611d3 100644 --- a/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt +++ b/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt @@ -1993,40 +1993,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "BitopsBitsInByte.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "BitopsBitsInByte.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "BitopsBitsInByte.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "BitopsBitsInByte.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt b/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt index 3de4efb575ef8fabb351ec0c06544a4461d1b705..26c14b0b75d69ee30f728896d6a0c8515112acb0 100644 --- a/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt +++ b/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt @@ -984,40 +984,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "BitopsBitwiseAnd.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "BitopsBitwiseAnd.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "BitopsBitwiseAnd.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "BitopsBitwiseAnd.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt b/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt index 72ba66e7312ca02ab1dab9cca260fd9e362aaf63..8b1ab7c272608c29110ef9bcfd47964003041dac 100644 --- a/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt +++ b/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt @@ -79,23 +79,71 @@ "type": "Identifier", "name": "isPrime", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + }, "loc": { "start": { - "line": 17, - "column": 26, + "line": 1, + "column": 1, "program": "BitopsNSieveBits.ets" }, "end": { - "line": 17, - "column": 29, + "line": 1, + "column": 3, "program": "BitopsNSieveBits.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -1908,23 +1956,71 @@ } ], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + }, "loc": { "start": { - "line": 35, - "column": 43, + "line": 1, + "column": 1, "program": "BitopsNSieveBits.ets" }, "end": { - "line": 35, - "column": 46, + "line": 1, + "column": 3, "program": "BitopsNSieveBits.ets" } } }, - "annotations": [], "loc": { "start": { "line": 35, @@ -1950,23 +2046,71 @@ "type": "Identifier", "name": "isPrime", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + }, "loc": { "start": { - "line": 37, - "column": 18, + "line": 1, + "column": 1, "program": "BitopsNSieveBits.ets" }, "end": { - "line": 37, - "column": 21, + "line": 1, + "column": 3, "program": "BitopsNSieveBits.ets" } } }, - "annotations": [], "loc": { "start": { "line": 37, @@ -2677,23 +2821,71 @@ "type": "Identifier", "name": "result", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "BitopsNSieveBits.ets" + } + } + }, "loc": { "start": { - "line": 47, - "column": 17, + "line": 1, + "column": 1, "program": "BitopsNSieveBits.ets" }, "end": { - "line": 47, - "column": 20, + "line": 1, + "column": 3, "program": "BitopsNSieveBits.ets" } } }, - "annotations": [], "loc": { "start": { "line": 47, @@ -3670,40 +3862,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "BitopsNSieveBits.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "BitopsNSieveBits.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "BitopsNSieveBits.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "BitopsNSieveBits.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/Boolean_bitwise-expected.txt b/ets2panda/test/parser/ets/Boolean_bitwise-expected.txt index cf8040c7f96071a106aa3ef45a4cfe624396a28a..987ba7181c882fa24765384f4ce1259960f731f4 100644 --- a/ets2panda/test/parser/ets/Boolean_bitwise-expected.txt +++ b/ets2panda/test/parser/ets/Boolean_bitwise-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Boolean_bitwise.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Boolean_bitwise.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Boolean_bitwise.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Boolean_bitwise.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt b/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt index 328ebd754a54cd2c9594c0f5abd497fc8f93b28b..a2e875bc56468b890b241be8e46959d66804ff97 100644 --- a/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt +++ b/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt @@ -3969,40 +3969,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ControlFlowRecursive.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ControlFlowRecursive.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/Dollar_dollar_1-expected.txt b/ets2panda/test/parser/ets/Dollar_dollar_1-expected.txt index 259c3b5d6c4bee97c33a0c1f70fcb0ee2f1bbe97..aea061a7eae277f1e460d5f03009f14714c4acbf 100644 --- a/ets2panda/test/parser/ets/Dollar_dollar_1-expected.txt +++ b/ets2panda/test/parser/ets/Dollar_dollar_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/Dollar_dollar_2-expected.txt b/ets2panda/test/parser/ets/Dollar_dollar_2-expected.txt index 572223c87f348c216beeead8ec95718a483c30a7..76f3c0ef7faa3d1533934b3f2c52637876b45602 100644 --- a/ets2panda/test/parser/ets/Dollar_dollar_2-expected.txt +++ b/ets2panda/test/parser/ets/Dollar_dollar_2-expected.txt @@ -1069,40 +1069,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/Dollar_dollar_3-expected.txt b/ets2panda/test/parser/ets/Dollar_dollar_3-expected.txt index 11abcabbb559e4de6b0e48c0b6ac59fbe0d41949..071680734f5b9fb7caf7084166e03d73e2aaa0c6 100644 --- a/ets2panda/test/parser/ets/Dollar_dollar_3-expected.txt +++ b/ets2panda/test/parser/ets/Dollar_dollar_3-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/Dollar_dollar_4-expected.txt b/ets2panda/test/parser/ets/Dollar_dollar_4-expected.txt index 53eafcd69d60d74a58ffa4bee8669dc5dc3cb0b3..4ff5791c5145a4284606f6aadeaa0a5229fc3eb3 100644 --- a/ets2panda/test/parser/ets/Dollar_dollar_4-expected.txt +++ b/ets2panda/test/parser/ets/Dollar_dollar_4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Dollar_dollar_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/FunctionInSwitch-expected.txt b/ets2panda/test/parser/ets/FunctionInSwitch-expected.txt index d3cc1fc1917189211c03fb6e99fe92f24bb9bc8a..98281fa216d2a8fcb21db04376a95dfaa58a88e5 100644 --- a/ets2panda/test/parser/ets/FunctionInSwitch-expected.txt +++ b/ets2panda/test/parser/ets/FunctionInSwitch-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionInSwitch.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionInSwitch.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionInSwitch.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionInSwitch.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/FunctionType-expected.txt b/ets2panda/test/parser/ets/FunctionType-expected.txt index 19e8b6da1042e2cfcbe69d75a63644c7e28024cb..04d5fe044f6a82998a0661da34ebffe59f5a2b07 100644 --- a/ets2panda/test/parser/ets/FunctionType-expected.txt +++ b/ets2panda/test/parser/ets/FunctionType-expected.txt @@ -507,40 +507,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionType.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionType.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument-expected.txt b/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument-expected.txt index 09d4f5c4ff4fd4b28581c436df73e0c8bad3b219..d2da9e851fad9143369149915dbdea0aa5b09a14 100644 --- a/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument-expected.txt +++ b/ets2panda/test/parser/ets/FunctionalTypeAsTypeArgument-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionalTypeAsTypeArgument.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionalTypeAsTypeArgument.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "FunctionalTypeAsTypeArgument.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "FunctionalTypeAsTypeArgument.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/InferTypeParamFromParam1-expected.txt b/ets2panda/test/parser/ets/InferTypeParamFromParam1-expected.txt index 43b40fe4b03c7ad3c3c84773481b6789e28e59c2..15c3c280b2e399b47c3074818383d5e8946b77aa 100644 --- a/ets2panda/test/parser/ets/InferTypeParamFromParam1-expected.txt +++ b/ets2panda/test/parser/ets/InferTypeParamFromParam1-expected.txt @@ -1830,40 +1830,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "InferTypeParamFromParam1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "InferTypeParamFromParam1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "InferTypeParamFromParam1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "InferTypeParamFromParam1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/InferTypeParamFromParam3-expected.txt b/ets2panda/test/parser/ets/InferTypeParamFromParam3-expected.txt index 2605e113e0ff05db1bb0db99a983dc8f4d44855e..3847671d302936292d9bf576d8dac1a5a00b75cb 100644 --- a/ets2panda/test/parser/ets/InferTypeParamFromParam3-expected.txt +++ b/ets2panda/test/parser/ets/InferTypeParamFromParam3-expected.txt @@ -2050,40 +2050,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "InferTypeParamFromParam3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "InferTypeParamFromParam3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "InferTypeParamFromParam3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "InferTypeParamFromParam3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/MathCordic-expected.txt b/ets2panda/test/parser/ets/MathCordic-expected.txt index c9c4eefdc93413b1c255f845911a2fad665686fd..c0750d7e2ca8b6464a175125100f1607277ce8a5 100644 --- a/ets2panda/test/parser/ets/MathCordic-expected.txt +++ b/ets2panda/test/parser/ets/MathCordic-expected.txt @@ -1300,23 +1300,71 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathCordic.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathCordic.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathCordic.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathCordic.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathCordic.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathCordic.ets" + } + } + }, "loc": { "start": { - "line": 20, - "column": 30, + "line": 1, + "column": 1, "program": "MathCordic.ets" }, "end": { - "line": 20, - "column": 36, + "line": 1, + "column": 3, "program": "MathCordic.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, @@ -5962,40 +6010,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "MathCordic.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "MathCordic.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "MathCordic.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "MathCordic.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/MathPartialSums-expected.txt b/ets2panda/test/parser/ets/MathPartialSums-expected.txt index 5e220a50ba95bc52237aa8e4070fefc0c70dc2a2..5f16c7c1104805d2065e8fa8e123c9b6c09d66f3 100644 --- a/ets2panda/test/parser/ets/MathPartialSums-expected.txt +++ b/ets2panda/test/parser/ets/MathPartialSums-expected.txt @@ -5448,40 +5448,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "MathPartialSums.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "MathPartialSums.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt b/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt index 8b5e4572f01f381f9b7c46f28b9c2ad8bf45bda5..23db51eb627de66e8143c1e32a482dbc41905089 100644 --- a/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt +++ b/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt @@ -588,23 +588,71 @@ "type": "Identifier", "name": "u", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 21, - "column": 26, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 21, - "column": 32, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 21, @@ -651,23 +699,71 @@ "type": "Identifier", "name": "v", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 21, - "column": 39, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 21, - "column": 45, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 21, @@ -1697,23 +1793,71 @@ "type": "Identifier", "name": "u", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 31, - "column": 27, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 31, - "column": 33, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 31, @@ -1760,23 +1904,71 @@ "type": "Identifier", "name": "v", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 31, - "column": 40, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 31, - "column": 46, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 31, @@ -2806,23 +2998,71 @@ "type": "Identifier", "name": "u", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 41, - "column": 28, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 41, - "column": 34, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 41, @@ -2869,23 +3109,71 @@ "type": "Identifier", "name": "v", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 41, - "column": 41, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 41, - "column": 47, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 41, @@ -2932,23 +3220,71 @@ "type": "Identifier", "name": "w", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 41, - "column": 54, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 41, - "column": 60, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 41, @@ -3489,23 +3825,71 @@ "type": "Identifier", "name": "u", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 49, - "column": 12, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 49, - "column": 18, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 49, @@ -3617,23 +4001,71 @@ "type": "Identifier", "name": "w", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 51, - "column": 12, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 51, - "column": 18, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 51, @@ -3745,23 +4177,71 @@ "type": "Identifier", "name": "v", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "MathSpectralNorm.ets" + } + } + }, "loc": { "start": { - "line": 53, - "column": 12, + "line": 1, + "column": 1, "program": "MathSpectralNorm.ets" }, "end": { - "line": 53, - "column": 18, + "line": 1, + "column": 3, "program": "MathSpectralNorm.ets" } } }, - "annotations": [], "loc": { "start": { "line": 53, @@ -6655,40 +7135,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "MathSpectralNorm.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "MathSpectralNorm.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "MathSpectralNorm.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "MathSpectralNorm.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/Morph3d-expected.txt b/ets2panda/test/parser/ets/Morph3d-expected.txt index 69211fc1b33a19e75b28cbdc0df3b9a2fbdb26a9..1ad08a5f9f34a1d63932dd09ffaaaa0dec19a25d 100644 --- a/ets2panda/test/parser/ets/Morph3d-expected.txt +++ b/ets2panda/test/parser/ets/Morph3d-expected.txt @@ -290,23 +290,71 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "Morph3d.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "Morph3d.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "Morph3d.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "Morph3d.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "Morph3d.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "Morph3d.ets" + } + } + }, "loc": { "start": { - "line": 22, - "column": 13, + "line": 1, + "column": 1, "program": "Morph3d.ets" }, "end": { - "line": 22, - "column": 19, + "line": 1, + "column": 3, "program": "Morph3d.ets" } } }, - "annotations": [], "loc": { "start": { "line": 22, @@ -4218,40 +4266,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Morph3d.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Morph3d.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Morph3d.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Morph3d.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/OptionalParametersWithGenericReturnTypes-expected.txt b/ets2panda/test/parser/ets/OptionalParametersWithGenericReturnTypes-expected.txt index 4830da9f975f979537aac5857939039438c6886e..4375ba7e0b4cf16676f49df5820c54230dda3e7a 100644 --- a/ets2panda/test/parser/ets/OptionalParametersWithGenericReturnTypes-expected.txt +++ b/ets2panda/test/parser/ets/OptionalParametersWithGenericReturnTypes-expected.txt @@ -360,6 +360,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + } + ], "loc": { "start": { "line": 17, @@ -971,6 +1123,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 23, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 8, + "program": "OptionalParametersWithGenericReturnTypes.ets" + }, + "end": { + "line": 25, + "column": 6, + "program": "OptionalParametersWithGenericReturnTypes.ets" + } + } + } + ], "loc": { "start": { "line": 23, @@ -1166,40 +1470,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "OptionalParametersWithGenericReturnTypes.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "OptionalParametersWithGenericReturnTypes.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "OptionalParametersWithGenericReturnTypes.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "OptionalParametersWithGenericReturnTypes.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/StaticFieldAndMethodSameName-expected.txt b/ets2panda/test/parser/ets/StaticFieldAndMethodSameName-expected.txt index aee7dd9541b88d9665298349818af7dd38eb7041..8f31f8f169731afb1418e48c0fab72b422144a53 100644 --- a/ets2panda/test/parser/ets/StaticFieldAndMethodSameName-expected.txt +++ b/ets2panda/test/parser/ets/StaticFieldAndMethodSameName-expected.txt @@ -402,40 +402,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "StaticFieldAndMethodSameName.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "StaticFieldAndMethodSameName.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "StaticFieldAndMethodSameName.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "StaticFieldAndMethodSameName.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/StaticFieldAndMethodSameNameInheritance-expected.txt b/ets2panda/test/parser/ets/StaticFieldAndMethodSameNameInheritance-expected.txt index 924fb2a4a7ac64818e478e6fa5c2678e9dbda5d2..25d1ccb54542eb73d8355c9655bdc9613a562ed3 100644 --- a/ets2panda/test/parser/ets/StaticFieldAndMethodSameNameInheritance-expected.txt +++ b/ets2panda/test/parser/ets/StaticFieldAndMethodSameNameInheritance-expected.txt @@ -603,40 +603,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "StaticFieldAndMethodSameNameInheritance.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "StaticFieldAndMethodSameNameInheritance.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "StaticFieldAndMethodSameNameInheritance.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "StaticFieldAndMethodSameNameInheritance.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/StringBase64-expected.txt b/ets2panda/test/parser/ets/StringBase64-expected.txt index 9fb9ae919868e5b93001d733993d1967c001475d..a307f1139eafd6725284e7736e39d1ee960b7e34 100644 --- a/ets2panda/test/parser/ets/StringBase64-expected.txt +++ b/ets2panda/test/parser/ets/StringBase64-expected.txt @@ -2289,23 +2289,71 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "StringBase64.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "StringBase64.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "StringBase64.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "StringBase64.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "StringBase64.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "StringBase64.ets" + } + } + }, "loc": { "start": { - "line": 19, - "column": 39, + "line": 1, + "column": 1, "program": "StringBase64.ets" }, "end": { - "line": 19, - "column": 42, + "line": 1, + "column": 3, "program": "StringBase64.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, @@ -11233,40 +11281,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "StringBase64.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "StringBase64.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "StringBase64.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "StringBase64.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/access_modifier_2-expected.txt b/ets2panda/test/parser/ets/access_modifier_2-expected.txt index 07b91f6b1fdd20fe2fb963b75906117c46c24305..156dc7a9746f46ef57c6125ab75ff9ebb802d7b3 100644 --- a/ets2panda/test/parser/ets/access_modifier_2-expected.txt +++ b/ets2panda/test/parser/ets/access_modifier_2-expected.txt @@ -299,40 +299,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "access_modifier_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "access_modifier_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "access_modifier_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "access_modifier_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/access_modifier_3-expected.txt b/ets2panda/test/parser/ets/access_modifier_3-expected.txt index f14665032481d060f908853264b4701a1c3fd505..ece74807b3ad47bff68bd68c856cc0586a3a23f2 100644 --- a/ets2panda/test/parser/ets/access_modifier_3-expected.txt +++ b/ets2panda/test/parser/ets/access_modifier_3-expected.txt @@ -233,40 +233,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "access_modifier_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "access_modifier_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "access_modifier_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "access_modifier_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/ambient_call_signature-expected.txt b/ets2panda/test/parser/ets/ambient_call_signature-expected.txt index 0255cc77e66690da9a20763d14cc69001048acd3..6b165ea86e1c323db24fc4d9ed36df8bf8996ff0 100644 --- a/ets2panda/test/parser/ets/ambient_call_signature-expected.txt +++ b/ets2panda/test/parser/ets/ambient_call_signature-expected.txt @@ -396,40 +396,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_call_signature.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_call_signature.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_call_signature.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_call_signature.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/ambient_declaration_final_class-expected.txt b/ets2panda/test/parser/ets/ambient_declaration_final_class-expected.txt index 7cd7a29100a2d9bb23b068dc0620da5057287c54..ade760ffa50da9d9c1a7d43812a5b54bd2e0647e 100644 --- a/ets2panda/test/parser/ets/ambient_declaration_final_class-expected.txt +++ b/ets2panda/test/parser/ets/ambient_declaration_final_class-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_declaration_final_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_declaration_final_class.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_declaration_final_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_declaration_final_class.ets" - } - } - } - ], "body": [], "loc": { "start": { diff --git a/ets2panda/test/parser/ets/ambient_indexer_1-expected.txt b/ets2panda/test/parser/ets/ambient_indexer_1-expected.txt index 6104cb85c6f50a0c2492c186bc1628bc72327112..a53827c724929652947533cab579d6374f4192b9 100644 --- a/ets2panda/test/parser/ets/ambient_indexer_1-expected.txt +++ b/ets2panda/test/parser/ets/ambient_indexer_1-expected.txt @@ -661,40 +661,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_indexer_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_indexer_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_indexer_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_indexer_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/ambient_indexer_6-expected.txt b/ets2panda/test/parser/ets/ambient_indexer_6-expected.txt index 8935451bd15c4194d29b471f8971d2d088046ae8..030e8a45840971a37d742dcd5929751af2bfa4ac 100644 --- a/ets2panda/test/parser/ets/ambient_indexer_6-expected.txt +++ b/ets2panda/test/parser/ets/ambient_indexer_6-expected.txt @@ -661,40 +661,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_indexer_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_indexer_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_indexer_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_indexer_6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/ambient_object_iterable-expected.txt b/ets2panda/test/parser/ets/ambient_object_iterable-expected.txt index 7fce9969344b053f93c2265989f8ef44398bfe07..1d1801928584cb11d67959fca87c39982e19c613 100644 --- a/ets2panda/test/parser/ets/ambient_object_iterable-expected.txt +++ b/ets2panda/test/parser/ets/ambient_object_iterable-expected.txt @@ -742,55 +742,103 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 16, - "program": "ambient_object_iterable.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "ambient_object_iterable.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "ambient_object_iterable.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "ambient_object_iterable.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "ambient_object_iterable.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "ambient_object_iterable.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "ambient_object_iterable.ets" + } + } }, - "end": { - "line": 27, - "column": 22, - "program": "ambient_object_iterable.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "ambient_object_iterable.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "ambient_object_iterable.ets" + } } } - }, + ], "loc": { "start": { - "line": 27, - "column": 16, + "line": 1, + "column": 3, "program": "ambient_object_iterable.ets" }, "end": { - "line": 27, - "column": 23, + "line": 1, + "column": 3, "program": "ambient_object_iterable.ets" } } }, "loc": { "start": { - "line": 27, - "column": 16, + "line": 1, + "column": 1, "program": "ambient_object_iterable.ets" }, "end": { - "line": 27, - "column": 23, + "line": 1, + "column": 3, "program": "ambient_object_iterable.ets" } } }, - "annotations": [], "loc": { "start": { "line": 27, @@ -1111,40 +1159,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_object_iterable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_object_iterable.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ambient_object_iterable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ambient_object_iterable.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/array-expected.txt b/ets2panda/test/parser/ets/array-expected.txt index d57d4dc542bfad8a7ca79c5679d6e4c2854a93f5..d47b76862c37accbc1e1ff73d63f082ef124105b 100644 --- a/ets2panda/test/parser/ets/array-expected.txt +++ b/ets2panda/test/parser/ets/array-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -523,23 +489,71 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, "loc": { "start": { - "line": 16, - "column": 8, + "line": 1, + "column": 1, "program": "array.ets" }, "end": { - "line": 16, - "column": 11, + "line": 1, + "column": 3, "program": "array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -594,55 +608,103 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "String", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 8, - "program": "array.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } }, - "end": { - "line": 17, - "column": 14, - "program": "array.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 8, + "line": 1, + "column": 3, "program": "array.ets" }, "end": { - "line": 17, - "column": 15, + "line": 1, + "column": 3, "program": "array.ets" } } }, "loc": { "start": { - "line": 17, - "column": 8, + "line": 1, + "column": 1, "program": "array.ets" }, "end": { - "line": 17, - "column": 15, + "line": 1, + "column": 3, "program": "array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -726,23 +788,71 @@ "type": "Identifier", "name": "arg", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, "loc": { "start": { - "line": 19, - "column": 20, + "line": 1, + "column": 1, "program": "array.ets" }, "end": { - "line": 19, - "column": 26, + "line": 1, + "column": 3, "program": "array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, @@ -1169,39 +1279,135 @@ "type": "Identifier", "name": "a", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], "loc": { "start": { - "line": 26, - "column": 12, + "line": 1, + "column": 1, "program": "array.ets" }, "end": { - "line": 26, - "column": 16, + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, "program": "array.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 26, - "column": 16, + "line": 1, + "column": 1, "program": "array.ets" }, "end": { - "line": 26, - "column": 18, + "line": 1, + "column": 3, "program": "array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 26, @@ -1347,39 +1553,135 @@ "type": "Identifier", "name": "b", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], "loc": { "start": { - "line": 27, - "column": 12, + "line": 1, + "column": 1, "program": "array.ets" }, "end": { - "line": 27, - "column": 16, + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array.ets" + }, + "end": { + "line": 1, + "column": 3, "program": "array.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 27, - "column": 16, + "line": 1, + "column": 1, "program": "array.ets" }, "end": { - "line": 27, - "column": 18, + "line": 1, + "column": 3, "program": "array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 27, diff --git a/ets2panda/test/parser/ets/arrayHoldingNullValue-expected.txt b/ets2panda/test/parser/ets/arrayHoldingNullValue-expected.txt index 08e55a573ebf9aef5e74dd936a55d09993a55bb5..ed0c39d42af0a7cae9fefbcd253acbfdac4c9fb0 100644 --- a/ets2panda/test/parser/ets/arrayHoldingNullValue-expected.txt +++ b/ets2panda/test/parser/ets/arrayHoldingNullValue-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "arrayHoldingNullValue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "arrayHoldingNullValue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "arrayHoldingNullValue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "arrayHoldingNullValue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -386,23 +352,71 @@ "type": "ETSUnionType", "types": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, "loc": { "start": { - "line": 16, - "column": 8, + "line": 1, + "column": 1, "program": "arrayHoldingNullValue.ets" }, "end": { - "line": 16, - "column": 11, + "line": 1, + "column": 3, "program": "arrayHoldingNullValue.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -489,23 +503,71 @@ "type": "ETSUnionType", "types": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, "loc": { "start": { - "line": 17, - "column": 8, + "line": 1, + "column": 1, "program": "arrayHoldingNullValue.ets" }, "end": { - "line": 17, - "column": 14, + "line": 1, + "column": 3, "program": "arrayHoldingNullValue.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -592,55 +654,103 @@ "type": "ETSUnionType", "types": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Double", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 8, - "program": "arrayHoldingNullValue.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } }, - "end": { - "line": 18, - "column": 14, - "program": "arrayHoldingNullValue.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } } } - }, + ], "loc": { "start": { - "line": 18, - "column": 8, + "line": 1, + "column": 3, "program": "arrayHoldingNullValue.ets" }, "end": { - "line": 18, - "column": 15, + "line": 1, + "column": 3, "program": "arrayHoldingNullValue.ets" } } }, "loc": { "start": { - "line": 18, - "column": 8, + "line": 1, + "column": 1, "program": "arrayHoldingNullValue.ets" }, "end": { - "line": 18, - "column": 15, + "line": 1, + "column": 3, "program": "arrayHoldingNullValue.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, @@ -777,23 +887,71 @@ "type": "ETSUnionType", "types": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, "loc": { "start": { - "line": 21, - "column": 14, + "line": 1, + "column": 1, "program": "arrayHoldingNullValue.ets" }, "end": { - "line": 21, - "column": 19, + "line": 1, + "column": 3, "program": "arrayHoldingNullValue.ets" } } }, - "annotations": [], "loc": { "start": { "line": 21, @@ -906,23 +1064,71 @@ "type": "ETSUnionType", "types": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayHoldingNullValue.ets" + } + } + }, "loc": { "start": { - "line": 22, - "column": 12, + "line": 1, + "column": 1, "program": "arrayHoldingNullValue.ets" }, "end": { - "line": 22, - "column": 16, + "line": 1, + "column": 3, "program": "arrayHoldingNullValue.ets" } } }, - "annotations": [], "loc": { "start": { "line": 22, diff --git a/ets2panda/test/parser/ets/arrayLiteralReassign-expected.txt b/ets2panda/test/parser/ets/arrayLiteralReassign-expected.txt index 024597387e66a2e971c0a412db59b38b266c0f30..b863fbac408a9690b8a45eadc38ed7003903a06f 100644 --- a/ets2panda/test/parser/ets/arrayLiteralReassign-expected.txt +++ b/ets2panda/test/parser/ets/arrayLiteralReassign-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "arrayLiteralReassign.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "arrayLiteralReassign.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "arrayLiteralReassign.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "arrayLiteralReassign.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -225,55 +191,103 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "number", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 14, - "program": "arrayLiteralReassign.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "arrayLiteralReassign.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayLiteralReassign.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayLiteralReassign.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayLiteralReassign.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayLiteralReassign.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayLiteralReassign.ets" + } + } }, - "end": { - "line": 17, - "column": 20, - "program": "arrayLiteralReassign.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "arrayLiteralReassign.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "arrayLiteralReassign.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 14, + "line": 1, + "column": 3, "program": "arrayLiteralReassign.ets" }, "end": { - "line": 17, - "column": 21, + "line": 1, + "column": 3, "program": "arrayLiteralReassign.ets" } } }, "loc": { "start": { - "line": 17, - "column": 14, + "line": 1, + "column": 1, "program": "arrayLiteralReassign.ets" }, "end": { - "line": 17, - "column": 21, + "line": 1, + "column": 3, "program": "arrayLiteralReassign.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/array_creation_expression-expected.txt b/ets2panda/test/parser/ets/array_creation_expression-expected.txt index 955a33169f19d0224b1d2407e9d8ead8474ba6c3..087eb6530f9b8a7a0eb6be2e93818ad54781bd67 100644 --- a/ets2panda/test/parser/ets/array_creation_expression-expected.txt +++ b/ets2panda/test/parser/ets/array_creation_expression-expected.txt @@ -854,87 +854,135 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 20, - "program": "array_creation_expression.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_creation_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + } + } }, - "end": { - "line": 27, - "column": 21, - "program": "array_creation_expression.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + } + } + }, + { + "type": "ETSUndefinedType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + } } } - }, + ], "loc": { "start": { - "line": 27, - "column": 20, + "line": 1, + "column": 3, "program": "array_creation_expression.ets" }, "end": { - "line": 27, - "column": 23, + "line": 1, + "column": 3, "program": "array_creation_expression.ets" } } - }, - "loc": { - "start": { - "line": 27, - "column": 20, - "program": "array_creation_expression.ets" - }, - "end": { - "line": 27, - "column": 23, - "program": "array_creation_expression.ets" - } } - }, - { - "type": "ETSUndefinedType", - "loc": { - "start": { - "line": 27, - "column": 24, - "program": "array_creation_expression.ets" - }, - "end": { - "line": 27, - "column": 33, - "program": "array_creation_expression.ets" - } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_creation_expression.ets" } } - ], + }, "loc": { "start": { - "line": 27, - "column": 19, + "line": 1, + "column": 1, "program": "array_creation_expression.ets" }, "end": { - "line": 27, - "column": 33, + "line": 1, + "column": 3, "program": "array_creation_expression.ets" } } }, - "annotations": [], "loc": { "start": { "line": 27, @@ -1067,40 +1115,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_creation_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_creation_expression.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_creation_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_creation_expression.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/array_expression_implicit_cast_assignment-expected.txt b/ets2panda/test/parser/ets/array_expression_implicit_cast_assignment-expected.txt index 88b2c7ce7445a05c58d92a62ecc3263355b1e538..c09c832b21f9d94af4aa3f463672afbcea53433a 100644 --- a/ets2panda/test/parser/ets/array_expression_implicit_cast_assignment-expected.txt +++ b/ets2panda/test/parser/ets/array_expression_implicit_cast_assignment-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_expression_implicit_cast_assignment.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_expression_implicit_cast_assignment.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_expression_implicit_cast_assignment.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_expression_implicit_cast_assignment.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -346,55 +312,103 @@ "type": "Identifier", "name": "x", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Double", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "array_expression_implicit_cast_assignment.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_expression_implicit_cast_assignment.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_assignment.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_assignment.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_assignment.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_assignment.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_assignment.ets" + } + } }, - "end": { - "line": 17, - "column": 19, - "program": "array_expression_implicit_cast_assignment.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_assignment.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_assignment.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 13, + "line": 1, + "column": 3, "program": "array_expression_implicit_cast_assignment.ets" }, "end": { - "line": 17, - "column": 20, + "line": 1, + "column": 3, "program": "array_expression_implicit_cast_assignment.ets" } } }, "loc": { "start": { - "line": 17, - "column": 13, + "line": 1, + "column": 1, "program": "array_expression_implicit_cast_assignment.ets" }, "end": { - "line": 17, - "column": 20, + "line": 1, + "column": 3, "program": "array_expression_implicit_cast_assignment.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/array_expression_implicit_cast_return-expected.txt b/ets2panda/test/parser/ets/array_expression_implicit_cast_return-expected.txt index 2f7b424caa7d4dbff2e427750a22769dcae30b8a..b01d4ec5a97510367d600a642a081272f683e4bc 100644 --- a/ets2panda/test/parser/ets/array_expression_implicit_cast_return-expected.txt +++ b/ets2panda/test/parser/ets/array_expression_implicit_cast_return-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_expression_implicit_cast_return.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_expression_implicit_cast_return.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_expression_implicit_cast_return.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_expression_implicit_cast_return.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -320,55 +286,103 @@ "expression": false, "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Double", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 17, - "program": "array_expression_implicit_cast_return.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_expression_implicit_cast_return.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_return.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_return.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_return.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_return.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_return.ets" + } + } }, - "end": { - "line": 16, - "column": 23, - "program": "array_expression_implicit_cast_return.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_return.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_expression_implicit_cast_return.ets" + } } } - }, + ], "loc": { "start": { - "line": 16, - "column": 17, + "line": 1, + "column": 3, "program": "array_expression_implicit_cast_return.ets" }, "end": { - "line": 16, - "column": 24, + "line": 1, + "column": 3, "program": "array_expression_implicit_cast_return.ets" } } }, "loc": { "start": { - "line": 16, - "column": 17, + "line": 1, + "column": 1, "program": "array_expression_implicit_cast_return.ets" }, "end": { - "line": 16, - "column": 24, + "line": 1, + "column": 3, "program": "array_expression_implicit_cast_return.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/array_new-expected.txt b/ets2panda/test/parser/ets/array_new-expected.txt index f2e90749f314ac974c10d33c25fd6c3c49a215c0..e14e6cf7b6326abf1c5383028a4bc351f29c3f84 100644 --- a/ets2panda/test/parser/ets/array_new-expected.txt +++ b/ets2panda/test/parser/ets/array_new-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_new.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_new.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_new.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_new.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/array_type_from_literal-expected.txt b/ets2panda/test/parser/ets/array_type_from_literal-expected.txt index f8cba5ad25f87afcefc7208dba6125dd29cac167..348b237ddb1dda09a7db01fd002f293c95fad39b 100644 --- a/ets2panda/test/parser/ets/array_type_from_literal-expected.txt +++ b/ets2panda/test/parser/ets/array_type_from_literal-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_type_from_literal.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_type_from_literal.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "array_type_from_literal.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "array_type_from_literal.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -320,23 +286,71 @@ "expression": false, "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_type_from_literal.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + } + } + }, "loc": { "start": { - "line": 16, - "column": 17, + "line": 1, + "column": 1, "program": "array_type_from_literal.ets" }, "end": { - "line": 16, - "column": 20, + "line": 1, + "column": 3, "program": "array_type_from_literal.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -489,23 +503,71 @@ "expression": false, "params": [], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_type_from_literal.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + } + } + }, "loc": { "start": { - "line": 20, - "column": 17, + "line": 1, + "column": 1, "program": "array_type_from_literal.ets" }, "end": { - "line": 20, - "column": 20, + "line": 1, + "column": 3, "program": "array_type_from_literal.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, @@ -543,23 +605,71 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "array_type_from_literal.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "array_type_from_literal.ets" + } + } + }, "loc": { "start": { - "line": 21, - "column": 18, + "line": 1, + "column": 1, "program": "array_type_from_literal.ets" }, "end": { - "line": 21, - "column": 21, + "line": 1, + "column": 3, "program": "array_type_from_literal.ets" } } }, - "annotations": [], "loc": { "start": { "line": 21, diff --git a/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt b/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt index 9d30970a184b959aa526dd72ee5b2af9fbc789ff..b375b4963ca04d9d9298d2be916e2a9a2c4e09d4 100644 --- a/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt +++ b/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "as_expression_unary_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "as_expression_unary_expression.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "as_expression_unary_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "as_expression_unary_expression.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/assert-expected.txt b/ets2panda/test/parser/ets/assert-expected.txt index 9a00f8d01190e001a2ca91f0146f9d58516803fc..223e74ab3fdb41ba7a9de7045f9ad123206184bb 100644 --- a/ets2panda/test/parser/ets/assert-expected.txt +++ b/ets2panda/test/parser/ets/assert-expected.txt @@ -874,40 +874,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assert.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assert.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assert.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assert.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/assign-expected.txt b/ets2panda/test/parser/ets/assign-expected.txt index 85e07ada0fcf8d7e7ada3d2b8092465b9a8f6ac2..b6142a48972ef35b4edb2574709e83ec7de73e98 100644 --- a/ets2panda/test/parser/ets/assign-expected.txt +++ b/ets2panda/test/parser/ets/assign-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assign.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assign.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assign.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assign.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/assign-func-expected.txt b/ets2panda/test/parser/ets/assign-func-expected.txt index dfcdb8f1d7f6967cc7e77ab135a9e2bae553c963..0f098d527bbf0e6405f58fbc83b83f3d3ed0a178 100644 --- a/ets2panda/test/parser/ets/assign-func-expected.txt +++ b/ets2panda/test/parser/ets/assign-func-expected.txt @@ -412,40 +412,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assign-func.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assign-func.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assign-func.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assign-func.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/assignNullableFromMethodToNullableParam-expected.txt b/ets2panda/test/parser/ets/assignNullableFromMethodToNullableParam-expected.txt index 9ef19b191876d22e3929439ea892ed94f3b2f00d..bd4085763f1e29e2ca1796938533b43532c25912 100644 --- a/ets2panda/test/parser/ets/assignNullableFromMethodToNullableParam-expected.txt +++ b/ets2panda/test/parser/ets/assignNullableFromMethodToNullableParam-expected.txt @@ -442,40 +442,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignNullableFromMethodToNullableParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignNullableFromMethodToNullableParam.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignNullableFromMethodToNullableParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignNullableFromMethodToNullableParam.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/assignNullableToNonNullable-expected.txt b/ets2panda/test/parser/ets/assignNullableToNonNullable-expected.txt index cc83a876d5667511ae68a788f2d7147e7fb8388e..ef02e1816ad6e66d6c3134ad1d3078cac7c6d997 100644 --- a/ets2panda/test/parser/ets/assignNullableToNonNullable-expected.txt +++ b/ets2panda/test/parser/ets/assignNullableToNonNullable-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullable.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullable.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/assignNullableToNonNullableArray-expected.txt b/ets2panda/test/parser/ets/assignNullableToNonNullableArray-expected.txt index 639443b444d12c2d71ea3f5e68b4372c24d68a13..bcd6041a94e46f3043c66c20b765e2b5cb3e2d56 100644 --- a/ets2panda/test/parser/ets/assignNullableToNonNullableArray-expected.txt +++ b/ets2panda/test/parser/ets/assignNullableToNonNullableArray-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullableArray.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullableArray.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullableArray.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullableArray.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -395,37 +361,86 @@ "type": "Identifier", "name": "xo", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 14, - "program": "assignNullableToNonNullableArray.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 14, + "program": "assignNullableToNonNullableArray.ets" + }, + "end": { + "line": 19, + "column": 24, + "program": "assignNullableToNonNullableArray.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 25, + "program": "assignNullableToNonNullableArray.ets" + }, + "end": { + "line": 19, + "column": 31, + "program": "assignNullableToNonNullableArray.ets" + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 25, + "program": "assignNullableToNonNullableArray.ets" + }, + "end": { + "line": 19, + "column": 32, + "program": "assignNullableToNonNullableArray.ets" + } + } }, - "end": { - "line": 19, - "column": 20, - "program": "assignNullableToNonNullableArray.ets" + "loc": { + "start": { + "line": 19, + "column": 25, + "program": "assignNullableToNonNullableArray.ets" + }, + "end": { + "line": 19, + "column": 32, + "program": "assignNullableToNonNullableArray.ets" + } } } - }, + ], "loc": { "start": { "line": 19, - "column": 14, + "column": 24, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 19, - "column": 21, + "column": 32, "program": "assignNullableToNonNullableArray.ets" } } @@ -438,21 +453,20 @@ }, "end": { "line": 19, - "column": 21, + "column": 33, "program": "assignNullableToNonNullableArray.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, - "column": 20, + "column": 14, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 19, - "column": 22, + "column": 33, "program": "assignNullableToNonNullableArray.ets" } } @@ -495,7 +509,7 @@ }, "end": { "line": 19, - "column": 23, + "column": 33, "program": "assignNullableToNonNullableArray.ets" } } @@ -512,37 +526,86 @@ "type": "ETSUnionType", "types": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 14, - "program": "assignNullableToNonNullableArray.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 14, + "program": "assignNullableToNonNullableArray.ets" + }, + "end": { + "line": 20, + "column": 24, + "program": "assignNullableToNonNullableArray.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 25, + "program": "assignNullableToNonNullableArray.ets" + }, + "end": { + "line": 20, + "column": 26, + "program": "assignNullableToNonNullableArray.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 25, + "program": "assignNullableToNonNullableArray.ets" + }, + "end": { + "line": 20, + "column": 27, + "program": "assignNullableToNonNullableArray.ets" + } + } }, - "end": { - "line": 20, - "column": 15, - "program": "assignNullableToNonNullableArray.ets" + "loc": { + "start": { + "line": 20, + "column": 25, + "program": "assignNullableToNonNullableArray.ets" + }, + "end": { + "line": 20, + "column": 27, + "program": "assignNullableToNonNullableArray.ets" + } } } - }, + ], "loc": { "start": { "line": 20, - "column": 14, + "column": 24, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 16, + "column": 27, "program": "assignNullableToNonNullableArray.ets" } } @@ -555,21 +618,20 @@ }, "end": { "line": 20, - "column": 16, + "column": 29, "program": "assignNullableToNonNullableArray.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, - "column": 15, + "column": 14, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 17, + "column": 29, "program": "assignNullableToNonNullableArray.ets" } } @@ -579,12 +641,12 @@ "loc": { "start": { "line": 20, - "column": 20, + "column": 30, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 24, + "column": 34, "program": "assignNullableToNonNullableArray.ets" } } @@ -593,12 +655,12 @@ "loc": { "start": { "line": 20, - "column": 15, + "column": 14, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 24, + "column": 34, "program": "assignNullableToNonNullableArray.ets" } } @@ -633,12 +695,12 @@ "loc": { "start": { "line": 20, - "column": 32, + "column": 42, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 33, + "column": 43, "program": "assignNullableToNonNullableArray.ets" } } @@ -646,12 +708,12 @@ "loc": { "start": { "line": 20, - "column": 32, + "column": 42, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 34, + "column": 44, "program": "assignNullableToNonNullableArray.ets" } } @@ -659,12 +721,12 @@ "loc": { "start": { "line": 20, - "column": 32, + "column": 42, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 34, + "column": 44, "program": "assignNullableToNonNullableArray.ets" } } @@ -673,12 +735,12 @@ "loc": { "start": { "line": 20, - "column": 28, + "column": 38, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 36, + "column": 46, "program": "assignNullableToNonNullableArray.ets" } } @@ -696,12 +758,12 @@ "loc": { "start": { "line": 20, - "column": 41, + "column": 51, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 42, + "column": 52, "program": "assignNullableToNonNullableArray.ets" } } @@ -709,12 +771,12 @@ "loc": { "start": { "line": 20, - "column": 41, + "column": 51, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 43, + "column": 53, "program": "assignNullableToNonNullableArray.ets" } } @@ -722,12 +784,12 @@ "loc": { "start": { "line": 20, - "column": 41, + "column": 51, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 43, + "column": 53, "program": "assignNullableToNonNullableArray.ets" } } @@ -736,12 +798,12 @@ "loc": { "start": { "line": 20, - "column": 37, + "column": 47, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 45, + "column": 55, "program": "assignNullableToNonNullableArray.ets" } } @@ -750,12 +812,12 @@ "loc": { "start": { "line": 20, - "column": 27, + "column": 37, "program": "assignNullableToNonNullableArray.ets" }, "end": { "line": 20, - "column": 45, + "column": 55, "program": "assignNullableToNonNullableArray.ets" } } @@ -768,7 +830,7 @@ }, "end": { "line": 20, - "column": 45, + "column": 55, "program": "assignNullableToNonNullableArray.ets" } } @@ -783,7 +845,7 @@ }, "end": { "line": 20, - "column": 46, + "column": 56, "program": "assignNullableToNonNullableArray.ets" } } diff --git a/ets2panda/test/parser/ets/assignNullableToNonNullableArray.ets b/ets2panda/test/parser/ets/assignNullableToNonNullableArray.ets index f6f2d00d342a612fb493be172077dc51ad9fe17f..79865c8908b3f8102e8993a23c3f60315e5596af 100644 --- a/ets2panda/test/parser/ets/assignNullableToNonNullableArray.ets +++ b/ets2panda/test/parser/ets/assignNullableToNonNullableArray.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 - 2024 Huawei Device Co., Ltd. + * 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 @@ -16,8 +16,8 @@ class A {} function main(): void { - let xo : Object[]; - let an : A[] | null = [new A(), new A()]; + let xo : FixedArray; + let an : FixedArray | null = [new A(), new A()]; xo = an; } diff --git a/ets2panda/test/parser/ets/assignNullableToNonNullableTypeAlias-expected.txt b/ets2panda/test/parser/ets/assignNullableToNonNullableTypeAlias-expected.txt index 8e612c173fde2973363f2438fdd9b2f1b6fbe0aa..3d1ab2fb66eda69379d47d9f7a619f6ab9b7ca0e 100644 --- a/ets2panda/test/parser/ets/assignNullableToNonNullableTypeAlias-expected.txt +++ b/ets2panda/test/parser/ets/assignNullableToNonNullableTypeAlias-expected.txt @@ -289,40 +289,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullableTypeAlias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullableTypeAlias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullableTypeAlias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignNullableToNonNullableTypeAlias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/assignments-expected.txt b/ets2panda/test/parser/ets/assignments-expected.txt index 61c0fc0d7b1342c5d25bc15b47cfb8aa627aa9ec..960e551480303b10faf96e09c5daf16b61638cc8 100644 --- a/ets2panda/test/parser/ets/assignments-expected.txt +++ b/ets2panda/test/parser/ets/assignments-expected.txt @@ -1915,40 +1915,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignments.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignments.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "assignments.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "assignments.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/async_func_return_type-expected.txt b/ets2panda/test/parser/ets/async_func_return_type-expected.txt index 5f7abf1a051f2d8ea5b3173526f4f001a6ad9e6f..8124a42ce89fa0cbad0257254c04445963916d40 100644 --- a/ets2panda/test/parser/ets/async_func_return_type-expected.txt +++ b/ets2panda/test/parser/ets/async_func_return_type-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "async_func_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "async_func_return_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "async_func_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "async_func_return_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/async_function-expected.txt b/ets2panda/test/parser/ets/async_function-expected.txt index f15275ce2f11c47fae9adb715a4e8d8d41c07383..c1469202d471d0f4a24c8ce6efa512160ff03540 100644 --- a/ets2panda/test/parser/ets/async_function-expected.txt +++ b/ets2panda/test/parser/ets/async_function-expected.txt @@ -459,40 +459,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "async_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "async_function.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "async_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "async_function.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/async_overload-expected.txt b/ets2panda/test/parser/ets/async_overload-expected.txt index d2764377ea6bc897a13336b3b38e0ae1a4341b6c..59d04c9e13999310666824b4dd888415e5ed2bfa 100644 --- a/ets2panda/test/parser/ets/async_overload-expected.txt +++ b/ets2panda/test/parser/ets/async_overload-expected.txt @@ -916,40 +916,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "async_overload.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "async_overload.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "async_overload.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "async_overload.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/async_with_lambda-expected.txt b/ets2panda/test/parser/ets/async_with_lambda-expected.txt index f22d63d617024f4cf3dbf45d8cbc354e2e22435a..caaaa0ae22d5b633653c247c56491e3368e215dd 100644 --- a/ets2panda/test/parser/ets/async_with_lambda-expected.txt +++ b/ets2panda/test/parser/ets/async_with_lambda-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "async_with_lambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "async_with_lambda.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "async_with_lambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "async_with_lambda.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/await_complex_promise-expected.txt b/ets2panda/test/parser/ets/await_complex_promise-expected.txt index a5561197f66326e2120b8128a1e1cff55839bdd1..401533bb2232855370ce4989fbad6a8efe57853f 100644 --- a/ets2panda/test/parser/ets/await_complex_promise-expected.txt +++ b/ets2panda/test/parser/ets/await_complex_promise-expected.txt @@ -230,40 +230,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "await_complex_promise.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "await_complex_promise.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "await_complex_promise.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "await_complex_promise.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -848,7 +814,7 @@ }, "end": { "line": 17, - "column": 34, + "column": 33, "program": "await_complex_promise.ets" } } @@ -861,7 +827,7 @@ }, "end": { "line": 17, - "column": 34, + "column": 33, "program": "await_complex_promise.ets" } } @@ -1435,7 +1401,7 @@ }, "end": { "line": 21, - "column": 41, + "column": 40, "program": "await_complex_promise.ets" } } @@ -1448,7 +1414,7 @@ }, "end": { "line": 21, - "column": 41, + "column": 40, "program": "await_complex_promise.ets" } } @@ -2086,7 +2052,7 @@ }, "end": { "line": 25, - "column": 41, + "column": 40, "program": "await_complex_promise.ets" } } @@ -2099,7 +2065,7 @@ }, "end": { "line": 25, - "column": 41, + "column": 40, "program": "await_complex_promise.ets" } } @@ -2609,7 +2575,7 @@ }, "end": { "line": 29, - "column": 39, + "column": 38, "program": "await_complex_promise.ets" } } @@ -2622,7 +2588,7 @@ }, "end": { "line": 29, - "column": 39, + "column": 38, "program": "await_complex_promise.ets" } } @@ -3068,7 +3034,7 @@ }, "end": { "line": 34, - "column": 41, + "column": 40, "program": "await_complex_promise.ets" } } @@ -3081,7 +3047,7 @@ }, "end": { "line": 34, - "column": 41, + "column": 40, "program": "await_complex_promise.ets" } } diff --git a/ets2panda/test/parser/ets/await_keyword-expected.txt b/ets2panda/test/parser/ets/await_keyword-expected.txt index ec35251add4d5d6f527d9b6881c5588538bf35cc..57cd2bae08f14bb7b08d8ccc9342c7b274e937ae 100644 --- a/ets2panda/test/parser/ets/await_keyword-expected.txt +++ b/ets2panda/test/parser/ets/await_keyword-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "await_keyword.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "await_keyword.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "await_keyword.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "await_keyword.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1036,7 +1002,7 @@ }, "end": { "line": 24, - "column": 45, + "column": 44, "program": "await_keyword.ets" } } @@ -1049,7 +1015,7 @@ }, "end": { "line": 24, - "column": 45, + "column": 44, "program": "await_keyword.ets" } } @@ -1859,7 +1825,7 @@ }, "end": { "line": 35, - "column": 45, + "column": 44, "program": "await_keyword.ets" } } @@ -1872,7 +1838,7 @@ }, "end": { "line": 35, - "column": 45, + "column": 44, "program": "await_keyword.ets" } } @@ -2086,7 +2052,7 @@ }, "end": { "line": 39, - "column": 41, + "column": 40, "program": "await_keyword.ets" } } @@ -2099,7 +2065,7 @@ }, "end": { "line": 39, - "column": 41, + "column": 40, "program": "await_keyword.ets" } } @@ -2112,7 +2078,7 @@ }, "end": { "line": 39, - "column": 41, + "column": 40, "program": "await_keyword.ets" } } @@ -3010,7 +2976,7 @@ }, "end": { "line": 18, - "column": 45, + "column": 44, "program": "await_keyword.ets" } } @@ -3023,7 +2989,7 @@ }, "end": { "line": 18, - "column": 45, + "column": 44, "program": "await_keyword.ets" } } @@ -4039,7 +4005,7 @@ }, "end": { "line": 30, - "column": 45, + "column": 44, "program": "await_keyword.ets" } } @@ -4052,7 +4018,7 @@ }, "end": { "line": 30, - "column": 45, + "column": 44, "program": "await_keyword.ets" } } @@ -4527,7 +4493,7 @@ }, "end": { "line": 39, - "column": 41, + "column": 40, "program": "await_keyword.ets" } } diff --git a/ets2panda/test/parser/ets/binary_op-expected.txt b/ets2panda/test/parser/ets/binary_op-expected.txt index 182ab2004d6e1109ce42705eef8ffe33dfae7abf..6ee5608b7e743501f7af6891bbff292e82b65dbc 100644 --- a/ets2panda/test/parser/ets/binary_op-expected.txt +++ b/ets2panda/test/parser/ets/binary_op-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "binary_op.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "binary_op.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "binary_op.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "binary_op.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/binary_operations-expected.txt b/ets2panda/test/parser/ets/binary_operations-expected.txt index 501839d4f5c969e54f9c1921534ec4888dae43f8..b720e56330d26f26a73e2358fea1dbd1255ea8bf 100644 --- a/ets2panda/test/parser/ets/binary_operations-expected.txt +++ b/ets2panda/test/parser/ets/binary_operations-expected.txt @@ -3098,40 +3098,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "binary_operations.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "binary_operations.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "binary_operations.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "binary_operations.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/blocks-expected.txt b/ets2panda/test/parser/ets/blocks-expected.txt index c60b758011c3ffa3c3b921a33745c2c684f0c1c7..8e49225a669e521a621baa9965c25a46a6adfea6 100644 --- a/ets2panda/test/parser/ets/blocks-expected.txt +++ b/ets2panda/test/parser/ets/blocks-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "blocks.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "blocks.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "blocks.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "blocks.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/blocks_scopes-expected.txt b/ets2panda/test/parser/ets/blocks_scopes-expected.txt index 976de9c02df880037f30076c23dc1eb0f91de936..e2b72d61928f4751577ef86eb5a531bee3e04df1 100644 --- a/ets2panda/test/parser/ets/blocks_scopes-expected.txt +++ b/ets2panda/test/parser/ets/blocks_scopes-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "blocks_scopes.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "blocks_scopes.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "blocks_scopes.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "blocks_scopes.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/boolean-expected.txt b/ets2panda/test/parser/ets/boolean-expected.txt index ed1ac1e8b3299ab31e9c0e72415ffc92ee1ef6fa..152eb7b11c0667fae39d20210d8c1e29304593c7 100644 --- a/ets2panda/test/parser/ets/boolean-expected.txt +++ b/ets2panda/test/parser/ets/boolean-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boolean.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boolean.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boolean.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boolean.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/boolean_cond-expected.txt b/ets2panda/test/parser/ets/boolean_cond-expected.txt index e75cfcb4e9794fb57fd8c68afe805ea371906320..5ede97c31639681fddc9431bcf09ff904c3370e0 100644 --- a/ets2panda/test/parser/ets/boolean_cond-expected.txt +++ b/ets2panda/test/parser/ets/boolean_cond-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boolean_cond.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boolean_cond.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boolean_cond.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boolean_cond.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/boolean_default-expected.txt b/ets2panda/test/parser/ets/boolean_default-expected.txt index 85bb67456ce46957ca21c4bdb809ae5a808b0cbc..fe91f0889bf2906024a0bba02752bde084850921 100644 --- a/ets2panda/test/parser/ets/boolean_default-expected.txt +++ b/ets2panda/test/parser/ets/boolean_default-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boolean_default.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boolean_default.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "boolean_default.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "boolean_default.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/break-expected.txt b/ets2panda/test/parser/ets/break-expected.txt index 217ae2e60a263f4e96bfac7161190f15dc9d5c5d..ca822b37c2a65a8ab9d0369b5aba4b6f58dd9e12 100644 --- a/ets2panda/test/parser/ets/break-expected.txt +++ b/ets2panda/test/parser/ets/break-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "break.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "break.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "break.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "break.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -304,23 +270,71 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "break.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "break.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "break.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "break.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "break.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "break.ets" + } + } + }, "loc": { "start": { - "line": 16, - "column": 8, + "line": 1, + "column": 1, "program": "break.ets" }, "end": { - "line": 16, - "column": 11, + "line": 1, + "column": 3, "program": "break.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/callFunctionWithNullableParam-expected.txt b/ets2panda/test/parser/ets/callFunctionWithNullableParam-expected.txt index db60226adc586c838b99f72750162a158bff451b..c7299e7b675508116064d8f63f224281c1257111 100644 --- a/ets2panda/test/parser/ets/callFunctionWithNullableParam-expected.txt +++ b/ets2panda/test/parser/ets/callFunctionWithNullableParam-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "callFunctionWithNullableParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "callFunctionWithNullableParam.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "callFunctionWithNullableParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "callFunctionWithNullableParam.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/callInterfaceMethodWithNullableParam-expected.txt b/ets2panda/test/parser/ets/callInterfaceMethodWithNullableParam-expected.txt index 220683963f3a59846132e3773eb489176810c787..9fdfdd0562899c92bfd9b65ed3ad7fa19506d8f6 100644 --- a/ets2panda/test/parser/ets/callInterfaceMethodWithNullableParam-expected.txt +++ b/ets2panda/test/parser/ets/callInterfaceMethodWithNullableParam-expected.txt @@ -677,40 +677,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "callInterfaceMethodWithNullableParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "callInterfaceMethodWithNullableParam.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "callInterfaceMethodWithNullableParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "callInterfaceMethodWithNullableParam.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/callMethodWithNullableParam-expected.txt b/ets2panda/test/parser/ets/callMethodWithNullableParam-expected.txt index 1ffa1c5ad4abf57c03d5b519de8d83920786f4d6..bde159a6eccb950f07b0b89b30c2ca8b0055b2bb 100644 --- a/ets2panda/test/parser/ets/callMethodWithNullableParam-expected.txt +++ b/ets2panda/test/parser/ets/callMethodWithNullableParam-expected.txt @@ -379,40 +379,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "callMethodWithNullableParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "callMethodWithNullableParam.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "callMethodWithNullableParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "callMethodWithNullableParam.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/calling_superclass_methods-expected.txt b/ets2panda/test/parser/ets/calling_superclass_methods-expected.txt index 04c13cd6659a1532c45a5cdc2cd3ec25435b906c..230b38802f47e9a0064dbdb804ab1e697ee07c57 100644 --- a/ets2panda/test/parser/ets/calling_superclass_methods-expected.txt +++ b/ets2panda/test/parser/ets/calling_superclass_methods-expected.txt @@ -688,40 +688,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "calling_superclass_methods.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "calling_superclass_methods.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "calling_superclass_methods.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "calling_superclass_methods.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/cast_const_union-expected.txt b/ets2panda/test/parser/ets/cast_const_union-expected.txt index 4f62838db3d0bf82ca225af6690a36ddf56d94b4..50812cab2038e924fb410def2c0380d5acb4ed36 100644 --- a/ets2panda/test/parser/ets/cast_const_union-expected.txt +++ b/ets2panda/test/parser/ets/cast_const_union-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_const_union.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_const_union.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_const_union.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_const_union.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/cast_expressions-expected.txt b/ets2panda/test/parser/ets/cast_expressions-expected.txt index ebd04d05f6606494166ad39f2fd869eae4e417f2..c7ca64e2b7c216bab5d73a13b3e74c4dfdf57267 100644 --- a/ets2panda/test/parser/ets/cast_expressions-expected.txt +++ b/ets2panda/test/parser/ets/cast_expressions-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_expressions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_expressions.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_expressions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_expressions.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/cast_expressions3-expected.txt b/ets2panda/test/parser/ets/cast_expressions3-expected.txt index c103271b9d6bb3f225d3bcb35e473e5c739c2ff9..9f0475e40eedfc2f028b99342db2694476dcbcdc 100644 --- a/ets2panda/test/parser/ets/cast_expressions3-expected.txt +++ b/ets2panda/test/parser/ets/cast_expressions3-expected.txt @@ -692,40 +692,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_expressions3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_expressions3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_expressions3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_expressions3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/cast_expressions4-expected.txt b/ets2panda/test/parser/ets/cast_expressions4-expected.txt index 432388c97533c266bee7e7abb1ec55b3b9e7428b..51ea1f17322b2ac91ba59501d72433075ce97ff1 100644 --- a/ets2panda/test/parser/ets/cast_expressions4-expected.txt +++ b/ets2panda/test/parser/ets/cast_expressions4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_expressions4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_expressions4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_expressions4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_expressions4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -346,37 +312,86 @@ "type": "Identifier", "name": "ints", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "cast_expressions4.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 13, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 17, + "column": 23, + "program": "cast_expressions4.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 24, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 17, + "column": 27, + "program": "cast_expressions4.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 17, + "column": 28, + "program": "cast_expressions4.ets" + } + } }, - "end": { - "line": 17, - "column": 16, - "program": "cast_expressions4.ets" + "loc": { + "start": { + "line": 17, + "column": 24, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 17, + "column": 28, + "program": "cast_expressions4.ets" + } } } - }, + ], "loc": { "start": { "line": 17, - "column": 13, + "column": 23, "program": "cast_expressions4.ets" }, "end": { "line": 17, - "column": 17, + "column": 28, "program": "cast_expressions4.ets" } } @@ -389,21 +404,20 @@ }, "end": { "line": 17, - "column": 17, + "column": 30, "program": "cast_expressions4.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, - "column": 16, + "column": 13, "program": "cast_expressions4.ets" }, "end": { "line": 17, - "column": 18, + "column": 30, "program": "cast_expressions4.ets" } } @@ -438,12 +452,12 @@ "loc": { "start": { "line": 17, - "column": 26, + "column": 36, "program": "cast_expressions4.ets" }, "end": { "line": 17, - "column": 29, + "column": 39, "program": "cast_expressions4.ets" } } @@ -451,12 +465,12 @@ "loc": { "start": { "line": 17, - "column": 26, + "column": 36, "program": "cast_expressions4.ets" }, "end": { "line": 17, - "column": 30, + "column": 40, "program": "cast_expressions4.ets" } } @@ -464,12 +478,12 @@ "loc": { "start": { "line": 17, - "column": 26, + "column": 36, "program": "cast_expressions4.ets" }, "end": { "line": 17, - "column": 30, + "column": 40, "program": "cast_expressions4.ets" } } @@ -478,12 +492,12 @@ "loc": { "start": { "line": 17, - "column": 22, + "column": 32, "program": "cast_expressions4.ets" }, "end": { "line": 17, - "column": 32, + "column": 42, "program": "cast_expressions4.ets" } } @@ -492,12 +506,12 @@ "loc": { "start": { "line": 17, - "column": 21, + "column": 31, "program": "cast_expressions4.ets" }, "end": { "line": 17, - "column": 32, + "column": 42, "program": "cast_expressions4.ets" } } @@ -510,7 +524,7 @@ }, "end": { "line": 17, - "column": 32, + "column": 42, "program": "cast_expressions4.ets" } } @@ -525,7 +539,7 @@ }, "end": { "line": 17, - "column": 33, + "column": 43, "program": "cast_expressions4.ets" } } @@ -539,37 +553,86 @@ "type": "Identifier", "name": "objects", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 16, - "program": "cast_expressions4.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 16, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 18, + "column": 26, + "program": "cast_expressions4.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 27, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 18, + "column": 33, + "program": "cast_expressions4.ets" + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 27, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 18, + "column": 34, + "program": "cast_expressions4.ets" + } + } }, - "end": { - "line": 18, - "column": 22, - "program": "cast_expressions4.ets" + "loc": { + "start": { + "line": 18, + "column": 27, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 18, + "column": 34, + "program": "cast_expressions4.ets" + } } } - }, + ], "loc": { "start": { "line": 18, - "column": 16, + "column": 26, "program": "cast_expressions4.ets" }, "end": { "line": 18, - "column": 23, + "column": 34, "program": "cast_expressions4.ets" } } @@ -582,21 +645,20 @@ }, "end": { "line": 18, - "column": 23, + "column": 36, "program": "cast_expressions4.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, - "column": 22, + "column": 16, "program": "cast_expressions4.ets" }, "end": { "line": 18, - "column": 24, + "column": 36, "program": "cast_expressions4.ets" } } @@ -624,48 +686,97 @@ "loc": { "start": { "line": 18, - "column": 27, + "column": 37, "program": "cast_expressions4.ets" }, "end": { "line": 18, - "column": 31, + "column": 41, "program": "cast_expressions4.ets" } } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 35, - "program": "cast_expressions4.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 45, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 18, + "column": 55, + "program": "cast_expressions4.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 56, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 18, + "column": 62, + "program": "cast_expressions4.ets" + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 56, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 18, + "column": 63, + "program": "cast_expressions4.ets" + } + } }, - "end": { - "line": 18, - "column": 41, - "program": "cast_expressions4.ets" + "loc": { + "start": { + "line": 18, + "column": 56, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 18, + "column": 63, + "program": "cast_expressions4.ets" + } } } - }, + ], "loc": { "start": { "line": 18, - "column": 35, + "column": 55, "program": "cast_expressions4.ets" }, "end": { "line": 18, - "column": 42, + "column": 63, "program": "cast_expressions4.ets" } } @@ -673,26 +784,25 @@ "loc": { "start": { "line": 18, - "column": 35, + "column": 45, "program": "cast_expressions4.ets" }, "end": { "line": 18, - "column": 42, + "column": 64, "program": "cast_expressions4.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, - "column": 41, + "column": 45, "program": "cast_expressions4.ets" }, "end": { "line": 18, - "column": 43, + "column": 64, "program": "cast_expressions4.ets" } } @@ -700,12 +810,12 @@ "loc": { "start": { "line": 18, - "column": 27, + "column": 37, "program": "cast_expressions4.ets" }, "end": { "line": 18, - "column": 31, + "column": 41, "program": "cast_expressions4.ets" } } @@ -718,7 +828,7 @@ }, "end": { "line": 18, - "column": 31, + "column": 41, "program": "cast_expressions4.ets" } } @@ -733,7 +843,7 @@ }, "end": { "line": 18, - "column": 44, + "column": 64, "program": "cast_expressions4.ets" } } @@ -747,37 +857,86 @@ "type": "Identifier", "name": "ints2", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 14, - "program": "cast_expressions4.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 14, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 19, + "column": 24, + "program": "cast_expressions4.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 25, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 19, + "column": 28, + "program": "cast_expressions4.ets" + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 25, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 19, + "column": 29, + "program": "cast_expressions4.ets" + } + } }, - "end": { - "line": 19, - "column": 17, - "program": "cast_expressions4.ets" + "loc": { + "start": { + "line": 19, + "column": 25, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 19, + "column": 29, + "program": "cast_expressions4.ets" + } } } - }, + ], "loc": { "start": { "line": 19, - "column": 14, + "column": 24, "program": "cast_expressions4.ets" }, "end": { "line": 19, - "column": 18, + "column": 29, "program": "cast_expressions4.ets" } } @@ -790,21 +949,20 @@ }, "end": { "line": 19, - "column": 18, + "column": 31, "program": "cast_expressions4.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, - "column": 17, + "column": 14, "program": "cast_expressions4.ets" }, "end": { "line": 19, - "column": 19, + "column": 31, "program": "cast_expressions4.ets" } } @@ -832,48 +990,97 @@ "loc": { "start": { "line": 19, - "column": 22, + "column": 32, "program": "cast_expressions4.ets" }, "end": { "line": 19, - "column": 29, + "column": 39, "program": "cast_expressions4.ets" } } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 33, - "program": "cast_expressions4.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 43, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 19, + "column": 53, + "program": "cast_expressions4.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 54, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 19, + "column": 57, + "program": "cast_expressions4.ets" + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 54, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 19, + "column": 58, + "program": "cast_expressions4.ets" + } + } }, - "end": { - "line": 19, - "column": 36, - "program": "cast_expressions4.ets" + "loc": { + "start": { + "line": 19, + "column": 54, + "program": "cast_expressions4.ets" + }, + "end": { + "line": 19, + "column": 58, + "program": "cast_expressions4.ets" + } } } - }, + ], "loc": { "start": { "line": 19, - "column": 33, + "column": 53, "program": "cast_expressions4.ets" }, "end": { "line": 19, - "column": 37, + "column": 58, "program": "cast_expressions4.ets" } } @@ -881,26 +1088,25 @@ "loc": { "start": { "line": 19, - "column": 33, + "column": 43, "program": "cast_expressions4.ets" }, "end": { "line": 19, - "column": 37, + "column": 59, "program": "cast_expressions4.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, - "column": 36, + "column": 43, "program": "cast_expressions4.ets" }, "end": { "line": 19, - "column": 38, + "column": 59, "program": "cast_expressions4.ets" } } @@ -908,12 +1114,12 @@ "loc": { "start": { "line": 19, - "column": 22, + "column": 32, "program": "cast_expressions4.ets" }, "end": { "line": 19, - "column": 29, + "column": 39, "program": "cast_expressions4.ets" } } @@ -926,7 +1132,7 @@ }, "end": { "line": 19, - "column": 29, + "column": 39, "program": "cast_expressions4.ets" } } @@ -941,7 +1147,7 @@ }, "end": { "line": 19, - "column": 39, + "column": 59, "program": "cast_expressions4.ets" } } @@ -953,7 +1159,7 @@ "type": "VariableDeclarator", "id": { "type": "Identifier", - "name": "object", + "name": "obj", "decorators": [], "loc": { "start": { @@ -963,7 +1169,7 @@ }, "end": { "line": 21, - "column": 13, + "column": 10, "program": "cast_expressions4.ets" } } @@ -977,12 +1183,12 @@ "loc": { "start": { "line": 21, - "column": 16, + "column": 13, "program": "cast_expressions4.ets" }, "end": { "line": 21, - "column": 21, + "column": 18, "program": "cast_expressions4.ets" } } @@ -998,12 +1204,12 @@ "loc": { "start": { "line": 21, - "column": 25, + "column": 22, "program": "cast_expressions4.ets" }, "end": { "line": 21, - "column": 31, + "column": 28, "program": "cast_expressions4.ets" } } @@ -1011,12 +1217,12 @@ "loc": { "start": { "line": 21, - "column": 25, + "column": 22, "program": "cast_expressions4.ets" }, "end": { "line": 21, - "column": 32, + "column": 29, "program": "cast_expressions4.ets" } } @@ -1024,12 +1230,12 @@ "loc": { "start": { "line": 21, - "column": 25, + "column": 22, "program": "cast_expressions4.ets" }, "end": { "line": 21, - "column": 32, + "column": 29, "program": "cast_expressions4.ets" } } @@ -1037,12 +1243,12 @@ "loc": { "start": { "line": 21, - "column": 16, + "column": 13, "program": "cast_expressions4.ets" }, "end": { "line": 21, - "column": 21, + "column": 18, "program": "cast_expressions4.ets" } } @@ -1055,7 +1261,7 @@ }, "end": { "line": 21, - "column": 21, + "column": 18, "program": "cast_expressions4.ets" } } @@ -1070,7 +1276,7 @@ }, "end": { "line": 21, - "column": 32, + "column": 29, "program": "cast_expressions4.ets" } } diff --git a/ets2panda/test/parser/ets/cast_expressions4.ets b/ets2panda/test/parser/ets/cast_expressions4.ets index 6b855e849c1a5d3fe68eb9c5b519544cd399af06..70c336bfeb1d74e9d604c37dccc7656c9aca4182 100644 --- a/ets2panda/test/parser/ets/cast_expressions4.ets +++ b/ets2panda/test/parser/ets/cast_expressions4.ets @@ -14,9 +14,9 @@ */ function widening_array_test(): void { - let ints: Int[] = [new Int()]; - let objects: Object[] = ints as Object[]; - let ints2: Int[] = objects as Int[]; + let ints: FixedArray = [new Int()]; + let objects: FixedArray = ints as FixedArray; + let ints2: FixedArray = objects as FixedArray; - let object = ints2 as Object; + let obj = ints2 as Object; } diff --git a/ets2panda/test/parser/ets/cast_expressions5-expected.txt b/ets2panda/test/parser/ets/cast_expressions5-expected.txt index a3ff3f525f47815e50230423a71a4fa5e3de6992..bc09d5b685b500e67bd02238e095b506257d666b 100644 --- a/ets2panda/test/parser/ets/cast_expressions5-expected.txt +++ b/ets2panda/test/parser/ets/cast_expressions5-expected.txt @@ -670,40 +670,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_expressions5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_expressions5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "cast_expressions5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "cast_expressions5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/class_init-expected.txt b/ets2panda/test/parser/ets/class_init-expected.txt index e3875b6336ddd45d6fae311983781204bf2920c2..a3a99d1115670602c19e8ddde7e40244701e20cc 100644 --- a/ets2panda/test/parser/ets/class_init-expected.txt +++ b/ets2panda/test/parser/ets/class_init-expected.txt @@ -446,40 +446,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_init.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_init.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_init.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_init.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/class_instance-expected.txt b/ets2panda/test/parser/ets/class_instance-expected.txt index fe94ba74199cc15bc277c736d4d0964c4390d8b8..e8c78b56b717cf0497a9b03ab56d0ece5413a4e1 100644 --- a/ets2panda/test/parser/ets/class_instance-expected.txt +++ b/ets2panda/test/parser/ets/class_instance-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_instance.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_instance.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_instance.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_instance.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/class_instance_creation-expected.txt b/ets2panda/test/parser/ets/class_instance_creation-expected.txt index 7bb44b9d664945a67bc031708b936d7428ac3f15..e1b669124bd34ab5c9f54ae4a2bb62102b0cd28a 100644 --- a/ets2panda/test/parser/ets/class_instance_creation-expected.txt +++ b/ets2panda/test/parser/ets/class_instance_creation-expected.txt @@ -1067,40 +1067,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_instance_creation.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_instance_creation.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_instance_creation.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_instance_creation.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/class_instance_import_alias-expected.txt b/ets2panda/test/parser/ets/class_instance_import_alias-expected.txt index d65a8379f090e4f383e03adf0bdd6c7f85300beb..af67a5ec66d686e29895df0df512a5367df76de9 100644 --- a/ets2panda/test/parser/ets/class_instance_import_alias-expected.txt +++ b/ets2panda/test/parser/ets/class_instance_import_alias-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_instance_import_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_instance_import_alias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_instance_import_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_instance_import_alias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/class_instance_initializer-expected.txt b/ets2panda/test/parser/ets/class_instance_initializer-expected.txt index 75453bdb6dace658057382085b1ac414e3611787..e1b5d92d377a4fd513e94fe8726ae49b305eea0b 100644 --- a/ets2panda/test/parser/ets/class_instance_initializer-expected.txt +++ b/ets2panda/test/parser/ets/class_instance_initializer-expected.txt @@ -3431,40 +3431,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_instance_initializer.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_instance_initializer.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_instance_initializer.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_instance_initializer.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/class_interface_enum_only_top_level_4-expected.txt b/ets2panda/test/parser/ets/class_interface_enum_only_top_level_4-expected.txt index 93c7908003dc0fea8b628a273865079c30195fa3..877b11b3cbdcb1e67bb071b190dba94e75cd4b0e 100644 --- a/ets2panda/test/parser/ets/class_interface_enum_only_top_level_4-expected.txt +++ b/ets2panda/test/parser/ets/class_interface_enum_only_top_level_4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_interface_enum_only_top_level_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_interface_enum_only_top_level_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_interface_enum_only_top_level_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_interface_enum_only_top_level_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/class_static_initializer-expected.txt b/ets2panda/test/parser/ets/class_static_initializer-expected.txt index eca9102e007bc17df97b6693eba1d592fa69063e..524a1ac1b929202d0d91cdb7c05b6f4a19b7c11a 100644 --- a/ets2panda/test/parser/ets/class_static_initializer-expected.txt +++ b/ets2panda/test/parser/ets/class_static_initializer-expected.txt @@ -795,40 +795,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_static_initializer.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_static_initializer.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_static_initializer.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_static_initializer.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/classes-expected.txt b/ets2panda/test/parser/ets/classes-expected.txt index 67f65f50c913bf41e6d2e14149aa16ee2a76bdcd..36eb887b8e305ebe9916be5aea8c86f1aa149921 100644 --- a/ets2panda/test/parser/ets/classes-expected.txt +++ b/ets2panda/test/parser/ets/classes-expected.txt @@ -689,40 +689,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "classes.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "classes.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "classes.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "classes.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/comment_block-expected.txt b/ets2panda/test/parser/ets/comment_block-expected.txt index 8620d29ca40501650cd38bf903ac0ddf1e1bb253..5d584272a87b6dfae3d04b7335034f25b1885d1f 100644 --- a/ets2panda/test/parser/ets/comment_block-expected.txt +++ b/ets2panda/test/parser/ets/comment_block-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "comment_block.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "comment_block.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "comment_block.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "comment_block.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/comment_line-expected.txt b/ets2panda/test/parser/ets/comment_line-expected.txt index a0188b91f876c5850730e23105301f63be3c643a..63592312132e2c17da9fec24d9cfb1b326445d7d 100644 --- a/ets2panda/test/parser/ets/comment_line-expected.txt +++ b/ets2panda/test/parser/ets/comment_line-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "comment_line.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "comment_line.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "comment_line.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "comment_line.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt b/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt index e007a013611c5f8836055a306bf194b80fa9654c..5d2945240a522c88cc46ee7fbce274b1343262b1 100644 --- a/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt +++ b/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "conditionalExpressionType.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "conditionalExpressionType.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/const-expected.txt b/ets2panda/test/parser/ets/const-expected.txt index 9035ac6defff65f040274ed22659e53fac402a57..d4eb5c420cfb4764be6fdabe1548dbd7f8e58f35 100644 --- a/ets2panda/test/parser/ets/const-expected.txt +++ b/ets2panda/test/parser/ets/const-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "const.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "const.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "const.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "const.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/constructorThrowsRethrows-expected.txt b/ets2panda/test/parser/ets/constructorThrowsRethrows-expected.txt index 8a0a76080c6a2e39ba3c652e4b29fac1dc8b12de..b4ef5220f5a6739752c6c660301c1e8f94f76ee9 100644 --- a/ets2panda/test/parser/ets/constructorThrowsRethrows-expected.txt +++ b/ets2panda/test/parser/ets/constructorThrowsRethrows-expected.txt @@ -497,40 +497,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructorThrowsRethrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructorThrowsRethrows.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructorThrowsRethrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructorThrowsRethrows.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/constructor_super_call1-expected.txt b/ets2panda/test/parser/ets/constructor_super_call1-expected.txt index 49cebe990c87fbb27c6887b9dc5aa24962412e1b..a4bad5265d2d1d0aaae7f0098265658f9f20d758 100644 --- a/ets2panda/test/parser/ets/constructor_super_call1-expected.txt +++ b/ets2panda/test/parser/ets/constructor_super_call1-expected.txt @@ -715,40 +715,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_super_call1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_super_call1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_super_call1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_super_call1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/constructor_super_call3-expected.txt b/ets2panda/test/parser/ets/constructor_super_call3-expected.txt index 69aca95035d8bc3ebe96dd66f2c2346c3aad290f..2f33fcc0e042a085e6bfb9415b6f5d24094c3cc4 100644 --- a/ets2panda/test/parser/ets/constructor_super_call3-expected.txt +++ b/ets2panda/test/parser/ets/constructor_super_call3-expected.txt @@ -429,40 +429,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_super_call3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_super_call3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_super_call3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_super_call3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/constructor_test-expected.txt b/ets2panda/test/parser/ets/constructor_test-expected.txt index e5a14152e5e0710d2ea936d271d135869e6b3316..1f51245e9fb50438e3bbb3e2104da04548e3f5af 100644 --- a/ets2panda/test/parser/ets/constructor_test-expected.txt +++ b/ets2panda/test/parser/ets/constructor_test-expected.txt @@ -1167,40 +1167,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_test.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_test.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_test.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_test.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/constructor_with_optional_parameter-expected.txt b/ets2panda/test/parser/ets/constructor_with_optional_parameter-expected.txt index bc89510f7d0d8409fb538f8719bc6e3c28c51844..abe99b5e5c3f3fedd8807cd8e36930925adbd1ac 100644 --- a/ets2panda/test/parser/ets/constructor_with_optional_parameter-expected.txt +++ b/ets2panda/test/parser/ets/constructor_with_optional_parameter-expected.txt @@ -576,40 +576,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_with_optional_parameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_with_optional_parameter.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_with_optional_parameter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_with_optional_parameter.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/constructor_with_return_2-expected.txt b/ets2panda/test/parser/ets/constructor_with_return_2-expected.txt index 4e37776ca0baa84b213ca5d3c7f711ab2d8ebd83..362d6bee8a0dd0bca4ed2bb502c1566ad9a1eacb 100644 --- a/ets2panda/test/parser/ets/constructor_with_return_2-expected.txt +++ b/ets2panda/test/parser/ets/constructor_with_return_2-expected.txt @@ -347,40 +347,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_with_return_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_with_return_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "constructor_with_return_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "constructor_with_return_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/continue-expected.txt b/ets2panda/test/parser/ets/continue-expected.txt index 3d3529d13a53697db6d82695d79171e859b1d074..235c278afecadc59f8e77b196db1942465e1bf80 100644 --- a/ets2panda/test/parser/ets/continue-expected.txt +++ b/ets2panda/test/parser/ets/continue-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "continue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "continue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "continue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "continue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -304,23 +270,71 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "continue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "continue.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "continue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "continue.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "continue.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "continue.ets" + } + } + }, "loc": { "start": { - "line": 16, - "column": 8, + "line": 1, + "column": 1, "program": "continue.ets" }, "end": { - "line": 16, - "column": 11, + "line": 1, + "column": 3, "program": "continue.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/conversions-expected.txt b/ets2panda/test/parser/ets/conversions-expected.txt index 04933dbb3fbe6a3d6e9198b19de22dd201cd3a60..de9e873fde2be36bd49965131f9ed277a44f1cb3 100644 --- a/ets2panda/test/parser/ets/conversions-expected.txt +++ b/ets2panda/test/parser/ets/conversions-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "conversions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "conversions.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "conversions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "conversions.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/decl_infer-expected.txt b/ets2panda/test/parser/ets/decl_infer-expected.txt index 17e4f40df09ae617f2a4661fc2581de8f10d4ee7..d019542239551efc0eb95ca02e7f0f43516c6bcc 100644 --- a/ets2panda/test/parser/ets/decl_infer-expected.txt +++ b/ets2panda/test/parser/ets/decl_infer-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "decl_infer.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "decl_infer.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "decl_infer.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "decl_infer.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/declare_ambient_const_variable-expected.txt b/ets2panda/test/parser/ets/declare_ambient_const_variable-expected.txt index 74f8366f6c78aa0fcf8e358ea5fd94821448c25d..823de09dd37eae588a10393cd336671700b749ad 100644 --- a/ets2panda/test/parser/ets/declare_ambient_const_variable-expected.txt +++ b/ets2panda/test/parser/ets/declare_ambient_const_variable-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_ambient_const_variable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_ambient_const_variable.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_ambient_const_variable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_ambient_const_variable.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/declare_class-expected.txt b/ets2panda/test/parser/ets/declare_class-expected.txt index b75400f8b1db3cf2f23ed215e1f66e580d5e3abf..0021db53e2214a037386e1a26ecd12636843d6fc 100644 --- a/ets2panda/test/parser/ets/declare_class-expected.txt +++ b/ets2panda/test/parser/ets/declare_class-expected.txt @@ -660,40 +660,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_class.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_class.ets" - } - } - } - ], "body": [], "loc": { "start": { diff --git a/ets2panda/test/parser/ets/declare_enum-expected.txt b/ets2panda/test/parser/ets/declare_enum-expected.txt index e2aaf71412302ac1294f93e5647e5508e5522531..ace3a9cf3788a8c5a40c6c6159c836a87a84c6fa 100644 --- a/ets2panda/test/parser/ets/declare_enum-expected.txt +++ b/ets2panda/test/parser/ets/declare_enum-expected.txt @@ -21,7 +21,85 @@ } } }, - "superClass": null, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "BaseEnum", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + }, + "end": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + }, + "end": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + }, + "end": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + }, + "end": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + }, + "end": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + } + } + }, "implements": [], "body": [ { @@ -174,82 +252,14 @@ "program": "declare_enum.ets" } } - } - ], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "MemberExpression", - "object": { - "type": "ThisExpression", - "loc": { - "start": { - "line": 16, - "column": 9, - "program": "declare_enum.ets" - }, - "end": { - "line": 16, - "column": 9, - "program": "declare_enum.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "#ordinal", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9, - "program": "declare_enum.ets" - }, - "end": { - "line": 16, - "column": 9, - "program": "declare_enum.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 16, - "column": 9, - "program": "declare_enum.ets" - }, - "end": { - "line": 16, - "column": 9, - "program": "declare_enum.ets" - } - } - }, - "right": { - "type": "Identifier", - "name": "ordinal", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9, - "program": "declare_enum.ets" - }, - "end": { - "line": 16, - "column": 9, - "program": "declare_enum.ets" - } - } - }, + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSPrimitiveType", "loc": { "start": { "line": 16, @@ -263,6 +273,7 @@ } } }, + "decorators": [], "loc": { "start": { "line": 16, @@ -275,8 +286,24 @@ "program": "declare_enum.ets" } } + }, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + }, + "end": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + } } - ], + } + ], + "body": { + "type": "BlockStatement", + "statements": [], "loc": { "start": { "line": 16, @@ -400,6 +427,22 @@ } }, "arguments": [ + { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + }, + "end": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + } + } + }, { "type": "NumberLiteral", "value": 0, @@ -567,6 +610,22 @@ } }, "arguments": [ + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + }, + "end": { + "line": 16, + "column": 9, + "program": "declare_enum.ets" + } + } + }, { "type": "NumberLiteral", "value": 1, @@ -2624,40 +2683,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_enum.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_enum.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_enum.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_enum.ets" - } - } - } - ], "body": [], "loc": { "start": { diff --git a/ets2panda/test/parser/ets/declare_func-expected.txt b/ets2panda/test/parser/ets/declare_func-expected.txt index 8a0b75ddac1578b98110a47af2dde161e0e6c9a8..90ec31f3de3f48589095b771523879dca0cc7d98 100644 --- a/ets2panda/test/parser/ets/declare_func-expected.txt +++ b/ets2panda/test/parser/ets/declare_func-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_func.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_func.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_func.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_func.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/declare_iface-expected.txt b/ets2panda/test/parser/ets/declare_iface-expected.txt index d64dcbbb713745dcb8899545bc13007e038ab5b0..6b06a3207e35077053afb144c98d1fe9dfe3e774 100644 --- a/ets2panda/test/parser/ets/declare_iface-expected.txt +++ b/ets2panda/test/parser/ets/declare_iface-expected.txt @@ -721,40 +721,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_iface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_iface.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "declare_iface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "declare_iface.ets" - } - } - } - ], "body": [], "loc": { "start": { diff --git a/ets2panda/test/parser/ets/default_parameter10-expected.txt b/ets2panda/test/parser/ets/default_parameter10-expected.txt index 957d9256773ae16df106aff8c7fc6eaacfeed1ce..1dd365944b344ec69fce131e25e5552cd54d2447 100644 --- a/ets2panda/test/parser/ets/default_parameter10-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter10-expected.txt @@ -215,6 +215,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "default_parameter10.ets" + }, + "end": { + "line": 17, + "column": 41, + "program": "default_parameter10.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "default_parameter10.ets" + }, + "end": { + "line": 17, + "column": 41, + "program": "default_parameter10.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "default_parameter10.ets" + }, + "end": { + "line": 17, + "column": 41, + "program": "default_parameter10.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "default_parameter10.ets" + }, + "end": { + "line": 17, + "column": 41, + "program": "default_parameter10.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "default_parameter10.ets" + }, + "end": { + "line": 17, + "column": 41, + "program": "default_parameter10.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "default_parameter10.ets" + }, + "end": { + "line": 17, + "column": 41, + "program": "default_parameter10.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "default_parameter10.ets" + }, + "end": { + "line": 17, + "column": 41, + "program": "default_parameter10.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "default_parameter10.ets" + }, + "end": { + "line": 17, + "column": 41, + "program": "default_parameter10.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "default_parameter10.ets" + }, + "end": { + "line": 17, + "column": 41, + "program": "default_parameter10.ets" + } + } + } + ], "loc": { "start": { "line": 17, @@ -410,40 +562,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter10.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter10.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/default_parameter5-expected.txt b/ets2panda/test/parser/ets/default_parameter5-expected.txt index 800988f4c6526b474d07f38ae7cc187d967921e3..3fa19f2329cc4fc47917cf3c29caf96a376536ee 100644 --- a/ets2panda/test/parser/ets/default_parameter5-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter5-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -932,6 +898,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter5.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter5.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter5.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter5.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter5.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter5.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter5.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter5.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter5.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter5.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter5.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter5.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter5.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter5.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter5.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter5.ets" + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter5.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter5.ets" + } + } + } + ], "loc": { "start": { "line": 21, diff --git a/ets2panda/test/parser/ets/default_parameter7-expected.txt b/ets2panda/test/parser/ets/default_parameter7-expected.txt index ce02eae67805defd3ff27af22e895ae9d6b3fe8f..1e2089524ac5e280bc6e03b19a13301c7b13a7d4 100644 --- a/ets2panda/test/parser/ets/default_parameter7-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter7-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -341,55 +307,103 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 21, - "program": "default_parameter7.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "default_parameter7.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter7.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "default_parameter7.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter7.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "default_parameter7.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter7.ets" + } + } }, - "end": { - "line": 16, - "column": 24, - "program": "default_parameter7.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "default_parameter7.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter7.ets" + } } } - }, + ], "loc": { "start": { - "line": 16, - "column": 21, + "line": 1, + "column": 3, "program": "default_parameter7.ets" }, "end": { - "line": 16, - "column": 25, + "line": 1, + "column": 3, "program": "default_parameter7.ets" } } }, "loc": { "start": { - "line": 16, - "column": 21, + "line": 1, + "column": 1, "program": "default_parameter7.ets" }, "end": { - "line": 16, - "column": 25, + "line": 1, + "column": 3, "program": "default_parameter7.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -1190,6 +1204,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter7.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter7.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter7.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter7.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter7.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter7.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter7.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter7.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter7.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter7.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter7.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter7.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter7.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter7.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter7.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter7.ets" + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "default_parameter7.ets" + }, + "end": { + "line": 24, + "column": 2, + "program": "default_parameter7.ets" + } + } + } + ], "loc": { "start": { "line": 21, diff --git a/ets2panda/test/parser/ets/default_parameter8-expected.txt b/ets2panda/test/parser/ets/default_parameter8-expected.txt index c4893d75e667881da39922444c29a0d2dfe29682..4e675b381d7160adeec1dd93a98bf28d98ea3a08 100644 --- a/ets2panda/test/parser/ets/default_parameter8-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter8-expected.txt @@ -906,6 +906,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "default_parameter8.ets" + }, + "end": { + "line": 23, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "default_parameter8.ets" + }, + "end": { + "line": 23, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "default_parameter8.ets" + }, + "end": { + "line": 23, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "default_parameter8.ets" + }, + "end": { + "line": 23, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "default_parameter8.ets" + }, + "end": { + "line": 23, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "default_parameter8.ets" + }, + "end": { + "line": 23, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "default_parameter8.ets" + }, + "end": { + "line": 23, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "default_parameter8.ets" + }, + "end": { + "line": 23, + "column": 6, + "program": "default_parameter8.ets" + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "default_parameter8.ets" + }, + "end": { + "line": 23, + "column": 6, + "program": "default_parameter8.ets" + } + } + } + ], "loc": { "start": { "line": 21, @@ -1691,6 +1843,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 17, + "program": "default_parameter8.ets" + }, + "end": { + "line": 32, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 17, + "program": "default_parameter8.ets" + }, + "end": { + "line": 32, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 17, + "program": "default_parameter8.ets" + }, + "end": { + "line": 32, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 17, + "program": "default_parameter8.ets" + }, + "end": { + "line": 32, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 17, + "program": "default_parameter8.ets" + }, + "end": { + "line": 32, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 17, + "program": "default_parameter8.ets" + }, + "end": { + "line": 32, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 30, + "column": 17, + "program": "default_parameter8.ets" + }, + "end": { + "line": 32, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 17, + "program": "default_parameter8.ets" + }, + "end": { + "line": 32, + "column": 6, + "program": "default_parameter8.ets" + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 17, + "program": "default_parameter8.ets" + }, + "end": { + "line": 32, + "column": 6, + "program": "default_parameter8.ets" + } + } + } + ], "loc": { "start": { "line": 30, @@ -2373,6 +2677,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 15, + "program": "default_parameter8.ets" + }, + "end": { + "line": 38, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 15, + "program": "default_parameter8.ets" + }, + "end": { + "line": 38, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 15, + "program": "default_parameter8.ets" + }, + "end": { + "line": 38, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 15, + "program": "default_parameter8.ets" + }, + "end": { + "line": 38, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 15, + "program": "default_parameter8.ets" + }, + "end": { + "line": 38, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 15, + "program": "default_parameter8.ets" + }, + "end": { + "line": 38, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 36, + "column": 15, + "program": "default_parameter8.ets" + }, + "end": { + "line": 38, + "column": 6, + "program": "default_parameter8.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 15, + "program": "default_parameter8.ets" + }, + "end": { + "line": 38, + "column": 6, + "program": "default_parameter8.ets" + } + } + } + ], + "loc": { + "start": { + "line": 36, + "column": 15, + "program": "default_parameter8.ets" + }, + "end": { + "line": 38, + "column": 6, + "program": "default_parameter8.ets" + } + } + } + ], "loc": { "start": { "line": 36, @@ -2568,40 +3024,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/default_parameter9-expected.txt b/ets2panda/test/parser/ets/default_parameter9-expected.txt index 5fe716c005ba30a4cc40f9bb9d0d7f084c3dc313..3ac72d8cf379b57e18556c24f0a2ccc693b2cf2d 100644 --- a/ets2panda/test/parser/ets/default_parameter9-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter9-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -325,55 +291,103 @@ "type": "Identifier", "name": "self", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 37, - "program": "default_parameter9.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "default_parameter9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + } + } }, - "end": { - "line": 16, - "column": 38, - "program": "default_parameter9.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + } } } - }, + ], "loc": { "start": { - "line": 16, - "column": 37, + "line": 1, + "column": 3, "program": "default_parameter9.ets" }, "end": { - "line": 16, - "column": 39, + "line": 1, + "column": 3, "program": "default_parameter9.ets" } } }, "loc": { "start": { - "line": 16, - "column": 37, + "line": 1, + "column": 1, "program": "default_parameter9.ets" }, "end": { - "line": 16, - "column": 39, + "line": 1, + "column": 3, "program": "default_parameter9.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -495,55 +509,103 @@ } ], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 57, - "program": "default_parameter9.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "default_parameter9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + } + } }, - "end": { - "line": 16, - "column": 58, - "program": "default_parameter9.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "default_parameter9.ets" + } } } - }, + ], "loc": { "start": { - "line": 16, - "column": 57, + "line": 1, + "column": 3, "program": "default_parameter9.ets" }, "end": { - "line": 16, - "column": 59, + "line": 1, + "column": 3, "program": "default_parameter9.ets" } } }, "loc": { "start": { - "line": 16, - "column": 57, + "line": 1, + "column": 1, "program": "default_parameter9.ets" }, "end": { - "line": 16, - "column": 59, + "line": 1, + "column": 3, "program": "default_parameter9.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -655,6 +717,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17, + "program": "default_parameter9.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter9.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17, + "program": "default_parameter9.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter9.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 17, + "program": "default_parameter9.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter9.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 17, + "program": "default_parameter9.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter9.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 17, + "program": "default_parameter9.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter9.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17, + "program": "default_parameter9.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter9.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 16, + "column": 17, + "program": "default_parameter9.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter9.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 17, + "program": "default_parameter9.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter9.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 17, + "program": "default_parameter9.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter9.ets" + } + } + } + ], "loc": { "start": { "line": 16, 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 467ec02d0cc57000716594e95159dc608fb17a66..b8edf0fab3da06d95517cb28fffa4f8fdaceba9e 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 @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -980,6 +946,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10, + "program": "default_parameter_implicitly_typed_return_void.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter_implicitly_typed_return_void.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10, + "program": "default_parameter_implicitly_typed_return_void.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter_implicitly_typed_return_void.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 10, + "program": "default_parameter_implicitly_typed_return_void.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter_implicitly_typed_return_void.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 10, + "program": "default_parameter_implicitly_typed_return_void.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter_implicitly_typed_return_void.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 10, + "program": "default_parameter_implicitly_typed_return_void.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter_implicitly_typed_return_void.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10, + "program": "default_parameter_implicitly_typed_return_void.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter_implicitly_typed_return_void.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 16, + "column": 10, + "program": "default_parameter_implicitly_typed_return_void.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter_implicitly_typed_return_void.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 10, + "program": "default_parameter_implicitly_typed_return_void.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter_implicitly_typed_return_void.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 10, + "program": "default_parameter_implicitly_typed_return_void.ets" + }, + "end": { + "line": 18, + "column": 2, + "program": "default_parameter_implicitly_typed_return_void.ets" + } + } + } + ], "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_decl_import-expected.txt b/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_decl_import-expected.txt index 7f5a47d9e0e9300fc601aca87c41f71467df34e2..05fee0aa190470ac95878a3a82fab0a29ed30855 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_decl_import-expected.txt +++ b/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_decl_import-expected.txt @@ -203,40 +203,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_decl_import.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_decl_import.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_decl_import.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_decl_import.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1949,6 +1915,2742 @@ "program": "dynamic_decl_import.ets" } } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "$jsnew", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "qname_start_from", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "accessibility": "private", + "static": true, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "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": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "JSRuntime", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "__initJSNewClass", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "arguments": [], + "optional": false, + "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": 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 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "$_invoke", + "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": "$_invoke", + "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": "obj", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_start", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_len", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p0", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p1", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + } + ], + "returnType": { + "type": "OpaqueType", + "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 + } + } + }, + "overloads": [], + "decorators": [], + "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 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "$jscall", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "qname_start_from", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "accessibility": "private", + "static": true, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "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": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "JSRuntime", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "__initJSCallClass", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "arguments": [], + "optional": false, + "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": 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 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "$_invoke", + "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": "$_invoke", + "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": "obj", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_start", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_len", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p0", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + } + ], + "returnType": { + "type": "OpaqueType", + "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 + } + } + }, + "overloads": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "$_invoke", + "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": "$_invoke", + "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": "obj", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_start", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_len", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + } + ], + "returnType": { + "type": "OpaqueType", + "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 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "$_invoke", + "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": "$_invoke", + "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": "obj", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_start", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_len", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p0", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + } + ], + "returnType": { + "type": "OpaqueType", + "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 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "$_invoke", + "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": "$_invoke", + "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": "obj", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_start", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_len", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + } + ], + "returnType": { + "type": "OpaqueType", + "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 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "$_invoke", + "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": "$_invoke", + "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": "obj", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_start", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "qname_len", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p0", + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "decorators": [], + "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 + } + } + } + ], + "returnType": { + "type": "OpaqueType", + "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 + } + } + }, + "overloads": [], + "decorators": [], + "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 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_module0", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "accessibility": "public", + "static": true, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "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": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_module0", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "JSRuntime", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "loadModule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "/home/anya/panda_reps/standalone_new/arkcompiler/runtime_core/static_core/tools/es2panda/test/parser/ets/dynamic_import_tests/modules/module.ets", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "optional": false, + "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": 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": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "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": [], + "returnType": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "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 + } + } + }, + "overloads": [], + "decorators": [], + "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": { diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_iface_decl_bad-expected.txt b/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_iface_decl_bad-expected.txt index 0b8c7754133bb0748d45953ddbb6264dcd43272e..7bf0cdf315ceb1807b25ad8ae5985e2e8df195c5 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_iface_decl_bad-expected.txt +++ b/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_iface_decl_bad-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_iface_decl_bad.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_iface_decl_bad.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_iface_decl_bad.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_iface_decl_bad.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -596,6 +562,482 @@ "program": "dynamic_iface_decl_bad.ets" } } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_module0", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "accessibility": "public", + "static": true, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "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": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "$dynmodule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "dynamic_import_tests_modules_module0", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "JSRuntime", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "property": { + "type": "Identifier", + "name": "loadModule", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "/home/anya/panda_reps/standalone_new/arkcompiler/runtime_core/static_core/tools/es2panda/test/parser/ets/dynamic_import_tests/modules/module.ets", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "optional": false, + "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": 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": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + { + "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": [], + "returnType": { + "type": "OpaqueType", + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [], + "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 + } + } + }, + "overloads": [], + "decorators": [], + "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": { diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_optional_decl-expected.txt b/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_optional_decl-expected.txt index 81f8725d29f0a5d2dfb431607ab4ad9a01ae2735..b15e5f1c093cf4f1b4516f49986539e1f6e6e214 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_optional_decl-expected.txt +++ b/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_optional_decl-expected.txt @@ -154,40 +154,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_optional_decl.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_optional_decl.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "dynamic_optional_decl.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "dynamic_optional_decl.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/modules/instanceof-expected.txt b/ets2panda/test/parser/ets/dynamic_import_tests/modules/instanceof-expected.txt index bed3a52ebae2e86a56ab54204d29dcbdb8adbbd3..0a0f28326ba50459ee88b72b51f9a33e9b363b39 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/modules/instanceof-expected.txt +++ b/ets2panda/test/parser/ets/dynamic_import_tests/modules/instanceof-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof.ets" - } - } - } - ], "body": [], "loc": { "start": { 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 ae27338c9cdd796f6b9543ae04dab6c0c2733fc9..e4848fa0570f4fb509e28ee002b9c17d5f2cd3cf 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 @@ -821,6 +821,158 @@ } }, "declare": true, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 26, + "column": 17, + "program": "module.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 26, + "column": 17, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 26, + "column": 17, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 26, + "column": 17, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 26, + "column": 17, + "program": "module.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 26, + "column": 17, + "program": "module.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 26, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 26, + "column": 17, + "program": "module.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 26, + "column": 17, + "program": "module.ets" + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 26, + "column": 17, + "program": "module.ets" + } + } + } + ], "loc": { "start": { "line": 26, @@ -1333,40 +1485,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "module.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "module.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "module.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "module.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1699,6 +1817,158 @@ } }, "declare": true, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 17, + "column": 37, + "program": "module.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 17, + "column": 37, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 17, + "column": 37, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 17, + "column": 37, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 17, + "column": 37, + "program": "module.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 17, + "column": 37, + "program": "module.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 17, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 17, + "column": 37, + "program": "module.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 17, + "column": 37, + "program": "module.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 17, + "column": 37, + "program": "module.ets" + } + } + } + ], "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/empty_class-expected.txt b/ets2panda/test/parser/ets/empty_class-expected.txt index 501ac546a7a12a920e192a36026dc406bf77f8d5..f5870a749a10ec164057ab1499bf07505fe5f60e 100644 --- a/ets2panda/test/parser/ets/empty_class-expected.txt +++ b/ets2panda/test/parser/ets/empty_class-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "empty_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "empty_class.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "empty_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "empty_class.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/empty_statement-expected.txt b/ets2panda/test/parser/ets/empty_statement-expected.txt index d3a0317f98f0aaa647ec73a8ae2952faec7137e2..94c8bbdbc02418bdc091f638aacd3d53748e3bf1 100644 --- a/ets2panda/test/parser/ets/empty_statement-expected.txt +++ b/ets2panda/test/parser/ets/empty_statement-expected.txt @@ -880,40 +880,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "empty_statement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "empty_statement.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "empty_statement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "empty_statement.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/exports-expected.txt b/ets2panda/test/parser/ets/exports-expected.txt index 47a122d24c4fdc8be8e9cbc05c5e4743d3ef3245..774017d3bbef04aa72825b8ac1457c99191e2b76 100644 --- a/ets2panda/test/parser/ets/exports-expected.txt +++ b/ets2panda/test/parser/ets/exports-expected.txt @@ -274,40 +274,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "exports.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "exports.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "exports.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "exports.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/external_cyclic_constructor_check-expected.txt b/ets2panda/test/parser/ets/external_cyclic_constructor_check-expected.txt index 42a9c1d15d396269d04f2b07cb3e438aa003470b..4cee1d6d40e0a6df029655deb08f3324169dba64 100644 --- a/ets2panda/test/parser/ets/external_cyclic_constructor_check-expected.txt +++ b/ets2panda/test/parser/ets/external_cyclic_constructor_check-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "external_cyclic_constructor_check.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "external_cyclic_constructor_check.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "external_cyclic_constructor_check.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "external_cyclic_constructor_check.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/field_decl-expected.txt b/ets2panda/test/parser/ets/field_decl-expected.txt index 7cf0822cd330cbb8928e7c96b92851235f253ee4..0ac292d2ba0ccaca18e2d14abe121b65c93b540f 100644 --- a/ets2panda/test/parser/ets/field_decl-expected.txt +++ b/ets2panda/test/parser/ets/field_decl-expected.txt @@ -753,40 +753,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "field_decl.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "field_decl.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "field_decl.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "field_decl.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/final_empty_class-expected.txt b/ets2panda/test/parser/ets/final_empty_class-expected.txt index 897ecc678ff95e63595d6b058136d553b92f7f5d..81ad39aa373cc319567c25467a5dbfa75e544881 100644 --- a/ets2panda/test/parser/ets/final_empty_class-expected.txt +++ b/ets2panda/test/parser/ets/final_empty_class-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "final_empty_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "final_empty_class.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "final_empty_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "final_empty_class.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/float_pont_format_1-expected.txt b/ets2panda/test/parser/ets/float_pont_format_1-expected.txt index 60b0bd89fd26ec0970877c9f6f2a7e4dc8137325..8fe9b1e9962a77e936d208c9aeaa97d04addfb7f 100644 --- a/ets2panda/test/parser/ets/float_pont_format_1-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/float_pont_format_2-expected.txt b/ets2panda/test/parser/ets/float_pont_format_2-expected.txt index 998ce94b76de1efef40fd972b3645b354f57f587..850d7b2cc21cdb260306e09db04b1f8d9978da7e 100644 --- a/ets2panda/test/parser/ets/float_pont_format_2-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/float_pont_format_3-expected.txt b/ets2panda/test/parser/ets/float_pont_format_3-expected.txt index 34b202049aa053352aa5bf11a20abaa85450f393..21d98fea126358a9f552056842d1764853f957b6 100644 --- a/ets2panda/test/parser/ets/float_pont_format_3-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/float_pont_format_4-expected.txt b/ets2panda/test/parser/ets/float_pont_format_4-expected.txt index 3cb0db53835f90386fed8465ee943d0980352384..db9f5816e99e3ff470ef137a5ab5f83962f47f5b 100644 --- a/ets2panda/test/parser/ets/float_pont_format_4-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/float_pont_format_5-expected.txt b/ets2panda/test/parser/ets/float_pont_format_5-expected.txt index 8c5622f4b6658431536341e6d7c1ab123cdb85b1..5624b9cbb9801ab2ba283cd4d0c32cafb89d83bc 100644 --- a/ets2panda/test/parser/ets/float_pont_format_5-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_5-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/float_pont_format_6-expected.txt b/ets2panda/test/parser/ets/float_pont_format_6-expected.txt index 28bc0ec2a72037d6d612aab0c487b93a312339bf..3a786d9c44513b5e7ae9d0116e1968cca0d82141 100644 --- a/ets2panda/test/parser/ets/float_pont_format_6-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_6-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/float_pont_format_7-expected.txt b/ets2panda/test/parser/ets/float_pont_format_7-expected.txt index 8919c9b1c733c12169ac6bf8c64da38c64b4734c..a913834768cbadcb92d5f7af7976685cae63384e 100644 --- a/ets2panda/test/parser/ets/float_pont_format_7-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_7-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/float_pont_format_8-expected.txt b/ets2panda/test/parser/ets/float_pont_format_8-expected.txt index a9670bf902030eb4e7907f8790b66c4fcb606ea7..f492de68b9ca6acd7130954270fbc7354d6b3a00 100644 --- a/ets2panda/test/parser/ets/float_pont_format_8-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_8-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_pont_format_8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/float_separator_1-expected.txt b/ets2panda/test/parser/ets/float_separator_1-expected.txt index ab9bbcb38c6a6e2a5f995ba40cfe12eeb3431d51..6457c933627ccc964a32a6f6cf2aa211228362df 100644 --- a/ets2panda/test/parser/ets/float_separator_1-expected.txt +++ b/ets2panda/test/parser/ets/float_separator_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_separator_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_separator_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "float_separator_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "float_separator_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/folder_import_index/index-expected.txt b/ets2panda/test/parser/ets/folder_import_index/index-expected.txt index 84d59f60fd396579621eb96c1b71f0662172104b..785feb50d8b955f3bd9945f5673ba0cd39df19a3 100644 --- a/ets2panda/test/parser/ets/folder_import_index/index-expected.txt +++ b/ets2panda/test/parser/ets/folder_import_index/index-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "index.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "index.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "index.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "index.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/for_of-expected.txt b/ets2panda/test/parser/ets/for_of-expected.txt index 7339c6f997222b3dd3470aa346b3948d743251f2..2a62e695955ccc39054ad9b8c5afd0acdcdb5522 100644 --- a/ets2panda/test/parser/ets/for_of-expected.txt +++ b/ets2panda/test/parser/ets/for_of-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "for_of.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "for_of.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "for_of.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "for_of.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -304,23 +270,71 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "for_of.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "for_of.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "for_of.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "for_of.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "for_of.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "for_of.ets" + } + } + }, "loc": { "start": { - "line": 17, - "column": 8, + "line": 1, + "column": 1, "program": "for_of.ets" }, "end": { - "line": 17, - "column": 11, + "line": 1, + "column": 3, "program": "for_of.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/for_with_break-expected.txt b/ets2panda/test/parser/ets/for_with_break-expected.txt index 4bae476c1dce7741d9bdf20e5a92a2b831f7371b..25c3039b126a8e4f19edd8a29bd696b45573fe1a 100644 --- a/ets2panda/test/parser/ets/for_with_break-expected.txt +++ b/ets2panda/test/parser/ets/for_with_break-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "for_with_break.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "for_with_break.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "for_with_break.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "for_with_break.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/forofUnboxing-expected.txt b/ets2panda/test/parser/ets/forofUnboxing-expected.txt index f0c300e6f111ad6e6eeb2b2b4c07d4fe861c8002..10cc306b5c6a136c8ce86b3fb97bdc78927fd3ec 100644 --- a/ets2panda/test/parser/ets/forofUnboxing-expected.txt +++ b/ets2panda/test/parser/ets/forofUnboxing-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "forofUnboxing.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "forofUnboxing.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -306,55 +272,103 @@ "type": "Identifier", "name": "arr", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Long", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 14, - "program": "forofUnboxing.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "forofUnboxing.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "forofUnboxing.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Long", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "forofUnboxing.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "forofUnboxing.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "forofUnboxing.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "forofUnboxing.ets" + } + } }, - "end": { - "line": 18, - "column": 18, - "program": "forofUnboxing.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "forofUnboxing.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "forofUnboxing.ets" + } } } - }, + ], "loc": { "start": { - "line": 18, - "column": 14, + "line": 1, + "column": 3, "program": "forofUnboxing.ets" }, "end": { - "line": 18, - "column": 19, + "line": 1, + "column": 3, "program": "forofUnboxing.ets" } } }, "loc": { "start": { - "line": 18, - "column": 14, + "line": 1, + "column": 1, "program": "forofUnboxing.ets" }, "end": { - "line": 18, - "column": 19, + "line": 1, + "column": 3, "program": "forofUnboxing.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, diff --git a/ets2panda/test/parser/ets/funcParamWithOptionalParam-expected.txt b/ets2panda/test/parser/ets/funcParamWithOptionalParam-expected.txt index 9dbf22528a5abfb8eb02d6858450900657b81fe6..edab393734f36d50bae75bae1ab4bc874c54dacf 100644 --- a/ets2panda/test/parser/ets/funcParamWithOptionalParam-expected.txt +++ b/ets2panda/test/parser/ets/funcParamWithOptionalParam-expected.txt @@ -290,40 +290,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "funcParamWithOptionalParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "funcParamWithOptionalParam.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "funcParamWithOptionalParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "funcParamWithOptionalParam.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/function-expected.txt b/ets2panda/test/parser/ets/function-expected.txt index 9868a881123026ac635ec948127b2858ba5cc58c..eb48d8435216977a2366dadc09fafce98bb24261 100644 --- a/ets2panda/test/parser/ets/function-expected.txt +++ b/ets2panda/test/parser/ets/function-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/functionThrowsRethrows-expected.txt b/ets2panda/test/parser/ets/functionThrowsRethrows-expected.txt index 0120cbfd93949aa0b42cc8772c89bb0047554f57..4d1c381ee196904ffc6c398171ceefcef08d1fd3 100644 --- a/ets2panda/test/parser/ets/functionThrowsRethrows-expected.txt +++ b/ets2panda/test/parser/ets/functionThrowsRethrows-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functionThrowsRethrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functionThrowsRethrows.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functionThrowsRethrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functionThrowsRethrows.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/functionTypeThrows-expected.txt b/ets2panda/test/parser/ets/functionTypeThrows-expected.txt index 3bd94bd73b706a94a87c7fabee22dd5bc548935c..072678965d159e3c7cb183f89f02cf44640dfa82 100644 --- a/ets2panda/test/parser/ets/functionTypeThrows-expected.txt +++ b/ets2panda/test/parser/ets/functionTypeThrows-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functionTypeThrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functionTypeThrows.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "functionTypeThrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "functionTypeThrows.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/function_implicit_return_type5-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type5-expected.txt index fd3c4fb8895239770ad5a245492055a4203888ed..3600cede6a83ba928b55cb26a5a1da322b31cfec 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type5-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type5-expected.txt @@ -316,40 +316,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/function_implicit_return_type6-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type6-expected.txt index 593fa91b788971ff245bfbfb2efdc6219ad43d18..4c8c6eb29bde7ec589d8be0413228b5162c530e6 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type6-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type6-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt index f6d9bcb309e3c66ad2eedafeb39c456417745fd3..4714961b8794da066fa49754609aad26c881d440 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt index a4462069f82ffab5dd243cd1482b8910488382b2..b9502a4e9991e475e49707a18b07c8aafd4b399f 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt @@ -363,40 +363,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "function_implicit_return_type9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/genericDefaultParam_1-expected.txt b/ets2panda/test/parser/ets/genericDefaultParam_1-expected.txt index 0a0e0245b53810f4c136d9343d98b1552325285c..54083cdaef6cf68fdbf96c76c550ddb19222035e 100644 --- a/ets2panda/test/parser/ets/genericDefaultParam_1-expected.txt +++ b/ets2panda/test/parser/ets/genericDefaultParam_1-expected.txt @@ -1592,40 +1592,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "genericDefaultParam_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "genericDefaultParam_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "genericDefaultParam_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "genericDefaultParam_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt b/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt index eb7f758d661fc4b676e475d45ff8a8e16d5ad88e..dba63f998451e4d55521c3841bd2730a2ad37bd1 100644 --- a/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt +++ b/ets2panda/test/parser/ets/genericDefaultParam_3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "genericDefaultParam_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "genericDefaultParam_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "genericDefaultParam_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "genericDefaultParam_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generic_function-expected.txt b/ets2panda/test/parser/ets/generic_function-expected.txt index bf8117a25f65422e9919b1c6245215956619c4c9..7259f200d0402a71cf6896370fa1f162a9afcdde 100644 --- a/ets2panda/test/parser/ets/generic_function-expected.txt +++ b/ets2panda/test/parser/ets/generic_function-expected.txt @@ -290,40 +290,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_function.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generic_resolve-expected.txt b/ets2panda/test/parser/ets/generic_resolve-expected.txt index 3dec4cc80aa9eb40f106e4ce79ce50400eeabe52..d3b80a2c42b7242f0f7060e95f501512f4a3df4f 100644 --- a/ets2panda/test/parser/ets/generic_resolve-expected.txt +++ b/ets2panda/test/parser/ets/generic_resolve-expected.txt @@ -1365,40 +1365,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_resolve.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_resolve.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generic_resolve.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generic_resolve.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_2-expected.txt b/ets2panda/test/parser/ets/generics_2-expected.txt index b990e08aad6e7322bc4e67c642288f45f0900071..8249c4cb803ec04427fea47b2f0afb2a25762dbc 100644 --- a/ets2panda/test/parser/ets/generics_2-expected.txt +++ b/ets2panda/test/parser/ets/generics_2-expected.txt @@ -1477,40 +1477,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_3-expected.txt b/ets2panda/test/parser/ets/generics_3-expected.txt index c236d59af0c46111f68af982c76a77f359eb9598..420b5968fa2217f13c5ede5819766b835667e9b2 100644 --- a/ets2panda/test/parser/ets/generics_3-expected.txt +++ b/ets2panda/test/parser/ets/generics_3-expected.txt @@ -259,40 +259,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_4-expected.txt b/ets2panda/test/parser/ets/generics_4-expected.txt index 2cdbf80fc82c214b917a4e4a67139e93fed2fb23..be1b9816a89d5839ec6001efb58298a6c1d3c2d3 100644 --- a/ets2panda/test/parser/ets/generics_4-expected.txt +++ b/ets2panda/test/parser/ets/generics_4-expected.txt @@ -291,40 +291,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_5-expected.txt b/ets2panda/test/parser/ets/generics_5-expected.txt index 11cdf6c52fdb8e13a1761e3d045d9f7c25bf8288..246ddfa0a48ad8299e9df8b23e2ca26a9c5d84db 100644 --- a/ets2panda/test/parser/ets/generics_5-expected.txt +++ b/ets2panda/test/parser/ets/generics_5-expected.txt @@ -227,40 +227,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_6-expected.txt b/ets2panda/test/parser/ets/generics_6-expected.txt index 766006a59cc106a8f73235f7920e184c48535c36..2cfd7603b00e09df6b9f38b541842ebf37132dca 100644 --- a/ets2panda/test/parser/ets/generics_6-expected.txt +++ b/ets2panda/test/parser/ets/generics_6-expected.txt @@ -463,40 +463,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_7-expected.txt b/ets2panda/test/parser/ets/generics_7-expected.txt index 31071ab8c2f109216d4623cd334a059697118cbc..4df7ac16fa3a047812b4eff73b1eabbd837b9c0f 100644 --- a/ets2panda/test/parser/ets/generics_7-expected.txt +++ b/ets2panda/test/parser/ets/generics_7-expected.txt @@ -463,40 +463,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_recursive-expected.txt b/ets2panda/test/parser/ets/generics_recursive-expected.txt index 16137aae7c672e16d7baba6fd34215ede19d61c1..d12bab322896a2bc574f870ad92bbb28416d781d 100644 --- a/ets2panda/test/parser/ets/generics_recursive-expected.txt +++ b/ets2panda/test/parser/ets/generics_recursive-expected.txt @@ -3110,40 +3110,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_recursive.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_recursive.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_recursive.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_recursive.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_1-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_1-expected.txt index cf9d430a5f76e446963df7e3d2b968fa11d2f031..ee6dbbddaa354b9e004dba9a1fcc5f9f73984e12 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_1-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_1-expected.txt @@ -338,40 +338,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_10-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_10-expected.txt index 2278fb7e08d410f596f4cdfaad8546532eb9ae59..4d3683d337ca1634e40e543bb99b80fc1ee8165d 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_10-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_10-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_10.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_10.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_11-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_11-expected.txt index 22459de1e9e0f1c469bded453823e5fe886d91f4..008accd3f114004517066a6abcfc4ddfd455f9cf 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_11-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_11-expected.txt @@ -1115,40 +1115,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_11.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_11.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_11.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_11.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_12-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_12-expected.txt index ad4fd202f0696753b43e13966018f85eec354564..e939edf546f8b500265917a2b1c6e5a4bca6735b 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_12-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_12-expected.txt @@ -1074,40 +1074,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_12.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_12.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_2-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_2-expected.txt index 928a2986aa6a467666cd0c438ce736085dd0ca29..3e279d79a35d8b71db0e20e479b54cf936bea879 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_2-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_2-expected.txt @@ -232,40 +232,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_3-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_3-expected.txt index 65b85878ff7e2eaa83c48bd55389c2bd76fe13ca..0c8ae7c3b3b068ab2a5432a74b882a2ad04a8ff4 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_3-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_4-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_4-expected.txt index e4ca0a5d567ac91f98ea3ac0f5acaf8aa7f08f72..ae119ef2ffb03d9629be285eb0151eb0f94c9342 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_4-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_4-expected.txt @@ -622,40 +622,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_5-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_5-expected.txt index 8254fba30b9a9b6de469df5a2652301d128f3f40..01493e7a88764de87dfe6e2bc2dc50f320a460aa 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_5-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_5-expected.txt @@ -918,40 +918,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_6-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_6-expected.txt index ce209704a382fa00e4bde10d7d80a0e518a33f4e..6020eed9e913e61bbb522c0458ecd59148df883e 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_6-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_6-expected.txt @@ -370,40 +370,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_7-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_7-expected.txt index 68da51bc46530c74c62ea45cf054471d1174c47e..2b3d80beb972a10410af9d52ae42d3e8dc35cf19 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_7-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_7-expected.txt @@ -338,40 +338,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/generics_type_param_constraint_9-expected.txt b/ets2panda/test/parser/ets/generics_type_param_constraint_9-expected.txt index a68b85635f9669d3d4012f887d7b6534b636fcfd..2e9f5872ee6dc26cb919444ca8fbf310dd6c5785 100644 --- a/ets2panda/test/parser/ets/generics_type_param_constraint_9-expected.txt +++ b/ets2panda/test/parser/ets/generics_type_param_constraint_9-expected.txt @@ -807,40 +807,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "generics_type_param_constraint_9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/getterOverride-expected.txt b/ets2panda/test/parser/ets/getterOverride-expected.txt index d0f4bfaf4b1091783493246852fff7a1baa16f03..64aef4f75fb0189142e8f69b1c6e06addc5ebc4d 100644 --- a/ets2panda/test/parser/ets/getterOverride-expected.txt +++ b/ets2panda/test/parser/ets/getterOverride-expected.txt @@ -132,13 +132,13 @@ "decorators": [], "loc": { "start": { - "line": 19, - "column": 1, + "line": 18, + "column": 15, "program": "getterOverride.ets" }, "end": { "line": 18, - "column": 15, + "column": 26, "program": "getterOverride.ets" } } @@ -613,40 +613,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "getterOverride.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "getterOverride.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "getterOverride.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "getterOverride.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/getter_setter_access_modifiers-expected.txt b/ets2panda/test/parser/ets/getter_setter_access_modifiers-expected.txt index 8fbef5c9edbf56a921ab52fb78fc4540a647d0e4..25155cb55341d4b606b596af3a75e6c12be927d6 100644 --- a/ets2panda/test/parser/ets/getter_setter_access_modifiers-expected.txt +++ b/ets2panda/test/parser/ets/getter_setter_access_modifiers-expected.txt @@ -1965,40 +1965,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "getter_setter_access_modifiers.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "getter_setter_access_modifiers.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "getter_setter_access_modifiers.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "getter_setter_access_modifiers.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/globalVarInLambdaInStatic-expected.txt b/ets2panda/test/parser/ets/globalVarInLambdaInStatic-expected.txt index c8f594842aa638b9506cc6b7b180179ad2770d7c..08a8f0e8bb4edeb2ea6a1e2c20d70d4d11020475 100644 --- a/ets2panda/test/parser/ets/globalVarInLambdaInStatic-expected.txt +++ b/ets2panda/test/parser/ets/globalVarInLambdaInStatic-expected.txt @@ -956,40 +956,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "globalVarInLambdaInStatic.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "globalVarInLambdaInStatic.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "globalVarInLambdaInStatic.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "globalVarInLambdaInStatic.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/global_const_vars3-expected.txt b/ets2panda/test/parser/ets/global_const_vars3-expected.txt index 360b8aef03206f28abe32b6c9d6997e068954d41..03532089003d8b41bb581d0b4bc225bf2026d151 100644 --- a/ets2panda/test/parser/ets/global_const_vars3-expected.txt +++ b/ets2panda/test/parser/ets/global_const_vars3-expected.txt @@ -531,40 +531,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "global_const_vars3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "global_const_vars3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "global_const_vars3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "global_const_vars3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/identifier-expected.txt b/ets2panda/test/parser/ets/identifier-expected.txt index 634e81407cfc53d4c8d735de8427e9d2546987c9..6769831643a9150e88a9bf76151de83a97e006ad 100644 --- a/ets2panda/test/parser/ets/identifier-expected.txt +++ b/ets2panda/test/parser/ets/identifier-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "identifier.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "identifier.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "identifier.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "identifier.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/if-expected.txt b/ets2panda/test/parser/ets/if-expected.txt index 0da4a587bc632ef1891ba8bf0b60b22baed8ffd1..5191a792b878b7fa3b848409529b0bf4776be038 100644 --- a/ets2panda/test/parser/ets/if-expected.txt +++ b/ets2panda/test/parser/ets/if-expected.txt @@ -3022,40 +3022,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "if.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "if.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "if.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "if.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/ifs-expected.txt b/ets2panda/test/parser/ets/ifs-expected.txt index a074772a703dff74af66aa441628ac67a13c2244..2718e28ed7e5ed16a87fa03a94eb1d53e181c639 100644 --- a/ets2panda/test/parser/ets/ifs-expected.txt +++ b/ets2panda/test/parser/ets/ifs-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ifs.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ifs.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ifs.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ifs.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_conts-expected.txt b/ets2panda/test/parser/ets/import_conts-expected.txt index ce8a79ea7726edfc2631b542c8632b575f5a3929..8254df01f76c4e2fa27841704718dcc459fbffb3 100644 --- a/ets2panda/test/parser/ets/import_conts-expected.txt +++ b/ets2panda/test/parser/ets/import_conts-expected.txt @@ -252,40 +252,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_conts.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_conts.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_conts.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_conts.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_folder-expected.txt b/ets2panda/test/parser/ets/import_folder-expected.txt index 9de65377ef3288307f0e6a9818417aba14314981..9e34c3fef47c5b18fe348b35765d067c61754922 100644 --- a/ets2panda/test/parser/ets/import_folder-expected.txt +++ b/ets2panda/test/parser/ets/import_folder-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_folder.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_folder.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_folder.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_folder.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/check_exported_2-expected.txt b/ets2panda/test/parser/ets/import_tests/check_exported_2-expected.txt index 3b29f0f918a7bcd59029ec9db52ae0b3e37ff11b..e102397efdb8caa279fd45caac913703aa9fd2ef 100644 --- a/ets2panda/test/parser/ets/import_tests/check_exported_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/check_exported_2-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "check_exported_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "check_exported_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "check_exported_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "check_exported_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/check_exported_3-expected.txt b/ets2panda/test/parser/ets/import_tests/check_exported_3-expected.txt index 9d8be056c32d06a8c2ecbd44e0b09ce70aef3ca1..2e90889a67667c6ca5f944c4dd617f310e701cc1 100644 --- a/ets2panda/test/parser/ets/import_tests/check_exported_3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/check_exported_3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "check_exported_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "check_exported_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "check_exported_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "check_exported_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/check_exported_default_class-expected.txt b/ets2panda/test/parser/ets/import_tests/check_exported_default_class-expected.txt index ae3209395c5625e7349e3f58070f7cbb0fe989bd..298a6f3d02f8791027dc81e67f0a2c33c82db7a6 100644 --- a/ets2panda/test/parser/ets/import_tests/check_exported_default_class-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/check_exported_default_class-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "check_exported_default_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "check_exported_default_class.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "check_exported_default_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "check_exported_default_class.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/default_import-expected.txt b/ets2panda/test/parser/ets/import_tests/default_import-expected.txt index bd3cf2db15abcaa4140a617729c390b1a9cbd516..b21ecc82955397873f9c3d273fef8d75acba2cfa 100644 --- a/ets2panda/test/parser/ets/import_tests/default_import-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/default_import-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_import.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_import.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_import.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_import.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/diamond/test1-expected.txt b/ets2panda/test/parser/ets/import_tests/diamond/test1-expected.txt index d206b1b2b9a9635aa146e601945fc9786b87e192..310273526fb9b688faed64711c32f1671ba5db50 100644 --- a/ets2panda/test/parser/ets/import_tests/diamond/test1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/diamond/test1-expected.txt @@ -187,40 +187,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/diamond/test2-expected.txt b/ets2panda/test/parser/ets/import_tests/diamond/test2-expected.txt index fb58025c74ac88f06aeadf1a970a9e7e17eeb2f1..7addb009673acabf93e32801cec4c8ad914e9d4c 100644 --- a/ets2panda/test/parser/ets/import_tests/diamond/test2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/diamond/test2-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/diamond/test3-expected.txt b/ets2panda/test/parser/ets/import_tests/diamond/test3-expected.txt index 9c90792f6b30239b563bf209f4ef53ed29267b3a..af733650c9ad49de4c7b752620baef3c2a0b63c9 100644 --- a/ets2panda/test/parser/ets/import_tests/diamond/test3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/diamond/test3-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/diamond/test4-expected.txt b/ets2panda/test/parser/ets/import_tests/diamond/test4-expected.txt index 9b415c0172496479bd76c40946080daf6dc9e1ed..ae9ea1042baa68f6fab3f6e266f2d110f77372e3 100644 --- a/ets2panda/test/parser/ets/import_tests/diamond/test4-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/diamond/test4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/duplicated/classdef-expected.txt b/ets2panda/test/parser/ets/import_tests/duplicated/classdef-expected.txt index aaed83bac713347c35f4139bf75bb50a967ee9b5..45ab9481057374835bd2a65e338d4e55b526b551 100644 --- a/ets2panda/test/parser/ets/import_tests/duplicated/classdef-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/duplicated/classdef-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "classdef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "classdef.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "classdef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "classdef.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/duplicated/extdef-expected.txt b/ets2panda/test/parser/ets/import_tests/duplicated/extdef-expected.txt index 96a8085659243c7af8a4dbef4dd8cbe1cbdf7542..0989c4685e0b956abae4fa6b311ab01976702606 100644 --- a/ets2panda/test/parser/ets/import_tests/duplicated/extdef-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/duplicated/extdef-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "extdef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "extdef.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "extdef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "extdef.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/duplicated/extusedef-expected.txt b/ets2panda/test/parser/ets/import_tests/duplicated/extusedef-expected.txt index e39395a49011da97ee40ba26180fb3249bcfe8f0..75b4a52596202adc75c6909bea482c59f375d53f 100644 --- a/ets2panda/test/parser/ets/import_tests/duplicated/extusedef-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/duplicated/extusedef-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "extusedef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "extusedef.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "extusedef.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "extusedef.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/export_type_alias-expected.txt b/ets2panda/test/parser/ets/import_tests/export_type_alias-expected.txt index e76e89049c38a1cbb2af72612f0b2422c2a39d3a..06d45cc4bdc49097c22bf06f570ca72d1ef2cfb2 100644 --- a/ets2panda/test/parser/ets/import_tests/export_type_alias-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/export_type_alias-expected.txt @@ -304,40 +304,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_type_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_type_alias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_type_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_type_alias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/folderWithoutIndexOrPackage/separate_module-expected.txt b/ets2panda/test/parser/ets/import_tests/folderWithoutIndexOrPackage/separate_module-expected.txt index 22b116782a1fc886e56f83a96d30cb23e910c637..fbcfef566b7a19cc028502eeccc8eca8d5c5226f 100644 --- a/ets2panda/test/parser/ets/import_tests/folderWithoutIndexOrPackage/separate_module-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/folderWithoutIndexOrPackage/separate_module-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "separate_module.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "separate_module.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "separate_module.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "separate_module.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_alias/export-expected.txt b/ets2panda/test/parser/ets/import_tests/import_alias/export-expected.txt index 8c69d07e4a3c176021b3c903058248403606aa24..26bd73fa077f6943011746112ba320e5acf23ff8 100644 --- a/ets2panda/test/parser/ets/import_tests/import_alias/export-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_alias/export-expected.txt @@ -545,40 +545,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_1-expected.txt index b1cfc1e8cad5050a0fff5533baca149f77c9893c..4b4b585589fc0f87f0b2a0ad17a8577a5ff87f7b 100644 --- a/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_alias/import_alias_1-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_alias_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_alias_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_1-expected.txt index 868f3fe857b99c4bd0b1bf473f8d07df6e85b6b7..48779566b1cfb47a37a0f71d1146fb6e409f37c8 100644 --- a/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_1-expected.txt @@ -170,40 +170,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_2-expected.txt index 2519966845ea6550fa2344f2d1eb089e98a3841e..b8ea87e11f5159db2c09e34ccc490fbd843272ae 100644 --- a/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_2-expected.txt @@ -252,40 +252,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_3-expected.txt b/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_3-expected.txt index 0162f6fc1b0edca56357d795d5eecf8ce80ac088..c7f28116554d43d14d747f8d569480647916ab25 100644 --- a/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_alias_and_without_alias_3-expected.txt @@ -252,40 +252,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_alias_and_without_alias_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_all-expected.txt b/ets2panda/test/parser/ets/import_tests/import_all-expected.txt index b2918d592e2e048ab8b613ec5821db79bf04270f..be878c9f406c944041621c47a9d78c14a2ec662e 100755 --- a/ets2panda/test/parser/ets/import_tests/import_all-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_all-expected.txt @@ -153,40 +153,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_all.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_all.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_all.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_all.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_all_3-expected.txt b/ets2panda/test/parser/ets/import_tests/import_all_3-expected.txt index 02172d4ee6a20104de43c274b93e15462b7290ec..54bfc27c40ad820735f7bc8f69371a41e2b557a1 100644 --- a/ets2panda/test/parser/ets/import_tests/import_all_3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_all_3-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_all_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_all_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_all_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_all_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_all_alias_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_all_alias_1-expected.txt index 71cf7b0b9bb720a3f698acd8513b943938d98cff..b048ff97aa870ac3fd6029cd948caf99b322e70e 100644 --- a/ets2panda/test/parser/ets/import_tests/import_all_alias_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_all_alias_1-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_all_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_all_alias_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_all_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_all_alias_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt b/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt index 4d8cf0ac9a5ebd65b9e71c5f68929397eceee72c..68fb4cac4050aae24c30ff442ed1ad343f2d7998 100644 --- a/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_all_type_alias-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_all_type_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_all_type_alias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_all_type_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_all_type_alias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_diff_paths-expected.txt b/ets2panda/test/parser/ets/import_tests/import_diff_paths-expected.txt index fb689356eb000fcc551eafaa081a614e0ccea2a3..813b3fb1ba9338ea6f54d3346a03c73ccd320526 100644 --- a/ets2panda/test/parser/ets/import_tests/import_diff_paths-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_diff_paths-expected.txt @@ -187,40 +187,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_diff_paths.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_diff_paths.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_diff_paths.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_diff_paths.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_extension/import_extension-expected.txt b/ets2panda/test/parser/ets/import_tests/import_extension/import_extension-expected.txt index 5db624fe5a67902038077f7d3116c3a8ffd182ae..971b99fd70e44f6f0e9fbe7780b7e67d7f7b7b85 100644 --- a/ets2panda/test/parser/ets/import_tests/import_extension/import_extension-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_extension/import_extension-expected.txt @@ -187,40 +187,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_extension.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_extension.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_extension.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_extension.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_extension/import_extension_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_extension/import_extension_1-expected.txt index 9d5f573f70473abb5bc2f5bc55641fbcd1205073..4dbe29d09cb5cc8c890c57f9b54ff7560095440b 100644 --- a/ets2panda/test/parser/ets/import_tests/import_extension/import_extension_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_extension/import_extension_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_extension_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_extension_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_extension_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_extension_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_extension/import_extension_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_extension/import_extension_2-expected.txt index 74d44f589fa1ee7c3c47c1d84eaa70c4176c1f4c..a6b21c9fceed3bbf7ad918ec1edf8c8d07f4dcf3 100644 --- a/ets2panda/test/parser/ets/import_tests/import_extension/import_extension_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_extension/import_extension_2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_extension_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_extension_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_extension_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_extension_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_function_overload-expected.txt b/ets2panda/test/parser/ets/import_tests/import_function_overload-expected.txt index ba2f99e358cf9494046e854ac627cb9ca9cd37c1..43bc9c4d8f3e007100349cd24ac5ac7c9730d772 100644 --- a/ets2panda/test/parser/ets/import_tests/import_function_overload-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_function_overload-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_function_overload.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_function_overload.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_function_overload.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_function_overload.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_interface_test-expected.txt b/ets2panda/test/parser/ets/import_tests/import_interface_test-expected.txt index 2edbe742e56618dbef3033e69f94db83fd2c1a99..5bc050082359f265b9410ad968bec2c293887588 100644 --- a/ets2panda/test/parser/ets/import_tests/import_interface_test-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_interface_test-expected.txt @@ -558,40 +558,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_interface_test.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_interface_test.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_interface_test.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_interface_test.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_interface_test_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_interface_test_1-expected.txt index 25906641fd3b2c0ca17c205b06bbce888b05a6b5..579475c53ee6f1577cb5491854af28e77418a9f6 100644 --- a/ets2panda/test/parser/ets/import_tests/import_interface_test_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_interface_test_1-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_interface_test_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_interface_test_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_interface_test_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_interface_test_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_interface_test_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_interface_test_2-expected.txt index 83d1ad8343b955006975c1044dc590f3f7b44026..451905f99ca205b777600e0ad655a8b5cd8ea633 100644 --- a/ets2panda/test/parser/ets/import_tests/import_interface_test_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_interface_test_2-expected.txt @@ -476,40 +476,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_interface_test_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_interface_test_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_interface_test_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_interface_test_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_max_as_alias-expected.txt b/ets2panda/test/parser/ets/import_tests/import_max_as_alias-expected.txt index f90ac8478f3758e26f0d1ae2c0a56886f0bcaeec..a22980af7b2e411e2c5d910e61b4dcd6ccea8392 100644 --- a/ets2panda/test/parser/ets/import_tests/import_max_as_alias-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_max_as_alias-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_max_as_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_max_as_alias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_max_as_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_max_as_alias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_name_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_name_1-expected.txt index 06fec81fb7b0c7950ee41176cfee627efc789814..3499dcfc7fd60e9f8d4fc22c4c6c96714937bd52 100755 --- a/ets2panda/test/parser/ets/import_tests/import_name_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_name_1-expected.txt @@ -203,40 +203,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_name_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_name_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_name_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_name_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_name_alias_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_name_alias_1-expected.txt index 6a9fee2c6e99e88a83b2bc37935a9e19702c78b8..699ce235c23a14da42c23967117ce9ceaf2c947d 100755 --- a/ets2panda/test/parser/ets/import_tests/import_name_alias_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_name_alias_1-expected.txt @@ -203,40 +203,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_name_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_name_alias_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_name_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_name_alias_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_1-expected.txt index dd796e2d0b7f1a08cd82ff6c76afe0f616cb2025..2e79b56dc3ff735c402ae9f4ebeabf7cd28bdddf 100644 --- a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_1-expected.txt @@ -388,40 +388,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "imported_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "imported_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "imported_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "imported_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt index 8a943aad19cb4a4e48247c462f44758eb0c53937..0f0b79893122df041613b015175524007968a109 100644 --- a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt @@ -388,40 +388,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "imported_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "imported_module_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "imported_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "imported_module_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_relative_path-expected.txt b/ets2panda/test/parser/ets/import_tests/import_relative_path-expected.txt index 232ea6c2cfb09136b2466dbdc976ada937b26ba2..9b428c93593306a1c143e88f4470518c78df09f9 100755 --- a/ets2panda/test/parser/ets/import_tests/import_relative_path-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_relative_path-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_relative_path.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_relative_path.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_relative_path.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_relative_path.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_several_1-expected.txt b/ets2panda/test/parser/ets/import_tests/import_several_1-expected.txt index f777e0c6216f9b869663b9bfbec75748fe56f124..edb6fdc92f042580ebfcad4ccdae03c5f457e641 100755 --- a/ets2panda/test/parser/ets/import_tests/import_several_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_several_1-expected.txt @@ -269,40 +269,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_several_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_several_2-expected.txt index c192825029093d8757f103581a41982645339950..01ca05519b024cfbeb301f4401fa6d4b04a19757 100755 --- a/ets2panda/test/parser/ets/import_tests/import_several_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_several_2-expected.txt @@ -154,40 +154,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_several_3-expected.txt b/ets2panda/test/parser/ets/import_tests/import_several_3-expected.txt index f5991c6b9885fa85ac95a88c32c972e29a5364b8..c3b5aca8114dce64b740f93a683c9e72bf064711 100755 --- a/ets2panda/test/parser/ets/import_tests/import_several_3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_several_3-expected.txt @@ -170,40 +170,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_several_4-expected.txt b/ets2panda/test/parser/ets/import_tests/import_several_4-expected.txt index 04a6536a8affa85eec64d2f0aeafa79d5fbb48fa..e976815b59f7d83d56178f7ca070a275b3e5070d 100644 --- a/ets2panda/test/parser/ets/import_tests/import_several_4-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_several_4-expected.txt @@ -170,40 +170,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_several_5-expected.txt b/ets2panda/test/parser/ets/import_tests/import_several_5-expected.txt index a3d207dce5938a607d3536ae5a2fe33adeeb1866..46b8037c4a2b34d01dd54ed15a7f46780f42acff 100755 --- a/ets2panda/test/parser/ets/import_tests/import_several_5-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_several_5-expected.txt @@ -170,40 +170,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_several_6-expected.txt b/ets2panda/test/parser/ets/import_tests/import_several_6-expected.txt index 9058b0a9108ab69a12e1eb079bf842eb6dd4e8ce..416b7f399cac4def13378a104dae530e3c86e2b1 100644 --- a/ets2panda/test/parser/ets/import_tests/import_several_6-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_several_6-expected.txt @@ -170,40 +170,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_several_7-expected.txt b/ets2panda/test/parser/ets/import_tests/import_several_7-expected.txt index a52b745a00d723b4cdfe443c123b20043a039e63..1a2800e1664ac1484c3fe2aa4f6a0dbfc42dde01 100755 --- a/ets2panda/test/parser/ets/import_tests/import_several_7-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_several_7-expected.txt @@ -252,40 +252,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_several_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_several_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/import_ts_file-expected.txt b/ets2panda/test/parser/ets/import_tests/import_ts_file-expected.txt index 8da3fb09cfd9d70bbbdd8f42909c5b11f60e0612..3904e7e7eec219ac0868d0373655408eecefffe9 100644 --- a/ets2panda/test/parser/ets/import_tests/import_ts_file-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_ts_file-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_ts_file.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_ts_file.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_ts_file.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_ts_file.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/internals-expected.txt b/ets2panda/test/parser/ets/import_tests/internals-expected.txt index 9a5f2a2c8613e58825d8b011287adbcf7968addf..4a28ca1e149499bb298b6e82d42c6c65615bb347 100644 --- a/ets2panda/test/parser/ets/import_tests/internals-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/internals-expected.txt @@ -539,40 +539,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "internals.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "internals.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "internals.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "internals.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/modules/class_default_module-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/class_default_module-expected.txt index 39b58715e373a79099a03270a37bdd4b7c77ae06..ea653065a6b4196b35054f983418850c4dd5eedc 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/class_default_module-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/class_default_module-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_default_module.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_default_module.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "class_default_module.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "class_default_module.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/modules/default_export-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/default_export-expected.txt index be8dc6e85fe5554300ba10fa54a7a33687754447..a14dec67cfa5fa1ffce0835ab5366ccc92a50f1e 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/default_export-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/default_export-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "default_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "default_export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/modules/missing_default_export-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/missing_default_export-expected.txt index 421aecc8ccf016a149aa3e65225a2f1e10a1712b..8ea40b2a5b3677f8a1aa7cd365aee45fe823b748 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/missing_default_export-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/missing_default_export-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "missing_default_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "missing_default_export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "missing_default_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "missing_default_export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file-expected.txt index e9f8bc4904110cc850d9c91ade6bddcf71daf397..51dad8f55e1291a903b43b64994562041f2a6654 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/module1/src/export_file-expected.txt @@ -102,40 +102,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_file.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_file.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_file.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_file.ets" - } - } - } - ], "body": [], "loc": { "start": { diff --git a/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file-expected.txt index c77d001687ebdd39aebdb6eb97443d1f6b69ff69..2f47549c0300aa270098380e7c28dc38bc161e95 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/module1/src/re_export_file-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_file.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_file.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_file.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_file.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file-expected.txt index 27b839d255f90fb08169aa0e4803b0c1c390cb3d..35f9aeb7455370b0e8a95f36e57ea7fafa9daaf3 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/module2/src/import_file-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_file.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_file.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_file.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_file.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file_2-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file_2-expected.txt index edccc0fb4e4633c56a0c3c94d51ace31f1c8d619..3c5cf52b91dfeae9d714d217cae5dfad61dc5324 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/module2/src/re_export_file_2-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_file_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_file_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_file_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_file_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/modules/test_lib1-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/test_lib1-expected.txt index fc3892cbdd5ff721ea52da23291338703de69d1c..00ac903d15b8a3daf46ec1f7bcf562a6c5644614 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/test_lib1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/test_lib1-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_lib1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_lib1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_lib1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_lib1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/modules/test_lib2-expected.txt b/ets2panda/test/parser/ets/import_tests/modules/test_lib2-expected.txt index 7f735aec9c3b722c7542ee7efde884ccf85eb9f7..c9903696aa18475c34e7aca7826ad8f0211a9cf5 100644 --- a/ets2panda/test/parser/ets/import_tests/modules/test_lib2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/modules/test_lib2-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_lib2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_lib2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_lib2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_lib2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/aliasWithoutAlias/import1/import1-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/aliasWithoutAlias/import1/import1-expected.txt index 912f41c9df1f6b8653236835a13ded2af2a1911a..f977566c955dd8f2b60a3a6f20b83bc6dc8dfece 100644 --- a/ets2panda/test/parser/ets/import_tests/packages/aliasWithoutAlias/import1/import1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/aliasWithoutAlias/import1/import1-expected.txt @@ -151,40 +151,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/aliasWithoutAlias/import2/import2-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/aliasWithoutAlias/import2/import2-expected.txt index 5ae16ba400c633ad3c0b80f3006cb68d08a14278..a62db9b7c233ba0bc47f3881be64ac11a2f37fe0 100644 --- a/ets2panda/test/parser/ets/import_tests/packages/aliasWithoutAlias/import2/import2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/aliasWithoutAlias/import2/import2-expected.txt @@ -151,40 +151,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/import_package_with_alias/import_package_with_alias-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/import_package_with_alias/import_package_with_alias-expected.txt index 06e9d2f75d5ba8a39d0cb14954b805f4f55c3f78..5ddf6d66a26a2fa7e652cbb440998a22260db69d 100644 --- a/ets2panda/test/parser/ets/import_tests/packages/import_package_with_alias/import_package_with_alias-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/import_package_with_alias/import_package_with_alias-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_package_with_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_package_with_alias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_package_with_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_package_with_alias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/import_package_with_alias/package/package_module-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/import_package_with_alias/package/package_module-expected.txt index 03819abd362046ccc6a01044326615eb886428a3..75cec07cb7a8f285380dce8a1b5d41e774a41803 100644 --- a/ets2panda/test/parser/ets/import_tests/packages/import_package_with_alias/package/package_module-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/import_package_with_alias/package/package_module-expected.txt @@ -55,40 +55,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt index c516fe31e5b8bfd5219f1f37b50e87a2f3112d11..b2003212002cfd90f02b6e95f55be89e306fd67b 100755 --- a/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt @@ -87,40 +87,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt index 06983d15e23dce172c179d99ff3077286906f833..b1d61276d998f51f6b8cece64749b90610cecfc8 100755 --- a/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt @@ -87,40 +87,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/subpackage-1/package_module_1-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/subpackage-1/package_module_1-expected.txt index 2e018cfa70c1385fcca6a8e9b0683cdc47f0c63f..e25f40ef08f2387215387e4e4b0e648511b6aeed 100644 --- a/ets2panda/test/parser/ets/import_tests/packages/subpackage-1/package_module_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/subpackage-1/package_module_1-expected.txt @@ -119,40 +119,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/subpackage-2/package_module_1-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/subpackage-2/package_module_1-expected.txt index faed71de21c168571bf2527af28eb64e4f2bc184..36d18749fb5a40143cc1c99179ae258d2bebb331 100644 --- a/ets2panda/test/parser/ets/import_tests/packages/subpackage-2/package_module_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/subpackage-2/package_module_1-expected.txt @@ -119,40 +119,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/subpackage/package_module_1-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/subpackage/package_module_1-expected.txt index 943d6415c4b5cf671df0945ee029cadbd18a1e0b..23880329309cd698d4b04f280634040628e546ed 100644 --- a/ets2panda/test/parser/ets/import_tests/packages/subpackage/package_module_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/subpackage/package_module_1-expected.txt @@ -119,40 +119,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "package_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/var-duplication/subpackage_module_1-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/var-duplication/subpackage_module_1-expected.txt index f17b659ea56106ef6d4d6dba6bca90fa22c4019d..f1c13672b849b0a8b2738e0f9ed745d6f58ae467 100755 --- a/ets2panda/test/parser/ets/import_tests/packages/var-duplication/subpackage_module_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/var-duplication/subpackage_module_1-expected.txt @@ -119,40 +119,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "subpackage_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "subpackage_module_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "subpackage_module_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "subpackage_module_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/packages/var-duplication/subpackage_module_2-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/var-duplication/subpackage_module_2-expected.txt index 4a8394e434d1966bdada333fc10554bb4bd1136f..7630965a4faf2357fef4906e6e6a94587df59d76 100755 --- a/ets2panda/test/parser/ets/import_tests/packages/var-duplication/subpackage_module_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/var-duplication/subpackage_module_2-expected.txt @@ -119,40 +119,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "subpackage_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "subpackage_module_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "subpackage_module_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "subpackage_module_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/relative_import/Line-expected.txt b/ets2panda/test/parser/ets/import_tests/relative_import/Line-expected.txt index 02e2a98f923c3c579ce06d20775d823393f98e27..c0ef3b977788d839874ca3125fa2395e857a1d24 100644 --- a/ets2panda/test/parser/ets/import_tests/relative_import/Line-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/relative_import/Line-expected.txt @@ -789,40 +789,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Line.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Line.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Line.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Line.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/relative_import/Point-expected.txt b/ets2panda/test/parser/ets/import_tests/relative_import/Point-expected.txt index e92093a8546d412a3a00cec77567b55f8555063b..32b77957aadcbec05a401dc6b1fadfa93d3b768c 100644 --- a/ets2panda/test/parser/ets/import_tests/relative_import/Point-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/relative_import/Point-expected.txt @@ -990,40 +990,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Point.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Point.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "Point.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "Point.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/relative_import/alias1-expected.txt b/ets2panda/test/parser/ets/import_tests/relative_import/alias1-expected.txt index a0c46fa4ca903f68f54158ac4c4381a35a921c2c..6d280e0677e32ae14b1580317930550a3026eeae 100644 --- a/ets2panda/test/parser/ets/import_tests/relative_import/alias1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/relative_import/alias1-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "alias1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "alias1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "alias1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "alias1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/relative_import/alias2-expected.txt b/ets2panda/test/parser/ets/import_tests/relative_import/alias2-expected.txt index f24ff30d9087162c31da499f7fffc459f6c24f63..932b2116bf48f37c12d56909b20b4f2d75f0d193 100644 --- a/ets2panda/test/parser/ets/import_tests/relative_import/alias2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/relative_import/alias2-expected.txt @@ -284,40 +284,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "alias2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "alias2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "alias2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "alias2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/repeat-expected.txt b/ets2panda/test/parser/ets/import_tests/repeat-expected.txt index 186c68673b99cd5e802e427555fcbb2ee369f564..e16b9ca6c17b1d1887cc62a1d7d5e87db3c579de 100644 --- a/ets2panda/test/parser/ets/import_tests/repeat-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/repeat-expected.txt @@ -545,40 +545,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "repeat.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "repeat.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "repeat.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "repeat.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder1/file1-expected.txt b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder1/file1-expected.txt index d0ad5d66da1a0c3ac1d5d06b2691cddf10d06c6a..edfa30e973ee4c8e41a43e3b6f95d46de88e027f 100644 --- a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder1/file1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder1/file1-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "file1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "file1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "file1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "file1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder2/file2-expected.txt b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder2/file2-expected.txt index 6b8d75ba71a44e80915705da718113776022612d..ae41b07faede719ec2687a712c840acb7a3038e4 100644 --- a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder2/file2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder2/file2-expected.txt @@ -260,40 +260,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "file2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "file2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "file2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "file2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder3/file3-expected.txt b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder3/file3-expected.txt index f7e13e81c0ecd7b8f9f16256295cf670b5ff3840..26be6a1da24d19a777459e60173335d30d135822 100644 --- a/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder3/file3-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/subsequent_relative_imports/folder3/file3-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "file3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "file3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "file3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "file3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/import_tests/type/type-expected.txt b/ets2panda/test/parser/ets/import_tests/type/type-expected.txt index 495dfc41c99967bb6c11952f9c6687ea5afd5b5c..fa52821c44fd2de2f04a0e0183344e598e1e91cd 100644 --- a/ets2panda/test/parser/ets/import_tests/type/type-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/type/type-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/index_expressions-expected.txt b/ets2panda/test/parser/ets/index_expressions-expected.txt index 1aac5e18dc536ed0697acc29682fd8f7bdfb5505..263d1ae04abc6eb85b561062bb10d979cf15d868 100644 --- a/ets2panda/test/parser/ets/index_expressions-expected.txt +++ b/ets2panda/test/parser/ets/index_expressions-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "index_expressions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "index_expressions.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "index_expressions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "index_expressions.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/infer_overriding_method_return_type-expected.txt b/ets2panda/test/parser/ets/infer_overriding_method_return_type-expected.txt index f1aa0952bbd72134807ab4f9987e574c9ae95f05..852c67f26d41286da3d2e1ef689279f0f72c6d6d 100644 --- a/ets2panda/test/parser/ets/infer_overriding_method_return_type-expected.txt +++ b/ets2panda/test/parser/ets/infer_overriding_method_return_type-expected.txt @@ -654,40 +654,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "infer_overriding_method_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "infer_overriding_method_return_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "infer_overriding_method_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "infer_overriding_method_return_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/inferingEntryPointReturn-expected.txt b/ets2panda/test/parser/ets/inferingEntryPointReturn-expected.txt index 96179792badf95ee22c237f0a0ebf79cfff741fa..85778e5450d042fd9c507cf2fae3585362c22cce 100644 --- a/ets2panda/test/parser/ets/inferingEntryPointReturn-expected.txt +++ b/ets2panda/test/parser/ets/inferingEntryPointReturn-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "inferingEntryPointReturn.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "inferingEntryPointReturn.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "inferingEntryPointReturn.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "inferingEntryPointReturn.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -225,23 +191,71 @@ "type": "Identifier", "name": "a", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "inferingEntryPointReturn.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "inferingEntryPointReturn.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "inferingEntryPointReturn.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "inferingEntryPointReturn.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "inferingEntryPointReturn.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "inferingEntryPointReturn.ets" + } + } + }, "loc": { "start": { - "line": 17, - "column": 12, + "line": 1, + "column": 1, "program": "inferingEntryPointReturn.ets" }, "end": { - "line": 17, - "column": 19, + "line": 1, + "column": 3, "program": "inferingEntryPointReturn.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/inheritance-expected.txt b/ets2panda/test/parser/ets/inheritance-expected.txt index 7da63bfe6b81655667c062bf50739976303cd5a2..b90a53a85199fbd802f3aa22c5816f315b0db5e4 100644 --- a/ets2panda/test/parser/ets/inheritance-expected.txt +++ b/ets2panda/test/parser/ets/inheritance-expected.txt @@ -1268,40 +1268,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "inheritance.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "inheritance.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "inheritance.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "inheritance.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/inheritance2-expected.txt b/ets2panda/test/parser/ets/inheritance2-expected.txt index 848109f2197ba7419600fa77d81f119a3d557f9c..be20d9b53d419a4466edf3da4e9d962cc14b70ab 100644 --- a/ets2panda/test/parser/ets/inheritance2-expected.txt +++ b/ets2panda/test/parser/ets/inheritance2-expected.txt @@ -781,40 +781,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "inheritance2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "inheritance2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "inheritance2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "inheritance2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/instanceof-expected.txt b/ets2panda/test/parser/ets/instanceof-expected.txt index d76d29d33ac3232386c9e61f3609e2b3bd3ad3dd..0f721d53092c5006ea1d7ad2f9ef62702f268485 100644 --- a/ets2panda/test/parser/ets/instanceof-expected.txt +++ b/ets2panda/test/parser/ets/instanceof-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "instanceof.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "instanceof.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -570,23 +536,71 @@ } }, "right": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "instanceof.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + } + } + }, "loc": { "start": { - "line": 19, - "column": 27, + "line": 1, + "column": 1, "program": "instanceof.ets" }, "end": { - "line": 19, - "column": 30, + "line": 1, + "column": 3, "program": "instanceof.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, @@ -684,55 +698,103 @@ } }, "right": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Double", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 27, - "program": "instanceof.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "instanceof.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Double", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + } + } }, - "end": { - "line": 21, - "column": 33, - "program": "instanceof.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "instanceof.ets" + } } } - }, + ], "loc": { "start": { - "line": 21, - "column": 27, + "line": 1, + "column": 3, "program": "instanceof.ets" }, "end": { - "line": 21, - "column": 34, + "line": 1, + "column": 3, "program": "instanceof.ets" } } }, "loc": { "start": { - "line": 21, - "column": 27, + "line": 1, + "column": 1, "program": "instanceof.ets" }, "end": { - "line": 21, - "column": 34, + "line": 1, + "column": 3, "program": "instanceof.ets" } } }, - "annotations": [], "loc": { "start": { "line": 21, @@ -990,3 +1052,4 @@ } } } +Warning: Type parameter is erased from type 'Array' when used in instanceof expression. [instanceof.ets:1:1] diff --git a/ets2panda/test/parser/ets/interfaceMethodWithOptional-expected.txt b/ets2panda/test/parser/ets/interfaceMethodWithOptional-expected.txt index 85cb67771cf06793a86c3930e0a1402c5932954c..2f5f153e60fcc19407d34422f6efbf9f1424580f 100644 --- a/ets2panda/test/parser/ets/interfaceMethodWithOptional-expected.txt +++ b/ets2panda/test/parser/ets/interfaceMethodWithOptional-expected.txt @@ -151,6 +151,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "interfaceMethodWithOptional.ets" + }, + "end": { + "line": 17, + "column": 20, + "program": "interfaceMethodWithOptional.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "interfaceMethodWithOptional.ets" + }, + "end": { + "line": 17, + "column": 20, + "program": "interfaceMethodWithOptional.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "interfaceMethodWithOptional.ets" + }, + "end": { + "line": 17, + "column": 20, + "program": "interfaceMethodWithOptional.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "interfaceMethodWithOptional.ets" + }, + "end": { + "line": 17, + "column": 20, + "program": "interfaceMethodWithOptional.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "interfaceMethodWithOptional.ets" + }, + "end": { + "line": 17, + "column": 20, + "program": "interfaceMethodWithOptional.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "interfaceMethodWithOptional.ets" + }, + "end": { + "line": 17, + "column": 20, + "program": "interfaceMethodWithOptional.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "interfaceMethodWithOptional.ets" + }, + "end": { + "line": 17, + "column": 20, + "program": "interfaceMethodWithOptional.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "interfaceMethodWithOptional.ets" + }, + "end": { + "line": 17, + "column": 20, + "program": "interfaceMethodWithOptional.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "interfaceMethodWithOptional.ets" + }, + "end": { + "line": 17, + "column": 20, + "program": "interfaceMethodWithOptional.ets" + } + } + } + ], "loc": { "start": { "line": 17, @@ -259,40 +411,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interfaceMethodWithOptional.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interfaceMethodWithOptional.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interfaceMethodWithOptional.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interfaceMethodWithOptional.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/interface_abstract_noreturn_function-expected.txt b/ets2panda/test/parser/ets/interface_abstract_noreturn_function-expected.txt index e90744a04b01b639582e332cedb85c3d70cd6961..df6360ab4253bbd3e15c410e22b175b75eb8643d 100644 --- a/ets2panda/test/parser/ets/interface_abstract_noreturn_function-expected.txt +++ b/ets2panda/test/parser/ets/interface_abstract_noreturn_function-expected.txt @@ -163,40 +163,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interface_abstract_noreturn_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interface_abstract_noreturn_function.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interface_abstract_noreturn_function.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interface_abstract_noreturn_function.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/interface_method_default_body-expected.txt b/ets2panda/test/parser/ets/interface_method_default_body-expected.txt index 345adff50894faef5911d694f822c1eb9ebb8995..dc4d7d30ae218d8e2013b7c35af0aa5dbf381cb5 100644 --- a/ets2panda/test/parser/ets/interface_method_default_body-expected.txt +++ b/ets2panda/test/parser/ets/interface_method_default_body-expected.txt @@ -856,40 +856,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interface_method_default_body.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interface_method_default_body.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interface_method_default_body.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interface_method_default_body.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/interfaces-expected.txt b/ets2panda/test/parser/ets/interfaces-expected.txt index 4289919bfb3ab9366624f6dd4604273e517328d1..020f98c54cc57d5318c6330c263cb614cff1e719 100644 --- a/ets2panda/test/parser/ets/interfaces-expected.txt +++ b/ets2panda/test/parser/ets/interfaces-expected.txt @@ -739,7 +739,7 @@ "loc": { "start": { "line": 22, - "column": 3, + "column": 11, "program": "interfaces.ets" }, "end": { @@ -1204,7 +1204,7 @@ "program": "interfaces.ets" }, "end": { - "line": 29, + "line": 31, "column": 1, "program": "interfaces.ets" } @@ -1232,40 +1232,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interfaces.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interfaces.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "interfaces.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "interfaces.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1514,7 +1480,7 @@ "program": "interfaces.ets" }, "end": { - "line": 29, + "line": 31, "column": 1, "program": "interfaces.ets" } diff --git a/ets2panda/test/parser/ets/interfaces.ets b/ets2panda/test/parser/ets/interfaces.ets index 4d9b87c7a08f5c7ce723174ed586c17c0e3131ba..e6ff2c2e03c8837850aab5225fdd798cd2fbac5b 100644 --- a/ets2panda/test/parser/ets/interfaces.ets +++ b/ets2panda/test/parser/ets/interfaces.ets @@ -26,3 +26,5 @@ interface I0 { interface I1 extends I, I0 { } + +/* @@? 22:28 Error TypeError: 'nopnop' is an instance property of 'I0' */ diff --git a/ets2panda/test/parser/ets/internalParsing-expected.txt b/ets2panda/test/parser/ets/internalParsing-expected.txt index 881001494d0b73294e4d459e6b0b5cc67e1caabd..a5ed8a2713657fe14b2853075afdf2f572bfe30a 100644 --- a/ets2panda/test/parser/ets/internalParsing-expected.txt +++ b/ets2panda/test/parser/ets/internalParsing-expected.txt @@ -700,40 +700,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "internalParsing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "internalParsing.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "internalParsing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "internalParsing.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/internalProtectedParsing-expected.txt b/ets2panda/test/parser/ets/internalProtectedParsing-expected.txt index b2bba426a88c4d18e054a0cbab205b0f3a989ae6..d1e05bda1b6a30378740e7d6d155fd5f770fb71e 100644 --- a/ets2panda/test/parser/ets/internalProtectedParsing-expected.txt +++ b/ets2panda/test/parser/ets/internalProtectedParsing-expected.txt @@ -937,40 +937,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "internalProtectedParsing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "internalProtectedParsing.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "internalProtectedParsing.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "internalProtectedParsing.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt b/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt index 2b8b790169084285665c731956e26d188f8790f0..4c37f7a5314935d5b25a1a9a757b2fd8cd5d638f 100644 --- a/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "labeledDoWhileStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "labeledDoWhileStatement.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "labeledDoWhileStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "labeledDoWhileStatement.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/labeledForStatement-expected.txt b/ets2panda/test/parser/ets/labeledForStatement-expected.txt index 00488b344c34969230c0c2a07d0dd6781218d8a4..bb8876b63ced9239fd0ffdcd3cdaa38fa5241702 100644 --- a/ets2panda/test/parser/ets/labeledForStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledForStatement-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "labeledForStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "labeledForStatement.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "labeledForStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "labeledForStatement.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/labeledSwitchStatement-expected.txt b/ets2panda/test/parser/ets/labeledSwitchStatement-expected.txt index a79f02caeb783b0fd727112f9e14d4bf8900cb93..4b46c8ed8454cf172364d8742badcd6a267b56ef 100644 --- a/ets2panda/test/parser/ets/labeledSwitchStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledSwitchStatement-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "labeledSwitchStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "labeledSwitchStatement.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "labeledSwitchStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "labeledSwitchStatement.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt b/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt index df23e910f84ad10c87d27ed19a563d6234c6bf5a..a5074ba1980618a08633c83c0f2a79dfd882b9ee 100644 --- a/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "labeledWhileStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "labeledWhileStatement.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "labeledWhileStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "labeledWhileStatement.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda-expected.txt b/ets2panda/test/parser/ets/lambda-expected.txt index edcfe9c6e1b0013b601a9036670d7a3fbc615d55..a0c5ccf1d3f50bfda8ffcc185819236e43ae85e1 100644 --- a/ets2panda/test/parser/ets/lambda-expected.txt +++ b/ets2panda/test/parser/ets/lambda-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda-lambda-expected.txt b/ets2panda/test/parser/ets/lambda-lambda-expected.txt index b6c12d775424ca1fd44d1631ff5ade406d39af06..6490826b5d996099f73e6424f217676845a91a54 100644 --- a/ets2panda/test/parser/ets/lambda-lambda-expected.txt +++ b/ets2panda/test/parser/ets/lambda-lambda-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-lambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-lambda.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-lambda.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-lambda.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda-type-inference-alias-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-alias-expected.txt index f1037d412f3eb7fdac08268b6366db8d28e0588f..6b44d7a5545e5a1602da70de5b3b3271fa874221 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-alias-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-alias-expected.txt @@ -213,40 +213,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-alias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-alias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda-type-inference-arg-no-type-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-arg-no-type-expected.txt index 84cf9cde0944de2ed65f218e5b63d763526be61c..150923b4a72c13f8b44b13f6414f12d5dda2ac66 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-arg-no-type-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-arg-no-type-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-arg-no-type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-arg-no-type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-arg-no-type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-arg-no-type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda-type-inference-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-expected.txt index 14ee82017cd22e864128b9dd48d0c03203c65fe1..677295a425c717bbca61d7489313ee4e27cef15e 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda-type-inference-no-ret-type-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-no-ret-type-expected.txt index 4c7d62bf874143f6f0d39be9d850469e8841f4e5..43937f2c21612aef77bfbd936722b18407e55c0e 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-no-ret-type-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-no-ret-type-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-no-ret-type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-no-ret-type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-no-ret-type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-no-ret-type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-2-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-2-expected.txt index ac01ecc2ef705c4324216ed3a8e2f08570b4dca8..c630d0ee9c9b9197caed6a10caf47d856a753514 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-2-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded-2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded-2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded-2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded-2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-3-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-3-expected.txt index 2aeb15d4d17e1035c8eb009cdd9568a890414c0f..e5fc5b698a29d75e04d0190897ba9fcc005f75f6 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-3-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-3-expected.txt @@ -1148,40 +1148,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded-3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded-3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded-3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded-3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt index 949ff031e6aa1b345ab4ea3c2d9972fe1bf2d2d7..2203a5146a498ba93346a9bcdc120d7fc3c8d873 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda-type-inference-overloaded.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1677,6 +1643,3 @@ } } } -TypeError: Reference to foo is ambiguous [lambda-type-inference-overloaded.ets:28:5] -TypeError: The type of parameter 'x' cannot be inferred [lambda-type-inference-overloaded.ets:31:10] -TypeError: The type of parameter 'y' cannot be inferred [lambda-type-inference-overloaded.ets:31:13] diff --git a/ets2panda/test/parser/ets/lambdaAsFunctionParam-expected.txt b/ets2panda/test/parser/ets/lambdaAsFunctionParam-expected.txt index c68d26196fb15e96c9408c91d00048ce94bdc9ad..3c4953d846a37814a89e8429cbb0424f716c34e7 100644 --- a/ets2panda/test/parser/ets/lambdaAsFunctionParam-expected.txt +++ b/ets2panda/test/parser/ets/lambdaAsFunctionParam-expected.txt @@ -439,6 +439,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "lambdaAsFunctionParam.ets" + }, + "end": { + "line": 19, + "column": 4, + "program": "lambdaAsFunctionParam.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "lambdaAsFunctionParam.ets" + }, + "end": { + "line": 19, + "column": 4, + "program": "lambdaAsFunctionParam.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "lambdaAsFunctionParam.ets" + }, + "end": { + "line": 19, + "column": 4, + "program": "lambdaAsFunctionParam.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "lambdaAsFunctionParam.ets" + }, + "end": { + "line": 19, + "column": 4, + "program": "lambdaAsFunctionParam.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "lambdaAsFunctionParam.ets" + }, + "end": { + "line": 19, + "column": 4, + "program": "lambdaAsFunctionParam.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "lambdaAsFunctionParam.ets" + }, + "end": { + "line": 19, + "column": 4, + "program": "lambdaAsFunctionParam.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "lambdaAsFunctionParam.ets" + }, + "end": { + "line": 19, + "column": 4, + "program": "lambdaAsFunctionParam.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "lambdaAsFunctionParam.ets" + }, + "end": { + "line": 19, + "column": 4, + "program": "lambdaAsFunctionParam.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "lambdaAsFunctionParam.ets" + }, + "end": { + "line": 19, + "column": 4, + "program": "lambdaAsFunctionParam.ets" + } + } + } + ], "loc": { "start": { "line": 17, @@ -634,40 +786,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaAsFunctionParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaAsFunctionParam.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaAsFunctionParam.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaAsFunctionParam.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatement-expected.txt b/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatement-expected.txt index 564ca5326e954d2984915e87e7309be79475689f..0574d6b08740cb7adc8fa2cce187fea2713b7c6a 100644 --- a/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatement-expected.txt +++ b/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatement-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatement.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatement.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatement.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementCallAVoidFunction-expected.txt b/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementCallAVoidFunction-expected.txt index a4bbf17b2f1ddde3ac4f4fc7c81bda65ae6342e6..1f25f4c85d00f4614e6d50b98a9ce7a26e51eac9 100644 --- a/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementCallAVoidFunction-expected.txt +++ b/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementCallAVoidFunction-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementCallAVoidFunction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementCallAVoidFunction.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementCallAVoidFunction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementCallAVoidFunction.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementVoid-expected.txt b/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementVoid-expected.txt index 64429a5f011478951a18647d2ea5b53d1c69b012..67e9abfc7fd317fd1315537801f1b3531157fafc 100644 --- a/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementVoid-expected.txt +++ b/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementVoid-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementVoid.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementVoid.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementVoid.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementVoid.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementWithFunctionParameters-expected.txt b/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementWithFunctionParameters-expected.txt index 6fc7d55d595365c3c066af5ce78b4fcb9e3ffce3..7e1877d4d1d76791d4e1dadd5199781af455efe1 100644 --- a/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementWithFunctionParameters-expected.txt +++ b/ets2panda/test/parser/ets/lambdaExpressionWithoutBlockStatementWithFunctionParameters-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementWithFunctionParameters.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementWithFunctionParameters.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementWithFunctionParameters.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaExpressionWithoutBlockStatementWithFunctionParameters.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambdaThrowsRethrows-expected.txt b/ets2panda/test/parser/ets/lambdaThrowsRethrows-expected.txt index 1cbd45f79f839cadf0ea3af250f9e2db3386207f..dc195cfcfabbf3bd8547764c2145eadd08ebe09a 100644 --- a/ets2panda/test/parser/ets/lambdaThrowsRethrows-expected.txt +++ b/ets2panda/test/parser/ets/lambdaThrowsRethrows-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaThrowsRethrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaThrowsRethrows.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambdaThrowsRethrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambdaThrowsRethrows.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt b/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt index fdbe7c16095eacf10fbd73a08ca52e428786ed96..7ed795442024b6458b58fcef2bc70e89dbcfd82b 100644 --- a/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-2-expected.txt @@ -199,40 +199,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1-2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1-2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1-2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1-2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1-3-expected.txt b/ets2panda/test/parser/ets/lambda_import_alias_1-3-expected.txt index a19b75562b1f757e692108dce11aec0370408984..d4342619d3e16fc43770e17f1900b8f02c1cb5e7 100644 --- a/ets2panda/test/parser/ets/lambda_import_alias_1-3-expected.txt +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-3-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1-3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1-3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1-3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1-3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt b/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt index 8e49a38030dcb4e44ca9f4b8ee61cfcd293cd742..e640881cb61c66bf1e0c897d2a9f5b17e46c3cb4 100644 --- a/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt +++ b/ets2panda/test/parser/ets/lambda_import_alias_1-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_import_alias_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/lambda_optional_param_1-expected.txt b/ets2panda/test/parser/ets/lambda_optional_param_1-expected.txt index eae7e13666a02c715ce609caf92c16936eeb33ad..cf1ddbd9f39cf5ddb1cc1238b036254f21375796 100644 --- a/ets2panda/test/parser/ets/lambda_optional_param_1-expected.txt +++ b/ets2panda/test/parser/ets/lambda_optional_param_1-expected.txt @@ -433,40 +433,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_optional_param_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_optional_param_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "lambda_optional_param_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "lambda_optional_param_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/launch-expected.txt b/ets2panda/test/parser/ets/launch-expected.txt index c289beb98739fb3c4bfbb58a991ef6fa54cb5b94..ae4da00d7db419e20d0497febadb799d7ce97656 100755 --- a/ets2panda/test/parser/ets/launch-expected.txt +++ b/ets2panda/test/parser/ets/launch-expected.txt @@ -1,6 +1,170 @@ { "type": "Program", "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/concurrency", + "loc": { + "start": { + "line": 16, + "column": 22, + "program": "launch.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1, + "program": "launch.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch.ets" + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/core", + "loc": { + "start": { + "line": 17, + "column": 19, + "program": "launch.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "launch.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 1, + "program": "launch.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "launch.ets" + } + } + }, { "type": "ClassDeclaration", "definition": { @@ -10,12 +174,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 7, "program": "launch.ets" }, "end": { - "line": 16, + "line": 19, "column": 14, "program": "launch.ets" } @@ -32,12 +196,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 20, "column": 19, "program": "launch.ets" }, "end": { - "line": 17, + "line": 20, "column": 25, "program": "launch.ets" } @@ -58,12 +222,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 20, "column": 19, "program": "launch.ets" }, "end": { - "line": 17, + "line": 20, "column": 25, "program": "launch.ets" } @@ -83,12 +247,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 20, "column": 29, "program": "launch.ets" }, "end": { - "line": 17, + "line": 20, "column": 35, "program": "launch.ets" } @@ -96,12 +260,12 @@ }, "loc": { "start": { - "line": 17, + "line": 20, "column": 29, "program": "launch.ets" }, "end": { - "line": 17, + "line": 20, "column": 37, "program": "launch.ets" } @@ -109,12 +273,12 @@ }, "loc": { "start": { - "line": 17, + "line": 20, "column": 29, "program": "launch.ets" }, "end": { - "line": 17, + "line": 20, "column": 37, "program": "launch.ets" } @@ -137,12 +301,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 21, "column": 20, "program": "launch.ets" }, "end": { - "line": 18, + "line": 21, "column": 26, "program": "launch.ets" } @@ -150,12 +314,12 @@ }, "loc": { "start": { - "line": 18, + "line": 21, "column": 20, "program": "launch.ets" }, "end": { - "line": 18, + "line": 21, "column": 27, "program": "launch.ets" } @@ -163,12 +327,12 @@ }, "loc": { "start": { - "line": 18, + "line": 21, "column": 20, "program": "launch.ets" }, "end": { - "line": 18, + "line": 21, "column": 27, "program": "launch.ets" } @@ -177,12 +341,12 @@ "arguments": [], "loc": { "start": { - "line": 18, + "line": 21, "column": 16, "program": "launch.ets" }, "end": { - "line": 18, + "line": 21, "column": 29, "program": "launch.ets" } @@ -190,12 +354,12 @@ }, "loc": { "start": { - "line": 18, + "line": 21, "column": 9, "program": "launch.ets" }, "end": { - "line": 18, + "line": 21, "column": 29, "program": "launch.ets" } @@ -204,12 +368,12 @@ ], "loc": { "start": { - "line": 17, + "line": 20, "column": 36, "program": "launch.ets" }, "end": { - "line": 19, + "line": 22, "column": 6, "program": "launch.ets" } @@ -217,12 +381,12 @@ }, "loc": { "start": { - "line": 17, + "line": 20, "column": 25, "program": "launch.ets" }, "end": { - "line": 19, + "line": 22, "column": 6, "program": "launch.ets" } @@ -230,12 +394,12 @@ }, "loc": { "start": { - "line": 17, + "line": 20, "column": 25, "program": "launch.ets" }, "end": { - "line": 19, + "line": 22, "column": 6, "program": "launch.ets" } @@ -245,12 +409,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 20, "column": 5, "program": "launch.ets" }, "end": { - "line": 19, + "line": 22, "column": 6, "program": "launch.ets" } @@ -264,20 +428,20 @@ "decorators": [], "loc": { "start": { - "line": 21, - "column": 12, + "line": 24, + "column": 19, "program": "launch.ets" }, "end": { - "line": 21, - "column": 15, + "line": 24, + "column": 22, "program": "launch.ets" } } }, "kind": "method", "accessibility": "public", - "static": false, + "static": true, "optional": false, "computed": false, "value": { @@ -290,13 +454,13 @@ "decorators": [], "loc": { "start": { - "line": 21, - "column": 12, + "line": 24, + "column": 19, "program": "launch.ets" }, "end": { - "line": 21, - "column": 15, + "line": 24, + "column": 22, "program": "launch.ets" } } @@ -315,39 +479,39 @@ "decorators": [], "loc": { "start": { - "line": 21, - "column": 19, + "line": 24, + "column": 26, "program": "launch.ets" }, "end": { - "line": 21, - "column": 25, + "line": 24, + "column": 32, "program": "launch.ets" } } }, "loc": { "start": { - "line": 21, - "column": 19, + "line": 24, + "column": 26, "program": "launch.ets" }, "end": { - "line": 21, - "column": 27, + "line": 24, + "column": 34, "program": "launch.ets" } } }, "loc": { "start": { - "line": 21, - "column": 19, + "line": 24, + "column": 26, "program": "launch.ets" }, "end": { - "line": 21, - "column": 27, + "line": 24, + "column": 34, "program": "launch.ets" } } @@ -369,12 +533,12 @@ "decorators": [], "loc": { "start": { - "line": 22, + "line": 25, "column": 20, "program": "launch.ets" }, "end": { - "line": 22, + "line": 25, "column": 26, "program": "launch.ets" } @@ -382,12 +546,12 @@ }, "loc": { "start": { - "line": 22, + "line": 25, "column": 20, "program": "launch.ets" }, "end": { - "line": 22, + "line": 25, "column": 27, "program": "launch.ets" } @@ -395,12 +559,12 @@ }, "loc": { "start": { - "line": 22, + "line": 25, "column": 20, "program": "launch.ets" }, "end": { - "line": 22, + "line": 25, "column": 27, "program": "launch.ets" } @@ -409,12 +573,12 @@ "arguments": [], "loc": { "start": { - "line": 22, + "line": 25, "column": 16, "program": "launch.ets" }, "end": { - "line": 22, + "line": 25, "column": 29, "program": "launch.ets" } @@ -422,12 +586,12 @@ }, "loc": { "start": { - "line": 22, + "line": 25, "column": 9, "program": "launch.ets" }, "end": { - "line": 22, + "line": 25, "column": 29, "program": "launch.ets" } @@ -436,12 +600,12 @@ ], "loc": { "start": { - "line": 21, - "column": 26, + "line": 24, + "column": 33, "program": "launch.ets" }, "end": { - "line": 23, + "line": 26, "column": 6, "program": "launch.ets" } @@ -449,12 +613,12 @@ }, "loc": { "start": { - "line": 21, - "column": 15, + "line": 24, + "column": 22, "program": "launch.ets" }, "end": { - "line": 23, + "line": 26, "column": 6, "program": "launch.ets" } @@ -462,12 +626,12 @@ }, "loc": { "start": { - "line": 21, - "column": 15, + "line": 24, + "column": 22, "program": "launch.ets" }, "end": { - "line": 23, + "line": 26, "column": 6, "program": "launch.ets" } @@ -477,12 +641,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 24, "column": 5, "program": "launch.ets" }, "end": { - "line": 23, + "line": 26, "column": 6, "program": "launch.ets" } @@ -496,12 +660,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" }, "end": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" } @@ -521,12 +685,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" }, "end": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" } @@ -541,12 +705,12 @@ "statements": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" }, "end": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" } @@ -554,12 +718,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" }, "end": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" } @@ -567,12 +731,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" }, "end": { - "line": 16, + "line": 19, "column": 16, "program": "launch.ets" } @@ -596,12 +760,12 @@ ], "loc": { "start": { - "line": 16, + "line": 19, "column": 15, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 9, "program": "launch.ets" } @@ -609,12 +773,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 1, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 9, "program": "launch.ets" } @@ -642,40 +806,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -791,12 +921,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 29, "column": 10, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 13, "program": "launch.ets" } @@ -817,12 +947,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 29, "column": 10, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 13, "program": "launch.ets" } @@ -841,12 +971,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 26, + "line": 29, "column": 17, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 20, "program": "launch.ets" } @@ -855,12 +985,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 29, "column": 14, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 20, "program": "launch.ets" } @@ -868,12 +998,12 @@ }, "loc": { "start": { - "line": 26, + "line": 29, "column": 14, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 20, "program": "launch.ets" } @@ -888,12 +1018,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 26, + "line": 29, "column": 25, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 30, "program": "launch.ets" } @@ -902,12 +1032,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 29, "column": 22, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 30, "program": "launch.ets" } @@ -915,12 +1045,12 @@ }, "loc": { "start": { - "line": 26, + "line": 29, "column": 22, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 30, "program": "launch.ets" } @@ -937,12 +1067,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 29, "column": 33, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 39, "program": "launch.ets" } @@ -950,12 +1080,12 @@ }, "loc": { "start": { - "line": 26, + "line": 29, "column": 33, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 41, "program": "launch.ets" } @@ -963,12 +1093,12 @@ }, "loc": { "start": { - "line": 26, + "line": 29, "column": 33, "program": "launch.ets" }, "end": { - "line": 26, + "line": 29, "column": 41, "program": "launch.ets" } @@ -991,12 +1121,12 @@ "decorators": [], "loc": { "start": { - "line": 27, + "line": 30, "column": 14, "program": "launch.ets" }, "end": { - "line": 27, + "line": 30, "column": 20, "program": "launch.ets" } @@ -1004,12 +1134,12 @@ }, "loc": { "start": { - "line": 27, + "line": 30, "column": 14, "program": "launch.ets" }, "end": { - "line": 27, + "line": 30, "column": 21, "program": "launch.ets" } @@ -1017,12 +1147,12 @@ }, "loc": { "start": { - "line": 27, + "line": 30, "column": 14, "program": "launch.ets" }, "end": { - "line": 27, + "line": 30, "column": 21, "program": "launch.ets" } @@ -1031,12 +1161,12 @@ "arguments": [], "loc": { "start": { - "line": 27, + "line": 30, "column": 10, "program": "launch.ets" }, "end": { - "line": 27, + "line": 30, "column": 23, "program": "launch.ets" } @@ -1044,12 +1174,12 @@ }, "loc": { "start": { - "line": 27, + "line": 30, "column": 3, "program": "launch.ets" }, "end": { - "line": 27, + "line": 30, "column": 23, "program": "launch.ets" } @@ -1058,12 +1188,12 @@ ], "loc": { "start": { - "line": 26, + "line": 29, "column": 40, "program": "launch.ets" }, "end": { - "line": 28, + "line": 31, "column": 2, "program": "launch.ets" } @@ -1071,12 +1201,12 @@ }, "loc": { "start": { - "line": 26, + "line": 29, "column": 10, "program": "launch.ets" }, "end": { - "line": 28, + "line": 31, "column": 2, "program": "launch.ets" } @@ -1084,12 +1214,12 @@ }, "loc": { "start": { - "line": 26, + "line": 29, "column": 10, "program": "launch.ets" }, "end": { - "line": 28, + "line": 31, "column": 2, "program": "launch.ets" } @@ -1099,12 +1229,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 29, "column": 1, "program": "launch.ets" }, "end": { - "line": 28, + "line": 31, "column": 2, "program": "launch.ets" } @@ -1118,12 +1248,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 33, "column": 10, "program": "launch.ets" }, "end": { - "line": 30, + "line": 33, "column": 13, "program": "launch.ets" } @@ -1144,12 +1274,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 33, "column": 10, "program": "launch.ets" }, "end": { - "line": 30, + "line": 33, "column": 13, "program": "launch.ets" } @@ -1168,12 +1298,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 30, + "line": 33, "column": 17, "program": "launch.ets" }, "end": { - "line": 30, + "line": 33, "column": 20, "program": "launch.ets" } @@ -1182,12 +1312,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 33, "column": 14, "program": "launch.ets" }, "end": { - "line": 30, + "line": 33, "column": 20, "program": "launch.ets" } @@ -1195,12 +1325,12 @@ }, "loc": { "start": { - "line": 30, + "line": 33, "column": 14, "program": "launch.ets" }, "end": { - "line": 30, + "line": 33, "column": 20, "program": "launch.ets" } @@ -1217,12 +1347,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 33, "column": 23, "program": "launch.ets" }, "end": { - "line": 30, + "line": 33, "column": 29, "program": "launch.ets" } @@ -1230,12 +1360,12 @@ }, "loc": { "start": { - "line": 30, + "line": 33, "column": 23, "program": "launch.ets" }, "end": { - "line": 30, + "line": 33, "column": 31, "program": "launch.ets" } @@ -1243,12 +1373,12 @@ }, "loc": { "start": { - "line": 30, + "line": 33, "column": 23, "program": "launch.ets" }, "end": { - "line": 30, + "line": 33, "column": 31, "program": "launch.ets" } @@ -1260,97 +1390,321 @@ { "type": "ExpressionStatement", "expression": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 3, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 9, + "program": "launch.ets" + } + } + }, + "arguments": [ + { "type": "Identifier", "name": "bar", "decorators": [], "loc": { "start": { - "line": 31, - "column": 10, + "line": 34, + "column": 43, "program": "launch.ets" }, "end": { - "line": 31, - "column": 13, + "line": 34, + "column": 46, "program": "launch.ets" } } }, - "arguments": [ - { - "type": "Identifier", - "name": "x", - "decorators": [], - "loc": { - "start": { - "line": 31, - "column": 14, - "program": "launch.ets" - }, - "end": { - "line": 31, - "column": 15, - "program": "launch.ets" - } + { + "type": "Identifier", + "name": "x", + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 47, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 48, + "program": "launch.ets" } - }, - { - "type": "NumberLiteral", - "value": 30, - "loc": { - "start": { - "line": 31, - "column": 17, - "program": "launch.ets" - }, - "end": { - "line": 31, - "column": 19, - "program": "launch.ets" - } + } + }, + { + "type": "NumberLiteral", + "value": 30, + "loc": { + "start": { + "line": 34, + "column": 50, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 52, + "program": "launch.ets" } } - ], - "optional": false, + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 10, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 16, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 10, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 17, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 10, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 17, + "program": "launch.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "i", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 34, + "column": 21, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 24, + "program": "launch.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 19, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 24, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 19, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 24, + "program": "launch.ets" + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "f", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 34, + "column": 27, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 32, + "program": "launch.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 25, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 32, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 25, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 32, + "program": "launch.ets" + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 35, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 41, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 35, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 42, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 35, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 42, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 34, + "column": 18, + "program": "launch.ets" + }, + "end": { + "line": 34, + "column": 42, + "program": "launch.ets" + } + } + } + ], "loc": { "start": { - "line": 31, - "column": 10, + "line": 34, + "column": 9, "program": "launch.ets" }, "end": { - "line": 31, - "column": 20, + "line": 34, + "column": 42, "program": "launch.ets" } } }, "loc": { "start": { - "line": 31, + "line": 34, "column": 3, "program": "launch.ets" }, "end": { - "line": 31, - "column": 20, + "line": 34, + "column": 53, "program": "launch.ets" } } }, "loc": { "start": { - "line": 31, + "line": 34, "column": 3, "program": "launch.ets" }, "end": { - "line": 31, - "column": 21, + "line": 34, + "column": 54, "program": "launch.ets" } } @@ -1369,12 +1723,12 @@ "decorators": [], "loc": { "start": { - "line": 32, + "line": 35, "column": 14, "program": "launch.ets" }, "end": { - "line": 32, + "line": 35, "column": 20, "program": "launch.ets" } @@ -1382,12 +1736,12 @@ }, "loc": { "start": { - "line": 32, + "line": 35, "column": 14, "program": "launch.ets" }, "end": { - "line": 32, + "line": 35, "column": 21, "program": "launch.ets" } @@ -1395,12 +1749,12 @@ }, "loc": { "start": { - "line": 32, + "line": 35, "column": 14, "program": "launch.ets" }, "end": { - "line": 32, + "line": 35, "column": 21, "program": "launch.ets" } @@ -1409,12 +1763,12 @@ "arguments": [], "loc": { "start": { - "line": 32, + "line": 35, "column": 10, "program": "launch.ets" }, "end": { - "line": 32, + "line": 35, "column": 23, "program": "launch.ets" } @@ -1422,12 +1776,12 @@ }, "loc": { "start": { - "line": 32, + "line": 35, "column": 3, "program": "launch.ets" }, "end": { - "line": 32, + "line": 35, "column": 23, "program": "launch.ets" } @@ -1436,12 +1790,12 @@ ], "loc": { "start": { - "line": 30, + "line": 33, "column": 30, "program": "launch.ets" }, "end": { - "line": 33, + "line": 36, "column": 2, "program": "launch.ets" } @@ -1449,12 +1803,12 @@ }, "loc": { "start": { - "line": 30, + "line": 33, "column": 10, "program": "launch.ets" }, "end": { - "line": 33, + "line": 36, "column": 2, "program": "launch.ets" } @@ -1462,12 +1816,12 @@ }, "loc": { "start": { - "line": 30, + "line": 33, "column": 10, "program": "launch.ets" }, "end": { - "line": 33, + "line": 36, "column": 2, "program": "launch.ets" } @@ -1477,12 +1831,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 33, "column": 1, "program": "launch.ets" }, "end": { - "line": 33, + "line": 36, "column": 2, "program": "launch.ets" } @@ -1496,12 +1850,12 @@ "decorators": [], "loc": { "start": { - "line": 35, + "line": 38, "column": 10, "program": "launch.ets" }, "end": { - "line": 35, + "line": 38, "column": 14, "program": "launch.ets" } @@ -1522,12 +1876,12 @@ "decorators": [], "loc": { "start": { - "line": 35, + "line": 38, "column": 10, "program": "launch.ets" }, "end": { - "line": 35, + "line": 38, "column": 14, "program": "launch.ets" } @@ -1541,12 +1895,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 35, + "line": 38, "column": 18, "program": "launch.ets" }, "end": { - "line": 35, + "line": 38, "column": 22, "program": "launch.ets" } @@ -1569,17 +1923,17 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "Promise", + "name": "Job", "decorators": [], "loc": { "start": { - "line": 36, + "line": 39, "column": 10, "program": "launch.ets" }, "end": { - "line": 36, - "column": 17, + "line": 39, + "column": 13, "program": "launch.ets" } } @@ -1597,39 +1951,39 @@ "decorators": [], "loc": { "start": { - "line": 36, - "column": 18, + "line": 39, + "column": 14, "program": "launch.ets" }, "end": { - "line": 36, - "column": 24, + "line": 39, + "column": 20, "program": "launch.ets" } } }, "loc": { "start": { - "line": 36, - "column": 18, + "line": 39, + "column": 14, "program": "launch.ets" }, "end": { - "line": 36, - "column": 25, + "line": 39, + "column": 21, "program": "launch.ets" } } }, "loc": { "start": { - "line": 36, - "column": 18, + "line": 39, + "column": 14, "program": "launch.ets" }, "end": { - "line": 36, - "column": 25, + "line": 39, + "column": 21, "program": "launch.ets" } } @@ -1637,39 +1991,39 @@ ], "loc": { "start": { - "line": 36, - "column": 17, + "line": 39, + "column": 13, "program": "launch.ets" }, "end": { - "line": 36, - "column": 25, + "line": 39, + "column": 21, "program": "launch.ets" } } }, "loc": { "start": { - "line": 36, + "line": 39, "column": 10, "program": "launch.ets" }, "end": { - "line": 36, - "column": 26, + "line": 39, + "column": 22, "program": "launch.ets" } } }, "loc": { "start": { - "line": 36, + "line": 39, "column": 10, "program": "launch.ets" }, "end": { - "line": 36, - "column": 26, + "line": 39, + "column": 22, "program": "launch.ets" } } @@ -1677,12 +2031,12 @@ "decorators": [], "loc": { "start": { - "line": 36, + "line": 39, "column": 7, "program": "launch.ets" }, "end": { - "line": 36, + "line": 39, "column": 8, "program": "launch.ets" } @@ -1691,12 +2045,12 @@ "init": null, "loc": { "start": { - "line": 36, + "line": 39, "column": 7, "program": "launch.ets" }, "end": { - "line": 36, + "line": 39, "column": 8, "program": "launch.ets" } @@ -1706,13 +2060,13 @@ "kind": "let", "loc": { "start": { - "line": 36, + "line": 39, "column": 3, "program": "launch.ets" }, "end": { - "line": 36, - "column": 26, + "line": 39, + "column": 22, "program": "launch.ets" } } @@ -1728,105 +2082,282 @@ "decorators": [], "loc": { "start": { - "line": 37, + "line": 40, "column": 3, "program": "launch.ets" }, "end": { - "line": 37, + "line": 40, "column": 4, "program": "launch.ets" } } }, "right": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 7, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 13, + "program": "launch.ets" + } + } + }, + "arguments": [ + { "type": "Identifier", "name": "foo", "decorators": [], "loc": { "start": { - "line": 37, - "column": 14, + "line": 40, + "column": 41, "program": "launch.ets" }, "end": { - "line": 37, - "column": 17, + "line": 40, + "column": 44, "program": "launch.ets" } } }, - "arguments": [ - { - "type": "NumberLiteral", - "value": 11, - "loc": { - "start": { - "line": 37, - "column": 18, - "program": "launch.ets" - }, - "end": { - "line": 37, - "column": 20, - "program": "launch.ets" - } + { + "type": "NumberLiteral", + "value": 11, + "loc": { + "start": { + "line": 40, + "column": 46, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 48, + "program": "launch.ets" } } - ], - "optional": false, - "loc": { - "start": { - "line": 37, - "column": 14, - "program": "launch.ets" - }, - "end": { - "line": 37, - "column": 21, - "program": "launch.ets" - } } - }, - "loc": { - "start": { - "line": 37, - "column": 7, - "program": "launch.ets" - }, - "end": { - "line": 37, - "column": 21, - "program": "launch.ets" + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 20, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 21, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 21, + "program": "launch.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "i", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 40, + "column": 25, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 28, + "program": "launch.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 23, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 28, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 23, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 28, + "program": "launch.ets" + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 33, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 39, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 33, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 40, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 33, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 40, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 22, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 40, + "program": "launch.ets" + } + } + } + ], + "loc": { + "start": { + "line": 40, + "column": 13, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 40, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 7, + "program": "launch.ets" + }, + "end": { + "line": 40, + "column": 49, + "program": "launch.ets" } } }, "loc": { "start": { - "line": 37, + "line": 40, "column": 3, "program": "launch.ets" }, "end": { - "line": 37, - "column": 21, + "line": 40, + "column": 49, "program": "launch.ets" } } }, "loc": { "start": { - "line": 37, + "line": 40, "column": 3, "program": "launch.ets" }, "end": { - "line": 37, - "column": 22, + "line": 40, + "column": 50, "program": "launch.ets" } } @@ -1842,22 +2373,38 @@ "decorators": [], "loc": { "start": { - "line": 38, + "line": 41, "column": 3, "program": "launch.ets" }, "end": { - "line": 38, + "line": 41, "column": 4, "program": "launch.ets" } } }, "right": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 7, + "program": "launch.ets" + }, + "end": { + "line": 41, + "column": 13, + "program": "launch.ets" + } + } + }, + "arguments": [ + { "type": "MemberExpression", "object": { "type": "Identifier", @@ -1865,99 +2412,213 @@ "decorators": [], "loc": { "start": { - "line": 38, + "line": 41, + "column": 36, + "program": "launch.ets" + }, + "end": { + "line": 41, + "column": 43, + "program": "launch.ets" + } + } + }, + "property": { + "type": "Identifier", + "name": "foobar", + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 44, + "program": "launch.ets" + }, + "end": { + "line": 41, + "column": 50, + "program": "launch.ets" + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 41, + "column": 36, + "program": "launch.ets" + }, + "end": { + "line": 41, + "column": 50, + "program": "launch.ets" + } + } + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 41, + "column": 20, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 41, + "column": 21, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 41, "column": 14, "program": "launch.ets" }, "end": { - "line": 38, + "line": 41, "column": 21, "program": "launch.ets" } - } - }, - "property": { - "type": "Identifier", - "name": "foobar", - "decorators": [], + } + }, + { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 41, + "column": 28, + "program": "launch.ets" + }, + "end": { + "line": 41, + "column": 34, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 28, + "program": "launch.ets" + }, + "end": { + "line": 41, + "column": 35, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 41, + "column": 28, + "program": "launch.ets" + }, + "end": { + "line": 41, + "column": 35, + "program": "launch.ets" + } + } + }, "loc": { "start": { - "line": 38, + "line": 41, "column": 22, "program": "launch.ets" }, "end": { - "line": 38, - "column": 28, + "line": 41, + "column": 35, "program": "launch.ets" } } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 38, - "column": 14, - "program": "launch.ets" - }, - "end": { - "line": 38, - "column": 28, - "program": "launch.ets" - } } - }, - "arguments": [], - "optional": false, + ], "loc": { "start": { - "line": 38, - "column": 14, + "line": 41, + "column": 13, "program": "launch.ets" }, "end": { - "line": 38, - "column": 30, + "line": 41, + "column": 35, "program": "launch.ets" } } }, "loc": { "start": { - "line": 38, + "line": 41, "column": 7, "program": "launch.ets" }, "end": { - "line": 38, - "column": 30, + "line": 41, + "column": 51, "program": "launch.ets" } } }, "loc": { "start": { - "line": 38, + "line": 41, "column": 3, "program": "launch.ets" }, "end": { - "line": 38, - "column": 30, + "line": 41, + "column": 51, "program": "launch.ets" } } }, "loc": { "start": { - "line": 38, + "line": 41, "column": 3, "program": "launch.ets" }, "end": { - "line": 38, - "column": 31, + "line": 41, + "column": 52, "program": "launch.ets" } } @@ -1973,82 +2634,52 @@ "decorators": [], "loc": { "start": { - "line": 39, + "line": 42, "column": 3, "program": "launch.ets" }, "end": { - "line": 39, + "line": 42, "column": 4, "program": "launch.ets" } } }, "right": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 42, + "column": 7, + "program": "launch.ets" + }, + "end": { + "line": 42, + "column": 13, + "program": "launch.ets" + } + } + }, + "arguments": [ + { "type": "MemberExpression", "object": { - "type": "ETSNewClassInstanceExpression", - "typeReference": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Example", - "decorators": [], - "loc": { - "start": { - "line": 39, - "column": 18, - "program": "launch.ets" - }, - "end": { - "line": 39, - "column": 25, - "program": "launch.ets" - } - } - }, - "loc": { - "start": { - "line": 39, - "column": 18, - "program": "launch.ets" - }, - "end": { - "line": 39, - "column": 26, - "program": "launch.ets" - } - } - }, - "loc": { - "start": { - "line": 39, - "column": 18, - "program": "launch.ets" - }, - "end": { - "line": 39, - "column": 26, - "program": "launch.ets" - } - } - }, - "arguments": [], + "type": "Identifier", + "name": "Example", + "decorators": [], "loc": { "start": { - "line": 39, - "column": 14, + "line": 42, + "column": 36, "program": "launch.ets" }, "end": { - "line": 39, - "column": 28, + "line": 42, + "column": 43, "program": "launch.ets" } } @@ -2059,13 +2690,13 @@ "decorators": [], "loc": { "start": { - "line": 39, - "column": 28, + "line": 42, + "column": 44, "program": "launch.ets" }, "end": { - "line": 39, - "column": 31, + "line": 42, + "column": 47, "program": "launch.ets" } } @@ -2074,180 +2705,181 @@ "optional": false, "loc": { "start": { - "line": 39, - "column": 14, + "line": 42, + "column": 36, "program": "launch.ets" }, "end": { - "line": 39, - "column": 31, + "line": 42, + "column": 47, "program": "launch.ets" } } - }, - "arguments": [], - "optional": false, - "loc": { - "start": { - "line": 39, - "column": 14, - "program": "launch.ets" - }, - "end": { - "line": 39, - "column": 33, - "program": "launch.ets" - } - } - }, - "loc": { - "start": { - "line": 39, - "column": 7, - "program": "launch.ets" - }, - "end": { - "line": 39, - "column": 33, - "program": "launch.ets" } - } - }, - "loc": { - "start": { - "line": 39, - "column": 3, - "program": "launch.ets" - }, - "end": { - "line": 39, - "column": 33, - "program": "launch.ets" - } - } - }, - "loc": { - "start": { - "line": 39, - "column": 3, - "program": "launch.ets" - }, - "end": { - "line": 39, - "column": 34, - "program": "launch.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "example", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 7, - "program": "launch.ets" + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 42, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 42, + "column": 20, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 42, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 42, + "column": 21, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 42, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 42, + "column": 21, + "program": "launch.ets" + } + } }, - "end": { - "line": 40, - "column": 14, - "program": "launch.ets" - } - } - }, - "init": { - "type": "ETSNewClassInstanceExpression", - "typeReference": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Example", - "decorators": [], + { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 42, + "column": 28, + "program": "launch.ets" + }, + "end": { + "line": 42, + "column": 34, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 42, + "column": 28, + "program": "launch.ets" + }, + "end": { + "line": 42, + "column": 35, + "program": "launch.ets" + } + } + }, "loc": { "start": { - "line": 40, - "column": 21, + "line": 42, + "column": 28, "program": "launch.ets" }, "end": { - "line": 40, - "column": 28, + "line": 42, + "column": 35, "program": "launch.ets" } } }, "loc": { "start": { - "line": 40, - "column": 21, + "line": 42, + "column": 22, "program": "launch.ets" }, "end": { - "line": 40, - "column": 29, + "line": 42, + "column": 35, "program": "launch.ets" } } - }, - "loc": { - "start": { - "line": 40, - "column": 21, - "program": "launch.ets" - }, - "end": { - "line": 40, - "column": 29, - "program": "launch.ets" - } } - }, - "arguments": [], + ], "loc": { "start": { - "line": 40, - "column": 17, + "line": 42, + "column": 13, "program": "launch.ets" }, "end": { - "line": 40, - "column": 31, + "line": 42, + "column": 35, "program": "launch.ets" } } }, "loc": { "start": { - "line": 40, + "line": 42, "column": 7, "program": "launch.ets" }, "end": { - "line": 40, - "column": 31, + "line": 42, + "column": 48, "program": "launch.ets" } } + }, + "loc": { + "start": { + "line": 42, + "column": 3, + "program": "launch.ets" + }, + "end": { + "line": 42, + "column": 48, + "program": "launch.ets" + } } - ], - "kind": "let", + }, "loc": { "start": { - "line": 40, + "line": 42, "column": 3, "program": "launch.ets" }, "end": { - "line": 40, - "column": 31, + "line": 42, + "column": 49, "program": "launch.ets" } } @@ -2263,36 +2895,52 @@ "decorators": [], "loc": { "start": { - "line": 41, + "line": 43, "column": 3, "program": "launch.ets" }, "end": { - "line": 41, + "line": 43, "column": 4, "program": "launch.ets" } } }, "right": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 43, + "column": 7, + "program": "launch.ets" + }, + "end": { + "line": 43, + "column": 13, + "program": "launch.ets" + } + } + }, + "arguments": [ + { "type": "MemberExpression", "object": { "type": "Identifier", - "name": "example", + "name": "Example", "decorators": [], "loc": { "start": { - "line": 41, - "column": 14, + "line": 43, + "column": 36, "program": "launch.ets" }, "end": { - "line": 41, - "column": 21, + "line": 43, + "column": 43, "program": "launch.ets" } } @@ -2303,13 +2951,13 @@ "decorators": [], "loc": { "start": { - "line": 41, - "column": 22, + "line": 43, + "column": 44, "program": "launch.ets" }, "end": { - "line": 41, - "column": 25, + "line": 43, + "column": 47, "program": "launch.ets" } } @@ -2318,67 +2966,181 @@ "optional": false, "loc": { "start": { - "line": 41, - "column": 14, + "line": 43, + "column": 36, "program": "launch.ets" }, "end": { - "line": 41, - "column": 25, + "line": 43, + "column": 47, "program": "launch.ets" } } - }, - "arguments": [], - "optional": false, + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 43, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 43, + "column": 20, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 43, + "column": 21, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 43, + "column": 21, + "program": "launch.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 43, + "column": 28, + "program": "launch.ets" + }, + "end": { + "line": 43, + "column": 34, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 28, + "program": "launch.ets" + }, + "end": { + "line": 43, + "column": 35, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 28, + "program": "launch.ets" + }, + "end": { + "line": 43, + "column": 35, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 22, + "program": "launch.ets" + }, + "end": { + "line": 43, + "column": 35, + "program": "launch.ets" + } + } + } + ], "loc": { "start": { - "line": 41, - "column": 14, + "line": 43, + "column": 13, "program": "launch.ets" }, "end": { - "line": 41, - "column": 27, + "line": 43, + "column": 35, "program": "launch.ets" } } }, "loc": { "start": { - "line": 41, + "line": 43, "column": 7, "program": "launch.ets" }, "end": { - "line": 41, - "column": 27, + "line": 43, + "column": 48, "program": "launch.ets" } } }, "loc": { "start": { - "line": 41, + "line": 43, "column": 3, "program": "launch.ets" }, "end": { - "line": 41, - "column": 27, + "line": 43, + "column": 48, "program": "launch.ets" } } }, "loc": { "start": { - "line": 41, + "line": 43, "column": 3, "program": "launch.ets" }, "end": { - "line": 41, - "column": 28, + "line": 43, + "column": 49, "program": "launch.ets" } } @@ -2403,12 +3165,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 42, + "line": 44, "column": 20, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 23, "program": "launch.ets" } @@ -2417,12 +3179,12 @@ "decorators": [], "loc": { "start": { - "line": 42, + "line": 44, "column": 17, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 23, "program": "launch.ets" } @@ -2430,12 +3192,12 @@ }, "loc": { "start": { - "line": 42, + "line": 44, "column": 17, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 23, "program": "launch.ets" } @@ -2452,12 +3214,12 @@ "decorators": [], "loc": { "start": { - "line": 42, + "line": 44, "column": 28, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 34, "program": "launch.ets" } @@ -2465,12 +3227,12 @@ }, "loc": { "start": { - "line": 42, + "line": 44, "column": 28, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 36, "program": "launch.ets" } @@ -2478,12 +3240,12 @@ }, "loc": { "start": { - "line": 42, + "line": 44, "column": 28, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 36, "program": "launch.ets" } @@ -2491,12 +3253,12 @@ }, "loc": { "start": { - "line": 42, + "line": 44, "column": 16, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 36, "program": "launch.ets" } @@ -2505,12 +3267,12 @@ "decorators": [], "loc": { "start": { - "line": 42, + "line": 44, "column": 7, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 14, "program": "launch.ets" } @@ -2522,12 +3284,12 @@ "decorators": [], "loc": { "start": { - "line": 42, + "line": 44, "column": 37, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 40, "program": "launch.ets" } @@ -2535,12 +3297,12 @@ }, "loc": { "start": { - "line": 42, + "line": 44, "column": 7, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 40, "program": "launch.ets" } @@ -2550,12 +3312,12 @@ "kind": "let", "loc": { "start": { - "line": 42, + "line": 44, "column": 3, "program": "launch.ets" }, "end": { - "line": 42, + "line": 44, "column": 41, "program": "launch.ets" } @@ -2572,105 +3334,282 @@ "decorators": [], "loc": { "start": { - "line": 43, + "line": 45, "column": 3, "program": "launch.ets" }, "end": { - "line": 43, + "line": 45, "column": 4, "program": "launch.ets" } } }, "right": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 45, + "column": 7, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 13, + "program": "launch.ets" + } + } + }, + "arguments": [ + { "type": "Identifier", "name": "foo_ref", "decorators": [], "loc": { "start": { - "line": 43, - "column": 14, + "line": 45, + "column": 41, "program": "launch.ets" }, "end": { - "line": 43, - "column": 21, + "line": 45, + "column": 48, "program": "launch.ets" } } }, - "arguments": [ + { + "type": "NumberLiteral", + "value": 5, + "loc": { + "start": { + "line": 45, + "column": 50, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 51, + "program": "launch.ets" + } + } + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ { - "type": "NumberLiteral", - "value": 5, + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 45, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 20, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 45, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 21, + "program": "launch.ets" + } + } + }, "loc": { "start": { - "line": 43, + "line": 45, + "column": 14, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 21, + "program": "launch.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "i", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 45, + "column": 25, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 28, + "program": "launch.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 45, + "column": 23, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 28, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 45, + "column": 23, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 28, + "program": "launch.ets" + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 45, + "column": 33, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 39, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 45, + "column": 33, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 40, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 45, + "column": 33, + "program": "launch.ets" + }, + "end": { + "line": 45, + "column": 40, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 45, "column": 22, "program": "launch.ets" }, "end": { - "line": 43, - "column": 23, + "line": 45, + "column": 40, "program": "launch.ets" } } } ], - "optional": false, "loc": { "start": { - "line": 43, - "column": 14, + "line": 45, + "column": 13, "program": "launch.ets" }, "end": { - "line": 43, - "column": 24, + "line": 45, + "column": 40, "program": "launch.ets" } } }, "loc": { "start": { - "line": 43, + "line": 45, "column": 7, "program": "launch.ets" }, "end": { - "line": 43, - "column": 24, + "line": 45, + "column": 52, "program": "launch.ets" } } }, "loc": { "start": { - "line": 43, + "line": 45, "column": 3, "program": "launch.ets" }, "end": { - "line": 43, - "column": 24, + "line": 45, + "column": 52, "program": "launch.ets" } } }, "loc": { "start": { - "line": 43, + "line": 45, "column": 3, "program": "launch.ets" }, "end": { - "line": 43, - "column": 25, + "line": 45, + "column": 53, "program": "launch.ets" } } @@ -2690,12 +3629,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 44, + "line": 46, "column": 21, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 25, "program": "launch.ets" } @@ -2703,12 +3642,12 @@ }, "loc": { "start": { - "line": 44, + "line": 46, "column": 15, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 25, "program": "launch.ets" } @@ -2717,12 +3656,12 @@ "decorators": [], "loc": { "start": { - "line": 44, + "line": 46, "column": 7, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 13, "program": "launch.ets" } @@ -2741,12 +3680,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 44, + "line": 46, "column": 32, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 36, "program": "launch.ets" } @@ -2760,12 +3699,12 @@ "argument": null, "loc": { "start": { - "line": 44, + "line": 46, "column": 42, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 49, "program": "launch.ets" } @@ -2774,12 +3713,12 @@ ], "loc": { "start": { - "line": 44, + "line": 46, "column": 40, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 51, "program": "launch.ets" } @@ -2787,12 +3726,12 @@ }, "loc": { "start": { - "line": 44, + "line": 46, "column": 28, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 51, "program": "launch.ets" } @@ -2800,12 +3739,12 @@ }, "loc": { "start": { - "line": 44, + "line": 46, "column": 28, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 51, "program": "launch.ets" } @@ -2813,12 +3752,12 @@ }, "loc": { "start": { - "line": 44, + "line": 46, "column": 7, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 51, "program": "launch.ets" } @@ -2828,12 +3767,12 @@ "kind": "let", "loc": { "start": { - "line": 44, + "line": 46, "column": 3, "program": "launch.ets" }, "end": { - "line": 44, + "line": 46, "column": 51, "program": "launch.ets" } @@ -2842,63 +3781,129 @@ { "type": "ExpressionStatement", "expression": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 47, + "column": 3, + "program": "launch.ets" + }, + "end": { + "line": 47, + "column": 9, + "program": "launch.ets" + } + } + }, + "arguments": [ + { "type": "Identifier", "name": "lambda", "decorators": [], "loc": { "start": { - "line": 45, - "column": 10, + "line": 47, + "column": 26, "program": "launch.ets" }, "end": { - "line": 45, - "column": 16, + "line": 47, + "column": 32, "program": "launch.ets" } } - }, - "arguments": [], - "optional": false, + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 47, + "column": 10, + "program": "launch.ets" + }, + "end": { + "line": 47, + "column": 14, + "program": "launch.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 47, + "column": 20, + "program": "launch.ets" + }, + "end": { + "line": 47, + "column": 24, + "program": "launch.ets" + } + } + }, + "loc": { + "start": { + "line": 47, + "column": 16, + "program": "launch.ets" + }, + "end": { + "line": 47, + "column": 24, + "program": "launch.ets" + } + } + } + ], "loc": { "start": { - "line": 45, - "column": 10, + "line": 47, + "column": 9, "program": "launch.ets" }, "end": { - "line": 45, - "column": 18, + "line": 47, + "column": 25, "program": "launch.ets" } } }, "loc": { "start": { - "line": 45, + "line": 47, "column": 3, "program": "launch.ets" }, "end": { - "line": 45, - "column": 18, + "line": 47, + "column": 33, "program": "launch.ets" } } }, "loc": { "start": { - "line": 45, + "line": 47, "column": 3, "program": "launch.ets" }, "end": { - "line": 45, - "column": 19, + "line": 47, + "column": 34, "program": "launch.ets" } } @@ -2906,12 +3911,12 @@ ], "loc": { "start": { - "line": 35, + "line": 38, "column": 23, "program": "launch.ets" }, "end": { - "line": 46, + "line": 48, "column": 2, "program": "launch.ets" } @@ -2919,12 +3924,12 @@ }, "loc": { "start": { - "line": 35, + "line": 38, "column": 10, "program": "launch.ets" }, "end": { - "line": 46, + "line": 48, "column": 2, "program": "launch.ets" } @@ -2932,12 +3937,12 @@ }, "loc": { "start": { - "line": 35, + "line": 38, "column": 10, "program": "launch.ets" }, "end": { - "line": 46, + "line": 48, "column": 2, "program": "launch.ets" } @@ -2947,12 +3952,12 @@ "decorators": [], "loc": { "start": { - "line": 35, + "line": 38, "column": 1, "program": "launch.ets" }, "end": { - "line": 46, + "line": 48, "column": 2, "program": "launch.ets" } @@ -2993,7 +3998,7 @@ "program": "launch.ets" }, "end": { - "line": 47, + "line": 49, "column": 1, "program": "launch.ets" } diff --git a/ets2panda/test/parser/ets/launch.ets b/ets2panda/test/parser/ets/launch.ets index f75fc2466764fa9b4fb0e1ebc656d96ef49e5b9c..8e8cdc9c51a793cf1b0fb9ebf9d2cf7c0fdfc60a 100644 --- a/ets2panda/test/parser/ets/launch.ets +++ b/ets2panda/test/parser/ets/launch.ets @@ -13,12 +13,15 @@ * limitations under the License. */ +import {launch} from "std/concurrency" +import {Job} from "std/core" + class Example { public static foobar(): Object { return new Object(); } - public baz(): Object { + public static baz(): Object { return new Object(); } } @@ -28,19 +31,18 @@ function bar(x: int, y: float): Object { } function foo(x: int): Object { - launch bar(x, 30); + launchObject>(bar,x, 30); return new Object(); } function main(): void { - let p: Promise; - p = launch foo(11); - p = launch Example.foobar(); - p = launch new Example().baz(); - let example = new Example(); - p = launch example.baz(); + let p: Job; + p = launch Object>(foo, 11); + p = launch Object>(Example.foobar); + p = launch Object>(Example.baz); + p = launch Object>(Example.baz); let foo_ref: (x: int) => Object = foo; - p = launch foo_ref(5); + p = launch Object>(foo_ref, 5); let lambda: () => void = (): void => { return; } - launch lambda(); + launchvoid>(lambda); } diff --git a/ets2panda/test/parser/ets/launch_function_returning_void-expected.txt b/ets2panda/test/parser/ets/launch_function_returning_void-expected.txt index df3937236b48ff462957e821951ff28a91be4669..5d1e83c6afeb18d751929c3453c042fe54139502 100644 --- a/ets2panda/test/parser/ets/launch_function_returning_void-expected.txt +++ b/ets2panda/test/parser/ets/launch_function_returning_void-expected.txt @@ -1,6 +1,170 @@ { "type": "Program", "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/concurrency", + "loc": { + "start": { + "line": 16, + "column": 22, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_function_returning_void.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_function_returning_void.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_function_returning_void.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_function_returning_void.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_function_returning_void.ets" + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/core", + "loc": { + "start": { + "line": 17, + "column": 19, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "launch_function_returning_void.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch_function_returning_void.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch_function_returning_void.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch_function_returning_void.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 1, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "launch_function_returning_void.ets" + } + } + }, { "type": "ClassDeclaration", "definition": { @@ -23,40 +187,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_function_returning_void.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_function_returning_void.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_function_returning_void.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_function_returning_void.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -172,12 +302,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 10, "program": "launch_function_returning_void.ets" }, "end": { - "line": 16, + "line": 19, "column": 13, "program": "launch_function_returning_void.ets" } @@ -198,12 +328,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 10, "program": "launch_function_returning_void.ets" }, "end": { - "line": 16, + "line": 19, "column": 13, "program": "launch_function_returning_void.ets" } @@ -218,12 +348,12 @@ "statements": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 15, "program": "launch_function_returning_void.ets" }, "end": { - "line": 16, + "line": 19, "column": 17, "program": "launch_function_returning_void.ets" } @@ -231,12 +361,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 10, "program": "launch_function_returning_void.ets" }, "end": { - "line": 16, + "line": 19, "column": 17, "program": "launch_function_returning_void.ets" } @@ -244,12 +374,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 10, "program": "launch_function_returning_void.ets" }, "end": { - "line": 16, + "line": 19, "column": 17, "program": "launch_function_returning_void.ets" } @@ -259,12 +389,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 1, "program": "launch_function_returning_void.ets" }, "end": { - "line": 16, + "line": 19, "column": 17, "program": "launch_function_returning_void.ets" } @@ -278,12 +408,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 21, "column": 10, "program": "launch_function_returning_void.ets" }, "end": { - "line": 18, + "line": 21, "column": 14, "program": "launch_function_returning_void.ets" } @@ -304,12 +434,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 21, "column": 10, "program": "launch_function_returning_void.ets" }, "end": { - "line": 18, + "line": 21, "column": 14, "program": "launch_function_returning_void.ets" } @@ -336,17 +466,17 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "Promise", + "name": "Job", "decorators": [], "loc": { "start": { - "line": 19, + "line": 22, "column": 12, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 19, + "line": 22, + "column": 15, "program": "launch_function_returning_void.ets" } } @@ -358,13 +488,13 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 19, - "column": 20, + "line": 22, + "column": 16, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 24, + "line": 22, + "column": 20, "program": "launch_function_returning_void.ets" } } @@ -372,39 +502,39 @@ ], "loc": { "start": { - "line": 19, - "column": 19, + "line": 22, + "column": 15, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 25, + "line": 22, + "column": 21, "program": "launch_function_returning_void.ets" } } }, "loc": { "start": { - "line": 19, + "line": 22, "column": 12, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 27, + "line": 22, + "column": 23, "program": "launch_function_returning_void.ets" } } }, "loc": { "start": { - "line": 19, + "line": 22, "column": 12, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 27, + "line": 22, + "column": 23, "program": "launch_function_returning_void.ets" } } @@ -412,75 +542,141 @@ "decorators": [], "loc": { "start": { - "line": 19, + "line": 22, "column": 9, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, + "line": 22, "column": 10, "program": "launch_function_returning_void.ets" } } }, "init": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 24, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 22, + "column": 30, + "program": "launch_function_returning_void.ets" + } + } + }, + "arguments": [ + { "type": "Identifier", "name": "foo", "decorators": [], "loc": { "start": { - "line": 19, - "column": 35, + "line": 22, + "column": 49, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 38, + "line": 22, + "column": 52, "program": "launch_function_returning_void.ets" } } - }, - "arguments": [], - "optional": false, + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 22, + "column": 31, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 22, + "column": 35, + "program": "launch_function_returning_void.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 22, + "column": 43, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 22, + "column": 47, + "program": "launch_function_returning_void.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 37, + "program": "launch_function_returning_void.ets" + }, + "end": { + "line": 22, + "column": 47, + "program": "launch_function_returning_void.ets" + } + } + } + ], "loc": { "start": { - "line": 19, - "column": 35, + "line": 22, + "column": 30, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 40, + "line": 22, + "column": 48, "program": "launch_function_returning_void.ets" } } }, "loc": { "start": { - "line": 19, - "column": 28, + "line": 22, + "column": 24, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 40, + "line": 22, + "column": 53, "program": "launch_function_returning_void.ets" } } }, "loc": { "start": { - "line": 19, + "line": 22, "column": 9, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 40, + "line": 22, + "column": 53, "program": "launch_function_returning_void.ets" } } @@ -489,13 +685,13 @@ "kind": "let", "loc": { "start": { - "line": 19, + "line": 22, "column": 5, "program": "launch_function_returning_void.ets" }, "end": { - "line": 19, - "column": 40, + "line": 22, + "column": 53, "program": "launch_function_returning_void.ets" } } @@ -503,12 +699,12 @@ ], "loc": { "start": { - "line": 18, + "line": 21, "column": 16, "program": "launch_function_returning_void.ets" }, "end": { - "line": 20, + "line": 23, "column": 2, "program": "launch_function_returning_void.ets" } @@ -516,12 +712,12 @@ }, "loc": { "start": { - "line": 18, + "line": 21, "column": 10, "program": "launch_function_returning_void.ets" }, "end": { - "line": 20, + "line": 23, "column": 2, "program": "launch_function_returning_void.ets" } @@ -529,12 +725,12 @@ }, "loc": { "start": { - "line": 18, + "line": 21, "column": 10, "program": "launch_function_returning_void.ets" }, "end": { - "line": 20, + "line": 23, "column": 2, "program": "launch_function_returning_void.ets" } @@ -544,12 +740,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 21, "column": 1, "program": "launch_function_returning_void.ets" }, "end": { - "line": 20, + "line": 23, "column": 2, "program": "launch_function_returning_void.ets" } @@ -590,8 +786,8 @@ "program": "launch_function_returning_void.ets" }, "end": { - "line": 20, - "column": 2, + "line": 24, + "column": 1, "program": "launch_function_returning_void.ets" } } diff --git a/ets2panda/test/parser/ets/launch_function_returning_void.ets b/ets2panda/test/parser/ets/launch_function_returning_void.ets index e209cc3733d59788cf97cc934ba9b73e46fd1321..def9bf343e9935379e1c7e3d3c7e2c6a8c629cd3 100644 --- a/ets2panda/test/parser/ets/launch_function_returning_void.ets +++ b/ets2panda/test/parser/ets/launch_function_returning_void.ets @@ -13,8 +13,11 @@ * limitations under the License. */ +import {launch} from "std/concurrency" +import {Job} from "std/core" + function foo(){} function main(){ - let r: Promise = launch foo() -} \ No newline at end of file + let r: Job = launch void>(foo) +} diff --git a/ets2panda/test/parser/ets/launch_ret-expected.txt b/ets2panda/test/parser/ets/launch_ret-expected.txt index 245cebb3a48c0129e699fca573ef8fe1ace86cd2..4180ac8afbdd59df6ca235a2fc652430df384873 100644 --- a/ets2panda/test/parser/ets/launch_ret-expected.txt +++ b/ets2panda/test/parser/ets/launch_ret-expected.txt @@ -1,6 +1,170 @@ { "type": "Program", "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/concurrency", + "loc": { + "start": { + "line": 16, + "column": 22, + "program": "launch_ret.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_ret.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_ret.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_ret.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_ret.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_ret.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_ret.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_ret.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1, + "program": "launch_ret.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_ret.ets" + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/core", + "loc": { + "start": { + "line": 17, + "column": 19, + "program": "launch_ret.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "launch_ret.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch_ret.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch_ret.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch_ret.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch_ret.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch_ret.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch_ret.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 1, + "program": "launch_ret.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "launch_ret.ets" + } + } + }, { "type": "ClassDeclaration", "definition": { @@ -23,40 +187,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_ret.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_ret.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_ret.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_ret.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -172,12 +302,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 10, "program": "launch_ret.ets" }, "end": { - "line": 16, + "line": 19, "column": 16, "program": "launch_ret.ets" } @@ -198,12 +328,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 10, "program": "launch_ret.ets" }, "end": { - "line": 16, + "line": 19, "column": 16, "program": "launch_ret.ets" } @@ -217,12 +347,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 16, + "line": 19, "column": 20, "program": "launch_ret.ets" }, "end": { - "line": 16, + "line": 19, "column": 23, "program": "launch_ret.ets" } @@ -238,12 +368,12 @@ "value": 5, "loc": { "start": { - "line": 17, + "line": 20, "column": 12, "program": "launch_ret.ets" }, "end": { - "line": 17, + "line": 20, "column": 13, "program": "launch_ret.ets" } @@ -251,12 +381,12 @@ }, "loc": { "start": { - "line": 17, + "line": 20, "column": 5, "program": "launch_ret.ets" }, "end": { - "line": 17, + "line": 20, "column": 14, "program": "launch_ret.ets" } @@ -265,12 +395,12 @@ ], "loc": { "start": { - "line": 16, + "line": 19, "column": 24, "program": "launch_ret.ets" }, "end": { - "line": 18, + "line": 21, "column": 2, "program": "launch_ret.ets" } @@ -278,12 +408,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 10, "program": "launch_ret.ets" }, "end": { - "line": 18, + "line": 21, "column": 2, "program": "launch_ret.ets" } @@ -291,12 +421,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 10, "program": "launch_ret.ets" }, "end": { - "line": 18, + "line": 21, "column": 2, "program": "launch_ret.ets" } @@ -306,12 +436,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 1, "program": "launch_ret.ets" }, "end": { - "line": 18, + "line": 21, "column": 2, "program": "launch_ret.ets" } @@ -325,12 +455,12 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 23, "column": 10, "program": "launch_ret.ets" }, "end": { - "line": 20, + "line": 23, "column": 14, "program": "launch_ret.ets" } @@ -351,12 +481,12 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 23, "column": 10, "program": "launch_ret.ets" }, "end": { - "line": 20, + "line": 23, "column": 14, "program": "launch_ret.ets" } @@ -370,12 +500,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 20, + "line": 23, "column": 18, "program": "launch_ret.ets" }, "end": { - "line": 20, + "line": 23, "column": 22, "program": "launch_ret.ets" } @@ -398,17 +528,17 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "Promise", + "name": "Job", "decorators": [], "loc": { "start": { - "line": 21, + "line": 24, "column": 12, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 19, + "line": 24, + "column": 15, "program": "launch_ret.ets" } } @@ -420,13 +550,13 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 21, - "column": 20, + "line": 24, + "column": 16, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 23, + "line": 24, + "column": 19, "program": "launch_ret.ets" } } @@ -434,39 +564,39 @@ ], "loc": { "start": { - "line": 21, - "column": 19, + "line": 24, + "column": 15, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 24, + "line": 24, + "column": 20, "program": "launch_ret.ets" } } }, "loc": { "start": { - "line": 21, + "line": 24, "column": 12, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 26, + "line": 24, + "column": 22, "program": "launch_ret.ets" } } }, "loc": { "start": { - "line": 21, + "line": 24, "column": 12, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 26, + "line": 24, + "column": 22, "program": "launch_ret.ets" } } @@ -474,75 +604,141 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 24, "column": 9, "program": "launch_ret.ets" }, "end": { - "line": 21, + "line": 24, "column": 10, "program": "launch_ret.ets" } } }, "init": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 23, + "program": "launch_ret.ets" + }, + "end": { + "line": 24, + "column": 29, + "program": "launch_ret.ets" + } + } + }, + "arguments": [ + { "type": "Identifier", "name": "fooInt", "decorators": [], "loc": { "start": { - "line": 21, - "column": 34, + "line": 24, + "column": 46, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 40, + "line": 24, + "column": 52, "program": "launch_ret.ets" } } - }, - "arguments": [], - "optional": false, + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 24, + "column": 30, + "program": "launch_ret.ets" + }, + "end": { + "line": 24, + "column": 33, + "program": "launch_ret.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 24, + "column": 41, + "program": "launch_ret.ets" + }, + "end": { + "line": 24, + "column": 44, + "program": "launch_ret.ets" + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 35, + "program": "launch_ret.ets" + }, + "end": { + "line": 24, + "column": 44, + "program": "launch_ret.ets" + } + } + } + ], "loc": { "start": { - "line": 21, - "column": 34, + "line": 24, + "column": 29, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 42, + "line": 24, + "column": 45, "program": "launch_ret.ets" } } }, "loc": { "start": { - "line": 21, - "column": 27, + "line": 24, + "column": 23, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 42, + "line": 24, + "column": 53, "program": "launch_ret.ets" } } }, "loc": { "start": { - "line": 21, + "line": 24, "column": 9, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 42, + "line": 24, + "column": 53, "program": "launch_ret.ets" } } @@ -551,13 +747,13 @@ "kind": "let", "loc": { "start": { - "line": 21, + "line": 24, "column": 5, "program": "launch_ret.ets" }, "end": { - "line": 21, - "column": 43, + "line": 24, + "column": 54, "program": "launch_ret.ets" } } @@ -565,12 +761,12 @@ ], "loc": { "start": { - "line": 20, + "line": 23, "column": 23, "program": "launch_ret.ets" }, "end": { - "line": 22, + "line": 25, "column": 2, "program": "launch_ret.ets" } @@ -578,12 +774,12 @@ }, "loc": { "start": { - "line": 20, + "line": 23, "column": 10, "program": "launch_ret.ets" }, "end": { - "line": 22, + "line": 25, "column": 2, "program": "launch_ret.ets" } @@ -591,12 +787,12 @@ }, "loc": { "start": { - "line": 20, + "line": 23, "column": 10, "program": "launch_ret.ets" }, "end": { - "line": 22, + "line": 25, "column": 2, "program": "launch_ret.ets" } @@ -606,12 +802,12 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 23, "column": 1, "program": "launch_ret.ets" }, "end": { - "line": 22, + "line": 25, "column": 2, "program": "launch_ret.ets" } @@ -652,7 +848,7 @@ "program": "launch_ret.ets" }, "end": { - "line": 23, + "line": 26, "column": 1, "program": "launch_ret.ets" } diff --git a/ets2panda/test/parser/ets/launch_ret.ets b/ets2panda/test/parser/ets/launch_ret.ets index ac9be23ddcb5664a672edede34ad741eb3ccd874..048de2c978922560e29352c7086b73bc7d94d218 100644 --- a/ets2panda/test/parser/ets/launch_ret.ets +++ b/ets2panda/test/parser/ets/launch_ret.ets @@ -13,10 +13,13 @@ * limitations under the License. */ +import {launch} from "std/concurrency" +import {Job} from "std/core" + function fooInt(): int { return 5; } function main(): void { - let p: Promise = launch fooInt(); + let p: Job = launch int>(fooInt); } diff --git a/ets2panda/test/parser/ets/launch_super-expected.txt b/ets2panda/test/parser/ets/launch_super-expected.txt index e5fedb878ac700676f10b86cb1a9a96dfe6a6e5f..1b6eb9618888865fb1e461e82f4b542d9740d30a 100755 --- a/ets2panda/test/parser/ets/launch_super-expected.txt +++ b/ets2panda/test/parser/ets/launch_super-expected.txt @@ -1,6 +1,88 @@ { "type": "Program", "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/concurrency", + "loc": { + "start": { + "line": 16, + "column": 22, + "program": "launch_super.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_super.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_super.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_super.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_super.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_super.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_super.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_super.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1, + "program": "launch_super.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_super.ets" + } + } + }, { "type": "ClassDeclaration", "definition": { @@ -10,12 +92,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 18, "column": 7, "program": "launch_super.ets" }, "end": { - "line": 16, + "line": 18, "column": 11, "program": "launch_super.ets" } @@ -32,13 +114,13 @@ "decorators": [], "loc": { "start": { - "line": 17, - "column": 13, + "line": 19, + "column": 12, "program": "launch_super.ets" }, "end": { - "line": 17, - "column": 16, + "line": 19, + "column": 15, "program": "launch_super.ets" } } @@ -58,13 +140,13 @@ "decorators": [], "loc": { "start": { - "line": 17, - "column": 13, + "line": 19, + "column": 12, "program": "launch_super.ets" }, "end": { - "line": 17, - "column": 16, + "line": 19, + "column": 15, "program": "launch_super.ets" } } @@ -77,13 +159,13 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 17, - "column": 20, + "line": 19, + "column": 19, "program": "launch_super.ets" }, "end": { - "line": 17, - "column": 24, + "line": 19, + "column": 23, "program": "launch_super.ets" } } @@ -93,39 +175,39 @@ "statements": [], "loc": { "start": { - "line": 17, - "column": 25, + "line": 19, + "column": 24, "program": "launch_super.ets" }, "end": { - "line": 17, - "column": 27, + "line": 19, + "column": 26, "program": "launch_super.ets" } } }, "loc": { "start": { - "line": 17, - "column": 16, + "line": 19, + "column": 15, "program": "launch_super.ets" }, "end": { - "line": 17, - "column": 27, + "line": 19, + "column": 26, "program": "launch_super.ets" } } }, "loc": { "start": { - "line": 17, - "column": 16, + "line": 19, + "column": 15, "program": "launch_super.ets" }, "end": { - "line": 17, - "column": 27, + "line": 19, + "column": 26, "program": "launch_super.ets" } } @@ -134,13 +216,13 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 19, "column": 5, "program": "launch_super.ets" }, "end": { - "line": 17, - "column": 27, + "line": 19, + "column": 26, "program": "launch_super.ets" } } @@ -153,12 +235,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" }, "end": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" } @@ -178,12 +260,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" }, "end": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" } @@ -198,12 +280,12 @@ "statements": [], "loc": { "start": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" }, "end": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" } @@ -211,12 +293,12 @@ }, "loc": { "start": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" }, "end": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" } @@ -224,12 +306,12 @@ }, "loc": { "start": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" }, "end": { - "line": 16, + "line": 18, "column": 13, "program": "launch_super.ets" } @@ -253,12 +335,12 @@ ], "loc": { "start": { - "line": 16, + "line": 18, "column": 12, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 6, "program": "launch_super.ets" } @@ -266,12 +348,12 @@ }, "loc": { "start": { - "line": 16, + "line": 18, "column": 1, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 6, "program": "launch_super.ets" } @@ -286,12 +368,12 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 22, "column": 7, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 14, "program": "launch_super.ets" } @@ -307,12 +389,12 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 22, "column": 23, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 27, "program": "launch_super.ets" } @@ -320,12 +402,12 @@ }, "loc": { "start": { - "line": 20, + "line": 22, "column": 23, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" } @@ -333,12 +415,12 @@ }, "loc": { "start": { - "line": 20, + "line": 22, "column": 23, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" } @@ -354,12 +436,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 23, "column": 14, "program": "launch_super.ets" }, "end": { - "line": 21, + "line": 23, "column": 17, "program": "launch_super.ets" } @@ -380,12 +462,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 23, "column": 14, "program": "launch_super.ets" }, "end": { - "line": 21, + "line": 23, "column": 17, "program": "launch_super.ets" } @@ -399,12 +481,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 21, + "line": 23, "column": 21, "program": "launch_super.ets" }, "end": { - "line": 21, + "line": 23, "column": 25, "program": "launch_super.ets" } @@ -416,22 +498,38 @@ { "type": "ExpressionStatement", "expression": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 9, + "program": "launch_super.ets" + }, + "end": { + "line": 24, + "column": 15, + "program": "launch_super.ets" + } + } + }, + "arguments": [ + { "type": "MemberExpression", "object": { "type": "Super", "loc": { "start": { - "line": 22, - "column": 16, + "line": 24, + "column": 34, "program": "launch_super.ets" }, "end": { - "line": 22, - "column": 21, + "line": 24, + "column": 39, "program": "launch_super.ets" } } @@ -442,13 +540,13 @@ "decorators": [], "loc": { "start": { - "line": 22, - "column": 22, + "line": 24, + "column": 40, "program": "launch_super.ets" }, "end": { - "line": 22, - "column": 25, + "line": 24, + "column": 43, "program": "launch_super.ets" } } @@ -457,54 +555,104 @@ "optional": false, "loc": { "start": { - "line": 22, - "column": 16, + "line": 24, + "column": 34, "program": "launch_super.ets" }, "end": { - "line": 22, - "column": 25, + "line": 24, + "column": 43, "program": "launch_super.ets" } } - }, - "arguments": [], - "optional": false, + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 24, + "column": 16, + "program": "launch_super.ets" + }, + "end": { + "line": 24, + "column": 20, + "program": "launch_super.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 24, + "column": 28, + "program": "launch_super.ets" + }, + "end": { + "line": 24, + "column": 32, + "program": "launch_super.ets" + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 22, + "program": "launch_super.ets" + }, + "end": { + "line": 24, + "column": 32, + "program": "launch_super.ets" + } + } + } + ], "loc": { "start": { - "line": 22, - "column": 16, + "line": 24, + "column": 15, "program": "launch_super.ets" }, "end": { - "line": 22, - "column": 27, + "line": 24, + "column": 33, "program": "launch_super.ets" } } }, "loc": { "start": { - "line": 22, + "line": 24, "column": 9, "program": "launch_super.ets" }, "end": { - "line": 22, - "column": 27, + "line": 24, + "column": 44, "program": "launch_super.ets" } } }, "loc": { "start": { - "line": 22, + "line": 24, "column": 9, "program": "launch_super.ets" }, "end": { - "line": 22, - "column": 28, + "line": 24, + "column": 45, "program": "launch_super.ets" } } @@ -512,12 +660,12 @@ ], "loc": { "start": { - "line": 21, + "line": 23, "column": 26, "program": "launch_super.ets" }, "end": { - "line": 23, + "line": 25, "column": 6, "program": "launch_super.ets" } @@ -525,12 +673,12 @@ }, "loc": { "start": { - "line": 21, + "line": 23, "column": 17, "program": "launch_super.ets" }, "end": { - "line": 23, + "line": 25, "column": 6, "program": "launch_super.ets" } @@ -538,12 +686,12 @@ }, "loc": { "start": { - "line": 21, + "line": 23, "column": 17, "program": "launch_super.ets" }, "end": { - "line": 23, + "line": 25, "column": 6, "program": "launch_super.ets" } @@ -553,12 +701,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 23, "column": 5, "program": "launch_super.ets" }, "end": { - "line": 23, + "line": 25, "column": 6, "program": "launch_super.ets" } @@ -572,12 +720,12 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" } @@ -597,12 +745,12 @@ "decorators": [], "loc": { "start": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" } @@ -617,12 +765,12 @@ "statements": [], "loc": { "start": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" } @@ -630,12 +778,12 @@ }, "loc": { "start": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" } @@ -643,12 +791,12 @@ }, "loc": { "start": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" }, "end": { - "line": 20, + "line": 22, "column": 29, "program": "launch_super.ets" } @@ -672,12 +820,12 @@ ], "loc": { "start": { - "line": 20, + "line": 22, "column": 28, "program": "launch_super.ets" }, "end": { - "line": 25, + "line": 27, "column": 1, "program": "launch_super.ets" } @@ -685,12 +833,12 @@ }, "loc": { "start": { - "line": 20, + "line": 22, "column": 1, "program": "launch_super.ets" }, "end": { - "line": 25, + "line": 27, "column": 1, "program": "launch_super.ets" } @@ -718,40 +866,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_super.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_super.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_super.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_super.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1000,7 +1114,7 @@ "program": "launch_super.ets" }, "end": { - "line": 25, + "line": 27, "column": 1, "program": "launch_super.ets" } diff --git a/ets2panda/test/parser/ets/launch_super.ets b/ets2panda/test/parser/ets/launch_super.ets index f479a62e6a37e2ba57c65277fbf4dfec0ae04d2e..bf1e68c2b6dc21354f94d65dfb9cdf2edb1fe520 100644 --- a/ets2panda/test/parser/ets/launch_super.ets +++ b/ets2panda/test/parser/ets/launch_super.ets @@ -13,12 +13,14 @@ * limitations under the License. */ +import {launch} from "std/concurrency" + class Base { - public foo(): void {} + public foo(): void {} } class Derived extends Base { override foo(): void { - launch super.foo(); + launch void>(super.foo); } } diff --git a/ets2panda/test/parser/ets/launch_this_callee-expected.txt b/ets2panda/test/parser/ets/launch_this_callee-expected.txt index 792f47433ad9a4bbcb87f0b30064590a0bfb3692..2c2a4475765377a0b230d6b230843d0d43c7d5ae 100755 --- a/ets2panda/test/parser/ets/launch_this_callee-expected.txt +++ b/ets2panda/test/parser/ets/launch_this_callee-expected.txt @@ -1,6 +1,170 @@ { "type": "Program", "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/concurrency", + "loc": { + "start": { + "line": 16, + "column": 22, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_this_callee.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_this_callee.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "launch_this_callee.ets" + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "launch_this_callee.ets" + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/core", + "loc": { + "start": { + "line": 17, + "column": 19, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "launch_this_callee.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch_this_callee.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "launch_this_callee.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 1, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "launch_this_callee.ets" + } + } + }, { "type": "ClassDeclaration", "definition": { @@ -10,12 +174,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 7, "program": "launch_this_callee.ets" }, "end": { - "line": 16, + "line": 19, "column": 10, "program": "launch_this_callee.ets" } @@ -32,12 +196,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 20, "column": 11, "program": "launch_this_callee.ets" }, "end": { - "line": 17, + "line": 20, "column": 14, "program": "launch_this_callee.ets" } @@ -58,12 +222,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 20, "column": 11, "program": "launch_this_callee.ets" }, "end": { - "line": 17, + "line": 20, "column": 14, "program": "launch_this_callee.ets" } @@ -79,17 +243,17 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "Promise", + "name": "Job", "decorators": [], "loc": { "start": { - "line": 17, + "line": 20, "column": 18, "program": "launch_this_callee.ets" }, "end": { - "line": 17, - "column": 25, + "line": 20, + "column": 21, "program": "launch_this_callee.ets" } } @@ -107,39 +271,39 @@ "decorators": [], "loc": { "start": { - "line": 17, - "column": 26, + "line": 20, + "column": 22, "program": "launch_this_callee.ets" }, "end": { - "line": 17, - "column": 29, + "line": 20, + "column": 25, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 17, - "column": 26, + "line": 20, + "column": 22, "program": "launch_this_callee.ets" }, "end": { - "line": 17, - "column": 30, + "line": 20, + "column": 26, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 17, - "column": 26, + "line": 20, + "column": 22, "program": "launch_this_callee.ets" }, "end": { - "line": 17, - "column": 30, + "line": 20, + "column": 26, "program": "launch_this_callee.ets" } } @@ -147,39 +311,39 @@ ], "loc": { "start": { - "line": 17, - "column": 25, + "line": 20, + "column": 21, "program": "launch_this_callee.ets" }, "end": { - "line": 17, - "column": 30, + "line": 20, + "column": 26, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 17, + "line": 20, "column": 18, "program": "launch_this_callee.ets" }, "end": { - "line": 17, - "column": 32, + "line": 20, + "column": 28, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 17, + "line": 20, "column": 18, "program": "launch_this_callee.ets" }, "end": { - "line": 17, - "column": 32, + "line": 20, + "column": 28, "program": "launch_this_callee.ets" } } @@ -190,22 +354,38 @@ { "type": "ReturnStatement", "argument": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 12, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 18, + "program": "launch_this_callee.ets" + } + } + }, + "arguments": [ + { "type": "MemberExpression", "object": { "type": "ThisExpression", "loc": { "start": { - "line": 18, - "column": 19, + "line": 21, + "column": 41, "program": "launch_this_callee.ets" }, "end": { - "line": 18, - "column": 23, + "line": 21, + "column": 45, "program": "launch_this_callee.ets" } } @@ -216,13 +396,13 @@ "decorators": [], "loc": { "start": { - "line": 18, - "column": 24, + "line": 21, + "column": 46, "program": "launch_this_callee.ets" }, "end": { - "line": 18, - "column": 27, + "line": 21, + "column": 49, "program": "launch_this_callee.ets" } } @@ -231,70 +411,263 @@ "optional": false, "loc": { "start": { - "line": 18, - "column": 19, + "line": 21, + "column": 41, "program": "launch_this_callee.ets" }, "end": { - "line": 18, - "column": 27, + "line": 21, + "column": 49, "program": "launch_this_callee.ets" } } }, - "arguments": [ + { + "type": "ThisExpression", + "loc": { + "start": { + "line": 21, + "column": 51, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 55, + "program": "launch_this_callee.ets" + } + } + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ { - "type": "ThisExpression", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Foo", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 19, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 22, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 19, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 23, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 19, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 23, + "program": "launch_this_callee.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "f", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Foo", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 28, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 31, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 28, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 32, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 28, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 32, + "program": "launch_this_callee.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 25, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 32, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 25, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 32, + "program": "launch_this_callee.ets" + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Foo", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 36, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 39, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 36, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 40, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 36, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 21, + "column": 40, + "program": "launch_this_callee.ets" + } + } + }, "loc": { "start": { - "line": 18, - "column": 28, + "line": 21, + "column": 24, "program": "launch_this_callee.ets" }, "end": { - "line": 18, - "column": 32, + "line": 21, + "column": 40, "program": "launch_this_callee.ets" } } } ], - "optional": false, "loc": { "start": { - "line": 18, - "column": 19, + "line": 21, + "column": 18, "program": "launch_this_callee.ets" }, "end": { - "line": 18, - "column": 33, + "line": 21, + "column": 40, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 18, + "line": 21, "column": 12, "program": "launch_this_callee.ets" }, "end": { - "line": 18, - "column": 33, + "line": 21, + "column": 56, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 18, + "line": 21, "column": 5, "program": "launch_this_callee.ets" }, "end": { - "line": 18, - "column": 34, + "line": 21, + "column": 57, "program": "launch_this_callee.ets" } } @@ -302,12 +675,12 @@ ], "loc": { "start": { - "line": 17, - "column": 31, + "line": 20, + "column": 27, "program": "launch_this_callee.ets" }, "end": { - "line": 19, + "line": 22, "column": 4, "program": "launch_this_callee.ets" } @@ -315,12 +688,12 @@ }, "loc": { "start": { - "line": 17, + "line": 20, "column": 14, "program": "launch_this_callee.ets" }, "end": { - "line": 19, + "line": 22, "column": 4, "program": "launch_this_callee.ets" } @@ -328,12 +701,12 @@ }, "loc": { "start": { - "line": 17, + "line": 20, "column": 14, "program": "launch_this_callee.ets" }, "end": { - "line": 19, + "line": 22, "column": 4, "program": "launch_this_callee.ets" } @@ -343,12 +716,12 @@ "decorators": [], "loc": { "start": { - "line": 17, + "line": 20, "column": 3, "program": "launch_this_callee.ets" }, "end": { - "line": 19, + "line": 22, "column": 4, "program": "launch_this_callee.ets" } @@ -362,12 +735,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 24, "column": 11, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 14, "program": "launch_this_callee.ets" } @@ -388,12 +761,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 24, "column": 11, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 14, "program": "launch_this_callee.ets" } @@ -418,12 +791,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 24, "column": 18, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 21, "program": "launch_this_callee.ets" } @@ -431,12 +804,12 @@ }, "loc": { "start": { - "line": 21, + "line": 24, "column": 18, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 22, "program": "launch_this_callee.ets" } @@ -444,12 +817,12 @@ }, "loc": { "start": { - "line": 21, + "line": 24, "column": 18, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 22, "program": "launch_this_callee.ets" } @@ -458,12 +831,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 24, "column": 15, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 22, "program": "launch_this_callee.ets" } @@ -471,12 +844,12 @@ }, "loc": { "start": { - "line": 21, + "line": 24, "column": 15, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 22, "program": "launch_this_callee.ets" } @@ -493,12 +866,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 24, "column": 24, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 27, "program": "launch_this_callee.ets" } @@ -506,12 +879,12 @@ }, "loc": { "start": { - "line": 21, + "line": 24, "column": 24, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 29, "program": "launch_this_callee.ets" } @@ -519,12 +892,12 @@ }, "loc": { "start": { - "line": 21, + "line": 24, "column": 24, "program": "launch_this_callee.ets" }, "end": { - "line": 21, + "line": 24, "column": 29, "program": "launch_this_callee.ets" } @@ -541,12 +914,12 @@ "decorators": [], "loc": { "start": { - "line": 22, + "line": 25, "column": 12, "program": "launch_this_callee.ets" }, "end": { - "line": 22, + "line": 25, "column": 13, "program": "launch_this_callee.ets" } @@ -554,12 +927,12 @@ }, "loc": { "start": { - "line": 22, + "line": 25, "column": 5, "program": "launch_this_callee.ets" }, "end": { - "line": 22, + "line": 25, "column": 14, "program": "launch_this_callee.ets" } @@ -568,12 +941,12 @@ ], "loc": { "start": { - "line": 21, + "line": 24, "column": 28, "program": "launch_this_callee.ets" }, "end": { - "line": 23, + "line": 26, "column": 4, "program": "launch_this_callee.ets" } @@ -581,12 +954,12 @@ }, "loc": { "start": { - "line": 21, + "line": 24, "column": 14, "program": "launch_this_callee.ets" }, "end": { - "line": 23, + "line": 26, "column": 4, "program": "launch_this_callee.ets" } @@ -594,12 +967,12 @@ }, "loc": { "start": { - "line": 21, + "line": 24, "column": 14, "program": "launch_this_callee.ets" }, "end": { - "line": 23, + "line": 26, "column": 4, "program": "launch_this_callee.ets" } @@ -609,12 +982,12 @@ "decorators": [], "loc": { "start": { - "line": 21, + "line": 24, "column": 3, "program": "launch_this_callee.ets" }, "end": { - "line": 23, + "line": 26, "column": 4, "program": "launch_this_callee.ets" } @@ -628,12 +1001,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 28, "column": 11, "program": "launch_this_callee.ets" }, "end": { - "line": 25, + "line": 28, "column": 15, "program": "launch_this_callee.ets" } @@ -654,12 +1027,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 28, "column": 11, "program": "launch_this_callee.ets" }, "end": { - "line": 25, + "line": 28, "column": 15, "program": "launch_this_callee.ets" } @@ -675,17 +1048,17 @@ "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "Promise", + "name": "Job", "decorators": [], "loc": { "start": { - "line": 25, + "line": 28, "column": 19, "program": "launch_this_callee.ets" }, "end": { - "line": 25, - "column": 26, + "line": 28, + "column": 22, "program": "launch_this_callee.ets" } } @@ -703,39 +1076,39 @@ "decorators": [], "loc": { "start": { - "line": 25, - "column": 27, + "line": 28, + "column": 23, "program": "launch_this_callee.ets" }, "end": { - "line": 25, - "column": 30, + "line": 28, + "column": 26, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 25, - "column": 27, + "line": 28, + "column": 23, "program": "launch_this_callee.ets" }, "end": { - "line": 25, - "column": 31, + "line": 28, + "column": 27, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 25, - "column": 27, + "line": 28, + "column": 23, "program": "launch_this_callee.ets" }, "end": { - "line": 25, - "column": 31, + "line": 28, + "column": 27, "program": "launch_this_callee.ets" } } @@ -743,39 +1116,39 @@ ], "loc": { "start": { - "line": 25, - "column": 26, + "line": 28, + "column": 22, "program": "launch_this_callee.ets" }, "end": { - "line": 25, - "column": 31, + "line": 28, + "column": 27, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 25, + "line": 28, "column": 19, "program": "launch_this_callee.ets" }, "end": { - "line": 25, - "column": 33, + "line": 28, + "column": 29, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 25, + "line": 28, "column": 19, "program": "launch_this_callee.ets" }, "end": { - "line": 25, - "column": 33, + "line": 28, + "column": 29, "program": "launch_this_callee.ets" } } @@ -786,22 +1159,38 @@ { "type": "ReturnStatement", "argument": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 12, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 18, + "program": "launch_this_callee.ets" + } + } + }, + "arguments": [ + { "type": "MemberExpression", "object": { "type": "ThisExpression", "loc": { "start": { - "line": 26, - "column": 19, + "line": 29, + "column": 49, "program": "launch_this_callee.ets" }, "end": { - "line": 26, - "column": 23, + "line": 29, + "column": 53, "program": "launch_this_callee.ets" } } @@ -812,13 +1201,13 @@ "decorators": [], "loc": { "start": { - "line": 26, - "column": 24, + "line": 29, + "column": 54, "program": "launch_this_callee.ets" }, "end": { - "line": 26, - "column": 28, + "line": 29, + "column": 58, "program": "launch_this_callee.ets" } } @@ -827,86 +1216,326 @@ "optional": false, "loc": { "start": { - "line": 26, - "column": 19, + "line": 29, + "column": 49, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 58, + "program": "launch_this_callee.ets" + } + } + }, + { + "type": "ThisExpression", + "loc": { + "start": { + "line": 29, + "column": 60, "program": "launch_this_callee.ets" }, "end": { - "line": 26, - "column": 28, + "line": 29, + "column": 64, "program": "launch_this_callee.ets" } } }, - "arguments": [ + { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 29, + "column": 66, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 67, + "program": "launch_this_callee.ets" + } + } + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ { - "type": "ThisExpression", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Foo", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 19, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 22, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 19, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 23, + "program": "launch_this_callee.ets" + } + } + }, "loc": { "start": { - "line": 26, - "column": 29, + "line": 29, + "column": 19, "program": "launch_this_callee.ets" }, "end": { - "line": 26, - "column": 33, + "line": 29, + "column": 23, "program": "launch_this_callee.ets" } } }, { - "type": "NumberLiteral", - "value": 1, + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "f", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Foo", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 28, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 31, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 28, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 32, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 28, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 32, + "program": "launch_this_callee.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 25, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 32, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 25, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 32, + "program": "launch_this_callee.ets" + } + } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "i", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 29, + "column": 36, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 39, + "program": "launch_this_callee.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 33, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 39, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 33, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 39, + "program": "launch_this_callee.ets" + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Foo", + "decorators": [], + "loc": { + "start": { + "line": 29, + "column": 44, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 47, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 44, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 48, + "program": "launch_this_callee.ets" + } + } + }, + "loc": { + "start": { + "line": 29, + "column": 44, + "program": "launch_this_callee.ets" + }, + "end": { + "line": 29, + "column": 48, + "program": "launch_this_callee.ets" + } + } + }, "loc": { "start": { - "line": 26, - "column": 35, + "line": 29, + "column": 24, "program": "launch_this_callee.ets" }, "end": { - "line": 26, - "column": 36, + "line": 29, + "column": 48, "program": "launch_this_callee.ets" } } } ], - "optional": false, "loc": { "start": { - "line": 26, - "column": 19, + "line": 29, + "column": 18, "program": "launch_this_callee.ets" }, "end": { - "line": 26, - "column": 37, + "line": 29, + "column": 48, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 26, + "line": 29, "column": 12, "program": "launch_this_callee.ets" }, "end": { - "line": 26, - "column": 37, + "line": 29, + "column": 68, "program": "launch_this_callee.ets" } } }, "loc": { "start": { - "line": 26, + "line": 29, "column": 5, "program": "launch_this_callee.ets" }, "end": { - "line": 26, - "column": 38, + "line": 29, + "column": 69, "program": "launch_this_callee.ets" } } @@ -914,12 +1543,12 @@ ], "loc": { "start": { - "line": 25, - "column": 32, + "line": 28, + "column": 28, "program": "launch_this_callee.ets" }, "end": { - "line": 27, + "line": 30, "column": 4, "program": "launch_this_callee.ets" } @@ -927,12 +1556,12 @@ }, "loc": { "start": { - "line": 25, + "line": 28, "column": 15, "program": "launch_this_callee.ets" }, "end": { - "line": 27, + "line": 30, "column": 4, "program": "launch_this_callee.ets" } @@ -940,12 +1569,12 @@ }, "loc": { "start": { - "line": 25, + "line": 28, "column": 15, "program": "launch_this_callee.ets" }, "end": { - "line": 27, + "line": 30, "column": 4, "program": "launch_this_callee.ets" } @@ -955,12 +1584,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 28, "column": 3, "program": "launch_this_callee.ets" }, "end": { - "line": 27, + "line": 30, "column": 4, "program": "launch_this_callee.ets" } @@ -974,12 +1603,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 32, "column": 11, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 15, "program": "launch_this_callee.ets" } @@ -1000,12 +1629,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 32, "column": 11, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 15, "program": "launch_this_callee.ets" } @@ -1030,12 +1659,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 32, "column": 19, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 22, "program": "launch_this_callee.ets" } @@ -1043,12 +1672,12 @@ }, "loc": { "start": { - "line": 29, + "line": 32, "column": 19, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 23, "program": "launch_this_callee.ets" } @@ -1056,12 +1685,12 @@ }, "loc": { "start": { - "line": 29, + "line": 32, "column": 19, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 23, "program": "launch_this_callee.ets" } @@ -1070,12 +1699,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 32, "column": 16, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 23, "program": "launch_this_callee.ets" } @@ -1083,12 +1712,12 @@ }, "loc": { "start": { - "line": 29, + "line": 32, "column": 16, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 23, "program": "launch_this_callee.ets" } @@ -1103,12 +1732,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 29, + "line": 32, "column": 27, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 30, "program": "launch_this_callee.ets" } @@ -1117,12 +1746,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 32, "column": 24, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 30, "program": "launch_this_callee.ets" } @@ -1130,12 +1759,12 @@ }, "loc": { "start": { - "line": 29, + "line": 32, "column": 24, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 30, "program": "launch_this_callee.ets" } @@ -1152,12 +1781,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 32, "column": 33, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 36, "program": "launch_this_callee.ets" } @@ -1165,12 +1794,12 @@ }, "loc": { "start": { - "line": 29, + "line": 32, "column": 33, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 38, "program": "launch_this_callee.ets" } @@ -1178,12 +1807,12 @@ }, "loc": { "start": { - "line": 29, + "line": 32, "column": 33, "program": "launch_this_callee.ets" }, "end": { - "line": 29, + "line": 32, "column": 38, "program": "launch_this_callee.ets" } @@ -1200,12 +1829,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 33, "column": 12, "program": "launch_this_callee.ets" }, "end": { - "line": 30, + "line": 33, "column": 13, "program": "launch_this_callee.ets" } @@ -1213,12 +1842,12 @@ }, "loc": { "start": { - "line": 30, + "line": 33, "column": 5, "program": "launch_this_callee.ets" }, "end": { - "line": 30, + "line": 33, "column": 14, "program": "launch_this_callee.ets" } @@ -1227,12 +1856,12 @@ ], "loc": { "start": { - "line": 29, + "line": 32, "column": 37, "program": "launch_this_callee.ets" }, "end": { - "line": 31, + "line": 34, "column": 4, "program": "launch_this_callee.ets" } @@ -1240,12 +1869,12 @@ }, "loc": { "start": { - "line": 29, + "line": 32, "column": 15, "program": "launch_this_callee.ets" }, "end": { - "line": 31, + "line": 34, "column": 4, "program": "launch_this_callee.ets" } @@ -1253,12 +1882,12 @@ }, "loc": { "start": { - "line": 29, + "line": 32, "column": 15, "program": "launch_this_callee.ets" }, "end": { - "line": 31, + "line": 34, "column": 4, "program": "launch_this_callee.ets" } @@ -1268,12 +1897,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 32, "column": 3, "program": "launch_this_callee.ets" }, "end": { - "line": 31, + "line": 34, "column": 4, "program": "launch_this_callee.ets" } @@ -1287,12 +1916,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" }, "end": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" } @@ -1312,12 +1941,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" }, "end": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" } @@ -1332,12 +1961,12 @@ "statements": [], "loc": { "start": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" }, "end": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" } @@ -1345,12 +1974,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" }, "end": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" } @@ -1358,12 +1987,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" }, "end": { - "line": 16, + "line": 19, "column": 12, "program": "launch_this_callee.ets" } @@ -1387,12 +2016,12 @@ ], "loc": { "start": { - "line": 16, + "line": 19, "column": 11, "program": "launch_this_callee.ets" }, "end": { - "line": 33, + "line": 36, "column": 1, "program": "launch_this_callee.ets" } @@ -1400,12 +2029,12 @@ }, "loc": { "start": { - "line": 16, + "line": 19, "column": 1, "program": "launch_this_callee.ets" }, "end": { - "line": 33, + "line": 36, "column": 1, "program": "launch_this_callee.ets" } @@ -1433,40 +2062,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_this_callee.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_this_callee.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_this_callee.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_this_callee.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1715,7 +2310,7 @@ "program": "launch_this_callee.ets" }, "end": { - "line": 33, + "line": 36, "column": 1, "program": "launch_this_callee.ets" } diff --git a/ets2panda/test/parser/ets/launch_this_callee.ets b/ets2panda/test/parser/ets/launch_this_callee.ets index 490a7f27282c0d38c38f35c2c9e430b0b0d75429..2f1985b8d37a2f9bd704db211c8364c6c1086ad4 100644 --- a/ets2panda/test/parser/ets/launch_this_callee.ets +++ b/ets2panda/test/parser/ets/launch_this_callee.ets @@ -13,17 +13,20 @@ * limitations under the License. */ +import {launch} from "std/concurrency" +import {Job} from "std/core" + class Foo { - public bar(): Promise { - return launch this.baz(this); + public bar(): Job { + return launch Foo>(this.baz, this); } public baz(x: Foo): Foo { return x; } - public bar2(): Promise { - return launch this.baz2(this, 1); + public bar2(): Job { + return launch Foo>(this.baz2, this, 1); } public baz2(x: Foo, y: int): Foo { diff --git a/ets2panda/test/parser/ets/launch_with_call_expression-expected.txt b/ets2panda/test/parser/ets/launch_with_call_expression-expected.txt index 7f792ce7ad8f81083c5726a09cb6e250cd98aff2..d242fffc6c67d90898f9a970bef232ad11c4b50b 100644 --- a/ets2panda/test/parser/ets/launch_with_call_expression-expected.txt +++ b/ets2panda/test/parser/ets/launch_with_call_expression-expected.txt @@ -284,40 +284,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_with_call_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_with_call_expression.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "launch_with_call_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "launch_with_call_expression.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -500,10 +466,26 @@ } }, "right": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 11, + "program": "launch_with_call_expression.ets" + }, + "end": { + "line": 21, + "column": 17, + "program": "launch_with_call_expression.ets" + } + } + }, + "arguments": [ + { "type": "MemberExpression", "object": { "type": "Identifier", @@ -512,12 +494,12 @@ "loc": { "start": { "line": 21, - "column": 18, + "column": 36, "program": "launch_with_call_expression.ets" }, "end": { "line": 21, - "column": 19, + "column": 37, "program": "launch_with_call_expression.ets" } } @@ -529,12 +511,12 @@ "loc": { "start": { "line": 21, - "column": 20, + "column": 38, "program": "launch_with_call_expression.ets" }, "end": { "line": 21, - "column": 23, + "column": 41, "program": "launch_with_call_expression.ets" } } @@ -544,27 +526,77 @@ "loc": { "start": { "line": 21, - "column": 18, + "column": 36, "program": "launch_with_call_expression.ets" }, "end": { "line": 21, - "column": 23, + "column": 41, "program": "launch_with_call_expression.ets" } } - }, - "arguments": [], - "optional": false, + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 21, + "column": 18, + "program": "launch_with_call_expression.ets" + }, + "end": { + "line": 21, + "column": 22, + "program": "launch_with_call_expression.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 21, + "column": 30, + "program": "launch_with_call_expression.ets" + }, + "end": { + "line": 21, + "column": 34, + "program": "launch_with_call_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 24, + "program": "launch_with_call_expression.ets" + }, + "end": { + "line": 21, + "column": 34, + "program": "launch_with_call_expression.ets" + } + } + } + ], "loc": { "start": { "line": 21, - "column": 18, + "column": 17, "program": "launch_with_call_expression.ets" }, "end": { "line": 21, - "column": 25, + "column": 35, "program": "launch_with_call_expression.ets" } } @@ -577,7 +609,7 @@ }, "end": { "line": 21, - "column": 25, + "column": 42, "program": "launch_with_call_expression.ets" } } @@ -590,7 +622,7 @@ }, "end": { "line": 21, - "column": 25, + "column": 42, "program": "launch_with_call_expression.ets" } } @@ -603,7 +635,7 @@ }, "end": { "line": 21, - "column": 25, + "column": 42, "program": "launch_with_call_expression.ets" } } @@ -683,10 +715,26 @@ } }, "value": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 11, + "program": "launch_with_call_expression.ets" + }, + "end": { + "line": 21, + "column": 17, + "program": "launch_with_call_expression.ets" + } + } + }, + "arguments": [ + { "type": "MemberExpression", "object": { "type": "Identifier", @@ -695,12 +743,12 @@ "loc": { "start": { "line": 21, - "column": 18, + "column": 36, "program": "launch_with_call_expression.ets" }, "end": { "line": 21, - "column": 19, + "column": 37, "program": "launch_with_call_expression.ets" } } @@ -712,12 +760,12 @@ "loc": { "start": { "line": 21, - "column": 20, + "column": 38, "program": "launch_with_call_expression.ets" }, "end": { "line": 21, - "column": 23, + "column": 41, "program": "launch_with_call_expression.ets" } } @@ -727,27 +775,77 @@ "loc": { "start": { "line": 21, - "column": 18, + "column": 36, "program": "launch_with_call_expression.ets" }, "end": { "line": 21, - "column": 23, + "column": 41, "program": "launch_with_call_expression.ets" } } - }, - "arguments": [], - "optional": false, + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 21, + "column": 18, + "program": "launch_with_call_expression.ets" + }, + "end": { + "line": 21, + "column": 22, + "program": "launch_with_call_expression.ets" + } + } + }, + { + "type": "ETSFunctionType", + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 21, + "column": 30, + "program": "launch_with_call_expression.ets" + }, + "end": { + "line": 21, + "column": 34, + "program": "launch_with_call_expression.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], "loc": { "start": { "line": 21, - "column": 18, + "column": 17, "program": "launch_with_call_expression.ets" }, "end": { "line": 21, - "column": 25, + "column": 35, "program": "launch_with_call_expression.ets" } } @@ -760,7 +858,7 @@ }, "end": { "line": 21, - "column": 25, + "column": 42, "program": "launch_with_call_expression.ets" } } @@ -781,7 +879,7 @@ }, "end": { "line": 21, - "column": 25, + "column": 42, "program": "launch_with_call_expression.ets" } } diff --git a/ets2panda/test/parser/ets/launch_with_call_expression.ets b/ets2panda/test/parser/ets/launch_with_call_expression.ets index e9e4ab920aabdb6cb266b194a8182f44c815ed18..5deac9f885ab4ed999fd6842e6505cf7803ef07d 100644 --- a/ets2panda/test/parser/ets/launch_with_call_expression.ets +++ b/ets2panda/test/parser/ets/launch_with_call_expression.ets @@ -18,4 +18,4 @@ class C { } } -let res = launch C.foo() +let res = launch void>(C.foo) diff --git a/ets2panda/test/parser/ets/literals-expected.txt b/ets2panda/test/parser/ets/literals-expected.txt index 0695f9b2e594209d270272346fb6af573a492cbd..5dffbbbbf62629a9dc45140ad69982e1902a4991 100644 --- a/ets2panda/test/parser/ets/literals-expected.txt +++ b/ets2panda/test/parser/ets/literals-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "literals.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "literals.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "literals.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "literals.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/local-class-expected.txt b/ets2panda/test/parser/ets/local-class-expected.txt index 1e942932aa2c93ccdbe737994ca2a98f787466f6..8b51c20764435b9364c1b05cfd81cd26c986c368 100644 --- a/ets2panda/test/parser/ets/local-class-expected.txt +++ b/ets2panda/test/parser/ets/local-class-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-class.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-class.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/local-interface-expected.txt b/ets2panda/test/parser/ets/local-interface-expected.txt index b57fa54949b64fdf8b108b54760660b340f2bb5b..064455264662cae3ec82439cea99991aea405d90 100644 --- a/ets2panda/test/parser/ets/local-interface-expected.txt +++ b/ets2panda/test/parser/ets/local-interface-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-interface.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-interface.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/localClassIsPermitted-expected.txt b/ets2panda/test/parser/ets/localClassIsPermitted-expected.txt index 09f26707f2723d019e6dd3615e7989c97359f33a..0995504c47e516997f6c36a44cf850c701fa0031 100644 --- a/ets2panda/test/parser/ets/localClassIsPermitted-expected.txt +++ b/ets2panda/test/parser/ets/localClassIsPermitted-expected.txt @@ -416,40 +416,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/localTypeAlias-expected.txt b/ets2panda/test/parser/ets/localTypeAlias-expected.txt index 17a49eaa608b0eba4ef0cc06ecea58ca3532460b..5e09636f3b9fa5b6b65b7f86f9893334a6eb25a1 100644 --- a/ets2panda/test/parser/ets/localTypeAlias-expected.txt +++ b/ets2panda/test/parser/ets/localTypeAlias-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localTypeAlias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localTypeAlias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localTypeAlias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localTypeAlias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/main_entry_point_1-expected.txt b/ets2panda/test/parser/ets/main_entry_point_1-expected.txt index 858179267f056efb9433d3adf90940d59f1a159c..94f1e5a503089c05d4a7555c258b9afe9b0b0de1 100644 --- a/ets2panda/test/parser/ets/main_entry_point_1-expected.txt +++ b/ets2panda/test/parser/ets/main_entry_point_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/main_entry_point_6-expected.txt b/ets2panda/test/parser/ets/main_entry_point_6-expected.txt index a504afc2e43d4dad3954eac437627d759641120a..5f3bcb8a34045fd83e0a3fd5b8a246dc8043a21e 100644 --- a/ets2panda/test/parser/ets/main_entry_point_6-expected.txt +++ b/ets2panda/test/parser/ets/main_entry_point_6-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -219,37 +185,86 @@ "type": "Identifier", "name": "i", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 19, - "program": "main_entry_point_6.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 19, + "program": "main_entry_point_6.ets" + }, + "end": { + "line": 16, + "column": 29, + "program": "main_entry_point_6.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 30, + "program": "main_entry_point_6.ets" + }, + "end": { + "line": 16, + "column": 36, + "program": "main_entry_point_6.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 30, + "program": "main_entry_point_6.ets" + }, + "end": { + "line": 16, + "column": 37, + "program": "main_entry_point_6.ets" + } + } }, - "end": { - "line": 16, - "column": 25, - "program": "main_entry_point_6.ets" + "loc": { + "start": { + "line": 16, + "column": 30, + "program": "main_entry_point_6.ets" + }, + "end": { + "line": 16, + "column": 37, + "program": "main_entry_point_6.ets" + } } } - }, + ], "loc": { "start": { "line": 16, - "column": 19, + "column": 29, "program": "main_entry_point_6.ets" }, "end": { "line": 16, - "column": 26, + "column": 37, "program": "main_entry_point_6.ets" } } @@ -262,21 +277,20 @@ }, "end": { "line": 16, - "column": 26, + "column": 38, "program": "main_entry_point_6.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, - "column": 25, + "column": 19, "program": "main_entry_point_6.ets" }, "end": { "line": 16, - "column": 27, + "column": 38, "program": "main_entry_point_6.ets" } } @@ -290,7 +304,7 @@ }, "end": { "line": 16, - "column": 27, + "column": 38, "program": "main_entry_point_6.ets" } } @@ -303,7 +317,7 @@ }, "end": { "line": 16, - "column": 27, + "column": 38, "program": "main_entry_point_6.ets" } } @@ -314,12 +328,12 @@ "loc": { "start": { "line": 16, - "column": 30, + "column": 40, "program": "main_entry_point_6.ets" }, "end": { "line": 16, - "column": 34, + "column": 44, "program": "main_entry_point_6.ets" } } @@ -347,7 +361,7 @@ "loc": { "start": { "line": 16, - "column": 35, + "column": 45, "program": "main_entry_point_6.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/main_entry_point_6.ets b/ets2panda/test/parser/ets/main_entry_point_6.ets index 29f24fce56edbf6d6a6d538d09b90779b7660130..f356927d3c7a1273409a8e49447d5de37a44fcb1 100644 --- a/ets2panda/test/parser/ets/main_entry_point_6.ets +++ b/ets2panda/test/parser/ets/main_entry_point_6.ets @@ -13,6 +13,6 @@ * limitations under the License. */ -function main(i : string[]): void { +function main(i : FixedArray): void { return; } diff --git a/ets2panda/test/parser/ets/main_entry_point_7-expected.txt b/ets2panda/test/parser/ets/main_entry_point_7-expected.txt index e07e26bd4a33d103b176ec64859c70adb8d6d919..2f96192faee2b17d29ca3c5efc7d62fc95520937 100644 --- a/ets2panda/test/parser/ets/main_entry_point_7-expected.txt +++ b/ets2panda/test/parser/ets/main_entry_point_7-expected.txt @@ -565,40 +565,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/main_entry_point_8-expected.txt b/ets2panda/test/parser/ets/main_entry_point_8-expected.txt index 663fe2d682dce38695fb3c1deb00345591a877f8..38d77076f55a74300ea6c521e1e6586da29a172e 100644 --- a/ets2panda/test/parser/ets/main_entry_point_8-expected.txt +++ b/ets2panda/test/parser/ets/main_entry_point_8-expected.txt @@ -102,40 +102,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -298,37 +264,86 @@ "type": "Identifier", "name": "i", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "TTT", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 19, - "program": "main_entry_point_8.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 19, + "program": "main_entry_point_8.ets" + }, + "end": { + "line": 18, + "column": 29, + "program": "main_entry_point_8.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "TTT", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 30, + "program": "main_entry_point_8.ets" + }, + "end": { + "line": 18, + "column": 33, + "program": "main_entry_point_8.ets" + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 30, + "program": "main_entry_point_8.ets" + }, + "end": { + "line": 18, + "column": 34, + "program": "main_entry_point_8.ets" + } + } }, - "end": { - "line": 18, - "column": 22, - "program": "main_entry_point_8.ets" + "loc": { + "start": { + "line": 18, + "column": 30, + "program": "main_entry_point_8.ets" + }, + "end": { + "line": 18, + "column": 34, + "program": "main_entry_point_8.ets" + } } } - }, + ], "loc": { "start": { "line": 18, - "column": 19, + "column": 29, "program": "main_entry_point_8.ets" }, "end": { "line": 18, - "column": 23, + "column": 34, "program": "main_entry_point_8.ets" } } @@ -341,21 +356,20 @@ }, "end": { "line": 18, - "column": 23, + "column": 35, "program": "main_entry_point_8.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, - "column": 22, + "column": 19, "program": "main_entry_point_8.ets" }, "end": { "line": 18, - "column": 24, + "column": 35, "program": "main_entry_point_8.ets" } } @@ -369,7 +383,7 @@ }, "end": { "line": 18, - "column": 24, + "column": 35, "program": "main_entry_point_8.ets" } } @@ -382,7 +396,7 @@ }, "end": { "line": 18, - "column": 24, + "column": 35, "program": "main_entry_point_8.ets" } } @@ -393,12 +407,12 @@ "loc": { "start": { "line": 18, - "column": 27, + "column": 37, "program": "main_entry_point_8.ets" }, "end": { "line": 18, - "column": 31, + "column": 41, "program": "main_entry_point_8.ets" } } @@ -426,7 +440,7 @@ "loc": { "start": { "line": 18, - "column": 32, + "column": 42, "program": "main_entry_point_8.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/main_entry_point_8.ets b/ets2panda/test/parser/ets/main_entry_point_8.ets index 8dda1f37f94a10085f0452addb033b8f47a872c2..30842980f0da771572c9de37b6807ed53757ef37 100644 --- a/ets2panda/test/parser/ets/main_entry_point_8.ets +++ b/ets2panda/test/parser/ets/main_entry_point_8.ets @@ -15,6 +15,6 @@ type TTT = string; -function main(i : TTT[]): void { +function main(i : FixedArray): void { return; } diff --git a/ets2panda/test/parser/ets/main_entry_point_9-expected.txt b/ets2panda/test/parser/ets/main_entry_point_9-expected.txt index dde066a938e3657162c224ac4006482516f9a72c..0828ec25dd6356c8a70727f413a52bce1bef5cca 100644 --- a/ets2panda/test/parser/ets/main_entry_point_9-expected.txt +++ b/ets2panda/test/parser/ets/main_entry_point_9-expected.txt @@ -21,37 +21,86 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "String", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 12, - "program": "main_entry_point_9.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "FixedArray", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 12, + "program": "main_entry_point_9.ets" + }, + "end": { + "line": 16, + "column": 22, + "program": "main_entry_point_9.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 23, + "program": "main_entry_point_9.ets" + }, + "end": { + "line": 16, + "column": 29, + "program": "main_entry_point_9.ets" + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 23, + "program": "main_entry_point_9.ets" + }, + "end": { + "line": 16, + "column": 30, + "program": "main_entry_point_9.ets" + } + } }, - "end": { - "line": 16, - "column": 18, - "program": "main_entry_point_9.ets" + "loc": { + "start": { + "line": 16, + "column": 23, + "program": "main_entry_point_9.ets" + }, + "end": { + "line": 16, + "column": 30, + "program": "main_entry_point_9.ets" + } } } - }, + ], "loc": { "start": { "line": 16, - "column": 12, + "column": 22, "program": "main_entry_point_9.ets" }, "end": { "line": 16, - "column": 19, + "column": 30, "program": "main_entry_point_9.ets" } } @@ -64,21 +113,20 @@ }, "end": { "line": 16, - "column": 19, + "column": 31, "program": "main_entry_point_9.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, - "column": 18, + "column": 12, "program": "main_entry_point_9.ets" }, "end": { "line": 16, - "column": 20, + "column": 31, "program": "main_entry_point_9.ets" } } @@ -91,7 +139,7 @@ }, "end": { "line": 16, - "column": 21, + "column": 31, "program": "main_entry_point_9.ets" } } @@ -118,40 +166,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "main_entry_point_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "main_entry_point_9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/main_entry_point_9.ets b/ets2panda/test/parser/ets/main_entry_point_9.ets index b8d633b590e8b9f00aa3dbd409fc6595db0a6a8a..4450de72e78f3a3242ff9fd9c0389405afdcc595 100644 --- a/ets2panda/test/parser/ets/main_entry_point_9.ets +++ b/ets2panda/test/parser/ets/main_entry_point_9.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -type TTT = String[]; +type TTT = FixedArray; function main(i : TTT): void { return; diff --git a/ets2panda/test/parser/ets/methodThrowsRethrows-expected.txt b/ets2panda/test/parser/ets/methodThrowsRethrows-expected.txt index cf7fa60a7871490ef0fc8c139eaeb232ebe3e873..093b36752fb1dddc242b9b574c380e5684156512 100644 --- a/ets2panda/test/parser/ets/methodThrowsRethrows-expected.txt +++ b/ets2panda/test/parser/ets/methodThrowsRethrows-expected.txt @@ -582,40 +582,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodThrowsRethrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodThrowsRethrows.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "methodThrowsRethrows.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "methodThrowsRethrows.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/method_empty-expected.txt b/ets2panda/test/parser/ets/method_empty-expected.txt index a4c9dd874839525f72cae9842012b71f4d23d5a7..3157560667c85fba3e3fd59696932822398ee500 100644 --- a/ets2panda/test/parser/ets/method_empty-expected.txt +++ b/ets2panda/test/parser/ets/method_empty-expected.txt @@ -638,40 +638,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method_empty.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method_empty.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method_empty.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method_empty.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/method_modifier_check_14-expected.txt b/ets2panda/test/parser/ets/method_modifier_check_14-expected.txt index 4abf82afef388a2008af73b09a4af9a00ad3eb3a..a72193ec3b46106cebd3dade4d9db156cc370650 100644 --- a/ets2panda/test/parser/ets/method_modifier_check_14-expected.txt +++ b/ets2panda/test/parser/ets/method_modifier_check_14-expected.txt @@ -283,40 +283,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method_modifier_check_14.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method_modifier_check_14.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method_modifier_check_14.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method_modifier_check_14.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/method_modifier_check_8-expected.txt b/ets2panda/test/parser/ets/method_modifier_check_8-expected.txt index 19632c78ddfdb54d3db2de8f953475f9cdd998ab..d255a51765f0295e2ff3ff46231deb53e7ddbe3d 100644 --- a/ets2panda/test/parser/ets/method_modifier_check_8-expected.txt +++ b/ets2panda/test/parser/ets/method_modifier_check_8-expected.txt @@ -283,40 +283,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method_modifier_check_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method_modifier_check_8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method_modifier_check_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method_modifier_check_8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/method_override_throw_1-expected.txt b/ets2panda/test/parser/ets/method_override_throw_1-expected.txt index b81396628567a8a18a0fc0897fc2ba966eeecb9a..c04044c9c42e678415143413d4c2418d4a548f15 100644 --- a/ets2panda/test/parser/ets/method_override_throw_1-expected.txt +++ b/ets2panda/test/parser/ets/method_override_throw_1-expected.txt @@ -2319,40 +2319,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method_override_throw_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method_override_throw_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "method_override_throw_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "method_override_throw_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/native_function_with_return_type-expected.txt b/ets2panda/test/parser/ets/native_function_with_return_type-expected.txt index d3e6387391317f732a302c192aa1bff42514b478..f5983b04093f7a1113dbe756e21fe7b9541b01e3 100644 --- a/ets2panda/test/parser/ets/native_function_with_return_type-expected.txt +++ b/ets2panda/test/parser/ets/native_function_with_return_type-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "native_function_with_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "native_function_with_return_type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "native_function_with_return_type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "native_function_with_return_type.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/new_expressions-expected.txt b/ets2panda/test/parser/ets/new_expressions-expected.txt index 0f15d45a947b8b052f2234f8cea280d7ce2d0de3..d7870311d69cc0aa9df4170155e417e00d23448d 100644 --- a/ets2panda/test/parser/ets/new_expressions-expected.txt +++ b/ets2panda/test/parser/ets/new_expressions-expected.txt @@ -179,40 +179,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "new_expressions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "new_expressions.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "new_expressions.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "new_expressions.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/new_object_3-expected.txt b/ets2panda/test/parser/ets/new_object_3-expected.txt index 88ed3c5f6f153552dae6014b97794c35075586a4..02a6235f92bf963f6502413d24aaa479e69d9aa4 100644 --- a/ets2panda/test/parser/ets/new_object_3-expected.txt +++ b/ets2panda/test/parser/ets/new_object_3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "new_object_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "new_object_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "new_object_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "new_object_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/null-expected.txt b/ets2panda/test/parser/ets/null-expected.txt index 538e1607db25f1560239b062d2e69334ac3d6ad4..c436378ae1e3b7b3e9090450649608207570b2a4 100644 --- a/ets2panda/test/parser/ets/null-expected.txt +++ b/ets2panda/test/parser/ets/null-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "null.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "null.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "null.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "null.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/null_valid-expected.txt b/ets2panda/test/parser/ets/null_valid-expected.txt index 530f61b0462a1cf00a93affb1198ff275f0667cb..f4d0b80cdb143ef46de7c502def756f237e15ac5 100644 --- a/ets2panda/test/parser/ets/null_valid-expected.txt +++ b/ets2panda/test/parser/ets/null_valid-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "null_valid.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "null_valid.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "null_valid.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "null_valid.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/nullableGenericSignature-expected.txt b/ets2panda/test/parser/ets/nullableGenericSignature-expected.txt index cd7cc74a094313a4fcba400ee2f4328bc8b108da..c168acc9816517595911b43f577899cc05efe15d 100644 --- a/ets2panda/test/parser/ets/nullableGenericSignature-expected.txt +++ b/ets2panda/test/parser/ets/nullableGenericSignature-expected.txt @@ -852,40 +852,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullableGenericSignature.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullableGenericSignature.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullableGenericSignature.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullableGenericSignature.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/nullable_union_array-expected.txt b/ets2panda/test/parser/ets/nullable_union_array-expected.txt index 44638a5900b3e7983ccae89b01fa3ff5f16d7876..d3f3de9f1694eb45f9c2b19f03c8a51f539340f9 100644 --- a/ets2panda/test/parser/ets/nullable_union_array-expected.txt +++ b/ets2panda/test/parser/ets/nullable_union_array-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullable_union_array.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullable_union_array.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "nullable_union_array.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "nullable_union_array.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -240,134 +206,182 @@ "type": "Identifier", "name": "values", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "nullable_union_array.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "nullable_union_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSUnionType", + "types": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + } + } }, - "end": { - "line": 17, - "column": 24, - "program": "nullable_union_array.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + } } - } - }, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "nullable_union_array.ets" }, - "end": { - "line": 17, - "column": 25, - "program": "nullable_union_array.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "nullable_union_array.ets" - }, - "end": { - "line": 17, - "column": 25, - "program": "nullable_union_array.ets" - } - } - }, - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 25, - "program": "nullable_union_array.ets" + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + } + } }, - "end": { - "line": 17, - "column": 28, - "program": "nullable_union_array.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + } + } + }, + { + "type": "ETSNullType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 25, + "line": 1, + "column": 3, "program": "nullable_union_array.ets" }, "end": { - "line": 17, - "column": 29, + "line": 1, + "column": 3, "program": "nullable_union_array.ets" } } - }, - "loc": { - "start": { - "line": 17, - "column": 25, - "program": "nullable_union_array.ets" - }, - "end": { - "line": 17, - "column": 29, - "program": "nullable_union_array.ets" - } } - }, - { - "type": "ETSNullType", - "loc": { - "start": { - "line": 17, - "column": 29, - "program": "nullable_union_array.ets" - }, - "end": { - "line": 17, - "column": 33, - "program": "nullable_union_array.ets" - } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "nullable_union_array.ets" } } - ], + }, "loc": { "start": { - "line": 17, - "column": 17, + "line": 1, + "column": 1, "program": "nullable_union_array.ets" }, "end": { - "line": 17, - "column": 33, + "line": 1, + "column": 3, "program": "nullable_union_array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/object-expected.txt b/ets2panda/test/parser/ets/object-expected.txt index 1e62905800ebc29409b5f7cd98462182bc6dec44..636e38a1476973a0600bc15217b4eae1693215f4 100644 --- a/ets2panda/test/parser/ets/object-expected.txt +++ b/ets2panda/test/parser/ets/object-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "object.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "object.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "object.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "object.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/optional-chaining-array-expected.txt b/ets2panda/test/parser/ets/optional-chaining-array-expected.txt index 875d245c3fe6c0aff1ac91bed43ab4bb7d2afff6..a67ef8231b3dab5efd43f3ec732e25ae519e1983 100644 --- a/ets2panda/test/parser/ets/optional-chaining-array-expected.txt +++ b/ets2panda/test/parser/ets/optional-chaining-array-expected.txt @@ -306,55 +306,103 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 38, - "program": "optional-chaining-array.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } + } }, - "end": { - "line": 16, - "column": 41, - "program": "optional-chaining-array.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } } } - }, + ], "loc": { "start": { - "line": 16, - "column": 38, + "line": 1, + "column": 3, "program": "optional-chaining-array.ets" }, "end": { - "line": 16, - "column": 42, + "line": 1, + "column": 3, "program": "optional-chaining-array.ets" } } }, "loc": { "start": { - "line": 16, - "column": 38, + "line": 1, + "column": 1, "program": "optional-chaining-array.ets" }, "end": { - "line": 16, - "column": 42, + "line": 1, + "column": 3, "program": "optional-chaining-array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -1109,55 +1157,103 @@ "type": "ETSUnionType", "types": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "optional-chaining-array.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Int", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } + } }, - "end": { - "line": 16, - "column": 13, - "program": "optional-chaining-array.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } } } - }, + ], "loc": { "start": { - "line": 16, - "column": 10, + "line": 1, + "column": 3, "program": "optional-chaining-array.ets" }, "end": { - "line": 16, - "column": 14, + "line": 1, + "column": 3, "program": "optional-chaining-array.ets" } } }, "loc": { "start": { - "line": 16, - "column": 10, + "line": 1, + "column": 1, "program": "optional-chaining-array.ets" }, "end": { - "line": 16, - "column": 14, + "line": 1, + "column": 3, "program": "optional-chaining-array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -1545,55 +1641,103 @@ "type": "ETSUnionType", "types": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "String", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 11, - "program": "optional-chaining-array.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } + } }, - "end": { - "line": 19, - "column": 17, - "program": "optional-chaining-array.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional-chaining-array.ets" + } } } - }, + ], "loc": { "start": { - "line": 19, - "column": 11, + "line": 1, + "column": 3, "program": "optional-chaining-array.ets" }, "end": { - "line": 19, - "column": 18, + "line": 1, + "column": 3, "program": "optional-chaining-array.ets" } } }, "loc": { "start": { - "line": 19, - "column": 11, + "line": 1, + "column": 1, "program": "optional-chaining-array.ets" }, "end": { - "line": 19, - "column": 18, + "line": 1, + "column": 3, "program": "optional-chaining-array.ets" } } }, - "annotations": [], "loc": { "start": { "line": 19, diff --git a/ets2panda/test/parser/ets/optional_chaining_nested_property-expected.txt b/ets2panda/test/parser/ets/optional_chaining_nested_property-expected.txt deleted file mode 100644 index edf4f156223560519f70da4b54030207c919b8c6..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/optional_chaining_nested_property-expected.txt +++ /dev/null @@ -1,1956 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "Car", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 7, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 17, - "column": 10, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "company", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 18, - "column": 12, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "value": { - "type": "StringLiteral", - "value": "", - "loc": { - "start": { - "line": 18, - "column": 23, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 18, - "column": 25, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "String", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 14, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 18, - "column": 20, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 14, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 18, - "column": 22, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 14, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 18, - "column": 22, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 18, - "column": 25, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "fuel", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 19, - "column": 9, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "value": { - "type": "StringLiteral", - "value": "", - "loc": { - "start": { - "line": 19, - "column": 20, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 19, - "column": 22, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "String", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 11, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 19, - "column": 17, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 11, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 19, - "column": 19, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 11, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 19, - "column": 19, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 19, - "column": 22, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "seats", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 20, - "column": 10, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "value": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 20, - "column": 18, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 20, - "column": 19, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 12, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 20, - "column": 15, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 12, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 20, - "column": 17, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 12, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 20, - "column": 17, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 20, - "column": 19, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "kind": "constructor", - "static": false, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "loc": { - "start": { - "line": 17, - "column": 11, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 23, - "column": 4, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 1, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 23, - "column": 4, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "superClass": null, - "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.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": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "Identifier", - "name": "car", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 23, - "column": 8, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "right": { - "type": "ObjectExpression", - "properties": [ - { - "type": "Property", - "method": false, - "shorthand": false, - "computed": false, - "key": { - "type": "Identifier", - "name": "company", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 24, - "column": 12, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "value": { - "type": "StringLiteral", - "value": "Mercedes", - "loc": { - "start": { - "line": 24, - "column": 14, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 24, - "column": 24, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "kind": "init", - "loc": { - "start": { - "line": 24, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 24, - "column": 24, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 23, - "column": 16, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "Identifier", - "name": "companyLength", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 18, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "right": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_17", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "init": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "init": { - "type": "Identifier", - "name": "car", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 24, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "alternate": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 33, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "company", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 26, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 33, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 33, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_17", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "alternate": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "gensym%%_17", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "length", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 35, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "car", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 23, - "column": 8, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Car", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 10, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 23, - "column": 13, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 10, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 23, - "column": 15, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 10, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 23, - "column": 15, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "companyLength", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 18, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "value": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_19", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "init": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_18", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "init": { - "type": "Identifier", - "name": "car", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 24, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_18", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "alternate": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "gensym%%_18", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 33, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "company", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 26, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 33, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 33, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_19", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "alternate": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "gensym%%_19", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "length", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 35, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 27, - "column": 41, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_nested_property.ets" - }, - "end": { - "line": 28, - "column": 1, - "program": "optional_chaining_nested_property.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/optional_chaining_object_property-expected.txt b/ets2panda/test/parser/ets/optional_chaining_object_property-expected.txt deleted file mode 100644 index adcdea8baa89e49243c424859ceef702e74ec3c5..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/optional_chaining_object_property-expected.txt +++ /dev/null @@ -1,1856 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "Dog", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 7, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 17, - "column": 10, - "program": "optional_chaining_object_property.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "name", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 18, - "column": 9, - "program": "optional_chaining_object_property.ets" - } - } - }, - "value": { - "type": "StringLiteral", - "value": "", - "loc": { - "start": { - "line": 18, - "column": 20, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 18, - "column": 22, - "program": "optional_chaining_object_property.ets" - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "String", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 11, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 18, - "column": 17, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 11, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 18, - "column": 19, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 11, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 18, - "column": 19, - "program": "optional_chaining_object_property.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 18, - "column": 22, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "legs", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 19, - "column": 9, - "program": "optional_chaining_object_property.ets" - } - } - }, - "value": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 19, - "column": 17, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 19, - "column": 18, - "program": "optional_chaining_object_property.ets" - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 11, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 19, - "column": 14, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 11, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 19, - "column": 16, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 11, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 19, - "column": 16, - "program": "optional_chaining_object_property.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 19, - "column": 18, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - } - } - }, - "kind": "constructor", - "static": false, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 17, - "column": 12, - "program": "optional_chaining_object_property.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "loc": { - "start": { - "line": 17, - "column": 11, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 22, - "column": 4, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 1, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 22, - "column": 4, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - } - } - }, - "superClass": null, - "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.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": [ - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "Identifier", - "name": "dog", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 22, - "column": 8, - "program": "optional_chaining_object_property.ets" - } - } - }, - "right": { - "type": "ObjectExpression", - "properties": [ - { - "type": "Property", - "method": false, - "shorthand": false, - "computed": false, - "key": { - "type": "Identifier", - "name": "name", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 23, - "column": 9, - "program": "optional_chaining_object_property.ets" - } - } - }, - "value": { - "type": "StringLiteral", - "value": "Scooby", - "loc": { - "start": { - "line": 23, - "column": 11, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 23, - "column": 19, - "program": "optional_chaining_object_property.ets" - } - } - }, - "kind": "init", - "loc": { - "start": { - "line": 23, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 23, - "column": 19, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 22, - "column": 16, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "Identifier", - "name": "name", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 9, - "program": "optional_chaining_object_property.ets" - } - } - }, - "right": { - "type": "LogicalExpression", - "operator": "??", - "left": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "init": { - "type": "Identifier", - "name": "dog", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 15, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "alternate": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 21, - "program": "optional_chaining_object_property.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "name", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 17, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 21, - "program": "optional_chaining_object_property.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 21, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - "right": { - "type": "StringLiteral", - "value": "Pluto", - "loc": { - "start": { - "line": 26, - "column": 25, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "Identifier", - "name": "legCount", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 13, - "program": "optional_chaining_object_property.ets" - } - } - }, - "right": { - "type": "LogicalExpression", - "operator": "??", - "left": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_17", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "init": { - "type": "Identifier", - "name": "dog", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 24, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 35, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_17", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "alternate": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "gensym%%_17", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 30, - "program": "optional_chaining_object_property.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "legs", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 26, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 30, - "program": "optional_chaining_object_property.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 30, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 35, - "program": "optional_chaining_object_property.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 4, - "loc": { - "start": { - "line": 27, - "column": 34, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 35, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 27, - "column": 21, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 35, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 35, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 35, - "program": "optional_chaining_object_property.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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "dog", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 22, - "column": 8, - "program": "optional_chaining_object_property.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Dog", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 10, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 22, - "column": 13, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 10, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 22, - "column": 15, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 10, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 22, - "column": 15, - "program": "optional_chaining_object_property.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "name", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 9, - "program": "optional_chaining_object_property.ets" - } - } - }, - "value": { - "type": "LogicalExpression", - "operator": "??", - "left": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_18", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "init": { - "type": "Identifier", - "name": "dog", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 15, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_18", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "alternate": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "gensym%%_18", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 21, - "program": "optional_chaining_object_property.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "name", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 17, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 21, - "program": "optional_chaining_object_property.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 21, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - "right": { - "type": "StringLiteral", - "value": "Pluto", - "loc": { - "start": { - "line": 26, - "column": 25, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "optional_chaining_object_property.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "legCount", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 13, - "program": "optional_chaining_object_property.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 27, - "column": 15, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 18, - "program": "optional_chaining_object_property.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 27, - "column": 35, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_chaining_object_property.ets" - }, - "end": { - "line": 28, - "column": 1, - "program": "optional_chaining_object_property.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/optional_field_class-expected.txt b/ets2panda/test/parser/ets/optional_field_class-expected.txt index 4a660454d01c2f4a45088ce9096c0dee053a5e07..f7512ccce8394964e218ba3bdb07272ca1f4d4d5 100644 --- a/ets2panda/test/parser/ets/optional_field_class-expected.txt +++ b/ets2panda/test/parser/ets/optional_field_class-expected.txt @@ -47,7 +47,7 @@ "static": false, "readonly": false, "declare": false, - "optional": false, + "optional": true, "computed": false, "typeAnnotation": { "type": "ETSUnionType", @@ -166,7 +166,7 @@ "static": true, "readonly": false, "declare": false, - "optional": false, + "optional": true, "computed": false, "typeAnnotation": { "type": "ETSUnionType", @@ -416,40 +416,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_class.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_class.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/optional_field_interface-expected.txt b/ets2panda/test/parser/ets/optional_field_interface-expected.txt index 3175a5747caa1d251befe07b1563de7d17d2e436..d96c964004a36bee90c4635d80e52da07db476e9 100644 --- a/ets2panda/test/parser/ets/optional_field_interface-expected.txt +++ b/ets2panda/test/parser/ets/optional_field_interface-expected.txt @@ -532,7 +532,7 @@ "static": false, "readonly": false, "declare": false, - "optional": false, + "optional": true, "computed": false, "typeAnnotation": { "type": "ETSUnionType", @@ -1349,40 +1349,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_interface.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_interface.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/optional_field_interfaceUnion-expected.txt b/ets2panda/test/parser/ets/optional_field_interfaceUnion-expected.txt index 8fddd788bcc8d99df10cf424c9b431f0174cfefd..7b334ffa2e7cee2f95fa638135b16a1f26f04275 100644 --- a/ets2panda/test/parser/ets/optional_field_interfaceUnion-expected.txt +++ b/ets2panda/test/parser/ets/optional_field_interfaceUnion-expected.txt @@ -754,7 +754,7 @@ "static": false, "readonly": false, "declare": false, - "optional": false, + "optional": true, "computed": false, "typeAnnotation": { "type": "ETSUnionType", @@ -1712,40 +1712,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_interfaceUnion.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_interfaceUnion.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_interfaceUnion.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_interfaceUnion.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/optional_field_variable-expected.txt b/ets2panda/test/parser/ets/optional_field_variable-expected.txt index c28003d7929617f3c1030e1fd31cbef17f6dfebf..09ac7c26a121993f309f0f78c7d269c544c68cb7 100644 --- a/ets2panda/test/parser/ets/optional_field_variable-expected.txt +++ b/ets2panda/test/parser/ets/optional_field_variable-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_variable.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_variable.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -1076,6 +1042,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "optional_field_variable.ets" + }, + "end": { + "line": 27, + "column": 2, + "program": "optional_field_variable.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "optional_field_variable.ets" + }, + "end": { + "line": 27, + "column": 2, + "program": "optional_field_variable.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "optional_field_variable.ets" + }, + "end": { + "line": 27, + "column": 2, + "program": "optional_field_variable.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "optional_field_variable.ets" + }, + "end": { + "line": 27, + "column": 2, + "program": "optional_field_variable.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "optional_field_variable.ets" + }, + "end": { + "line": 27, + "column": 2, + "program": "optional_field_variable.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "optional_field_variable.ets" + }, + "end": { + "line": 27, + "column": 2, + "program": "optional_field_variable.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "optional_field_variable.ets" + }, + "end": { + "line": 27, + "column": 2, + "program": "optional_field_variable.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "optional_field_variable.ets" + }, + "end": { + "line": 27, + "column": 2, + "program": "optional_field_variable.ets" + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 10, + "program": "optional_field_variable.ets" + }, + "end": { + "line": 27, + "column": 2, + "program": "optional_field_variable.ets" + } + } + } + ], "loc": { "start": { "line": 21, diff --git a/ets2panda/test/parser/ets/optional_field_variable_2-expected.txt b/ets2panda/test/parser/ets/optional_field_variable_2-expected.txt deleted file mode 100644 index 94e5ec5f43aeea131ad24d0c75d169ec7007f992..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/optional_field_variable_2-expected.txt +++ /dev/null @@ -1,1440 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "C", - "decorators": [], - "loc": { - "start": { - "line": 15, - "column": 7, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 15, - "column": 8, - "program": "optional_field_variable_2.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "once", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 5, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 16, - "column": 9, - "program": "optional_field_variable_2.ets" - } - } - }, - "value": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 16, - "column": 22, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 16, - "column": 26, - "program": "optional_field_variable_2.ets" - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 16, - "column": 12, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 16, - "column": 19, - "program": "optional_field_variable_2.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 5, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 16, - "column": 26, - "program": "optional_field_variable_2.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "kind": "constructor", - "static": false, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 15, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "loc": { - "start": { - "line": 15, - "column": 9, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 19, - "column": 6, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 15, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 19, - "column": 6, - "program": "optional_field_variable_2.ets" - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "A", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 7, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 19, - "column": 8, - "program": "optional_field_variable_2.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 5, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 20, - "column": 8, - "program": "optional_field_variable_2.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": false, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "foo", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 5, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 20, - "column": 8, - "program": "optional_field_variable_2.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "global", - "typeAnnotation": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 22, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 21, - "column": 29, - "program": "optional_field_variable_2.ets" - } - } - }, - { - "type": "ETSUndefinedType", - "loc": { - "start": { - "line": 21, - "column": 32, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 21, - "column": 41, - "program": "optional_field_variable_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 21, - "column": 22, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 21, - "column": 41, - "program": "optional_field_variable_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 13, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 21, - "column": 19, - "program": "optional_field_variable_2.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 21, - "column": 44, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 21, - "column": 48, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 21, - "column": 13, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 21, - "column": 48, - "program": "optional_field_variable_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 21, - "column": 48, - "program": "optional_field_variable_2.ets" - } - } - }, - { - "type": "IfStatement", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "global", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 13, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 19, - "program": "optional_field_variable_2.ets" - } - } - }, - "right": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 22, - "column": 23, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 32, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 13, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 32, - "program": "optional_field_variable_2.ets" - } - } - }, - "consequent": { - "type": "ExpressionStatement", - "expression": { - "type": "AssignmentExpression", - "operator": "=", - "left": { - "type": "Identifier", - "name": "global", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 34, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 40, - "program": "optional_field_variable_2.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "!=", - "left": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - } - } - }, - "init": { - "type": "MemberExpression", - "object": { - "type": "ThisExpression", - "loc": { - "start": { - "line": 22, - "column": 43, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 47, - "program": "optional_field_variable_2.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "current", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 48, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 55, - "program": "optional_field_variable_2.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 22, - "column": 43, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 55, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 22, - "column": 43, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 69, - "program": "optional_field_variable_2.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - } - } - }, - "alternate": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 43, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 61, - "program": "optional_field_variable_2.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "once", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 57, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 61, - "program": "optional_field_variable_2.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 22, - "column": 43, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 61, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "optional_field_variable_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 22, - "column": 43, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 69, - "program": "optional_field_variable_2.ets" - } - } - }, - "right": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 22, - "column": 65, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 69, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 43, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 69, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 34, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 69, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 34, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 69, - "program": "optional_field_variable_2.ets" - } - } - }, - "alternate": null, - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 22, - "column": 69, - "program": "optional_field_variable_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 20, - "column": 11, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 23, - "column": 6, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 8, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 23, - "column": 6, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 8, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 23, - "column": 6, - "program": "optional_field_variable_2.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 5, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 23, - "column": 6, - "program": "optional_field_variable_2.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "current", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 5, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 24, - "column": 12, - "program": "optional_field_variable_2.ets" - } - } - }, - "accessibility": "public", - "static": false, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "C", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 15, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 24, - "column": 16, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 15, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 24, - "column": 18, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 15, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 24, - "column": 18, - "program": "optional_field_variable_2.ets" - } - } - }, - { - "type": "ETSUndefinedType", - "loc": { - "start": { - "line": 24, - "column": 19, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 24, - "column": 28, - "program": "optional_field_variable_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 24, - "column": 15, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 24, - "column": 28, - "program": "optional_field_variable_2.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 5, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 24, - "column": 28, - "program": "optional_field_variable_2.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "kind": "constructor", - "static": false, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 19, - "column": 10, - "program": "optional_field_variable_2.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 26, - "column": 1, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 26, - "column": 1, - "program": "optional_field_variable_2.ets" - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - } - } - }, - "superClass": null, - "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - } - } - } - ], - "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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_field_variable_2.ets" - }, - "end": { - "line": 26, - "column": 1, - "program": "optional_field_variable_2.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/optional_union_paramter-expected.txt b/ets2panda/test/parser/ets/optional_union_paramter-expected.txt index de12c48130d1b9656df70fbac7fe98894c1474e2..ed1274a9ea48f55ba381e80a22cac52c4810d391 100644 --- a/ets2panda/test/parser/ets/optional_union_paramter-expected.txt +++ b/ets2panda/test/parser/ets/optional_union_paramter-expected.txt @@ -297,55 +297,103 @@ } ], "returnType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "String", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 61, - "program": "optional_union_paramter.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional_union_paramter.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional_union_paramter.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional_union_paramter.ets" + } + } }, - "end": { - "line": 17, - "column": 67, - "program": "optional_union_paramter.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "optional_union_paramter.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 61, + "line": 1, + "column": 3, "program": "optional_union_paramter.ets" }, "end": { - "line": 17, - "column": 68, + "line": 1, + "column": 3, "program": "optional_union_paramter.ets" } } }, "loc": { "start": { - "line": 17, - "column": 61, + "line": 1, + "column": 1, "program": "optional_union_paramter.ets" }, "end": { - "line": 17, - "column": 68, + "line": 1, + "column": 3, "program": "optional_union_paramter.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -424,6 +472,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 18, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "optional_union_paramter.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 18, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "optional_union_paramter.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "optional_union_paramter.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "optional_union_paramter.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 18, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "optional_union_paramter.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 18, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "optional_union_paramter.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 17, + "column": 18, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "optional_union_paramter.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 18, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "optional_union_paramter.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 18, + "program": "optional_union_paramter.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "optional_union_paramter.ets" + } + } + } + ], "loc": { "start": { "line": 17, @@ -619,40 +819,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_union_paramter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_union_paramter.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "optional_union_paramter.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "optional_union_paramter.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/override-expected.txt b/ets2panda/test/parser/ets/override-expected.txt index 03d8bef3f5475b15c9b93ed9aec5f1730ab02125..64a1433e4e89ecf57bf259701e1c1e290cd3089d 100644 --- a/ets2panda/test/parser/ets/override-expected.txt +++ b/ets2panda/test/parser/ets/override-expected.txt @@ -377,6 +377,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "override.ets" + }, + "end": { + "line": 17, + "column": 36, + "program": "override.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "override.ets" + }, + "end": { + "line": 17, + "column": 36, + "program": "override.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "override.ets" + }, + "end": { + "line": 17, + "column": 36, + "program": "override.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "override.ets" + }, + "end": { + "line": 17, + "column": 36, + "program": "override.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "override.ets" + }, + "end": { + "line": 17, + "column": 36, + "program": "override.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "override.ets" + }, + "end": { + "line": 17, + "column": 36, + "program": "override.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "override.ets" + }, + "end": { + "line": 17, + "column": 36, + "program": "override.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "override.ets" + }, + "end": { + "line": 17, + "column": 36, + "program": "override.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 6, + "program": "override.ets" + }, + "end": { + "line": 17, + "column": 36, + "program": "override.ets" + } + } + } + ], "loc": { "start": { "line": 17, @@ -1036,6 +1188,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 15, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 45, + "program": "override.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 15, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 45, + "program": "override.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 15, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 45, + "program": "override.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 15, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 45, + "program": "override.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 15, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 45, + "program": "override.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 15, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 45, + "program": "override.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 20, + "column": 15, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 45, + "program": "override.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 15, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 45, + "program": "override.ets" + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 15, + "program": "override.ets" + }, + "end": { + "line": 20, + "column": 45, + "program": "override.ets" + } + } + } + ], "loc": { "start": { "line": 20, @@ -1231,40 +1535,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "override.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "override.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/overrideStaticFunc-expected.txt b/ets2panda/test/parser/ets/overrideStaticFunc-expected.txt index db9a60fa01eedc10ec47a22a8029fb2514e01cb6..3c52f8c03c79288b30aef6cfd24e5f4b9811ee9c 100644 --- a/ets2panda/test/parser/ets/overrideStaticFunc-expected.txt +++ b/ets2panda/test/parser/ets/overrideStaticFunc-expected.txt @@ -792,40 +792,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "overrideStaticFunc.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "overrideStaticFunc.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "overrideStaticFunc.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "overrideStaticFunc.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt b/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt index 8ad8861a8dd62c25cec96b542937c9af19d85029..06f443f4b1f6fbb45b36851a6978b8aa7f3a7fd8 100644 --- a/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt +++ b/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "parentheses_expression_value.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "parentheses_expression_value.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "parentheses_expression_value.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "parentheses_expression_value.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/predefined_types-expected.txt b/ets2panda/test/parser/ets/predefined_types-expected.txt index 1f7b74f91de478370fb43fea515deb06a28d995f..7d6959d452e59c0abfbfad5b916d82c56b6cd3da 100644 --- a/ets2panda/test/parser/ets/predefined_types-expected.txt +++ b/ets2panda/test/parser/ets/predefined_types-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "predefined_types.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "predefined_types.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "predefined_types.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "predefined_types.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/promiseCasting-expected.txt b/ets2panda/test/parser/ets/promiseCasting-expected.txt index 52e09277486a6dd59b204594750b49eb3f25e5cc..834c9464f0d2f4d1f1c37ca195991badcd2d2fb3 100644 --- a/ets2panda/test/parser/ets/promiseCasting-expected.txt +++ b/ets2panda/test/parser/ets/promiseCasting-expected.txt @@ -2,61 +2,302 @@ "type": "Program", "statements": [ { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/concurrency", + "loc": { + "start": { + "line": 16, + "column": 22, + "program": "promiseCasting.ets" + }, + "end": { + "line": 16, + "column": 39, + "program": "promiseCasting.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "promiseCasting.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "promiseCasting.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 9, + "program": "promiseCasting.ets" + }, + "end": { + "line": 16, + "column": 15, + "program": "promiseCasting.ets" + } + } + }, "loc": { "start": { - "line": 1, - "column": 1, + "line": 16, + "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 1, - "column": 1, + "line": 16, + "column": 15, "program": "promiseCasting.ets" } } + } + ], + "loc": { + "start": { + "line": 16, + "column": 1, + "program": "promiseCasting.ets" }, - "superClass": null, - "implements": [], - "annotations": [ + "end": { + "line": 16, + "column": 39, + "program": "promiseCasting.ets" + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "std/core", + "loc": { + "start": { + "line": 17, + "column": 19, + "program": "promiseCasting.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "promiseCasting.ets" + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "promiseCasting.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "promiseCasting.ets" + } + } + }, + "imported": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "promiseCasting.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "promiseCasting.ets" + }, + "end": { + "line": 17, + "column": 12, + "program": "promiseCasting.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 1, + "program": "promiseCasting.ets" + }, + "end": { + "line": 17, + "column": 29, + "program": "promiseCasting.ets" + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "Cb", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 6, + "program": "promiseCasting.ets" + }, + "end": { + "line": 19, + "column": 8, + "program": "promiseCasting.ets" + } + } + }, + "typeAnnotation": { + "type": "ETSFunctionType", + "params": [ { - "expr_": { + "type": "ETSParameterExpression", + "name": { "type": "Identifier", - "name": "Module", + "name": "p", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 19, + "column": 15, + "program": "promiseCasting.ets" + }, + "end": { + "line": 19, + "column": 18, + "program": "promiseCasting.ets" + } + } + }, "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, + "line": 19, + "column": 12, "program": "promiseCasting.ets" }, "end": { - "line": 1, - "column": 1, + "line": 19, + "column": 18, "program": "promiseCasting.ets" } } }, - "properties": [], "loc": { "start": { - "line": 1, - "column": 1, + "line": 19, + "column": 12, "program": "promiseCasting.ets" }, "end": { - "line": 1, - "column": 1, + "line": 19, + "column": 18, "program": "promiseCasting.ets" } } } ], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 19, + "column": 23, + "program": "promiseCasting.ets" + }, + "end": { + "line": 19, + "column": 26, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 11, + "program": "promiseCasting.ets" + }, + "end": { + "line": 19, + "column": 26, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1, + "program": "promiseCasting.ets" + }, + "end": { + "line": 19, + "column": 27, + "program": "promiseCasting.ets" + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "promiseCasting.ets" + }, + "end": { + "line": 1, + "column": 1, + "program": "promiseCasting.ets" + } + } + }, + "superClass": null, + "implements": [], "body": [ { "type": "MethodDefinition", @@ -109,7 +350,72 @@ "params": [], "body": { "type": "BlockStatement", - "statements": [], + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "fs", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 5, + "program": "promiseCasting.ets" + }, + "end": { + "line": 21, + "column": 7, + "program": "promiseCasting.ets" + } + } + }, + "right": { + "type": "ArrayExpression", + "elements": [], + "loc": { + "start": { + "line": 21, + "column": 16, + "program": "promiseCasting.ets" + }, + "end": { + "line": 21, + "column": 18, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 5, + "program": "promiseCasting.ets" + }, + "end": { + "line": 21, + "column": 18, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 5, + "program": "promiseCasting.ets" + }, + "end": { + "line": 21, + "column": 18, + "program": "promiseCasting.ets" + } + } + } + ], "loc": { "start": { "line": 1, @@ -172,12 +478,12 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 21, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 16, + "line": 21, "column": 7, "program": "promiseCasting.ets" } @@ -190,96 +496,112 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSFunctionType", - "params": [ - { - "type": "ETSParameterExpression", - "name": { - "type": "Identifier", - "name": "p", - "typeAnnotation": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "promiseCasting.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Cb", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + } + } + }, "loc": { "start": { - "line": 16, - "column": 14, + "line": 1, + "column": 3, "program": "promiseCasting.ets" }, "end": { - "line": 16, - "column": 17, + "line": 1, + "column": 3, "program": "promiseCasting.ets" } } }, - "decorators": [], "loc": { "start": { - "line": 16, - "column": 11, + "line": 1, + "column": 3, "program": "promiseCasting.ets" }, "end": { - "line": 16, - "column": 17, + "line": 1, + "column": 3, "program": "promiseCasting.ets" } } - }, - "loc": { - "start": { - "line": 16, - "column": 11, - "program": "promiseCasting.ets" - }, - "end": { - "line": 16, - "column": 17, - "program": "promiseCasting.ets" - } } - } - ], - "returnType": { - "type": "ETSPrimitiveType", + ], "loc": { "start": { - "line": 16, - "column": 22, + "line": 1, + "column": 3, "program": "promiseCasting.ets" }, "end": { - "line": 16, - "column": 25, + "line": 1, + "column": 3, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 16, - "column": 9, + "line": 1, + "column": 1, "program": "promiseCasting.ets" }, "end": { - "line": 16, - "column": 25, + "line": 1, + "column": 3, "program": "promiseCasting.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 16, - "column": 26, + "line": 21, + "column": 11, "program": "promiseCasting.ets" }, "end": { - "line": 16, - "column": 28, + "line": 21, + "column": 13, "program": "promiseCasting.ets" } } @@ -288,13 +610,13 @@ "decorators": [], "loc": { "start": { - "line": 16, + "line": 21, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 16, - "column": 7, + "line": 21, + "column": 18, "program": "promiseCasting.ets" } } @@ -307,12 +629,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 23, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 18, + "line": 23, "column": 13, "program": "promiseCasting.ets" } @@ -333,12 +655,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 23, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 18, + "line": 23, "column": 13, "program": "promiseCasting.ets" } @@ -357,12 +679,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 18, + "line": 23, "column": 17, "program": "promiseCasting.ets" }, "end": { - "line": 18, + "line": 23, "column": 20, "program": "promiseCasting.ets" } @@ -371,12 +693,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 23, "column": 14, "program": "promiseCasting.ets" }, "end": { - "line": 18, + "line": 23, "column": 20, "program": "promiseCasting.ets" } @@ -384,12 +706,12 @@ }, "loc": { "start": { - "line": 18, + "line": 23, "column": 14, "program": "promiseCasting.ets" }, "end": { - "line": 18, + "line": 23, "column": 20, "program": "promiseCasting.ets" } @@ -397,80 +719,48 @@ } ], "returnType": { - "type": "ETSFunctionType", - "params": [ - { - "type": "ETSParameterExpression", - "name": { - "type": "Identifier", - "name": "p", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 28, - "program": "promiseCasting.ets" - }, - "end": { - "line": 18, - "column": 31, - "program": "promiseCasting.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 25, - "program": "promiseCasting.ets" - }, - "end": { - "line": 18, - "column": 31, - "program": "promiseCasting.ets" - } - } - }, + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Cb", + "decorators": [], "loc": { "start": { - "line": 18, - "column": 25, + "line": 23, + "column": 23, "program": "promiseCasting.ets" }, "end": { - "line": 18, - "column": 31, + "line": 23, + "column": 25, "program": "promiseCasting.ets" } } - } - ], - "returnType": { - "type": "ETSPrimitiveType", + }, "loc": { "start": { - "line": 18, - "column": 36, + "line": 23, + "column": 23, "program": "promiseCasting.ets" }, "end": { - "line": 18, - "column": 39, + "line": 23, + "column": 27, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 18, + "line": 23, "column": 23, "program": "promiseCasting.ets" }, "end": { - "line": 18, - "column": 39, + "line": 23, + "column": 27, "program": "promiseCasting.ets" } } @@ -488,12 +778,12 @@ "decorators": [], "loc": { "start": { - "line": 19, + "line": 24, "column": 12, "program": "promiseCasting.ets" }, "end": { - "line": 19, + "line": 24, "column": 14, "program": "promiseCasting.ets" } @@ -505,12 +795,12 @@ "decorators": [], "loc": { "start": { - "line": 19, + "line": 24, "column": 15, "program": "promiseCasting.ets" }, "end": { - "line": 19, + "line": 24, "column": 16, "program": "promiseCasting.ets" } @@ -520,12 +810,12 @@ "optional": false, "loc": { "start": { - "line": 19, + "line": 24, "column": 12, "program": "promiseCasting.ets" }, "end": { - "line": 19, + "line": 24, "column": 17, "program": "promiseCasting.ets" } @@ -533,12 +823,12 @@ }, "loc": { "start": { - "line": 19, + "line": 24, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 19, + "line": 24, "column": 17, "program": "promiseCasting.ets" } @@ -547,12 +837,12 @@ ], "loc": { "start": { - "line": 18, - "column": 41, + "line": 23, + "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 20, + "line": 25, "column": 2, "program": "promiseCasting.ets" } @@ -560,12 +850,12 @@ }, "loc": { "start": { - "line": 18, + "line": 23, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 20, + "line": 25, "column": 2, "program": "promiseCasting.ets" } @@ -573,12 +863,12 @@ }, "loc": { "start": { - "line": 18, + "line": 23, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 20, + "line": 25, "column": 2, "program": "promiseCasting.ets" } @@ -588,12 +878,12 @@ "decorators": [], "loc": { "start": { - "line": 18, + "line": 23, "column": 1, "program": "promiseCasting.ets" }, "end": { - "line": 20, + "line": 25, "column": 2, "program": "promiseCasting.ets" } @@ -607,12 +897,12 @@ "decorators": [], "loc": { "start": { - "line": 22, + "line": 27, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 22, + "line": 27, "column": 14, "program": "promiseCasting.ets" } @@ -633,12 +923,12 @@ "decorators": [], "loc": { "start": { - "line": 22, + "line": 27, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 22, + "line": 27, "column": 14, "program": "promiseCasting.ets" } @@ -662,12 +952,12 @@ "decorators": [], "loc": { "start": { - "line": 23, + "line": 28, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 23, + "line": 28, "column": 7, "program": "promiseCasting.ets" } @@ -694,12 +984,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 24, + "line": 29, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 24, + "line": 29, "column": 16, "program": "promiseCasting.ets" } @@ -708,12 +998,12 @@ "decorators": [], "loc": { "start": { - "line": 24, + "line": 29, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 24, + "line": 29, "column": 16, "program": "promiseCasting.ets" } @@ -721,12 +1011,12 @@ }, "loc": { "start": { - "line": 24, + "line": 29, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 24, + "line": 29, "column": 16, "program": "promiseCasting.ets" } @@ -737,12 +1027,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 24, + "line": 29, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 24, + "line": 29, "column": 22, "program": "promiseCasting.ets" } @@ -762,12 +1052,12 @@ "decorators": [], "loc": { "start": { - "line": 24, + "line": 29, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 24, + "line": 29, "column": 27, "program": "promiseCasting.ets" } @@ -778,12 +1068,12 @@ "value": 1, "loc": { "start": { - "line": 24, + "line": 29, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 24, + "line": 29, "column": 31, "program": "promiseCasting.ets" } @@ -791,12 +1081,12 @@ }, "loc": { "start": { - "line": 24, + "line": 29, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 24, + "line": 29, "column": 31, "program": "promiseCasting.ets" } @@ -831,12 +1121,12 @@ }, "loc": { "start": { - "line": 24, + "line": 29, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 24, + "line": 29, "column": 31, "program": "promiseCasting.ets" } @@ -844,12 +1134,12 @@ }, "loc": { "start": { - "line": 24, + "line": 29, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 24, + "line": 29, "column": 31, "program": "promiseCasting.ets" } @@ -873,12 +1163,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 25, + "line": 30, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 25, + "line": 30, "column": 16, "program": "promiseCasting.ets" } @@ -887,12 +1177,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 30, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 25, + "line": 30, "column": 16, "program": "promiseCasting.ets" } @@ -900,12 +1190,12 @@ }, "loc": { "start": { - "line": 25, + "line": 30, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 25, + "line": 30, "column": 16, "program": "promiseCasting.ets" } @@ -916,12 +1206,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 25, + "line": 30, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 25, + "line": 30, "column": 22, "program": "promiseCasting.ets" } @@ -941,12 +1231,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 30, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 25, + "line": 30, "column": 27, "program": "promiseCasting.ets" } @@ -957,12 +1247,12 @@ "value": 2, "loc": { "start": { - "line": 25, + "line": 30, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 25, + "line": 30, "column": 31, "program": "promiseCasting.ets" } @@ -970,12 +1260,12 @@ }, "loc": { "start": { - "line": 25, + "line": 30, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 25, + "line": 30, "column": 31, "program": "promiseCasting.ets" } @@ -1010,12 +1300,12 @@ }, "loc": { "start": { - "line": 25, + "line": 30, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 25, + "line": 30, "column": 31, "program": "promiseCasting.ets" } @@ -1023,12 +1313,12 @@ }, "loc": { "start": { - "line": 25, + "line": 30, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 25, + "line": 30, "column": 31, "program": "promiseCasting.ets" } @@ -1052,12 +1342,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 26, + "line": 31, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 26, + "line": 31, "column": 16, "program": "promiseCasting.ets" } @@ -1066,12 +1356,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 31, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 26, + "line": 31, "column": 16, "program": "promiseCasting.ets" } @@ -1079,12 +1369,12 @@ }, "loc": { "start": { - "line": 26, + "line": 31, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 26, + "line": 31, "column": 16, "program": "promiseCasting.ets" } @@ -1095,12 +1385,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 26, + "line": 31, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 26, + "line": 31, "column": 22, "program": "promiseCasting.ets" } @@ -1120,12 +1410,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 31, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 26, + "line": 31, "column": 27, "program": "promiseCasting.ets" } @@ -1136,12 +1426,12 @@ "value": 3, "loc": { "start": { - "line": 26, + "line": 31, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 26, + "line": 31, "column": 31, "program": "promiseCasting.ets" } @@ -1149,12 +1439,12 @@ }, "loc": { "start": { - "line": 26, + "line": 31, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 26, + "line": 31, "column": 31, "program": "promiseCasting.ets" } @@ -1189,12 +1479,12 @@ }, "loc": { "start": { - "line": 26, + "line": 31, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 26, + "line": 31, "column": 31, "program": "promiseCasting.ets" } @@ -1202,12 +1492,12 @@ }, "loc": { "start": { - "line": 26, + "line": 31, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 26, + "line": 31, "column": 31, "program": "promiseCasting.ets" } @@ -1231,12 +1521,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 27, + "line": 32, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 27, + "line": 32, "column": 16, "program": "promiseCasting.ets" } @@ -1245,12 +1535,12 @@ "decorators": [], "loc": { "start": { - "line": 27, + "line": 32, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 27, + "line": 32, "column": 16, "program": "promiseCasting.ets" } @@ -1258,12 +1548,12 @@ }, "loc": { "start": { - "line": 27, + "line": 32, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 27, + "line": 32, "column": 16, "program": "promiseCasting.ets" } @@ -1274,12 +1564,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 27, + "line": 32, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 27, + "line": 32, "column": 22, "program": "promiseCasting.ets" } @@ -1299,12 +1589,12 @@ "decorators": [], "loc": { "start": { - "line": 27, + "line": 32, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 27, + "line": 32, "column": 27, "program": "promiseCasting.ets" } @@ -1315,12 +1605,12 @@ "value": 4, "loc": { "start": { - "line": 27, + "line": 32, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 27, + "line": 32, "column": 31, "program": "promiseCasting.ets" } @@ -1328,12 +1618,12 @@ }, "loc": { "start": { - "line": 27, + "line": 32, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 27, + "line": 32, "column": 31, "program": "promiseCasting.ets" } @@ -1368,12 +1658,12 @@ }, "loc": { "start": { - "line": 27, + "line": 32, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 27, + "line": 32, "column": 31, "program": "promiseCasting.ets" } @@ -1381,12 +1671,12 @@ }, "loc": { "start": { - "line": 27, + "line": 32, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 27, + "line": 32, "column": 31, "program": "promiseCasting.ets" } @@ -1410,12 +1700,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 28, + "line": 33, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 28, + "line": 33, "column": 16, "program": "promiseCasting.ets" } @@ -1424,12 +1714,12 @@ "decorators": [], "loc": { "start": { - "line": 28, + "line": 33, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 28, + "line": 33, "column": 16, "program": "promiseCasting.ets" } @@ -1437,12 +1727,12 @@ }, "loc": { "start": { - "line": 28, + "line": 33, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 28, + "line": 33, "column": 16, "program": "promiseCasting.ets" } @@ -1453,12 +1743,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 28, + "line": 33, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 28, + "line": 33, "column": 22, "program": "promiseCasting.ets" } @@ -1478,12 +1768,12 @@ "decorators": [], "loc": { "start": { - "line": 28, + "line": 33, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 28, + "line": 33, "column": 27, "program": "promiseCasting.ets" } @@ -1494,12 +1784,12 @@ "value": 5, "loc": { "start": { - "line": 28, + "line": 33, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 28, + "line": 33, "column": 31, "program": "promiseCasting.ets" } @@ -1507,12 +1797,12 @@ }, "loc": { "start": { - "line": 28, + "line": 33, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 28, + "line": 33, "column": 31, "program": "promiseCasting.ets" } @@ -1547,12 +1837,12 @@ }, "loc": { "start": { - "line": 28, + "line": 33, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 28, + "line": 33, "column": 31, "program": "promiseCasting.ets" } @@ -1560,12 +1850,12 @@ }, "loc": { "start": { - "line": 28, + "line": 33, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 28, + "line": 33, "column": 31, "program": "promiseCasting.ets" } @@ -1589,12 +1879,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 29, + "line": 34, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 29, + "line": 34, "column": 16, "program": "promiseCasting.ets" } @@ -1603,12 +1893,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 34, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 29, + "line": 34, "column": 16, "program": "promiseCasting.ets" } @@ -1616,12 +1906,12 @@ }, "loc": { "start": { - "line": 29, + "line": 34, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 29, + "line": 34, "column": 16, "program": "promiseCasting.ets" } @@ -1632,12 +1922,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 29, + "line": 34, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 29, + "line": 34, "column": 22, "program": "promiseCasting.ets" } @@ -1657,12 +1947,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 34, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 29, + "line": 34, "column": 27, "program": "promiseCasting.ets" } @@ -1673,12 +1963,12 @@ "value": 6, "loc": { "start": { - "line": 29, + "line": 34, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 29, + "line": 34, "column": 31, "program": "promiseCasting.ets" } @@ -1686,12 +1976,12 @@ }, "loc": { "start": { - "line": 29, + "line": 34, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 29, + "line": 34, "column": 31, "program": "promiseCasting.ets" } @@ -1726,12 +2016,12 @@ }, "loc": { "start": { - "line": 29, + "line": 34, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 29, + "line": 34, "column": 31, "program": "promiseCasting.ets" } @@ -1739,12 +2029,12 @@ }, "loc": { "start": { - "line": 29, + "line": 34, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 29, + "line": 34, "column": 31, "program": "promiseCasting.ets" } @@ -1768,12 +2058,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 30, + "line": 35, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 30, + "line": 35, "column": 16, "program": "promiseCasting.ets" } @@ -1782,12 +2072,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 35, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 30, + "line": 35, "column": 16, "program": "promiseCasting.ets" } @@ -1795,12 +2085,12 @@ }, "loc": { "start": { - "line": 30, + "line": 35, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 30, + "line": 35, "column": 16, "program": "promiseCasting.ets" } @@ -1811,12 +2101,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 30, + "line": 35, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 30, + "line": 35, "column": 22, "program": "promiseCasting.ets" } @@ -1836,12 +2126,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 35, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 30, + "line": 35, "column": 27, "program": "promiseCasting.ets" } @@ -1852,12 +2142,12 @@ "value": 7, "loc": { "start": { - "line": 30, + "line": 35, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 30, + "line": 35, "column": 31, "program": "promiseCasting.ets" } @@ -1865,12 +2155,12 @@ }, "loc": { "start": { - "line": 30, + "line": 35, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 30, + "line": 35, "column": 31, "program": "promiseCasting.ets" } @@ -1905,12 +2195,12 @@ }, "loc": { "start": { - "line": 30, + "line": 35, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 30, + "line": 35, "column": 31, "program": "promiseCasting.ets" } @@ -1918,12 +2208,12 @@ }, "loc": { "start": { - "line": 30, + "line": 35, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 30, + "line": 35, "column": 31, "program": "promiseCasting.ets" } @@ -1947,12 +2237,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 31, + "line": 36, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 31, + "line": 36, "column": 16, "program": "promiseCasting.ets" } @@ -1961,12 +2251,12 @@ "decorators": [], "loc": { "start": { - "line": 31, + "line": 36, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 31, + "line": 36, "column": 16, "program": "promiseCasting.ets" } @@ -1974,12 +2264,12 @@ }, "loc": { "start": { - "line": 31, + "line": 36, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 31, + "line": 36, "column": 16, "program": "promiseCasting.ets" } @@ -1990,12 +2280,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 31, + "line": 36, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 31, + "line": 36, "column": 22, "program": "promiseCasting.ets" } @@ -2015,12 +2305,12 @@ "decorators": [], "loc": { "start": { - "line": 31, + "line": 36, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 31, + "line": 36, "column": 27, "program": "promiseCasting.ets" } @@ -2031,12 +2321,12 @@ "value": 8, "loc": { "start": { - "line": 31, + "line": 36, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 31, + "line": 36, "column": 31, "program": "promiseCasting.ets" } @@ -2044,12 +2334,12 @@ }, "loc": { "start": { - "line": 31, + "line": 36, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 31, + "line": 36, "column": 31, "program": "promiseCasting.ets" } @@ -2084,12 +2374,12 @@ }, "loc": { "start": { - "line": 31, + "line": 36, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 31, + "line": 36, "column": 31, "program": "promiseCasting.ets" } @@ -2097,12 +2387,12 @@ }, "loc": { "start": { - "line": 31, + "line": 36, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 31, + "line": 36, "column": 31, "program": "promiseCasting.ets" } @@ -2126,12 +2416,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 32, + "line": 37, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 32, + "line": 37, "column": 16, "program": "promiseCasting.ets" } @@ -2140,12 +2430,12 @@ "decorators": [], "loc": { "start": { - "line": 32, + "line": 37, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 32, + "line": 37, "column": 16, "program": "promiseCasting.ets" } @@ -2153,12 +2443,12 @@ }, "loc": { "start": { - "line": 32, + "line": 37, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 32, + "line": 37, "column": 16, "program": "promiseCasting.ets" } @@ -2169,12 +2459,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 32, + "line": 37, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 32, + "line": 37, "column": 22, "program": "promiseCasting.ets" } @@ -2194,12 +2484,12 @@ "decorators": [], "loc": { "start": { - "line": 32, + "line": 37, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 32, + "line": 37, "column": 27, "program": "promiseCasting.ets" } @@ -2210,12 +2500,12 @@ "value": 9, "loc": { "start": { - "line": 32, + "line": 37, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 32, + "line": 37, "column": 31, "program": "promiseCasting.ets" } @@ -2223,12 +2513,12 @@ }, "loc": { "start": { - "line": 32, + "line": 37, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 32, + "line": 37, "column": 31, "program": "promiseCasting.ets" } @@ -2263,12 +2553,12 @@ }, "loc": { "start": { - "line": 32, + "line": 37, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 32, + "line": 37, "column": 31, "program": "promiseCasting.ets" } @@ -2276,12 +2566,12 @@ }, "loc": { "start": { - "line": 32, + "line": 37, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 32, + "line": 37, "column": 31, "program": "promiseCasting.ets" } @@ -2305,12 +2595,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 33, + "line": 38, "column": 13, "program": "promiseCasting.ets" }, "end": { - "line": 33, + "line": 38, "column": 16, "program": "promiseCasting.ets" } @@ -2319,12 +2609,12 @@ "decorators": [], "loc": { "start": { - "line": 33, + "line": 38, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 33, + "line": 38, "column": 16, "program": "promiseCasting.ets" } @@ -2332,12 +2622,12 @@ }, "loc": { "start": { - "line": 33, + "line": 38, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 33, + "line": 38, "column": 16, "program": "promiseCasting.ets" } @@ -2348,12 +2638,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 33, + "line": 38, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 33, + "line": 38, "column": 22, "program": "promiseCasting.ets" } @@ -2373,12 +2663,12 @@ "decorators": [], "loc": { "start": { - "line": 33, + "line": 38, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 33, + "line": 38, "column": 27, "program": "promiseCasting.ets" } @@ -2389,12 +2679,12 @@ "value": 0, "loc": { "start": { - "line": 33, + "line": 38, "column": 30, "program": "promiseCasting.ets" }, "end": { - "line": 33, + "line": 38, "column": 31, "program": "promiseCasting.ets" } @@ -2402,12 +2692,12 @@ }, "loc": { "start": { - "line": 33, + "line": 38, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 33, + "line": 38, "column": 31, "program": "promiseCasting.ets" } @@ -2442,12 +2732,12 @@ }, "loc": { "start": { - "line": 33, + "line": 38, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 33, + "line": 38, "column": 31, "program": "promiseCasting.ets" } @@ -2455,12 +2745,12 @@ }, "loc": { "start": { - "line": 33, + "line": 38, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 33, + "line": 38, "column": 31, "program": "promiseCasting.ets" } @@ -2469,12 +2759,12 @@ ], "loc": { "start": { - "line": 23, + "line": 28, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 34, + "line": 39, "column": 6, "program": "promiseCasting.ets" } @@ -2482,12 +2772,12 @@ }, "loc": { "start": { - "line": 23, + "line": 28, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 34, + "line": 39, "column": 6, "program": "promiseCasting.ets" } @@ -2495,12 +2785,12 @@ }, "loc": { "start": { - "line": 23, + "line": 28, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 34, + "line": 39, "column": 6, "program": "promiseCasting.ets" } @@ -2515,63 +2805,111 @@ "type": "Identifier", "name": "ps", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 37, - "column": 13, - "program": "promiseCasting.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "promiseCasting.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + } + } }, - "end": { - "line": 37, - "column": 19, - "program": "promiseCasting.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "promiseCasting.ets" + } } } - }, + ], "loc": { "start": { - "line": 37, - "column": 13, + "line": 1, + "column": 3, "program": "promiseCasting.ets" }, "end": { - "line": 37, - "column": 20, + "line": 1, + "column": 3, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 37, - "column": 13, + "line": 1, + "column": 1, "program": "promiseCasting.ets" }, "end": { - "line": 37, - "column": 20, + "line": 1, + "column": 3, "program": "promiseCasting.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 37, + "line": 42, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 37, + "line": 42, "column": 21, "program": "promiseCasting.ets" } @@ -2580,12 +2918,12 @@ "decorators": [], "loc": { "start": { - "line": 37, + "line": 42, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 37, + "line": 42, "column": 11, "program": "promiseCasting.ets" } @@ -2603,12 +2941,12 @@ "decorators": [], "loc": { "start": { - "line": 37, + "line": 42, "column": 28, "program": "promiseCasting.ets" }, "end": { - "line": 37, + "line": 42, "column": 34, "program": "promiseCasting.ets" } @@ -2616,12 +2954,12 @@ }, "loc": { "start": { - "line": 37, + "line": 42, "column": 28, "program": "promiseCasting.ets" }, "end": { - "line": 37, + "line": 42, "column": 35, "program": "promiseCasting.ets" } @@ -2629,12 +2967,12 @@ }, "loc": { "start": { - "line": 37, + "line": 42, "column": 28, "program": "promiseCasting.ets" }, "end": { - "line": 37, + "line": 42, "column": 35, "program": "promiseCasting.ets" } @@ -2645,12 +2983,12 @@ "value": 10, "loc": { "start": { - "line": 37, + "line": 42, "column": 35, "program": "promiseCasting.ets" }, "end": { - "line": 37, + "line": 42, "column": 37, "program": "promiseCasting.ets" } @@ -2658,12 +2996,12 @@ }, "loc": { "start": { - "line": 37, + "line": 42, "column": 24, "program": "promiseCasting.ets" }, "end": { - "line": 37, + "line": 42, "column": 38, "program": "promiseCasting.ets" } @@ -2671,12 +3009,12 @@ }, "loc": { "start": { - "line": 37, + "line": 42, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 37, + "line": 42, "column": 38, "program": "promiseCasting.ets" } @@ -2686,12 +3024,12 @@ "kind": "let", "loc": { "start": { - "line": 37, + "line": 42, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 37, + "line": 42, "column": 38, "program": "promiseCasting.ets" } @@ -2710,12 +3048,12 @@ "decorators": [], "loc": { "start": { - "line": 38, + "line": 43, "column": 14, "program": "promiseCasting.ets" }, "end": { - "line": 38, + "line": 43, "column": 15, "program": "promiseCasting.ets" } @@ -2726,12 +3064,12 @@ "value": 0, "loc": { "start": { - "line": 38, + "line": 43, "column": 18, "program": "promiseCasting.ets" }, "end": { - "line": 38, + "line": 43, "column": 19, "program": "promiseCasting.ets" } @@ -2739,12 +3077,12 @@ }, "loc": { "start": { - "line": 38, + "line": 43, "column": 14, "program": "promiseCasting.ets" }, "end": { - "line": 38, + "line": 43, "column": 19, "program": "promiseCasting.ets" } @@ -2754,12 +3092,12 @@ "kind": "let", "loc": { "start": { - "line": 38, + "line": 43, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 38, + "line": 43, "column": 19, "program": "promiseCasting.ets" } @@ -2774,12 +3112,12 @@ "decorators": [], "loc": { "start": { - "line": 38, + "line": 43, "column": 21, "program": "promiseCasting.ets" }, "end": { - "line": 38, + "line": 43, "column": 22, "program": "promiseCasting.ets" } @@ -2790,12 +3128,12 @@ "value": 10, "loc": { "start": { - "line": 38, + "line": 43, "column": 25, "program": "promiseCasting.ets" }, "end": { - "line": 38, + "line": 43, "column": 27, "program": "promiseCasting.ets" } @@ -2803,12 +3141,12 @@ }, "loc": { "start": { - "line": 38, + "line": 43, "column": 21, "program": "promiseCasting.ets" }, "end": { - "line": 38, + "line": 43, "column": 27, "program": "promiseCasting.ets" } @@ -2824,12 +3162,12 @@ "decorators": [], "loc": { "start": { - "line": 38, + "line": 43, "column": 29, "program": "promiseCasting.ets" }, "end": { - "line": 38, + "line": 43, "column": 30, "program": "promiseCasting.ets" } @@ -2837,12 +3175,12 @@ }, "loc": { "start": { - "line": 38, + "line": 43, "column": 29, "program": "promiseCasting.ets" }, "end": { - "line": 38, + "line": 43, "column": 32, "program": "promiseCasting.ets" } @@ -2864,12 +3202,12 @@ "decorators": [], "loc": { "start": { - "line": 39, + "line": 44, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 39, + "line": 44, "column": 11, "program": "promiseCasting.ets" } @@ -2881,12 +3219,12 @@ "decorators": [], "loc": { "start": { - "line": 39, + "line": 44, "column": 12, "program": "promiseCasting.ets" }, "end": { - "line": 39, + "line": 44, "column": 13, "program": "promiseCasting.ets" } @@ -2896,106 +3234,283 @@ "optional": false, "loc": { "start": { - "line": 39, + "line": 44, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 39, + "line": 44, "column": 14, "program": "promiseCasting.ets" } } }, "right": { - "type": "ETSLaunchExpression", - "expr": { - "type": "CallExpression", - "callee": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "launch", + "decorators": [], + "loc": { + "start": { + "line": 44, + "column": 17, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 23, + "program": "promiseCasting.ets" + } + } + }, + "arguments": [ + { "type": "Identifier", "name": "foo", "decorators": [], "loc": { "start": { - "line": 39, - "column": 24, + "line": 44, + "column": 44, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 47, + "program": "promiseCasting.ets" + } + } + }, + { + "type": "Identifier", + "name": "i", + "decorators": [], + "loc": { + "start": { + "line": 44, + "column": 49, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 50, "program": "promiseCasting.ets" + } + } + } + ], + "optional": false, + "typeParameters": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Cb", + "decorators": [], + "loc": { + "start": { + "line": 44, + "column": 24, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 26, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 44, + "column": 24, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 27, + "program": "promiseCasting.ets" + } + } }, - "end": { - "line": 39, - "column": 27, - "program": "promiseCasting.ets" + "loc": { + "start": { + "line": 44, + "column": 24, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 27, + "program": "promiseCasting.ets" + } } - } - }, - "arguments": [ + }, { - "type": "Identifier", - "name": "i", - "decorators": [], + "type": "ETSFunctionType", + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "i", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 44, + "column": 32, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 35, + "program": "promiseCasting.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 44, + "column": 29, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 35, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 44, + "column": 29, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 35, + "program": "promiseCasting.ets" + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Cb", + "decorators": [], + "loc": { + "start": { + "line": 44, + "column": 40, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 42, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 44, + "column": 40, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 43, + "program": "promiseCasting.ets" + } + } + }, + "loc": { + "start": { + "line": 44, + "column": 40, + "program": "promiseCasting.ets" + }, + "end": { + "line": 44, + "column": 43, + "program": "promiseCasting.ets" + } + } + }, "loc": { "start": { - "line": 39, + "line": 44, "column": 28, "program": "promiseCasting.ets" }, "end": { - "line": 39, - "column": 29, + "line": 44, + "column": 43, "program": "promiseCasting.ets" } } } ], - "optional": false, "loc": { "start": { - "line": 39, - "column": 24, + "line": 44, + "column": 23, "program": "promiseCasting.ets" }, "end": { - "line": 39, - "column": 30, + "line": 44, + "column": 43, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 39, + "line": 44, "column": 17, "program": "promiseCasting.ets" }, "end": { - "line": 39, - "column": 30, + "line": 44, + "column": 51, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 39, + "line": 44, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 39, - "column": 30, + "line": 44, + "column": 51, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 39, + "line": 44, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 39, - "column": 30, + "line": 44, + "column": 51, "program": "promiseCasting.ets" } } @@ -3003,12 +3518,12 @@ ], "loc": { "start": { - "line": 38, + "line": 43, "column": 34, "program": "promiseCasting.ets" }, "end": { - "line": 40, + "line": 45, "column": 6, "program": "promiseCasting.ets" } @@ -3016,12 +3531,12 @@ }, "loc": { "start": { - "line": 38, + "line": 43, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 40, + "line": 45, "column": 6, "program": "promiseCasting.ets" } @@ -3038,12 +3553,12 @@ "decorators": [], "loc": { "start": { - "line": 42, + "line": 47, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 42, + "line": 47, "column": 12, "program": "promiseCasting.ets" } @@ -3054,12 +3569,12 @@ "value": 0, "loc": { "start": { - "line": 42, + "line": 47, "column": 15, "program": "promiseCasting.ets" }, "end": { - "line": 42, + "line": 47, "column": 16, "program": "promiseCasting.ets" } @@ -3067,12 +3582,12 @@ }, "loc": { "start": { - "line": 42, + "line": 47, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 42, + "line": 47, "column": 16, "program": "promiseCasting.ets" } @@ -3082,12 +3597,12 @@ "kind": "let", "loc": { "start": { - "line": 42, + "line": 47, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 42, + "line": 47, "column": 16, "program": "promiseCasting.ets" } @@ -3106,12 +3621,12 @@ "decorators": [], "loc": { "start": { - "line": 43, + "line": 48, "column": 14, "program": "promiseCasting.ets" }, "end": { - "line": 43, + "line": 48, "column": 15, "program": "promiseCasting.ets" } @@ -3122,12 +3637,12 @@ "value": 9, "loc": { "start": { - "line": 43, + "line": 48, "column": 18, "program": "promiseCasting.ets" }, "end": { - "line": 43, + "line": 48, "column": 19, "program": "promiseCasting.ets" } @@ -3135,12 +3650,12 @@ }, "loc": { "start": { - "line": 43, + "line": 48, "column": 14, "program": "promiseCasting.ets" }, "end": { - "line": 43, + "line": 48, "column": 19, "program": "promiseCasting.ets" } @@ -3150,12 +3665,12 @@ "kind": "let", "loc": { "start": { - "line": 43, + "line": 48, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 43, + "line": 48, "column": 19, "program": "promiseCasting.ets" } @@ -3170,12 +3685,12 @@ "decorators": [], "loc": { "start": { - "line": 43, + "line": 48, "column": 21, "program": "promiseCasting.ets" }, "end": { - "line": 43, + "line": 48, "column": 22, "program": "promiseCasting.ets" } @@ -3186,12 +3701,12 @@ "value": 0, "loc": { "start": { - "line": 43, + "line": 48, "column": 26, "program": "promiseCasting.ets" }, "end": { - "line": 43, + "line": 48, "column": 27, "program": "promiseCasting.ets" } @@ -3199,12 +3714,12 @@ }, "loc": { "start": { - "line": 43, + "line": 48, "column": 21, "program": "promiseCasting.ets" }, "end": { - "line": 43, + "line": 48, "column": 27, "program": "promiseCasting.ets" } @@ -3220,12 +3735,12 @@ "decorators": [], "loc": { "start": { - "line": 43, + "line": 48, "column": 29, "program": "promiseCasting.ets" }, "end": { - "line": 43, + "line": 48, "column": 30, "program": "promiseCasting.ets" } @@ -3233,12 +3748,12 @@ }, "loc": { "start": { - "line": 43, + "line": 48, "column": 29, "program": "promiseCasting.ets" }, "end": { - "line": 43, + "line": 48, "column": 32, "program": "promiseCasting.ets" } @@ -3258,12 +3773,12 @@ "decorators": [], "loc": { "start": { - "line": 44, + "line": 49, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 44, + "line": 49, "column": 12, "program": "promiseCasting.ets" } @@ -3272,225 +3787,229 @@ "right": { "type": "CallExpression", "callee": { - "type": "AwaitExpression", - "argument": { - "type": "TSAsExpression", - "expression": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "ps", - "decorators": [], - "loc": { - "start": { - "line": 44, - "column": 23, - "program": "promiseCasting.ets" - }, - "end": { - "line": 44, - "column": 25, - "program": "promiseCasting.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "i", - "decorators": [], - "loc": { - "start": { - "line": 44, - "column": 26, - "program": "promiseCasting.ets" - }, - "end": { - "line": 44, - "column": 27, - "program": "promiseCasting.ets" + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "TSAsExpression", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "ps", + "decorators": [], + "loc": { + "start": { + "line": 49, + "column": 18, + "program": "promiseCasting.ets" + }, + "end": { + "line": 49, + "column": 20, + "program": "promiseCasting.ets" + } } - } - }, - "computed": true, - "optional": false, - "loc": { - "start": { - "line": 44, - "column": 23, - "program": "promiseCasting.ets" }, - "end": { - "line": 44, - "column": 28, - "program": "promiseCasting.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { + "property": { "type": "Identifier", - "name": "Promise", + "name": "i", "decorators": [], "loc": { "start": { - "line": 44, - "column": 32, + "line": 49, + "column": 21, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 39, + "line": 49, + "column": 22, "program": "promiseCasting.ets" } } }, - "typeParams": { - "type": "TSTypeParameterInstantiation", - "params": [ - { - "type": "ETSFunctionType", - "params": [ - { - "type": "ETSParameterExpression", + "computed": true, + "optional": false, + "loc": { + "start": { + "line": 49, + "column": 18, + "program": "promiseCasting.ets" + }, + "end": { + "line": 49, + "column": 23, + "program": "promiseCasting.ets" + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Job", + "decorators": [], + "loc": { + "start": { + "line": 49, + "column": 27, + "program": "promiseCasting.ets" + }, + "end": { + "line": 49, + "column": 30, + "program": "promiseCasting.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "p", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 44, - "column": 44, - "program": "promiseCasting.ets" - }, - "end": { - "line": 44, - "column": 47, - "program": "promiseCasting.ets" - } - } - }, + "name": "Cb", "decorators": [], "loc": { "start": { - "line": 44, - "column": 41, + "line": 49, + "column": 31, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 47, + "line": 49, + "column": 33, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 44, - "column": 41, + "line": 49, + "column": 31, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 47, + "line": 49, + "column": 34, "program": "promiseCasting.ets" } } - } - ], - "returnType": { - "type": "ETSPrimitiveType", + }, "loc": { "start": { - "line": 44, - "column": 52, + "line": 49, + "column": 31, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 55, + "line": 49, + "column": 34, "program": "promiseCasting.ets" } } + } + ], + "loc": { + "start": { + "line": 49, + "column": 30, + "program": "promiseCasting.ets" }, - "loc": { - "start": { - "line": 44, - "column": 40, - "program": "promiseCasting.ets" - }, - "end": { - "line": 44, - "column": 55, - "program": "promiseCasting.ets" - } + "end": { + "line": 49, + "column": 34, + "program": "promiseCasting.ets" } } - ], + }, "loc": { "start": { - "line": 44, - "column": 39, + "line": 49, + "column": 27, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 56, + "line": 49, + "column": 35, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 44, - "column": 32, + "line": 49, + "column": 27, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 57, + "line": 49, + "column": 35, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 44, - "column": 32, + "line": 49, + "column": 17, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 57, + "line": 49, + "column": 35, + "program": "promiseCasting.ets" + } + } + }, + "property": { + "type": "Identifier", + "name": "Await", + "decorators": [], + "loc": { + "start": { + "line": 49, + "column": 36, + "program": "promiseCasting.ets" + }, + "end": { + "line": 49, + "column": 41, "program": "promiseCasting.ets" } } }, + "computed": false, + "optional": false, "loc": { "start": { - "line": 44, - "column": 23, + "line": 49, + "column": 17, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 28, + "line": 49, + "column": 41, "program": "promiseCasting.ets" } } }, + "arguments": [], + "optional": false, "loc": { "start": { - "line": 44, + "line": 49, "column": 16, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 57, + "line": 49, + "column": 44, "program": "promiseCasting.ets" } } @@ -3502,13 +4021,13 @@ "decorators": [], "loc": { "start": { - "line": 44, - "column": 58, + "line": 49, + "column": 45, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 59, + "line": 49, + "column": 46, "program": "promiseCasting.ets" } } @@ -3517,39 +4036,39 @@ "optional": false, "loc": { "start": { - "line": 44, + "line": 49, "column": 16, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 60, + "line": 49, + "column": 47, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 44, + "line": 49, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 60, + "line": 49, + "column": 47, "program": "promiseCasting.ets" } } }, "loc": { "start": { - "line": 44, + "line": 49, "column": 9, "program": "promiseCasting.ets" }, "end": { - "line": 44, - "column": 60, + "line": 49, + "column": 47, "program": "promiseCasting.ets" } } @@ -3557,12 +4076,12 @@ ], "loc": { "start": { - "line": 43, + "line": 48, "column": 34, "program": "promiseCasting.ets" }, "end": { - "line": 45, + "line": 50, "column": 6, "program": "promiseCasting.ets" } @@ -3570,12 +4089,12 @@ }, "loc": { "start": { - "line": 43, + "line": 48, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 45, + "line": 50, "column": 6, "program": "promiseCasting.ets" } @@ -3591,12 +4110,12 @@ "decorators": [], "loc": { "start": { - "line": 46, + "line": 51, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 46, + "line": 51, "column": 13, "program": "promiseCasting.ets" } @@ -3609,12 +4128,12 @@ "decorators": [], "loc": { "start": { - "line": 46, + "line": 51, "column": 14, "program": "promiseCasting.ets" }, "end": { - "line": 46, + "line": 51, "column": 17, "program": "promiseCasting.ets" } @@ -3625,12 +4144,12 @@ "value": 90, "loc": { "start": { - "line": 46, + "line": 51, "column": 19, "program": "promiseCasting.ets" }, "end": { - "line": 46, + "line": 51, "column": 21, "program": "promiseCasting.ets" } @@ -3640,12 +4159,12 @@ "optional": false, "loc": { "start": { - "line": 46, + "line": 51, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 46, + "line": 51, "column": 22, "program": "promiseCasting.ets" } @@ -3653,12 +4172,12 @@ }, "loc": { "start": { - "line": 46, + "line": 51, "column": 5, "program": "promiseCasting.ets" }, "end": { - "line": 46, + "line": 51, "column": 23, "program": "promiseCasting.ets" } @@ -3667,12 +4186,12 @@ ], "loc": { "start": { - "line": 22, + "line": 27, "column": 17, "program": "promiseCasting.ets" }, "end": { - "line": 47, + "line": 52, "column": 2, "program": "promiseCasting.ets" } @@ -3680,12 +4199,12 @@ }, "loc": { "start": { - "line": 22, + "line": 27, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 47, + "line": 52, "column": 2, "program": "promiseCasting.ets" } @@ -3693,12 +4212,12 @@ }, "loc": { "start": { - "line": 22, + "line": 27, "column": 10, "program": "promiseCasting.ets" }, "end": { - "line": 47, + "line": 52, "column": 2, "program": "promiseCasting.ets" } @@ -3708,12 +4227,12 @@ "decorators": [], "loc": { "start": { - "line": 22, + "line": 27, "column": 1, "program": "promiseCasting.ets" }, "end": { - "line": 47, + "line": 52, "column": 2, "program": "promiseCasting.ets" } @@ -3754,10 +4273,9 @@ "program": "promiseCasting.ets" }, "end": { - "line": 48, + "line": 53, "column": 1, "program": "promiseCasting.ets" } } } -Warning: Variable 'fs' is used before being assigned. [promiseCasting.ets:19:12] diff --git a/ets2panda/test/parser/ets/promiseCasting.ets b/ets2panda/test/parser/ets/promiseCasting.ets index b150f8c0365ba4dad2a648ed0f8f93998e341f85..d0bfde8e00b74d51dfd5333f2d8207c20af08697 100644 --- a/ets2panda/test/parser/ets/promiseCasting.ets +++ b/ets2panda/test/parser/ets/promiseCasting.ets @@ -13,9 +13,14 @@ * limitations under the License. */ -let fs: ((p: int) => int)[] +import {launch} from "std/concurrency" +import {Job} from "std/core" -function foo(i: int): ((p: int) => int) { +type Cb = (p: int) => int; + +let fs: Cb[] = [] + +function foo(i: int): Cb { return fs[i] } @@ -36,12 +41,12 @@ function main() { // array of promises let ps: Object[] = new Object[10] for (let i = 0; i < 10; i++) { - ps[i] = launch foo(i) + ps[i] = launch Cb>(foo, i) } let cnt = 0 for (let i = 9; i >= 0; i--) { - cnt += (await ps[i] as Promise<(p: int) => int>)(i) // <- complains on this line + cnt += ((ps[i] as Job).Await())(i) // <- complains on this line } assertEQ(cnt, 90); } diff --git a/ets2panda/test/parser/ets/proxyVoidGeneration-expected.txt b/ets2panda/test/parser/ets/proxyVoidGeneration-expected.txt index 8b0a2770079c6eb4532dfcc253e050088ea13f77..f6c9b7b86348b1905645a427b226e106cf62a1bb 100644 --- a/ets2panda/test/parser/ets/proxyVoidGeneration-expected.txt +++ b/ets2panda/test/parser/ets/proxyVoidGeneration-expected.txt @@ -537,6 +537,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 17, + "column": 45, + "program": "proxyVoidGeneration.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 17, + "column": 45, + "program": "proxyVoidGeneration.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 17, + "column": 45, + "program": "proxyVoidGeneration.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 17, + "column": 45, + "program": "proxyVoidGeneration.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 17, + "column": 45, + "program": "proxyVoidGeneration.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 17, + "column": 45, + "program": "proxyVoidGeneration.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 17, + "column": 45, + "program": "proxyVoidGeneration.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 17, + "column": 45, + "program": "proxyVoidGeneration.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 9, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 17, + "column": 45, + "program": "proxyVoidGeneration.ets" + } + } + } + ], "loc": { "start": { "line": 17, @@ -738,6 +890,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 11, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 18, + "column": 36, + "program": "proxyVoidGeneration.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 11, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 18, + "column": 36, + "program": "proxyVoidGeneration.ets" + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 11, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 18, + "column": 36, + "program": "proxyVoidGeneration.ets" + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 11, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 18, + "column": 36, + "program": "proxyVoidGeneration.ets" + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 11, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 18, + "column": 36, + "program": "proxyVoidGeneration.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 11, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 18, + "column": 36, + "program": "proxyVoidGeneration.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 0, + "loc": { + "start": { + "line": 18, + "column": 11, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 18, + "column": 36, + "program": "proxyVoidGeneration.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 11, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 18, + "column": 36, + "program": "proxyVoidGeneration.ets" + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 11, + "program": "proxyVoidGeneration.ets" + }, + "end": { + "line": 18, + "column": 36, + "program": "proxyVoidGeneration.ets" + } + } + } + ], "loc": { "start": { "line": 18, @@ -933,40 +1237,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "proxyVoidGeneration.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "proxyVoidGeneration.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "proxyVoidGeneration.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "proxyVoidGeneration.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/proxy_method-expected.txt b/ets2panda/test/parser/ets/proxy_method-expected.txt index 4c3b5eceae2d19fde6ecb09cb6f7fd52285f7ca5..82842049454e8deb38b6feea4b886fd2b3c96d86 100644 --- a/ets2panda/test/parser/ets/proxy_method-expected.txt +++ b/ets2panda/test/parser/ets/proxy_method-expected.txt @@ -382,6 +382,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "proxy_method.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "proxy_method.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "proxy_method.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "proxy_method.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "proxy_method.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "proxy_method.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "proxy_method.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "proxy_method.ets" + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "proxy_method.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "proxy_method.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "proxy_method.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "proxy_method.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "proxy_method.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "proxy_method.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "proxy_method.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "proxy_method.ets" + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 8, + "program": "proxy_method.ets" + }, + "end": { + "line": 19, + "column": 6, + "program": "proxy_method.ets" + } + } + } + ], "loc": { "start": { "line": 17, @@ -577,40 +729,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "proxy_method.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "proxy_method.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "proxy_method.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "proxy_method.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/diamond/A-expected.txt b/ets2panda/test/parser/ets/re_export/diamond/A-expected.txt index ff55665e5f67f56daf95ca4235b2cfff90e9ee81..615f5ec20843216700cb8943e49771c93b59794a 100644 --- a/ets2panda/test/parser/ets/re_export/diamond/A-expected.txt +++ b/ets2panda/test/parser/ets/re_export/diamond/A-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "A.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "A.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "A.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "A.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/diamond/B-expected.txt b/ets2panda/test/parser/ets/re_export/diamond/B-expected.txt index 422ecbae90018977f740e84d1ed8ca1ac0b05a2d..696c8558c37fcbe8557a520c1550e106373cfea2 100644 --- a/ets2panda/test/parser/ets/re_export/diamond/B-expected.txt +++ b/ets2panda/test/parser/ets/re_export/diamond/B-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "B.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "B.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "B.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "B.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/diamond/B2-expected.txt b/ets2panda/test/parser/ets/re_export/diamond/B2-expected.txt index 62712365ddca0e9c9ac97b497db95cd27f233aef..ce3d37857326d8e77e71ab4a659e606355d621b6 100644 --- a/ets2panda/test/parser/ets/re_export/diamond/B2-expected.txt +++ b/ets2panda/test/parser/ets/re_export/diamond/B2-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "B2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "B2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "B2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "B2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/diamond/C-expected.txt b/ets2panda/test/parser/ets/re_export/diamond/C-expected.txt index b8eec2a2ad653be3bd2ef04e729608e502b2eebe..6e85e269d62c6a503c965977b29fb359815df8cd 100644 --- a/ets2panda/test/parser/ets/re_export/diamond/C-expected.txt +++ b/ets2panda/test/parser/ets/re_export/diamond/C-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "C.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "C.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "C.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "C.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/diamond/C2-expected.txt b/ets2panda/test/parser/ets/re_export/diamond/C2-expected.txt index bd4d24e6da3d01c900749f1fa0a9f312060249b7..89615244b941abc2ef7a7b9ff2bb19ba0e0f7ff8 100644 --- a/ets2panda/test/parser/ets/re_export/diamond/C2-expected.txt +++ b/ets2panda/test/parser/ets/re_export/diamond/C2-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "C2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "C2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "C2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "C2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/diamond/D-expected.txt b/ets2panda/test/parser/ets/re_export/diamond/D-expected.txt index 1f85bac72609f938dc0038a763cae377d365e368..87ef6e7f5329bbd8f0cea0e19485ba35190fe40c 100644 --- a/ets2panda/test/parser/ets/re_export/diamond/D-expected.txt +++ b/ets2panda/test/parser/ets/re_export/diamond/D-expected.txt @@ -153,40 +153,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "D.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "D.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "D.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "D.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/diamond/D2-expected.txt b/ets2panda/test/parser/ets/re_export/diamond/D2-expected.txt index c2cbb73613d814241252ca2252a4e4d9e97443a5..9fe8f42c76b7a39a11d24dac27cc1cd72ae10050 100644 --- a/ets2panda/test/parser/ets/re_export/diamond/D2-expected.txt +++ b/ets2panda/test/parser/ets/re_export/diamond/D2-expected.txt @@ -153,40 +153,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "D2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "D2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "D2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "D2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/export-expected.txt b/ets2panda/test/parser/ets/re_export/export-expected.txt index 31fcf8d152e33ed14fbc1dbbd9bf19ecb4ab1bd3..c10cf4198c7249827182ad9b4838145d45d764bf 100644 --- a/ets2panda/test/parser/ets/re_export/export-expected.txt +++ b/ets2panda/test/parser/ets/re_export/export-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/export_2-expected.txt b/ets2panda/test/parser/ets/re_export/export_2-expected.txt index dde19dc455685cb5f2e3f9533ea4de27c283355f..a78d3223db209bab1faaadb31cda063df528ee87 100644 --- a/ets2panda/test/parser/ets/re_export/export_2-expected.txt +++ b/ets2panda/test/parser/ets/re_export/export_2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/export_3-expected.txt b/ets2panda/test/parser/ets/re_export/export_3-expected.txt index 1720414890a90436f0acff017e22dae857d0aef4..990e3c747c92f14cee5a62c5d979e4d88ee3611f 100644 --- a/ets2panda/test/parser/ets/re_export/export_3-expected.txt +++ b/ets2panda/test/parser/ets/re_export/export_3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/folder/export-expected.txt b/ets2panda/test/parser/ets/re_export/folder/export-expected.txt index 31fcf8d152e33ed14fbc1dbbd9bf19ecb4ab1bd3..c10cf4198c7249827182ad9b4838145d45d764bf 100644 --- a/ets2panda/test/parser/ets/re_export/folder/export-expected.txt +++ b/ets2panda/test/parser/ets/re_export/folder/export-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/folder/folder2/export-expected.txt b/ets2panda/test/parser/ets/re_export/folder/folder2/export-expected.txt index 31fcf8d152e33ed14fbc1dbbd9bf19ecb4ab1bd3..c10cf4198c7249827182ad9b4838145d45d764bf 100644 --- a/ets2panda/test/parser/ets/re_export/folder/folder2/export-expected.txt +++ b/ets2panda/test/parser/ets/re_export/folder/folder2/export-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/folder/re_export_6-expected.txt b/ets2panda/test/parser/ets/re_export/folder/re_export_6-expected.txt index 4d2ee8557aedad529c35a50754bf41d045e12c0e..10e735b0e938a1147e1a5ba6d45f0c4f227498b9 100644 --- a/ets2panda/test/parser/ets/re_export/folder/re_export_6-expected.txt +++ b/ets2panda/test/parser/ets/re_export/folder/re_export_6-expected.txt @@ -103,40 +103,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/folder/re_export_7-expected.txt b/ets2panda/test/parser/ets/re_export/folder/re_export_7-expected.txt index 2e046adf2ffabcaf01c4744dcc89e08ecc3c2333..e00178f99c3fb543e40eeb8948a4a1f86c3a913a 100644 --- a/ets2panda/test/parser/ets/re_export/folder/re_export_7-expected.txt +++ b/ets2panda/test/parser/ets/re_export/folder/re_export_7-expected.txt @@ -103,40 +103,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/folderIndex/index-expected.txt b/ets2panda/test/parser/ets/re_export/folderIndex/index-expected.txt index cc60a07658fe11ba08ba824f602ab5af5864bfcc..5a0839b190be4d721cfc3652cb57263ed1e8421d 100644 --- a/ets2panda/test/parser/ets/re_export/folderIndex/index-expected.txt +++ b/ets2panda/test/parser/ets/re_export/folderIndex/index-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "index.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "index.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "index.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "index.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/folderIndex/test-expected.txt b/ets2panda/test/parser/ets/re_export/folderIndex/test-expected.txt index 91b143592c162ec851de061b3b328bdd1824a249..a429b641b1ed172875ea356863e4f6c253b3b401 100644 --- a/ets2panda/test/parser/ets/re_export/folderIndex/test-expected.txt +++ b/ets2panda/test/parser/ets/re_export/folderIndex/test-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/folderIndex2/index-expected.txt b/ets2panda/test/parser/ets/re_export/folderIndex2/index-expected.txt index d34d0b46075b84f8503181d1f751468b9cc87319..01b819fb79c3747defd3366d73a6c392804ebc1c 100644 --- a/ets2panda/test/parser/ets/re_export/folderIndex2/index-expected.txt +++ b/ets2panda/test/parser/ets/re_export/folderIndex2/index-expected.txt @@ -217,40 +217,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "index.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "index.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "index.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "index.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/folderIndex2/key-expected.txt b/ets2panda/test/parser/ets/re_export/folderIndex2/key-expected.txt index d5a1ff2a2bfe861045513e8cbcbb55fc9720c1fe..adce9c43d8c692b8e8c62d23bbf5eaa169337ee6 100644 --- a/ets2panda/test/parser/ets/re_export/folderIndex2/key-expected.txt +++ b/ets2panda/test/parser/ets/re_export/folderIndex2/key-expected.txt @@ -539,40 +539,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "key.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "key.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "key.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "key.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/folderIndex2/type-expected.txt b/ets2panda/test/parser/ets/re_export/folderIndex2/type-expected.txt index 8e917a234272cb3f04a933f71a47f8074e3f0573..5771878865279937af6600a202052a000b945892 100644 --- a/ets2panda/test/parser/ets/re_export/folderIndex2/type-expected.txt +++ b/ets2panda/test/parser/ets/re_export/folderIndex2/type-expected.txt @@ -102,40 +102,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type.ets" - } - } - } - ], "body": [], "loc": { "start": { diff --git a/ets2panda/test/parser/ets/re_export/import-expected.txt b/ets2panda/test/parser/ets/re_export/import-expected.txt index 5d381b19474b72e5f843b945b37c81e7c5855742..c4555cef6a40bd9a116df0ce0e72238169ff820d 100644 --- a/ets2panda/test/parser/ets/re_export/import-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_10-expected.txt b/ets2panda/test/parser/ets/re_export/import_10-expected.txt index 62143ea4820f8944f331ef8a44ed9d101fa4f359..21522024230d4c9763450a7899c86c5129758d31 100644 --- a/ets2panda/test/parser/ets/re_export/import_10-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_10-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_10.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_10.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -408,4 +374,4 @@ } } } -TypeError: Ambiguous export "foo" [re_export_4.ets:17:8] +TypeError: Ambiguous export 'foo' [re_export_4.ets:16:8] diff --git a/ets2panda/test/parser/ets/re_export/import_11-expected.txt b/ets2panda/test/parser/ets/re_export/import_11-expected.txt index 52bde5a1d3f23889b6ac84bf33d84357c2e26b6c..ea9d0aaa0d05bb1f129f841a36fa09e46e47d980 100644 --- a/ets2panda/test/parser/ets/re_export/import_11-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_11-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_11.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_11.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_11.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_11.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_12-expected.txt b/ets2panda/test/parser/ets/re_export/import_12-expected.txt index d4901eddcab3944869972a82bc64256e2f2631ae..26aac25beb0255dc99c3ee7bdae795e3b6c7309f 100644 --- a/ets2panda/test/parser/ets/re_export/import_12-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_12-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_12.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_12.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_13-expected.txt b/ets2panda/test/parser/ets/re_export/import_13-expected.txt index 2ddc505122806106cbc106dbd900afeeac959c92..071835ff81dec1a0154597f2b08a6b3b2f5e4529 100644 --- a/ets2panda/test/parser/ets/re_export/import_13-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_13-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_13.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_13.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_13.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_13.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_14-expected.txt b/ets2panda/test/parser/ets/re_export/import_14-expected.txt index 6682a7667554d2de4fd19e9805810c8819d7baf0..baf95e0b3bbb9e5ed89f05f0e177679f9bf23d63 100644 --- a/ets2panda/test/parser/ets/re_export/import_14-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_14-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_14.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_14.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_14.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_14.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_15-expected.txt b/ets2panda/test/parser/ets/re_export/import_15-expected.txt index 0b257f1e0b1f6c2d1b84445152ee11f91c98a117..c8d44adc39c6cea88715f619e136288952082385 100644 --- a/ets2panda/test/parser/ets/re_export/import_15-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_15-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_15.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_15.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_15.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_15.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_2-expected.txt b/ets2panda/test/parser/ets/re_export/import_2-expected.txt index 67297d50a043d20ad2a3c85a78079ac98155812d..415dd9dd6e824ccc54cbab9a11cc8e1513f8a80e 100644 --- a/ets2panda/test/parser/ets/re_export/import_2-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_2-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_3-expected.txt b/ets2panda/test/parser/ets/re_export/import_3-expected.txt index 024320aeb20c83e908acc57d6b9a6ae1fbba11b0..f7d16ecb3c5b8250bdbb26054bd665fb2a02e366 100644 --- a/ets2panda/test/parser/ets/re_export/import_3-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_3-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_6-expected.txt b/ets2panda/test/parser/ets/re_export/import_6-expected.txt index 14f32a904f48ed3c67baf2764ed1bf1003eb30dd..89385a92b708526b4cf62a5a543b2f324eafdcef 100644 --- a/ets2panda/test/parser/ets/re_export/import_6-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_6-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_7-expected.txt b/ets2panda/test/parser/ets/re_export/import_7-expected.txt index e3f89ab4d45dba027787ada0d3d8a37a9407482b..61bdc33e1d67efa5a90a92d864a339b61ca716bc 100644 --- a/ets2panda/test/parser/ets/re_export/import_7-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_7-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_8-expected.txt b/ets2panda/test/parser/ets/re_export/import_8-expected.txt index 883248e34d3d57cd50267b7147fc13a617610d14..a2ec6219137e18d0ca360a6b8896e3f491311e9d 100644 --- a/ets2panda/test/parser/ets/re_export/import_8-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_8-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_9-expected.txt b/ets2panda/test/parser/ets/re_export/import_9-expected.txt index 7d623ce3baf32c278445a02bea36fa0b77adc3bd..147783e0d930212917f23eddc5df4e35a6d63b2e 100644 --- a/ets2panda/test/parser/ets/re_export/import_9-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_9-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_index-expected.txt b/ets2panda/test/parser/ets/re_export/import_index-expected.txt index 5e16944853062a870cfb37e51fb40886ebf9ec36..2152c6a9d0e98682b31e738386195dce07e9cebe 100644 --- a/ets2panda/test/parser/ets/re_export/import_index-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_index-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_index.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_index.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_index.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_index.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_index_2-expected.txt b/ets2panda/test/parser/ets/re_export/import_index_2-expected.txt index 464a303478d3a4cb00483ee1f76e2d3f01aeb115..671af9dde71a582cc29be85c24c8b9579bb3a76f 100644 --- a/ets2panda/test/parser/ets/re_export/import_index_2-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_index_2-expected.txt @@ -105,40 +105,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_index_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_index_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_index_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_index_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/import_index_3-expected.txt b/ets2panda/test/parser/ets/re_export/import_index_3-expected.txt index e7fd3585d4d14a9a07083713dc535e0410c0f4ec..53043501efb901b3da594ff0ba0cbae169d9c107 100644 --- a/ets2panda/test/parser/ets/re_export/import_index_3-expected.txt +++ b/ets2panda/test/parser/ets/re_export/import_index_3-expected.txt @@ -154,40 +154,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_index_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_index_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_index_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_index_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export-expected.txt b/ets2panda/test/parser/ets/re_export/re_export-expected.txt index e6324f484690b5929ef5fb26dea4eda3ff181a05..f16ec402b76463131bbb936ce2c4da178d93abdd 100644 --- a/ets2panda/test/parser/ets/re_export/re_export-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export-expected.txt @@ -103,40 +103,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export_10-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_10-expected.txt index 23c8a0f40642ec6f2975dc155c777bd9e2fe3d22..8cf2f783ef50a9c4c191536d398a40a3549b1a07 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_10-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_10-expected.txt @@ -103,40 +103,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_10.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_10.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_10.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export_11-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_11-expected.txt index 1fcb79c6aa5ef11393eb408af6b603f8899e6851..85b263f83b3923e8f08b06acc9bd023371b6087a 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_11-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_11-expected.txt @@ -200,40 +200,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_11.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_11.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_11.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_11.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export_12-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_12-expected.txt index 612beebafafcec2ee4dbdce55e0dcc88e64974db..2b7521bf9626b137a946e67fdc4ae164f9ac734c 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_12-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_12-expected.txt @@ -183,40 +183,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_12.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_12.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_12.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export_2-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_2-expected.txt index a75c38c16718bc9b93e0ba27089870cc8bb547df..d1693124bb4f62575c1d763e5b2fdc2189b26eb4 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_2-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_2-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export_3-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_3-expected.txt index 6a9368a3185284727ef5ef9cc22dd82cc41c168f..25da675026f4ed138e673425d2ff8b2692d3390f 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_3-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_3-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export_4-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_4-expected.txt index cb83b0c0ac97132bfa24bd5dc250f3b4cabaec1f..23266085b04a3b8123302cca339ef97225492d25 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_4-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_4-expected.txt @@ -217,40 +217,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -505,4 +471,4 @@ } } } -TypeError: Ambiguous export "foo" [re_export_4.ets:17:8] +TypeError: Ambiguous export 'foo' [re_export_4.ets:16:8] diff --git a/ets2panda/test/parser/ets/re_export/re_export_5-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_5-expected.txt index 82c25c96f290c5a492adfff1979f0ddb03a3f971..b7a59b0bdb3c5781c6a6eba547f53276ca76217c 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_5-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_5-expected.txt @@ -183,40 +183,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export_7-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_7-expected.txt index 717243b0aeb21e6cdeb2cf7ce55f0f6511eed2b2..347afbe778593a6fee652539b6d292d6a5f73baf 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_7-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_7-expected.txt @@ -200,40 +200,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export_8-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_8-expected.txt index 1224b4b4522dc028150c4073d922920d9dc8b714..eafe5f6b5417cea0b421f05a78e57880da396a46 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_8-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_8-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/re_export/re_export_9-expected.txt b/ets2panda/test/parser/ets/re_export/re_export_9-expected.txt index be9512b1ef6b133c4a6be8e5e0b6c9ee5c846a32..993f53396b37d0ca9d5bbbddaf6852148e33115c 100644 --- a/ets2panda/test/parser/ets/re_export/re_export_9-expected.txt +++ b/ets2panda/test/parser/ets/re_export/re_export_9-expected.txt @@ -120,40 +120,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "re_export_9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "re_export_9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/regression-target-type-context-expected.txt b/ets2panda/test/parser/ets/regression-target-type-context-expected.txt index 4b57ce8f7b8c4314fef07e53b816e2d3a74f7f5b..13fefb7ff773dbf3fd8899b0fdf9d5e238026e4d 100644 --- a/ets2panda/test/parser/ets/regression-target-type-context-expected.txt +++ b/ets2panda/test/parser/ets/regression-target-type-context-expected.txt @@ -1511,40 +1511,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "regression-target-type-context.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "regression-target-type-context.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "regression-target-type-context.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "regression-target-type-context.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/rest_parameter_01-expected.txt b/ets2panda/test/parser/ets/rest_parameter_01-expected.txt index 1e9997f7d221b2eb3375112a7eee87e757a1f8d2..3cd64b9f9933f055065022e17c3380d50a9726a0 100644 --- a/ets2panda/test/parser/ets/rest_parameter_01-expected.txt +++ b/ets2panda/test/parser/ets/rest_parameter_01-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rest_parameter_01.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rest_parameter_01.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rest_parameter_01.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rest_parameter_01.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -622,23 +588,71 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "rest_parameter_01.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "rest_parameter_01.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "rest_parameter_01.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "rest_parameter_01.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "rest_parameter_01.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "rest_parameter_01.ets" + } + } + }, "loc": { "start": { - "line": 20, - "column": 29, + "line": 1, + "column": 1, "program": "rest_parameter_01.ets" }, "end": { - "line": 20, - "column": 32, + "line": 1, + "column": 3, "program": "rest_parameter_01.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/rest_parameter_02-expected.txt b/ets2panda/test/parser/ets/rest_parameter_02-expected.txt index 790996ccb2c624a7b3f7939e25c55809b2acb13d..ee060d72bbd56a2d98857652e5ff34ecdc786ffe 100644 --- a/ets2panda/test/parser/ets/rest_parameter_02-expected.txt +++ b/ets2panda/test/parser/ets/rest_parameter_02-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rest_parameter_02.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rest_parameter_02.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rest_parameter_02.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rest_parameter_02.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -388,23 +354,71 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "rest_parameter_02.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "rest_parameter_02.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "rest_parameter_02.ets" + } + } + }, "loc": { "start": { - "line": 16, - "column": 29, + "line": 1, + "column": 1, "program": "rest_parameter_02.ets" }, "end": { - "line": 16, - "column": 32, + "line": 1, + "column": 3, "program": "rest_parameter_02.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -981,6 +995,158 @@ } } }, + "annotations": [ + { + "expr_": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "functions", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "rest_parameter_02.ets" + } + } + }, + "right": { + "type": "Identifier", + "name": "OptionalParametersAnnotation", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "rest_parameter_02.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "rest_parameter_02.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "rest_parameter_02.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "rest_parameter_02.ets" + } + } + }, + "properties": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "minArgCount", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "rest_parameter_02.ets" + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "rest_parameter_02.ets" + } + } + }, + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "rest_parameter_02.ets" + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 10, + "program": "rest_parameter_02.ets" + }, + "end": { + "line": 22, + "column": 2, + "program": "rest_parameter_02.ets" + } + } + } + ], "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/rethrow-func-1-expected.txt b/ets2panda/test/parser/ets/rethrow-func-1-expected.txt index ccb337ee56784864bd3332d0f315dc687719f4d0..76388e85f7e856dc52a03f3696a340312cb9c9d7 100644 --- a/ets2panda/test/parser/ets/rethrow-func-1-expected.txt +++ b/ets2panda/test/parser/ets/rethrow-func-1-expected.txt @@ -87,40 +87,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrow-func-1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrow-func-1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "rethrow-func-1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "rethrow-func-1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/return-expected.txt b/ets2panda/test/parser/ets/return-expected.txt index 49c69a9d632da15e2734337e2423a306c8571245..0fcf6104d70033044ae567d91bdcb8e88d95f278 100644 --- a/ets2panda/test/parser/ets/return-expected.txt +++ b/ets2panda/test/parser/ets/return-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "return.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "return.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "return.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "return.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -304,23 +270,71 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "return.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "return.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "return.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "return.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "return.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "return.ets" + } + } + }, "loc": { "start": { - "line": 16, - "column": 8, + "line": 1, + "column": 1, "program": "return.ets" }, "end": { - "line": 16, - "column": 11, + "line": 1, + "column": 3, "program": "return.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/returnNullableFromFunction-expected.txt b/ets2panda/test/parser/ets/returnNullableFromFunction-expected.txt index b29d86e4e42771d2bae8a7b3edd01a67c224afc6..9f3ab9a53f848e8cd7da1865d30b590f7a2f7371 100644 --- a/ets2panda/test/parser/ets/returnNullableFromFunction-expected.txt +++ b/ets2panda/test/parser/ets/returnNullableFromFunction-expected.txt @@ -178,40 +178,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "returnNullableFromFunction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "returnNullableFromFunction.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "returnNullableFromFunction.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "returnNullableFromFunction.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/returnNullableFromMethod-expected.txt b/ets2panda/test/parser/ets/returnNullableFromMethod-expected.txt index 560c80cced035074aa22a9ea054ed2c7e8914263..805c5a6ddb8e33b5d005bf5f0739ae55b87c6dbd 100644 --- a/ets2panda/test/parser/ets/returnNullableFromMethod-expected.txt +++ b/ets2panda/test/parser/ets/returnNullableFromMethod-expected.txt @@ -556,40 +556,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "returnNullableFromMethod.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "returnNullableFromMethod.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "returnNullableFromMethod.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "returnNullableFromMethod.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/scoped_decl-expected.txt b/ets2panda/test/parser/ets/scoped_decl-expected.txt index 06c75ffdea822ba85debbc0a31b644207ae4ac3d..043975b70e749434982fad7cb00d5350223230da 100644 --- a/ets2panda/test/parser/ets/scoped_decl-expected.txt +++ b/ets2panda/test/parser/ets/scoped_decl-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "scoped_decl.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "scoped_decl.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "scoped_decl.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "scoped_decl.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/selective_export/import_1-expected.txt b/ets2panda/test/parser/ets/selective_export/import_1-expected.txt index e14e377372a57c47aaf6276f710c1cfd59db2e28..2e0577fb37280cbd81b4ff57ba7adab230e41735 100644 --- a/ets2panda/test/parser/ets/selective_export/import_1-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/import_1-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/selective_export/import_2-expected.txt b/ets2panda/test/parser/ets/selective_export/import_2-expected.txt index 5b7297f219dfc9e0f97e91c220188a668d643171..18ee277c6a3c14484fed50d07bcebc2512d3003f 100644 --- a/ets2panda/test/parser/ets/selective_export/import_2-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/import_2-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/selective_export/import_3-expected.txt b/ets2panda/test/parser/ets/selective_export/import_3-expected.txt index 3fed2ef29d89c6e9bdd7556d4e3815ac27d7291d..15c116300de87e2c580c2ad1c9e7481b5d40436f 100644 --- a/ets2panda/test/parser/ets/selective_export/import_3-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/import_3-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/selective_export/import_4-expected.txt b/ets2panda/test/parser/ets/selective_export/import_4-expected.txt index 6773576ecab6bc2c74ed083d0258167368f85bfa..65e3fa5157f0eff2e419be99763b375fbb660a13 100644 --- a/ets2panda/test/parser/ets/selective_export/import_4-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/import_4-expected.txt @@ -88,40 +88,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "import_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "import_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_1-expected.txt b/ets2panda/test/parser/ets/selective_export/selective_export_1-expected.txt index 601f9e7943781c3e417361098c17bfc0b0c6bae2..f2aa382e5274630464be54d18924621d7cc7aecc 100644 --- a/ets2panda/test/parser/ets/selective_export/selective_export_1-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/selective_export_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_2-expected.txt b/ets2panda/test/parser/ets/selective_export/selective_export_2-expected.txt index ca8627f4566f1ab483c2c649ef7294fb7748e019..3e7e0d9c4b4c505eac058c418759de48c444f188 100644 --- a/ets2panda/test/parser/ets/selective_export/selective_export_2-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/selective_export_2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_3-expected.txt b/ets2panda/test/parser/ets/selective_export/selective_export_3-expected.txt index 78f495a95b10f59c64fad355c90eff391afcd2f5..59533da4d3c58e0fc5a223163f9e55493497d16b 100644 --- a/ets2panda/test/parser/ets/selective_export/selective_export_3-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/selective_export_3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/selective_export/selective_export_4-expected.txt b/ets2panda/test/parser/ets/selective_export/selective_export_4-expected.txt index 384b9321cde628c6da57ac68413981da4c8b2643..148a80d1943ac48c8180d7ae300ad144e3cb1419 100644 --- a/ets2panda/test/parser/ets/selective_export/selective_export_4-expected.txt +++ b/ets2panda/test/parser/ets/selective_export/selective_export_4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "selective_export_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "selective_export_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/simple_types-expected.txt b/ets2panda/test/parser/ets/simple_types-expected.txt index 3fb6093b7e9732d9479890b6df75658580bffbcc..02ebb2a18137878e991c7a4a3d9416def893ab2a 100644 --- a/ets2panda/test/parser/ets/simple_types-expected.txt +++ b/ets2panda/test/parser/ets/simple_types-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "simple_types.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "simple_types.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "simple_types.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "simple_types.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/static_function_override_1-expected.txt b/ets2panda/test/parser/ets/static_function_override_1-expected.txt index 6c22623123a195988674a4ed8b1901a1a60027e5..5de5aa2765d66aac95c7b5d9bab024b67cf1da6c 100644 --- a/ets2panda/test/parser/ets/static_function_override_1-expected.txt +++ b/ets2panda/test/parser/ets/static_function_override_1-expected.txt @@ -621,40 +621,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "static_function_override_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "static_function_override_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "static_function_override_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "static_function_override_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/static_function_override_2-expected.txt b/ets2panda/test/parser/ets/static_function_override_2-expected.txt index dd1d6f89d3ed6c6f2c9f2efc2cd9a17b892f1ff1..72db14fe328d180f003360aecc6afc2cf2f687d1 100644 --- a/ets2panda/test/parser/ets/static_function_override_2-expected.txt +++ b/ets2panda/test/parser/ets/static_function_override_2-expected.txt @@ -621,40 +621,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "static_function_override_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "static_function_override_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "static_function_override_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "static_function_override_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/static_function_override_3-expected.txt b/ets2panda/test/parser/ets/static_function_override_3-expected.txt index e60640ace638463feed1ba8ea6fa942e222f1136..4f6abf5bb82292616985199f8a1cb8f3eb777856 100644 --- a/ets2panda/test/parser/ets/static_function_override_3-expected.txt +++ b/ets2panda/test/parser/ets/static_function_override_3-expected.txt @@ -621,40 +621,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "static_function_override_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "static_function_override_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "static_function_override_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "static_function_override_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/string-expected.txt b/ets2panda/test/parser/ets/string-expected.txt index 80908fa403e625dff55aa7ee5196d90bdb0d1443..cd9fbe932b6903b0850552b11abeede4e79bfb63 100644 --- a/ets2panda/test/parser/ets/string-expected.txt +++ b/ets2panda/test/parser/ets/string-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/string_template_1-expected.txt b/ets2panda/test/parser/ets/string_template_1-expected.txt index 41c7f35d0665f6c824cb12ff522405f149bf8441..2de19277093303c00dcb56973b1813d27e131af7 100644 --- a/ets2panda/test/parser/ets/string_template_1-expected.txt +++ b/ets2panda/test/parser/ets/string_template_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string_template_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string_template_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string_template_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string_template_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/string_template_2-expected.txt b/ets2panda/test/parser/ets/string_template_2-expected.txt index 647221586bdabdd56bb14f2b316edb1430298973..2574c1b4a29501449d343a2fb1c25d56fe539610 100644 --- a/ets2panda/test/parser/ets/string_template_2-expected.txt +++ b/ets2panda/test/parser/ets/string_template_2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string_template_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string_template_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string_template_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string_template_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/string_template_3-expected.txt b/ets2panda/test/parser/ets/string_template_3-expected.txt index 5d02887d3bc510e19106535aeb35d34b0d64b136..b0c8377dd373ae5c54aaff09ab5973dd06bc106d 100644 --- a/ets2panda/test/parser/ets/string_template_3-expected.txt +++ b/ets2panda/test/parser/ets/string_template_3-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string_template_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string_template_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string_template_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string_template_3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/string_template_4-expected.txt b/ets2panda/test/parser/ets/string_template_4-expected.txt index dede298625dead44f019e8301975efa84117f663..17b8cf3405a63dba7fbabdc5afb74852e5bd54a5 100644 --- a/ets2panda/test/parser/ets/string_template_4-expected.txt +++ b/ets2panda/test/parser/ets/string_template_4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string_template_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string_template_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "string_template_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "string_template_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch-expected.txt b/ets2panda/test/parser/ets/switch-expected.txt index 507a6441f80ad4b8d60d21f7d22fc27aa0329c25..f3c60add8cb9b735b27e2e4ad9f44e30df09155a 100644 --- a/ets2panda/test/parser/ets/switch-expected.txt +++ b/ets2panda/test/parser/ets/switch-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch2-expected.txt b/ets2panda/test/parser/ets/switch2-expected.txt index b58d4bc7a107873dba182ae892380e2e1c76e177..f2edf576416bc4e62b134f724c5bc9be15f9af0c 100644 --- a/ets2panda/test/parser/ets/switch2-expected.txt +++ b/ets2panda/test/parser/ets/switch2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch_alive_1-expected.txt b/ets2panda/test/parser/ets/switch_alive_1-expected.txt index f3b50bed3f45abc4670df5f1f319676767308efc..b353cc3ed5c844735a4bd0634b7c88dbd9b6306c 100644 --- a/ets2panda/test/parser/ets/switch_alive_1-expected.txt +++ b/ets2panda/test/parser/ets/switch_alive_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_alive_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_alive_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_alive_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_alive_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch_alive_4-expected.txt b/ets2panda/test/parser/ets/switch_alive_4-expected.txt index 41471abb229bcdeb7931301eacb6e327ffe513ee..ffc2d56df5eef6718c45707cda1e2e7fd6574fc2 100644 --- a/ets2panda/test/parser/ets/switch_alive_4-expected.txt +++ b/ets2panda/test/parser/ets/switch_alive_4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_alive_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_alive_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_alive_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_alive_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt b/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt index 8d5e872d0ceefbc8f29449a0a63e79dea25a8175..dd1cbe89ced3aff5ead3f32dc22496faaef26278 100644 --- a/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt +++ b/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_char_compare_num.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_char_compare_num.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_char_compare_num.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_char_compare_num.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt b/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt index 6c09ac3917933944b06e4041368e0643b941266c..5d62c072a34dc0ab611cfb8c0b1b37a688f042e3 100644 --- a/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt +++ b/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt @@ -21,7 +21,117 @@ } } }, - "superClass": null, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "BaseEnum", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, "implements": [], "body": [ { @@ -280,11 +390,155 @@ "program": "switch_enum_string_case.ets" } } + }, + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "String", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } } ], "body": { "type": "BlockStatement", "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Super", + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } + }, { "type": "ExpressionStatement", "expression": { @@ -521,6 +775,22 @@ "program": "switch_enum_string_case.ets" } } + }, + { + "type": "StringLiteral", + "value": "A", + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } } ], "loc": { @@ -688,6 +958,22 @@ "program": "switch_enum_string_case.ets" } } + }, + { + "type": "StringLiteral", + "value": "B", + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } } ], "loc": { @@ -855,6 +1141,22 @@ "program": "switch_enum_string_case.ets" } } + }, + { + "type": "StringLiteral", + "value": "C", + "loc": { + "start": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + }, + "end": { + "line": 20, + "column": 1, + "program": "switch_enum_string_case.ets" + } + } } ], "loc": { @@ -4851,40 +5153,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_enum_string_case.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_enum_string_case.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_enum_string_case.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_enum_string_case.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch_num_compare_char-expected.txt b/ets2panda/test/parser/ets/switch_num_compare_char-expected.txt index 405f139eb6d0ee4cf4273ca986a58630d962751b..4ac04baf6c30607ac14146134c155196b5539003 100644 --- a/ets2panda/test/parser/ets/switch_num_compare_char-expected.txt +++ b/ets2panda/test/parser/ets/switch_num_compare_char-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_num_compare_char.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_num_compare_char.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_num_compare_char.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_num_compare_char.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch_readonly_member-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member-expected.txt index 6172839605b707ab72b276136560740464c484e9..c9dceaf4f62001a5bfe6590149dc3a383dc03bb7 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member-expected.txt @@ -445,40 +445,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_readonly_member.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_readonly_member.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt index 21a80a6b99c15a52a5e84578fd5a8b564892c53b..f8f43cea1ab1b0a8572f3f6ee2fda742216d235c 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt @@ -445,40 +445,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_readonly_member_compare_char.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_readonly_member_compare_char.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt index 697100275d969cd255ae5ac33374ca428ef3fbac..e6f846ba4c25ac5d341179f4f4d9a3b04637d402 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt @@ -445,40 +445,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/ternary-expected.txt b/ets2panda/test/parser/ets/ternary-expected.txt index eb955d193730b2e2ab45f9d3e6c2ed65a0c64589..9e8ae9dcaa4457df4f2008ace9588a4a10f119f6 100644 --- a/ets2panda/test/parser/ets/ternary-expected.txt +++ b/ets2panda/test/parser/ets/ternary-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ternary.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ternary.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "ternary.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "ternary.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test-type-alias-call1-expected.txt b/ets2panda/test/parser/ets/test-type-alias-call1-expected.txt index d09009bddf07ca4aec5150b75d30b66bf857b399..8ac00a419bb9e7fd3646ac9ac07254ad0533f3d8 100644 --- a/ets2panda/test/parser/ets/test-type-alias-call1-expected.txt +++ b/ets2panda/test/parser/ets/test-type-alias-call1-expected.txt @@ -712,40 +712,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test-type-alias-call2-expected.txt b/ets2panda/test/parser/ets/test-type-alias-call2-expected.txt index cd4111877406143cdd23c1d8ddb82522173569df..b5a969e76763b5f30a42549d386be92f1c1ce8bb 100644 --- a/ets2panda/test/parser/ets/test-type-alias-call2-expected.txt +++ b/ets2panda/test/parser/ets/test-type-alias-call2-expected.txt @@ -870,40 +870,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test-type-alias-call3-expected.txt b/ets2panda/test/parser/ets/test-type-alias-call3-expected.txt index 2fa1a8d7694decd017ed4590f19ab3d4df525bf1..89111efb1c236aa0c3d12ccf56b39a72f3051196 100644 --- a/ets2panda/test/parser/ets/test-type-alias-call3-expected.txt +++ b/ets2panda/test/parser/ets/test-type-alias-call3-expected.txt @@ -714,40 +714,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call3.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test-type-alias-call4-expected.txt b/ets2panda/test/parser/ets/test-type-alias-call4-expected.txt index 91feabdc8b2856feefe448a9613c150f11b8b067..392a44864a25fb26d7bb1de06f3d0f2350f9cbb0 100644 --- a/ets2panda/test/parser/ets/test-type-alias-call4-expected.txt +++ b/ets2panda/test/parser/ets/test-type-alias-call4-expected.txt @@ -714,40 +714,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test-type-alias-call5-expected.txt b/ets2panda/test/parser/ets/test-type-alias-call5-expected.txt index dbc7530f3967fec7f2a42ba16a29740e85d028c5..39628d2def388baafeb4d89cc0178e2d2a84f93a 100644 --- a/ets2panda/test/parser/ets/test-type-alias-call5-expected.txt +++ b/ets2panda/test/parser/ets/test-type-alias-call5-expected.txt @@ -934,40 +934,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call5.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test-type-alias-call6-expected.txt b/ets2panda/test/parser/ets/test-type-alias-call6-expected.txt index 65888eb960ea2fee69bc268b50d3170402937d47..9da14f69eb48551d1ffe6d15903ea101ca2d2904 100644 --- a/ets2panda/test/parser/ets/test-type-alias-call6-expected.txt +++ b/ets2panda/test/parser/ets/test-type-alias-call6-expected.txt @@ -1013,40 +1013,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test-type-alias-call7-expected.txt b/ets2panda/test/parser/ets/test-type-alias-call7-expected.txt index aebfb3cf189ce9933e3d5781aabab03527f18d98..cbd58d6eb9707c995eea359295ac74ea0f3fa21f 100644 --- a/ets2panda/test/parser/ets/test-type-alias-call7-expected.txt +++ b/ets2panda/test/parser/ets/test-type-alias-call7-expected.txt @@ -134,40 +134,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test-type-alias-call8-expected.txt b/ets2panda/test/parser/ets/test-type-alias-call8-expected.txt index f6fd83b46d47b05d669b3e968f9216239035ddfd..e8be79828e93aa1a75463bfb15feb2b2a588da54 100644 --- a/ets2panda/test/parser/ets/test-type-alias-call8-expected.txt +++ b/ets2panda/test/parser/ets/test-type-alias-call8-expected.txt @@ -683,40 +683,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test-type-alias-call8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test-type-alias-call8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test_interface-expected.txt b/ets2panda/test/parser/ets/test_interface-expected.txt index 1c6ea9dc12329735ccca1c89329fc8d5b273541c..2661e891fd69f197dac43538d730edfe621ab39c 100644 --- a/ets2panda/test/parser/ets/test_interface-expected.txt +++ b/ets2panda/test/parser/ets/test_interface-expected.txt @@ -913,7 +913,7 @@ "loc": { "start": { "line": 24, - "column": 5, + "column": 13, "program": "test_interface.ets" }, "end": { @@ -1005,40 +1005,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_interface.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_interface.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_interface.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test_jsvalue-expected.txt b/ets2panda/test/parser/ets/test_jsvalue-expected.txt index af1bad5f4c8fa82b884d8fe9195a08501e4141e4..55691eb57118a9d3f3b8f0356a08528b2b147e7d 100644 --- a/ets2panda/test/parser/ets/test_jsvalue-expected.txt +++ b/ets2panda/test/parser/ets/test_jsvalue-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test_jsvalue_get_double-expected.txt b/ets2panda/test/parser/ets/test_jsvalue_get_double-expected.txt index 91bd20479019bd106de0ea662083a648629386bc..2bec7be6dc36f5c8c50a4a5bc4597d7c86ce3930 100644 --- a/ets2panda/test/parser/ets/test_jsvalue_get_double-expected.txt +++ b/ets2panda/test/parser/ets/test_jsvalue_get_double-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_double.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_double.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_double.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_double.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -519,4 +485,4 @@ } } } -Warning: Variable 'v' is used before being assigned. [test_jsvalue_get_double.ets:17:21] +TypeError: Variable 'v' is used before being assigned. [test_jsvalue_get_double.ets:17:21] diff --git a/ets2panda/test/parser/ets/test_jsvalue_get_property_1-expected.txt b/ets2panda/test/parser/ets/test_jsvalue_get_property_1-expected.txt index 78277ec6e49dbaaffc7107899e053114875c6eec..e504509871128b4b75a4d62708025cf000b32cd3 100644 --- a/ets2panda/test/parser/ets/test_jsvalue_get_property_1-expected.txt +++ b/ets2panda/test/parser/ets/test_jsvalue_get_property_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_property_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_property_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_property_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_property_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -585,4 +551,4 @@ } } } -Warning: Variable 'v' is used before being assigned. [test_jsvalue_get_property_1.ets:17:21] +TypeError: Variable 'v' is used before being assigned. [test_jsvalue_get_property_1.ets:17:21] diff --git a/ets2panda/test/parser/ets/test_jsvalue_get_property_2-expected.txt b/ets2panda/test/parser/ets/test_jsvalue_get_property_2-expected.txt index 246427ada5ef6ac2df3bb5ea2f5d511eb9d7b922..119b19fc3c2c25fcc4daced9319d5a7ed61fab24 100644 --- a/ets2panda/test/parser/ets/test_jsvalue_get_property_2-expected.txt +++ b/ets2panda/test/parser/ets/test_jsvalue_get_property_2-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_property_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_property_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_property_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue_get_property_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -619,4 +585,4 @@ } } } -Warning: Variable 'v' is used before being assigned. [test_jsvalue_get_property_2.ets:17:21] +TypeError: Variable 'v' is used before being assigned. [test_jsvalue_get_property_2.ets:17:21] diff --git a/ets2panda/test/parser/ets/test_jsvalue_set_double-expected.txt b/ets2panda/test/parser/ets/test_jsvalue_set_double-expected.txt index cb7cd687c5b67eda20e0d033b0829346865f0d88..004962b3a5fb1e40b8083229e772816fc2aae73f 100644 --- a/ets2panda/test/parser/ets/test_jsvalue_set_double-expected.txt +++ b/ets2panda/test/parser/ets/test_jsvalue_set_double-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue_set_double.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue_set_double.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_jsvalue_set_double.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_jsvalue_set_double.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test_type_alias5-expected.txt b/ets2panda/test/parser/ets/test_type_alias5-expected.txt index f3baaa92af9515c078e3febd1d93fcb64496d56f..a68c4a110b8a3d90fc052a01a45d3e3fcdff1961 100644 --- a/ets2panda/test/parser/ets/test_type_alias5-expected.txt +++ b/ets2panda/test/parser/ets/test_type_alias5-expected.txt @@ -70,40 +70,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias5.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias5.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias5.ets" - } - } - } - ], "body": [], "loc": { "start": { diff --git a/ets2panda/test/parser/ets/test_type_alias6-expected.txt b/ets2panda/test/parser/ets/test_type_alias6-expected.txt index 400503aef812cf8a226a796c85c7de15f0a386c5..3107be32be5857d1747434ca6f1f84ee8aef5a66 100644 --- a/ets2panda/test/parser/ets/test_type_alias6-expected.txt +++ b/ets2panda/test/parser/ets/test_type_alias6-expected.txt @@ -70,40 +70,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias6.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test_type_alias7-expected.txt b/ets2panda/test/parser/ets/test_type_alias7-expected.txt index 5c91161ea40aea98a2387d6929cef35b0903043a..c573847b4cd3046b1185966d04cd0fb7346c9998 100644 --- a/ets2panda/test/parser/ets/test_type_alias7-expected.txt +++ b/ets2panda/test/parser/ets/test_type_alias7-expected.txt @@ -70,40 +70,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias7.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias7.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias7.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test_type_alias8-expected.txt b/ets2panda/test/parser/ets/test_type_alias8-expected.txt index 5a0d1d827580057b46d64878ed25f1491197fd8f..9419cab8768d0e38740a5f5c6293f434a2663067 100644 --- a/ets2panda/test/parser/ets/test_type_alias8-expected.txt +++ b/ets2panda/test/parser/ets/test_type_alias8-expected.txt @@ -102,40 +102,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias8.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias8.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias8.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/test_type_alias9-expected.txt b/ets2panda/test/parser/ets/test_type_alias9-expected.txt index 27ab7903834e2dd5f594eca1b2a295703cd10487..03175a1639c415f123156c469d25fbfaa202bce6 100644 --- a/ets2panda/test/parser/ets/test_type_alias9-expected.txt +++ b/ets2panda/test/parser/ets/test_type_alias9-expected.txt @@ -68,39 +68,135 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "test_type_alias9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "test_type_alias9.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "test_type_alias9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "test_type_alias9.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "test_type_alias9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "test_type_alias9.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "test_type_alias9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "test_type_alias9.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "test_type_alias9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "test_type_alias9.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "test_type_alias9.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "test_type_alias9.ets" + } + } + } + ], "loc": { "start": { - "line": 17, - "column": 15, + "line": 1, + "column": 3, "program": "test_type_alias9.ets" }, "end": { - "line": 17, - "column": 21, + "line": 1, + "column": 3, "program": "test_type_alias9.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 17, - "column": 21, + "line": 1, + "column": 1, "program": "test_type_alias9.ets" }, "end": { - "line": 17, - "column": 23, + "line": 1, + "column": 3, "program": "test_type_alias9.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -149,40 +245,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias9.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "test_type_alias9.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "test_type_alias9.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/this_callee-expected.txt b/ets2panda/test/parser/ets/this_callee-expected.txt index 6bbb8f604b4daaeb30039c681497fed0810954d9..c457dda06cf97748b1d4081b230fcedf5e49f9b5 100644 --- a/ets2panda/test/parser/ets/this_callee-expected.txt +++ b/ets2panda/test/parser/ets/this_callee-expected.txt @@ -1275,40 +1275,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_callee.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_callee.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_callee.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_callee.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/this_cmp_object-expected.txt b/ets2panda/test/parser/ets/this_cmp_object-expected.txt index 677245e0a3189ffa80fca5bc800833b4a1b14509..68323c16cd6aaaac7d16fa50f6dcf46ea794078f 100644 --- a/ets2panda/test/parser/ets/this_cmp_object-expected.txt +++ b/ets2panda/test/parser/ets/this_cmp_object-expected.txt @@ -585,40 +585,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_cmp_object.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_cmp_object.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_cmp_object.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_cmp_object.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/this_equality-expected.txt b/ets2panda/test/parser/ets/this_equality-expected.txt index cfd450b08b38996cfdef966aaaf3e5e67207c834..282156505cf13c88447466c0fa809c3f51df5788 100644 --- a/ets2panda/test/parser/ets/this_equality-expected.txt +++ b/ets2panda/test/parser/ets/this_equality-expected.txt @@ -441,40 +441,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_equality.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_equality.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_equality.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_equality.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/this_expression-expected.txt b/ets2panda/test/parser/ets/this_expression-expected.txt index 67b05e149abac05cc8b2207ca0a33cda24109d7f..2dad6ed7aa61f59e0dd5143c91b2ff1759dfe102 100644 --- a/ets2panda/test/parser/ets/this_expression-expected.txt +++ b/ets2panda/test/parser/ets/this_expression-expected.txt @@ -398,40 +398,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_expression.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_expression.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_expression.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/this_type_class_method_return_valid-expected.txt b/ets2panda/test/parser/ets/this_type_class_method_return_valid-expected.txt index 2dd20b490af128a610a686be143be81111681e4f..09196a980094ceb90fbf87177354baba03ca8ace 100644 --- a/ets2panda/test/parser/ets/this_type_class_method_return_valid-expected.txt +++ b/ets2panda/test/parser/ets/this_type_class_method_return_valid-expected.txt @@ -378,40 +378,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_type_class_method_return_valid.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_type_class_method_return_valid.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "this_type_class_method_return_valid.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "this_type_class_method_return_valid.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/throwsRethrowsAsVariables-expected.txt b/ets2panda/test/parser/ets/throwsRethrowsAsVariables-expected.txt index e560472a606c636fc9801d166ceca8ce440fba2f..3e02fd2143b2ad178d1dfefce275728aafe998bd 100644 --- a/ets2panda/test/parser/ets/throwsRethrowsAsVariables-expected.txt +++ b/ets2panda/test/parser/ets/throwsRethrowsAsVariables-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwsRethrowsAsVariables.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwsRethrowsAsVariables.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "throwsRethrowsAsVariables.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "throwsRethrowsAsVariables.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body-expected.txt b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body-expected.txt index 829a91cca48392d4adbe22a3f7ffe489295b08d9..d48d221b31e9bef4c763af1c56117e6bb6a2440f 100644 --- a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body-expected.txt +++ b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_define_lambda_in_body.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_define_lambda_in_body.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_define_lambda_in_body.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_define_lambda_in_body.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body_capture_variable-expected.txt b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body_capture_variable-expected.txt index f3db4b2b9f761554fe1a3ae88336ac925d48b1d3..b39d9d47b3f4e6eeea3d1f4ec190939f932d228a 100644 --- a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body_capture_variable-expected.txt +++ b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body_capture_variable-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_define_lambda_in_body_capture_variable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_define_lambda_in_body_capture_variable.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_define_lambda_in_body_capture_variable.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_define_lambda_in_body_capture_variable.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_overload-expected.txt b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_overload-expected.txt index 6946a0644af14de819daaf2efe1d971c8c6b7c6a..c4d7a62427a7436e505179719912aaec5be07f9e 100644 --- a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_overload-expected.txt +++ b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_overload-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_overload.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_overload.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_overload.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_overload.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_overload_1-expected.txt b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_overload_1-expected.txt index 77b61783f7b61de4d6239470b97eabceada03c70..16492ab381ca47e2575cbc08aa356a8690a7897a 100644 --- a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_overload_1-expected.txt +++ b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_overload_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_overload_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_overload_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_overload_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_overload_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_transform_trailing_block-expected.txt b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_transform_trailing_block-expected.txt index 1d7dd000afb819438f06f9186b91355225c6b198..66508e10cafa3227679368268fbe75890ebdb10a 100644 --- a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_transform_trailing_block-expected.txt +++ b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_transform_trailing_block-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_transform_trailing_block.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_transform_trailing_block.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_transform_trailing_block.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_transform_trailing_block.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_type_alias-expected.txt b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_type_alias-expected.txt index 43bc93bd91f853a3ce149c256676dfaa1db85c18..06a0e752e64b6724989c9055327702662ec0ca6c 100644 --- a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_type_alias-expected.txt +++ b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_type_alias-expected.txt @@ -86,40 +86,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_type_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_type_alias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_type_alias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_type_alias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_with_throw-expected.txt b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_with_throw-expected.txt index d003416a3f306f89c91ca727b498245784d2c033..edeeb7a5946c23d7a08b718ab57245f78afc2d01 100644 --- a/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_with_throw-expected.txt +++ b/ets2panda/test/parser/ets/trailing_lambda_tests/trailing_lambda_with_throw-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_with_throw.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_with_throw.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "trailing_lambda_with_throw.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "trailing_lambda_with_throw.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/tryFinallyBlockOnly-expected.txt b/ets2panda/test/parser/ets/tryFinallyBlockOnly-expected.txt index 0f1a0ee84dcc5fc9ee3882783c18b3b207fea833..efc705927983098b4a58c43559247d535522ddd0 100644 --- a/ets2panda/test/parser/ets/tryFinallyBlockOnly-expected.txt +++ b/ets2panda/test/parser/ets/tryFinallyBlockOnly-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tryFinallyBlockOnly.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tryFinallyBlockOnly.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tryFinallyBlockOnly.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tryFinallyBlockOnly.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/tupleAsTypeParam1-expected.txt b/ets2panda/test/parser/ets/tupleAsTypeParam1-expected.txt index 53cbb7400e74ff89306b1fc18cec7890cdd659c5..7498cb54ad4763b3bca19ff136c0b5e8a4c8a371 100644 --- a/ets2panda/test/parser/ets/tupleAsTypeParam1-expected.txt +++ b/ets2panda/test/parser/ets/tupleAsTypeParam1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tupleAsTypeParam1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tupleAsTypeParam1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tupleAsTypeParam1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tupleAsTypeParam1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -219,55 +185,103 @@ "type": "Identifier", "name": "val", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 22, - "program": "tupleAsTypeParam1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tupleAsTypeParam1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam1.ets" + } + } }, - "end": { - "line": 16, - "column": 23, - "program": "tupleAsTypeParam1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam1.ets" + } } } - }, + ], "loc": { "start": { - "line": 16, - "column": 22, + "line": 1, + "column": 3, "program": "tupleAsTypeParam1.ets" }, "end": { - "line": 16, - "column": 24, + "line": 1, + "column": 3, "program": "tupleAsTypeParam1.ets" } } }, "loc": { "start": { - "line": 16, - "column": 22, + "line": 1, + "column": 1, "program": "tupleAsTypeParam1.ets" }, "end": { - "line": 16, - "column": 24, + "line": 1, + "column": 3, "program": "tupleAsTypeParam1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, diff --git a/ets2panda/test/parser/ets/tupleAsTypeParam2-expected.txt b/ets2panda/test/parser/ets/tupleAsTypeParam2-expected.txt index 76b23fc5978ba1e690c429a658aa2c0b7bb25ce6..3df264a32d88569df4e9a159daff48d56a93380d 100644 --- a/ets2panda/test/parser/ets/tupleAsTypeParam2-expected.txt +++ b/ets2panda/test/parser/ets/tupleAsTypeParam2-expected.txt @@ -99,55 +99,103 @@ "optional": false, "computed": false, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 15, - "program": "tupleAsTypeParam2.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tupleAsTypeParam2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + } + } }, - "end": { - "line": 17, - "column": 16, - "program": "tupleAsTypeParam2.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + } } } - }, + ], "loc": { "start": { - "line": 17, - "column": 15, + "line": 1, + "column": 3, "program": "tupleAsTypeParam2.ets" }, "end": { - "line": 17, - "column": 17, + "line": 1, + "column": 3, "program": "tupleAsTypeParam2.ets" } } }, "loc": { "start": { - "line": 17, - "column": 15, + "line": 1, + "column": 1, "program": "tupleAsTypeParam2.ets" }, "end": { - "line": 17, - "column": 17, + "line": 1, + "column": 3, "program": "tupleAsTypeParam2.ets" } } }, - "annotations": [], "loc": { "start": { "line": 17, @@ -231,55 +279,103 @@ "type": "Identifier", "name": "x", "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "T", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 27, - "program": "tupleAsTypeParam2.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "tupleAsTypeParam2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + } + } }, - "end": { - "line": 18, - "column": 28, - "program": "tupleAsTypeParam2.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "tupleAsTypeParam2.ets" + } } } - }, + ], "loc": { "start": { - "line": 18, - "column": 27, + "line": 1, + "column": 3, "program": "tupleAsTypeParam2.ets" }, "end": { - "line": 18, - "column": 29, + "line": 1, + "column": 3, "program": "tupleAsTypeParam2.ets" } } }, "loc": { "start": { - "line": 18, - "column": 27, + "line": 1, + "column": 1, "program": "tupleAsTypeParam2.ets" }, "end": { - "line": 18, - "column": 29, + "line": 1, + "column": 3, "program": "tupleAsTypeParam2.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, @@ -525,40 +621,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tupleAsTypeParam2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tupleAsTypeParam2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tupleAsTypeParam2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tupleAsTypeParam2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt index 96f58b0175527774b0d6fcdcb1420fc71a318873..f72997ce91c0e8c163c7518cf60103b9bdcbefd3 100644 --- a/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt +++ b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tupleIndexWithNumbers.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tupleIndexWithNumbers.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tupleIndexWithNumbers.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tupleIndexWithNumbers.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/tuple_type_1-expected.txt b/ets2panda/test/parser/ets/tuple_type_1-expected.txt index 080fbd068cde34da6ec4db141bbf3496ebbe6f7c..753dcbb9638a645c8e2c33fa0ba4000d66d5b3c7 100644 --- a/ets2panda/test/parser/ets/tuple_type_1-expected.txt +++ b/ets2panda/test/parser/ets/tuple_type_1-expected.txt @@ -262,40 +262,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_type_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_type_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "tuple_type_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "tuple_type_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/type_alias_1-expected.txt b/ets2panda/test/parser/ets/type_alias_1-expected.txt index 2e88908dfb39d742dc5ca8f6df0762910b7b5a96..15681894ec81c6f25fe1d967b3ea3498b285fd80 100644 --- a/ets2panda/test/parser/ets/type_alias_1-expected.txt +++ b/ets2panda/test/parser/ets/type_alias_1-expected.txt @@ -21,39 +21,135 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], "loc": { "start": { - "line": 16, - "column": 15, + "line": 1, + "column": 1, "program": "type_alias_1.ets" }, "end": { - "line": 16, - "column": 18, + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "type_alias_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "type_alias_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_alias_1.ets" + }, + "end": { + "line": 1, + "column": 3, "program": "type_alias_1.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 16, - "column": 18, + "line": 1, + "column": 1, "program": "type_alias_1.ets" }, "end": { - "line": 16, - "column": 20, + "line": 1, + "column": 3, "program": "type_alias_1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 16, @@ -102,40 +198,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type_alias_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type_alias_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type_alias_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/type_alias_2-expected.txt b/ets2panda/test/parser/ets/type_alias_2-expected.txt index 62e22a68e2bafaa012381924ec02b86392569e77..15825e7d9186497275cbe1f49cf51f031ce00edc 100644 --- a/ets2panda/test/parser/ets/type_alias_2-expected.txt +++ b/ets2panda/test/parser/ets/type_alias_2-expected.txt @@ -111,39 +111,135 @@ } }, "typeAnnotation": { - "type": "TSArrayType", - "elementType": { - "type": "TSArrayType", - "elementType": { - "type": "ETSPrimitiveType", + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], "loc": { "start": { - "line": 18, - "column": 19, + "line": 1, + "column": 1, "program": "type_alias_2.ets" }, "end": { - "line": 18, - "column": 22, + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "type_alias_2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "type_alias_2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_alias_2.ets" + }, + "end": { + "line": 1, + "column": 3, "program": "type_alias_2.ets" } } }, - "annotations": [], "loc": { "start": { - "line": 18, - "column": 22, + "line": 1, + "column": 1, "program": "type_alias_2.ets" }, "end": { - "line": 18, - "column": 24, + "line": 1, + "column": 3, "program": "type_alias_2.ets" } } }, - "annotations": [], "loc": { "start": { "line": 18, @@ -379,40 +475,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type_alias_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type_alias_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type_alias_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type_alias_2.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/type_cast-expected.txt b/ets2panda/test/parser/ets/type_cast-expected.txt index 9900fe58cd86e0bb962ecfa3920cf39e6677e292..a721015acb0d7af7dd9a3379daf782dd3d032b50 100644 --- a/ets2panda/test/parser/ets/type_cast-expected.txt +++ b/ets2panda/test/parser/ets/type_cast-expected.txt @@ -793,40 +793,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type_cast.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type_cast.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type_cast.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type_cast.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/type_variance1-expected.txt b/ets2panda/test/parser/ets/type_variance1-expected.txt index 6de37ebd6c21256cecaaf07c120b9a82869e6238..d129a48009641db72e39ed3c032ed04e4fec9acc 100644 --- a/ets2panda/test/parser/ets/type_variance1-expected.txt +++ b/ets2panda/test/parser/ets/type_variance1-expected.txt @@ -2005,40 +2005,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type_variance1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type_variance1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "type_variance1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "type_variance1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", @@ -2298,55 +2264,103 @@ "type": "TSTypeParameterInstantiation", "params": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 37, - "program": "type_variance1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } }, - "end": { - "line": 20, - "column": 43, - "program": "type_variance1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } } } - }, + ], "loc": { "start": { - "line": 20, - "column": 37, + "line": 1, + "column": 3, "program": "type_variance1.ets" }, "end": { - "line": 20, - "column": 44, + "line": 1, + "column": 3, "program": "type_variance1.ets" } } }, "loc": { "start": { - "line": 20, - "column": 37, + "line": 1, + "column": 1, "program": "type_variance1.ets" }, "end": { - "line": 20, - "column": 44, + "line": 1, + "column": 3, "program": "type_variance1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, @@ -2445,55 +2459,103 @@ "type": "TSTypeParameterInstantiation", "params": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 19, - "program": "type_variance1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } }, - "end": { - "line": 20, - "column": 25, - "program": "type_variance1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } } } - }, + ], "loc": { "start": { - "line": 20, - "column": 19, + "line": 1, + "column": 3, "program": "type_variance1.ets" }, "end": { - "line": 20, - "column": 26, + "line": 1, + "column": 3, "program": "type_variance1.ets" } } }, "loc": { "start": { - "line": 20, - "column": 19, + "line": 1, + "column": 1, "program": "type_variance1.ets" }, "end": { - "line": 20, - "column": 26, + "line": 1, + "column": 3, "program": "type_variance1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 20, @@ -2950,55 +3012,103 @@ "type": "TSTypeParameterInstantiation", "params": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 18, - "program": "type_variance1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } }, - "end": { - "line": 40, - "column": 24, - "program": "type_variance1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } } } - }, + ], "loc": { "start": { - "line": 40, - "column": 18, + "line": 1, + "column": 3, "program": "type_variance1.ets" }, "end": { - "line": 40, - "column": 25, + "line": 1, + "column": 3, "program": "type_variance1.ets" } } }, "loc": { "start": { - "line": 40, - "column": 18, + "line": 1, + "column": 1, "program": "type_variance1.ets" }, "end": { - "line": 40, - "column": 25, + "line": 1, + "column": 3, "program": "type_variance1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 40, @@ -3093,55 +3203,103 @@ "type": "TSTypeParameterInstantiation", "params": [ { - "type": "TSArrayType", - "elementType": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Object", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 37, - "program": "type_variance1.ets" + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Array", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Object", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } + } }, - "end": { - "line": 40, - "column": 43, - "program": "type_variance1.ets" + "loc": { + "start": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + }, + "end": { + "line": 1, + "column": 3, + "program": "type_variance1.ets" + } } } - }, + ], "loc": { "start": { - "line": 40, - "column": 37, + "line": 1, + "column": 3, "program": "type_variance1.ets" }, "end": { - "line": 40, - "column": 44, + "line": 1, + "column": 3, "program": "type_variance1.ets" } } }, "loc": { "start": { - "line": 40, - "column": 37, + "line": 1, + "column": 1, "program": "type_variance1.ets" }, "end": { - "line": 40, - "column": 44, + "line": 1, + "column": 3, "program": "type_variance1.ets" } } }, - "annotations": [], "loc": { "start": { "line": 40, diff --git a/ets2panda/test/parser/ets/unary_op-expected.txt b/ets2panda/test/parser/ets/unary_op-expected.txt index f02b6cdbc8e44786e9674c92cb0c4418e5fa22dd..10516d0b64527f41a9159f8e30e62c2ac679e95b 100644 --- a/ets2panda/test/parser/ets/unary_op-expected.txt +++ b/ets2panda/test/parser/ets/unary_op-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "unary_op.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "unary_op.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "unary_op.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "unary_op.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/unary_operations-expected.txt b/ets2panda/test/parser/ets/unary_operations-expected.txt index 70609e3d2e156df3b252b92392f69b647dc66626..a9ba27db68f18ea3aa93af58990db2c14978b4c3 100644 --- a/ets2panda/test/parser/ets/unary_operations-expected.txt +++ b/ets2panda/test/parser/ets/unary_operations-expected.txt @@ -1288,40 +1288,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "unary_operations.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "unary_operations.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "unary_operations.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "unary_operations.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/undefinedNullObjectTypeAnnotation-expected.txt b/ets2panda/test/parser/ets/undefinedNullObjectTypeAnnotation-expected.txt index 4cb5338db79bb39a0f1a44e281e4da8461350cdc..78996b58f8aa80db672beb860628b4077962c94e 100644 --- a/ets2panda/test/parser/ets/undefinedNullObjectTypeAnnotation-expected.txt +++ b/ets2panda/test/parser/ets/undefinedNullObjectTypeAnnotation-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "undefinedNullObjectTypeAnnotation.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "undefinedNullObjectTypeAnnotation.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "undefinedNullObjectTypeAnnotation.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "undefinedNullObjectTypeAnnotation.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/undefinedNullTypeAlias-expected.txt b/ets2panda/test/parser/ets/undefinedNullTypeAlias-expected.txt index 8eb33934b1a0d6f69e2f501e380c31e82e61a1b8..4b3e2ea06889ca3961e7e4bca4f002a743870f71 100644 --- a/ets2panda/test/parser/ets/undefinedNullTypeAlias-expected.txt +++ b/ets2panda/test/parser/ets/undefinedNullTypeAlias-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "undefinedNullTypeAlias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "undefinedNullTypeAlias.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "undefinedNullTypeAlias.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "undefinedNullTypeAlias.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/union_generic_field_access-expected.txt b/ets2panda/test/parser/ets/union_generic_field_access-expected.txt deleted file mode 100644 index b823903a78871d8200a0f9e9a9a70824f51d59f6..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/union_generic_field_access-expected.txt +++ /dev/null @@ -1,1270 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "TSTypeAliasDeclaration", - "id": { - "type": "Identifier", - "name": "TypedArray", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 6, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 16, - "column": 16, - "program": "union_generic_field_access.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int8Array", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 17, - "column": 14, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 18, - "column": 6, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 18, - "column": 6, - "program": "union_generic_field_access.ets" - } - } - }, - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int16Array", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 18, - "column": 17, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 19, - "column": 6, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 19, - "column": 6, - "program": "union_generic_field_access.ets" - } - } - }, - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Int32Array", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 19, - "column": 17, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 20, - "column": 6, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 20, - "column": 6, - "program": "union_generic_field_access.ets" - } - } - }, - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Float32Array", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 20, - "column": 19, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 21, - "column": 6, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 21, - "column": 6, - "program": "union_generic_field_access.ets" - } - } - }, - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "Float64Array", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 21, - "column": 19, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 21, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 9, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 21, - "column": 7, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 9, - "program": "union_generic_field_access.ets" - } - } - } - ], - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 9, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 9, - "program": "union_generic_field_access.ets" - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - } - } - }, - "superClass": null, - "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - } - } - } - ], - "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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "withArray", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 10, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 19, - "program": "union_generic_field_access.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "withArray", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 10, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 19, - "program": "union_generic_field_access.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [ - { - "type": "ETSParameterExpression", - "name": { - "type": "Identifier", - "name": "data", - "typeAnnotation": { - "type": "ETSUnionType", - "types": [ - { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "C", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 48, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 49, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 48, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 51, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 48, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 51, - "program": "union_generic_field_access.ets" - } - } - }, - { - "type": "ETSUndefinedType", - "loc": { - "start": { - "line": 24, - "column": 52, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 61, - "program": "union_generic_field_access.ets" - } - } - } - ], - "loc": { - "start": { - "line": 24, - "column": 48, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 61, - "program": "union_generic_field_access.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 42, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 61, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 42, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 61, - "program": "union_generic_field_access.ets" - } - } - } - ], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 24, - "column": 64, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 71, - "program": "union_generic_field_access.ets" - } - } - }, - "typeParameters": { - "type": "TSTypeParameterDeclaration", - "params": [ - { - "type": "TSTypeParameter", - "name": { - "type": "Identifier", - "name": "C", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 20, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 21, - "program": "union_generic_field_access.ets" - } - } - }, - "constraint": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "TypedArray", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 30, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 40, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 30, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 41, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 30, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 41, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 20, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 41, - "program": "union_generic_field_access.ets" - } - } - } - ], - "loc": { - "start": { - "line": 24, - "column": 19, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 24, - "column": 41, - "program": "union_generic_field_access.ets" - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "len", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 9, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 12, - "program": "union_generic_field_access.ets" - } - } - }, - "init": { - "type": "LogicalExpression", - "operator": "??", - "left": { - "type": "BlockExpression", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - } - } - }, - "init": { - "type": "Identifier", - "name": "data", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 15, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 19, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 25, - "column": 15, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 32, - "program": "union_generic_field_access.ets" - } - } - }, - { - "type": "ExpressionStatement", - "expression": { - "type": "ConditionalExpression", - "test": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - } - } - }, - "right": { - "type": "NullLiteral", - "value": null, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - } - } - }, - "consequent": { - "type": "UndefinedLiteral", - "value": "undefined", - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - } - } - }, - "alternate": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "gensym%%_16", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 15, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 27, - "program": "union_generic_field_access.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "length", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 21, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 27, - "program": "union_generic_field_access.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 25, - "column": 15, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 27, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 3, - "program": "union_generic_field_access.ets" - } - } - } - ], - "loc": { - "start": { - "line": 25, - "column": 15, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 32, - "program": "union_generic_field_access.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 25, - "column": 31, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 32, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 25, - "column": 15, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 32, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 25, - "column": 9, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 32, - "program": "union_generic_field_access.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 25, - "column": 5, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 25, - "column": 33, - "program": "union_generic_field_access.ets" - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 26, - "column": 12, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 26, - "column": 16, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 5, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 26, - "column": 17, - "program": "union_generic_field_access.ets" - } - } - } - ], - "loc": { - "start": { - "line": 24, - "column": 72, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 27, - "column": 2, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 10, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 27, - "column": 2, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 10, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 27, - "column": 2, - "program": "union_generic_field_access.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 27, - "column": 2, - "program": "union_generic_field_access.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_generic_field_access.ets" - }, - "end": { - "line": 27, - "column": 2, - "program": "union_generic_field_access.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/union_lowering_common_property-expected.txt b/ets2panda/test/parser/ets/union_lowering_common_property-expected.txt index cc5e27a018faa3440e32338b2539e574b6b778b1..e8fc70c1a2bfea41a7a66b3eb974658afb1cdf1e 100644 --- a/ets2panda/test/parser/ets/union_lowering_common_property-expected.txt +++ b/ets2panda/test/parser/ets/union_lowering_common_property-expected.txt @@ -682,40 +682,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_lowering_common_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_lowering_common_property.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "union_lowering_common_property.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "union_lowering_common_property.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/user_defined_1-expected.txt b/ets2panda/test/parser/ets/user_defined_1-expected.txt deleted file mode 100644 index caf22ff02c97fa4cca25cccc6abd63920fbd14bd..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/user_defined_1-expected.txt +++ /dev/null @@ -1,800 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - }, - "superClass": null, - "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - } - ], - "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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_1.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_1.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": "user_defined_1.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_1.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "float", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 17, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 24, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 14, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 17, - "column": 27, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 32, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 32, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 17, - "column": 33, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "double", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 18, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 25, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 15, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 18, - "column": 28, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 33, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 33, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 18, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 18, - "column": 34, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "byte", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 16, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 23, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 13, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 19, - "column": 26, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 31, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 31, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 19, - "column": 32, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "short", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 17, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 24, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 14, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 20, - "column": 27, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 32, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 32, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 20, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 20, - "column": 33, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "int", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 15, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 22, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 12, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 21, - "column": 25, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 30, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 30, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 21, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 21, - "column": 31, - "program": "user_defined_1.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "char", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 22, - "column": 16, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 23, - "program": "user_defined_1.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 13, - "program": "user_defined_1.ets" - } - } - }, - "init": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 22, - "column": 26, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 31, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 31, - "program": "user_defined_1.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 22, - "column": 5, - "program": "user_defined_1.ets" - }, - "end": { - "line": 22, - "column": 32, - "program": "user_defined_1.ets" - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 17, - "program": "user_defined_1.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_1.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_1.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "user_defined_1.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 24, - "column": 2, - "program": "user_defined_1.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_1.ets" - }, - "end": { - "line": 25, - "column": 1, - "program": "user_defined_1.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/user_defined_2-expected.txt b/ets2panda/test/parser/ets/user_defined_2-expected.txt deleted file mode 100644 index b3d63c5a1d8a869f6582e405cd88d624a67b7e8a..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/user_defined_2-expected.txt +++ /dev/null @@ -1,842 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - }, - "superClass": null, - "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - } - ], - "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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_2.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_2.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": "user_defined_2.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_2.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "float", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 17, - "program": "user_defined_2.ets" - }, - "end": { - "line": 17, - "column": 22, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 17, - "column": 14, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 17, - "column": 14, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 17, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 17, - "column": 23, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "boolean", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 19, - "program": "user_defined_2.ets" - }, - "end": { - "line": 18, - "column": 26, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 18, - "column": 16, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 18, - "column": 16, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 18, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 18, - "column": 27, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "double", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 18, - "program": "user_defined_2.ets" - }, - "end": { - "line": 19, - "column": 24, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 19, - "column": 15, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 19, - "column": 15, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 19, - "column": 25, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "byte", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 16, - "program": "user_defined_2.ets" - }, - "end": { - "line": 20, - "column": 20, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 20, - "column": 13, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 20, - "column": 13, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 20, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 20, - "column": 21, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "short", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 17, - "program": "user_defined_2.ets" - }, - "end": { - "line": 21, - "column": 22, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 21, - "column": 14, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 21, - "column": 14, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 21, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 21, - "column": 23, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "int", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 22, - "column": 15, - "program": "user_defined_2.ets" - }, - "end": { - "line": 22, - "column": 18, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 22, - "column": 12, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 22, - "column": 12, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 22, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 22, - "column": 19, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "char", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 16, - "program": "user_defined_2.ets" - }, - "end": { - "line": 23, - "column": 20, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 23, - "column": 13, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 23, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 23, - "column": 13, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 23, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 23, - "column": 21, - "program": "user_defined_2.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "long", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 24, - "column": 16, - "program": "user_defined_2.ets" - }, - "end": { - "line": 24, - "column": 20, - "program": "user_defined_2.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 24, - "column": 13, - "program": "user_defined_2.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 24, - "column": 9, - "program": "user_defined_2.ets" - }, - "end": { - "line": 24, - "column": 13, - "program": "user_defined_2.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 24, - "column": 5, - "program": "user_defined_2.ets" - }, - "end": { - "line": 24, - "column": 21, - "program": "user_defined_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 17, - "program": "user_defined_2.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "user_defined_2.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_2.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "user_defined_2.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_2.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "user_defined_2.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 25, - "column": 2, - "program": "user_defined_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_2.ets" - }, - "end": { - "line": 26, - "column": 1, - "program": "user_defined_2.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/user_defined_22-expected.txt b/ets2panda/test/parser/ets/user_defined_22-expected.txt index 7c8109d86da8e6d4198893de13d2f17bed21e877..51cd61406c12061db16bb557a84b80d9f0096b84 100644 --- a/ets2panda/test/parser/ets/user_defined_22-expected.txt +++ b/ets2panda/test/parser/ets/user_defined_22-expected.txt @@ -360,40 +360,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_22.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_22.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_22.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_22.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/user_defined_3-expected.txt b/ets2panda/test/parser/ets/user_defined_3-expected.txt deleted file mode 100644 index 59833fcae9989ea50155299a018bb625ebf839e8..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/user_defined_3-expected.txt +++ /dev/null @@ -1,1282 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - }, - "superClass": null, - "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - } - ], - "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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "float", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 16, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 16, - "column": 22, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "boolean", - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 17, - "column": 16, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 19, - "program": "user_defined_3.ets" - }, - "end": { - "line": 17, - "column": 26, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 17, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 17, - "column": 16, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "double", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 18, - "column": 15, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 18, - "program": "user_defined_3.ets" - }, - "end": { - "line": 18, - "column": 24, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 18, - "column": 15, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "byte", - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 19, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 19, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 19, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 19, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "short", - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 20, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 20, - "column": 22, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 20, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 20, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "int", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 21, - "column": 12, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 15, - "program": "user_defined_3.ets" - }, - "end": { - "line": 21, - "column": 18, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 21, - "column": 12, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "char", - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 22, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 22, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 22, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 22, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "ClassProperty", - "key": { - "type": "Identifier", - "name": "long", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 23, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "accessibility": "public", - "static": true, - "readonly": false, - "declare": false, - "optional": false, - "computed": false, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 23, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "definite": false, - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 23, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "user_defined_3.ets" - }, - "end": { - "line": 25, - "column": 14, - "program": "user_defined_3.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": 25, - "column": 10, - "program": "user_defined_3.ets" - }, - "end": { - "line": 25, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "float", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 26, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 26, - "column": 22, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 26, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 26, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 26, - "column": 14, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 26, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 26, - "column": 23, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "boolean", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 27, - "column": 19, - "program": "user_defined_3.ets" - }, - "end": { - "line": 27, - "column": 26, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 27, - "column": 16, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 27, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 27, - "column": 16, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 27, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 27, - "column": 27, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "double", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 28, - "column": 18, - "program": "user_defined_3.ets" - }, - "end": { - "line": 28, - "column": 24, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 28, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 28, - "column": 15, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 28, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 28, - "column": 15, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 28, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 28, - "column": 25, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "byte", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 29, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 29, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 29, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 29, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 29, - "column": 13, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 29, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 29, - "column": 21, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "short", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 30, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 30, - "column": 22, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 30, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 30, - "column": 14, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 30, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 30, - "column": 14, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 30, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 30, - "column": 23, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "int", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 31, - "column": 15, - "program": "user_defined_3.ets" - }, - "end": { - "line": 31, - "column": 18, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 31, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 31, - "column": 12, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 31, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 31, - "column": 12, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 31, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 31, - "column": 19, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "char", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 32, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 32, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 32, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 32, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 32, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 32, - "column": 13, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 32, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 32, - "column": 21, - "program": "user_defined_3.ets" - } - } - }, - { - "type": "VariableDeclaration", - "declarations": [ - { - "type": "VariableDeclarator", - "id": { - "type": "Identifier", - "name": "long", - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 33, - "column": 16, - "program": "user_defined_3.ets" - }, - "end": { - "line": 33, - "column": 20, - "program": "user_defined_3.ets" - } - } - }, - "decorators": [], - "loc": { - "start": { - "line": 33, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 33, - "column": 13, - "program": "user_defined_3.ets" - } - } - }, - "init": null, - "loc": { - "start": { - "line": 33, - "column": 9, - "program": "user_defined_3.ets" - }, - "end": { - "line": 33, - "column": 13, - "program": "user_defined_3.ets" - } - } - } - ], - "kind": "let", - "loc": { - "start": { - "line": 33, - "column": 5, - "program": "user_defined_3.ets" - }, - "end": { - "line": 33, - "column": 21, - "program": "user_defined_3.ets" - } - } - } - ], - "loc": { - "start": { - "line": 25, - "column": 17, - "program": "user_defined_3.ets" - }, - "end": { - "line": 34, - "column": 2, - "program": "user_defined_3.ets" - } - } - }, - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "user_defined_3.ets" - }, - "end": { - "line": 34, - "column": 2, - "program": "user_defined_3.ets" - } - } - }, - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "user_defined_3.ets" - }, - "end": { - "line": 34, - "column": 2, - "program": "user_defined_3.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 34, - "column": 2, - "program": "user_defined_3.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_3.ets" - }, - "end": { - "line": 35, - "column": 1, - "program": "user_defined_3.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/user_defined_4-expected.txt b/ets2panda/test/parser/ets/user_defined_4-expected.txt index 340ff644fe1a374fd8f07b6a43a5627a45bb35f3..7336d1d411712f6ffa19fb8761b0f41c1f14016d 100644 --- a/ets2panda/test/parser/ets/user_defined_4-expected.txt +++ b/ets2panda/test/parser/ets/user_defined_4-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_4.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_4.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_4.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/user_defined_6-expected.txt b/ets2panda/test/parser/ets/user_defined_6-expected.txt deleted file mode 100644 index d3285daa26e39fe4e116d7bc99f3d9b28de92d1b..0000000000000000000000000000000000000000 --- a/ets2panda/test/parser/ets/user_defined_6-expected.txt +++ /dev/null @@ -1,419 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - }, - "superClass": null, - "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - } - ], - "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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.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": 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 - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "float", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_6.ets" - }, - "end": { - "line": 16, - "column": 15, - "program": "user_defined_6.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "float", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_6.ets" - }, - "end": { - "line": 16, - "column": 15, - "program": "user_defined_6.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 16, - "column": 18, - "program": "user_defined_6.ets" - }, - "end": { - "line": 17, - "column": 2, - "program": "user_defined_6.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_6.ets" - }, - "end": { - "line": 17, - "column": 2, - "program": "user_defined_6.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "user_defined_6.ets" - }, - "end": { - "line": 17, - "column": 2, - "program": "user_defined_6.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 17, - "column": 2, - "program": "user_defined_6.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "user_defined_6.ets" - }, - "end": { - "line": 18, - "column": 1, - "program": "user_defined_6.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/var_declare-expected.txt b/ets2panda/test/parser/ets/var_declare-expected.txt index 4fb4378ee53fc230e67be27f214ea2dafdef69b1..e6c6ab3282f043e944e6b49a0d220c8ace43fb78 100644 --- a/ets2panda/test/parser/ets/var_declare-expected.txt +++ b/ets2panda/test/parser/ets/var_declare-expected.txt @@ -802,40 +802,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "var_declare.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "var_declare.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "var_declare.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "var_declare.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/variable_throw_function_1-expected.txt b/ets2panda/test/parser/ets/variable_throw_function_1-expected.txt index 0fe1d01f9db4bf50a78c91e5a1eb0a1cffe05b61..68ebafcd7a72a8821b984bc038f07af4a6a73229 100644 --- a/ets2panda/test/parser/ets/variable_throw_function_1-expected.txt +++ b/ets2panda/test/parser/ets/variable_throw_function_1-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "variable_throw_function_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "variable_throw_function_1.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "variable_throw_function_1.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "variable_throw_function_1.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/void-expected.txt b/ets2panda/test/parser/ets/void-expected.txt index 8bcec14a9c83213055f8067cd2807df89f93ff8e..45431713d721e26a5dc0a8d974c3019bcd4721b0 100644 --- a/ets2panda/test/parser/ets/void-expected.txt +++ b/ets2panda/test/parser/ets/void-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "void.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "void.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "void.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "void.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/parser/ets/voidAsTypeArg-expected.txt b/ets2panda/test/parser/ets/voidAsTypeArg-expected.txt index 6504393055763f25af7277fed5b5a6fc4ba444c6..8b60ada3668500c00d87506430bb0874c1fd5924 100644 --- a/ets2panda/test/parser/ets/voidAsTypeArg-expected.txt +++ b/ets2panda/test/parser/ets/voidAsTypeArg-expected.txt @@ -23,40 +23,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "voidAsTypeArg.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "voidAsTypeArg.ets" - } - } - }, - "properties": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "voidAsTypeArg.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "voidAsTypeArg.ets" - } - } - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/runtime/ets/15656.ets b/ets2panda/test/runtime/ets/15656.ets index 1459139905a446cd1b48ea3520e7580ebc387a68..b106aaec8eccf88d0710ebdadff434527fb0805a 100644 --- a/ets2panda/test/runtime/ets/15656.ets +++ b/ets2panda/test/runtime/ets/15656.ets @@ -19,5 +19,5 @@ function foo(lmb: (i: number) => number): number { } function main(): int { - return foo((i:number): number => { return i }) as int + return Double.toInt(foo((i:number): number => { return i })) } diff --git a/ets2panda/test/runtime/ets/AccessNBody.ets b/ets2panda/test/runtime/ets/AccessNBody.ets index 4a9fb94062641be2b2ea4f9fa1e5bfa437be28cf..88ed759dadd6723410dc96372f22fa8347475e41 100644 --- a/ets2panda/test/runtime/ets/AccessNBody.ets +++ b/ets2panda/test/runtime/ets/AccessNBody.ets @@ -50,7 +50,7 @@ class NBodySystem { let px : double = 0.0; let py : double = 0.0; let pz : double = 0.0; - let size : int = this.bodies.length; + let size : int = Double.toInt(this.bodies.length); for (let i : int = 0; i < size; i++) { let b : Body = this.bodies[i]; let m : double = b.mass; @@ -67,7 +67,7 @@ class NBodySystem { let dz : double ; let distance : double ; let mag : double ; - let size : int = this.bodies.length; + let size : int = Double.toInt(this.bodies.length); for (let i : int = 0; i < size; i++) { let bodyi : Body = this.bodies[i]; for (let j : int = i + 1; j < size; j++) { @@ -98,7 +98,7 @@ class NBodySystem { let dz : double ; let distance : double ; let e : double = 0.0; - let size : int = this.bodies.length; + let size : int = Double.toInt(this.bodies.length); for (let i : int = 0; i < size; i++) { let bodyi : Body = this.bodies[i]; e += 0.5 * bodyi.mass * (bodyi.vx * bodyi.vx + bodyi.vy * bodyi.vy + bodyi.vz * bodyi.vz); diff --git a/ets2panda/test/runtime/ets/AliasArray.ets b/ets2panda/test/runtime/ets/AliasArray.ets index ed76077692f919469adeca08fbf57bf6cec6520b..053f8d3e1e6828369cc06a6de3bdec7723040351 100644 --- a/ets2panda/test/runtime/ets/AliasArray.ets +++ b/ets2panda/test/runtime/ets/AliasArray.ets @@ -32,13 +32,13 @@ type Alias9Array = [C][]; function main() { let v1 : double[] = [1,2,3]; // double[] - v1[0] = new Int(4); + v1[0] = new Double(4); assertEQ(v1[0], 4) assertEQ(v1[1], 2) assertEQ(v1[2], 3) let v2 : Alias1Array = [5, 6, 7]; // double[] - v2[0] = new Int(8); + v2[0] = new Double(8); assertEQ(v2[0], 8) assertEQ(v2[1], 6) assertEQ(v2[2], 7) diff --git a/ets2panda/test/runtime/ets/AliasPrimitive.ets b/ets2panda/test/runtime/ets/AliasPrimitive.ets index 8f1d2e43c607da4d75f865ca9c0f81dec151fc98..92c5c3601f6eb7baaaba78685f761da9ea94552d 100644 --- a/ets2panda/test/runtime/ets/AliasPrimitive.ets +++ b/ets2panda/test/runtime/ets/AliasPrimitive.ets @@ -16,23 +16,18 @@ type AliasPrimitive = T; type AliasAlias = AliasPrimitive; -function fn(p: double) -{ - assertEQ(p, 42) -} - function fn(p: Double) { - assertTrue(false) + assertEQ(p, 42) } function main() { - let v1 : double = new Int(42); // unboxing -> widening - fn(v1); + let v1 : double = new Int(42); // widening + fn(v1); - let v2 : AliasPrimitive = new Int(42); // unboxing -> widening - fn(v2); + let v2 : AliasPrimitive = new Int(42); // widening + fn(v2); - let v3 : AliasAlias = new Int(42); // unboxing -> widening - fn(v3); + let v3 : AliasAlias = new Int(42); // widening + fn(v3); } diff --git a/ets2panda/test/runtime/ets/AliasTuple.ets b/ets2panda/test/runtime/ets/AliasTuple.ets index 73cd48b2f32b5cade652cc1014eb50d0dc63a669..e02c0cef30c4bc59575050fc50c2b3df52dd9e4a 100644 --- a/ets2panda/test/runtime/ets/AliasTuple.ets +++ b/ets2panda/test/runtime/ets/AliasTuple.ets @@ -30,7 +30,7 @@ function main() { let v1: [double] = [new Int(1)]; // [double] let v2: [double, Int] = [new Double(2), new Int(3)]; // [Double, Int] - let v3: Alias1Tuple = [new Int(4)]; // [double] + let v3: Alias1Tuple = [new Int(4)]; // [double] let v4: Alias2Tuple = [new Double(5), new Int(6)]; // [Double, Int] let v5: Alias3Tuple = [new C(7), 8]; // [C, Double] diff --git a/ets2panda/test/runtime/ets/AnnotationConstExpression.ets b/ets2panda/test/runtime/ets/AnnotationConstExpression.ets index f16093d7c41f9265bcf72c10081e8ca2f8d080ea..53b7ab53d75aebc1ea55eeed1d1aac688a6b609e 100644 --- a/ets2panda/test/runtime/ets/AnnotationConstExpression.ets +++ b/ets2panda/test/runtime/ets/AnnotationConstExpression.ets @@ -20,8 +20,8 @@ } @interface Anno { - a: boolean[] = [true & false, false ^ true, true | false] - b: int[] = [1 + 1 + 1 ^ 11, 48 ? 10 : 20] + a: FixedArray = [true & false, false ^ true, true | false] + b: FixedArray = [1 + 1 + 1 ^ 11, 48 ? 10 : 20] c: string = "a" + "b" } diff --git a/ets2panda/test/runtime/ets/AnnotationOfClassPropertyInherit.ets b/ets2panda/test/runtime/ets/AnnotationOfClassPropertyInherit.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7f39edabb87d52a23d71d18bb2eba8e5f0be4a5 --- /dev/null +++ b/ets2panda/test/runtime/ets/AnnotationOfClassPropertyInherit.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. + */ + +@interface JSONRename { + name:string = "" +} + +class A { + @JSONRename("ID") + name2: string = "" + pwd2: string = "" +} + +class B extends A {} diff --git a/ets2panda/test/runtime/ets/ArrayLiteral.ets b/ets2panda/test/runtime/ets/ArrayLiteral.ets index a541cb9b164cc54ef58cabab049885aa02b41f75..b4a11058434a0ea1c72c87bbf28bea6e5803073b 100644 --- a/ets2panda/test/runtime/ets/ArrayLiteral.ets +++ b/ets2panda/test/runtime/ets/ArrayLiteral.ets @@ -18,7 +18,7 @@ function main(): void { let b: short = 20000; let c: int = 2000000; let d: long = 200000000000; - let e: float = 2.2; + let e: float = 2.2f; let f: double = 2.2222222222; let g: double[] = [a, b, c, d, e, f]; assertEQ(g[0], 2) @@ -32,9 +32,9 @@ function main(): void { const i: short = 2; const j: int = 2; const k: long = 2; - const l: float = 2.0; + const l: float = 2.0f; const m: double = 2.0; - const n: byte[] = [h, i, j, k, l, m]; + const n: byte[] = [h, i, j, k, Float.toByte(l), Double.toByte(m)]; assertEQ(n[0], 2) assertEQ(n[1], 2) assertEQ(n[2], 2) diff --git a/ets2panda/test/runtime/ets/CastPrimitive.ets b/ets2panda/test/runtime/ets/CastPrimitive.ets index 40b174bdfee1b0cf9dd786c590bcac8bb277ce51..07263656daa0be4823b6fee42ca04638ff20b858 100644 --- a/ets2panda/test/runtime/ets/CastPrimitive.ets +++ b/ets2panda/test/runtime/ets/CastPrimitive.ets @@ -30,7 +30,7 @@ function main(): void { assertEQ(a as char, c'\u0000') assertEQ(a as byte, 0) - let b : float = 70000.9921875; + let b : float = 70000.9921875f; assertEQ(b as double, 70000.9921875) assertEQ(b as long, 70000 ) // rounded, 70000 == 0x11170 assertEQ(b as int, 70000) diff --git a/ets2panda/test/runtime/ets/CastReference.ets b/ets2panda/test/runtime/ets/CastReference.ets index 3b57468e775c7e55b699fc35b09a2725bca3e4ab..e2adc3233a5fd50fa142d7f80b1052057aa38bd9 100644 --- a/ets2panda/test/runtime/ets/CastReference.ets +++ b/ets2panda/test/runtime/ets/CastReference.ets @@ -54,9 +54,9 @@ function reference_reference_test(): void { } function array_test(): void { - let Bs: B[] = [new B(), new B(), new B()]; + let Bs: FixedArray = [new B(), new B(), new B()]; - let B_As: A[] = Bs as A[]; + let B_As: FixedArray = Bs as FixedArray; for (let i: int = 0; i < B_As.length; i++) { assertEQ(B_As[i].name(), c'B') assertEQ(B_As[i].a(), c'A') @@ -64,7 +64,7 @@ function array_test(): void { let Object_: Object = B_As as Object; - let Object_Bs: B[] = Object_ as B[]; + let Object_Bs: FixedArray = Object_ as FixedArray; for (let i: int = 0; i < Object_Bs.length; i++) { assertEQ(Object_Bs[i].name(), c'B') assertEQ(Object_Bs[i].b(), c'B') @@ -72,9 +72,9 @@ function array_test(): void { } function multi_array_test(): void { - let Bs: B[][] = [[new B()], [new B()], [new B()]]; + let Bs: FixedArray> = [[new B()], [new B()], [new B()]]; - let B_As: A[][] = Bs as A[][]; + let B_As: FixedArray> = Bs as FixedArray>; for (let i: int = 0; i < B_As.length; i++) { for (let j: int = 0; j < B_As[i].length; j++) { assertEQ(B_As[i][j].name(), c'B') @@ -84,7 +84,7 @@ function multi_array_test(): void { let Object_: Object = B_As as Object; - let Object_Bs: B[][] = Object_ as B[][]; + let Object_Bs: FixedArray> = Object_ as FixedArray>; for (let i: int = 0; i < Object_Bs.length; i++) { for (let j: int = 0; j < Object_Bs[i].length; j++) { assertEQ(Object_Bs[i][j].name(), c'B') @@ -97,7 +97,7 @@ function primitive_reference_test(): void { let int_: int = 42; let Int_ = int_ as Int; assertTrue(Int_ instanceof Int) - assertEQ(Int_.intValue(), 42) + assertEQ(Int_.toInt(), 42) assertEQ(Int_.add(1) as int, 43) } diff --git a/ets2panda/test/runtime/ets/CastReference3.ets b/ets2panda/test/runtime/ets/CastReference3.ets index 2a5b41ef6372a7367f8796034739fbd56647bea8..73c1c2034df20b75c043da9dc1646d8278ecbf3e 100644 --- a/ets2panda/test/runtime/ets/CastReference3.ets +++ b/ets2panda/test/runtime/ets/CastReference3.ets @@ -23,28 +23,28 @@ class C extends B { name = c'C'; } -function clear_accumlator_type(As: A[]): A[] { +function clear_accumlator_type(As: FixedArray): FixedArray { return As; } function main() { { - let As: A[] = new C[1]; + let As: FixedArray = new C[1]; As[0] = new C(); As = clear_accumlator_type(As); // workaround for: // Verifier warning 22: Redundant check cast - // Accumulator type 'C[]' is always a subtype of 'B[]'. Checkcast is redundant here. + // Accumulator type 'C[]' is always a subtype of 'FixedArray'. Checkcast is redundant here. // It may be a sign of possible error here. - let Bs: B[] = As as B[]; + let Bs: FixedArray = As as FixedArray; assertEQ(Bs[0].name, c'B') } { let caught = false; try { - let As: A[] = new A[1]; - let Bs = As as B[]; + let As: FixedArray = new A[1]; + let Bs = As as FixedArray; } catch (e: ClassCastError) { caught = true; } catch (e) { diff --git a/ets2panda/test/runtime/ets/CastReference4.ets b/ets2panda/test/runtime/ets/CastReference4.ets index 19cc43a5dbf270d3d287ea2ceee4cb8949f68c0c..368d8bf28e2a03810b5c582ac38960f03b583214 100644 --- a/ets2panda/test/runtime/ets/CastReference4.ets +++ b/ets2panda/test/runtime/ets/CastReference4.ets @@ -17,13 +17,13 @@ interface I {} class A implements I {} class B implements I {} -function clear_accumlator_type(Is: I[]): I[] { +function clear_accumlator_type(Is: FixedArray): FixedArray { return Is; } function main() { - let As: A[] = new A[1]; - let Is: I[] = As as I[]; + let As: FixedArray = new A[1]; + let Is: FixedArray = As as FixedArray; let caught = false; try { @@ -31,7 +31,7 @@ function main() { // Verifier warning 24: Impossible array check cast // Element type in array in accumulator is of incompatible type 'A'. // Instruction 'checkcast' will always throw an exception here. It may be a sign of possible error here. - let Bs: B[] = Is as B[]; + let Bs: FixedArray = Is as FixedArray; } catch (e: ClassCastError) { caught = true; } catch (e) { @@ -43,6 +43,6 @@ function main() { // Verifier warning 24: Impossible array check cast // Element type in array in accumulator is of incompatible type 'B'. // Instruction 'checkcast' will always throw an exception here. It may be a sign of possible error here. - let As2 = Is as A[]; + let As2 = Is as FixedArray; } diff --git a/ets2panda/test/runtime/ets/ClassMemberAccess.ets b/ets2panda/test/runtime/ets/ClassMemberAccess.ets index 26f7423f089a8dcd44ce3f1d3f0e44c740411aba..2be609f08566c39676f0d6a0f92df0d613f80b1a 100644 --- a/ets2panda/test/runtime/ets/ClassMemberAccess.ets +++ b/ets2panda/test/runtime/ets/ClassMemberAccess.ets @@ -43,7 +43,7 @@ class B extends A { } super_name(): char { - return super.name; + return super.get_name(); } } @@ -60,7 +60,7 @@ final class C extends B { } override super_name(): char { - return super.name; + return super.get_name(); } } diff --git a/ets2panda/test/runtime/ets/ConditionalExpression_01.ets b/ets2panda/test/runtime/ets/ConditionalExpression_01.ets index 9bf3f0fd1440b585cbb57cce4102372bdc27bc70..3cbebde2924d78d9bbd3b9e3508f9cfaad7ba0c5 100644 --- a/ets2panda/test/runtime/ets/ConditionalExpression_01.ets +++ b/ets2panda/test/runtime/ets/ConditionalExpression_01.ets @@ -27,14 +27,14 @@ function main() { assertEQ(z2, 4.0) let x3 = (): int | undefined => { return 5; }(); - let y3: int = !x3 ? 3.1 : x3; - let z3: int = x3 ? x3 : 4.1; + let y3: int = !x3 ? Double.toInt(3.1) : x3; + let z3: int = x3 ? x3 : Double.toInt(4.1); assertEQ(y3, 5) assertEQ(z3, 5) let x4 = (): int | undefined => { return undefined; }(); - let y4: int = x4 == undefined ? 3.1 : x4; - let z4: int = x4 != undefined ? x4 : 4.1; + let y4: int = x4 == undefined ? Double.toInt(3.1) : x4; + let z4: int = x4 != undefined ? x4 : Double.toInt(4.1); assertEQ(y4, 3) assertEQ(z4, 4) } diff --git a/ets2panda/test/runtime/ets/FixFunctionCall.ets b/ets2panda/test/runtime/ets/FixFunctionCall.ets new file mode 100644 index 0000000000000000000000000000000000000000..d33f420a54f3261ac18281fafd0191f6cfa27ac5 --- /dev/null +++ b/ets2panda/test/runtime/ets/FixFunctionCall.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. + */ + +export type AsyncCallback = (err: T, data: T) => void; + +function getBundleInfo(userId?: number):void {} +function getBundleInfo(callback: AsyncCallback): void { + callback(666, 66); +} + +getBundleInfo((err, data) => { + assertEQ(err, 666); + assertEQ(data, 66) +}); diff --git a/ets2panda/test/runtime/ets/GenericArray_1.ets b/ets2panda/test/runtime/ets/GenericArray_1.ets index c29719cb5cb0bbf10444de210fa4cf5222fe3754..5dc63b25f2a2145b9c37e31c9915f30bfe16ec5d 100644 --- a/ets2panda/test/runtime/ets/GenericArray_1.ets +++ b/ets2panda/test/runtime/ets/GenericArray_1.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -function createMap(keys: K[], values: V[]): Map { +function createMap(keys: FixedArray, values: FixedArray): Map { assertEQ(keys.length, values.length) let map = new Map(); for (let i = 0; i < keys.length; i++) { diff --git a/ets2panda/test/runtime/ets/GenericBridges_04.ets b/ets2panda/test/runtime/ets/GenericBridges_04.ets new file mode 100644 index 0000000000000000000000000000000000000000..56a06ce7abf80e21b2f817eef5a427c7d36a4894 --- /dev/null +++ b/ets2panda/test/runtime/ets/GenericBridges_04.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 Base { + foo(i: Number | string) : string { return "Hello"; } +} + +class Derived2 extends Base { + static foo(i: Number) : string { return "World"; } +} + +function main(): void { + let a = new Derived2(); + + assertEQ(a.foo(12), "Hello"); + assertEQ(Derived2.foo(12), "World"); +} diff --git a/ets2panda/test/runtime/ets/GenericRestParamsInGenericClass.ets b/ets2panda/test/runtime/ets/GenericRestParamsInGenericClass.ets index 9d0a19c65f1795744a71ed23a52dfb9811f2c64b..2855ee72b51d1b61fa6a6fb7210b09b9ab80e839 100644 --- a/ets2panda/test/runtime/ets/GenericRestParamsInGenericClass.ets +++ b/ets2panda/test/runtime/ets/GenericRestParamsInGenericClass.ets @@ -17,8 +17,8 @@ class A { public static of(...values: T[]): A { return new A(); } -} - -function main(): void { - let x = A.of(1,2,3); -} \ No newline at end of file + } + + function main(): void { + let x = A.of(1,2,3); + } \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/GenericRestParamsInGenericClass_FixedArray.ets b/ets2panda/test/runtime/ets/GenericRestParamsInGenericClass_FixedArray.ets new file mode 100644 index 0000000000000000000000000000000000000000..0b088f29615ea9d889199bc18321740cfafc8dfb --- /dev/null +++ b/ets2panda/test/runtime/ets/GenericRestParamsInGenericClass_FixedArray.ets @@ -0,0 +1,24 @@ +/* + * 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 { + public static of(...values: FixedArray): A { + return new A(); + } + } + + function main(): void { + let x = A.of(1,2,3); + } \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/InterfacePrivateMethod.ets b/ets2panda/test/runtime/ets/InterfacePrivateMethod.ets similarity index 87% rename from ets2panda/test/ast/parser/ets/InterfacePrivateMethod.ets rename to ets2panda/test/runtime/ets/InterfacePrivateMethod.ets index ab7a71d2191121dd7fae7abaf198343b06dff9a4..775cdd1052f380eed7ada0c7be60edf4b9f3f651 100644 --- a/ets2panda/test/ast/parser/ets/InterfacePrivateMethod.ets +++ b/ets2panda/test/runtime/ets/InterfacePrivateMethod.ets @@ -18,7 +18,7 @@ interface Vehicle { return (rpm * trq) / 5252; } - getPwrIndex/* @@ label */(trq: int): int{ + getPwrIndex(trq: int): int{ return this.getHorsePower3(5252, trq); } } @@ -28,5 +28,3 @@ class Car implements Vehicle{} function main(): void { assertEQ(new Car().getPwrIndex(1), 1); } - -/* @@@ label Error TypeError: Cannot reference 'this' in this context. */ diff --git a/ets2panda/test/runtime/ets/JsDocInfoTest.ets b/ets2panda/test/runtime/ets/JsDocInfoTest.ets new file mode 100644 index 0000000000000000000000000000000000000000..68cf3ffb27355f7acf92503fa8413d1e96aa2f73 --- /dev/null +++ b/ets2panda/test/runtime/ets/JsDocInfoTest.ets @@ -0,0 +1,194 @@ +/* + * 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. + */ + +/** +* JsDocTest on namespace +* +* @JsDocRecord1 comments +* @JsDocRecord2 { JsDocRecord1 param } comments +* @JsDocRecord3 {} comments +*/ +namespace ns { + /** + * JsDocTest on interface. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 param } comments + * @JsDocRecord3 {} comments + */ + export interface itfc1 { + /** + * JsDocTest on method. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 'param' } comments + * @JsDocRecord3 {} comments + */ + foo():void + + /** + * JsDocTest on prop. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 'param' } comments + * @JsDocRecord3 {} comments + */ + prop:number + } + + /** + * JsDocTest on class. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 param } comments + * @JsDocRecord3 {} comments + */ + export class cls { + /** + * JsDocTest on method. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 'param' } comments + * @JsDocRecord3 {} comments + */ + foo():void {} + + /** + * JsDocTest on prop. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 'param' } comments + * @JsDocRecord3 {} comments + */ + prop:number + } + + /** + * JsDocTest on namespace + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 param } comments + * @JsDocRecord3 {} comments + */ + namespace ns_inner {} +} + +/** + * JsDocTest on interface. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 param } comments + * @JsDocRecord3 {} comments + */ +export interface itfc1 { + /** + * JsDocTest on method. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 'param' } comments + * @JsDocRecord3 {} comments + */ + foo():void + + /** + * JsDocTest on prop. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 'param' } comments + * @JsDocRecord3 {} comments + */ + prop:number +} + + + +/** + * JsDocTest on class. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 param } comments + * @JsDocRecord3 {} comments + */ +export class cls { + /** + * JsDocTest on method. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 'param' } comments + * @JsDocRecord3 {} comments + */ + foo():void {} + + /** + * JsDocTest on prop. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 'param' } comments + * @JsDocRecord3 {} comments + */ + prop:number +} + +/** +* JsDocTest on arrow function. +* +* @JsDocRecord1 comments +* @JsDocRecord2 { JsDocRecord1 'param' } comments +* @JsDocRecord3 {} comments +*/ +let arrowFunc:() => void = ():void => {} + +/** +* JsDocTest on function decl. +* +* @JsDocRecord1 comments +* @JsDocRecord2 { JsDocRecord1 'param' } comments +* @JsDocRecord3 {} comments +*/ +function testFunc():void {} + +/** +* JsDocTest on typeAlias. +* +* @JsDocRecord1 comments +* @JsDocRecord2 { JsDocRecord1 'param' } comments +* @JsDocRecord3 {} comments +*/ +type xx = +/** +* @xx {xx} xx +*/ +'somexx' +/** +* @xx {xx} xx +*/ +| 'somexx2' +/** +* @xx {xx} xx +*/ +| 'somexx3' + +function main() { + /** + * JsDocTest on arrow variable decl. + * + * @JsDocRecord1 comments + * @JsDocRecord2 { JsDocRecord1 'param' } comments + * @JsDocRecord3 {} comments + */ + let val:string = "ssss" + assertTrue(true); + assertEQ(val, "ssss") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/ManyLocalOutRegInstruction.ets b/ets2panda/test/runtime/ets/ManyLocalOutRegInstruction.ets index 446347c6ce03a5f388a322e90fde41cc5b442f19..6f0b34ac0f412f7fef82e6622d5cbc46472cf270 100644 --- a/ets2panda/test/runtime/ets/ManyLocalOutRegInstruction.ets +++ b/ets2panda/test/runtime/ets/ManyLocalOutRegInstruction.ets @@ -32,6 +32,6 @@ function main(): int { let x14 = 14; let x15 = 15; let x16 = 16; - let x = new int[10]; + let x:FixedArray = new int[10]; return x[0]; } diff --git a/ets2panda/test/runtime/ets/MathCordic.ets b/ets2panda/test/runtime/ets/MathCordic.ets index 0e861bbf6c33ad5a64939084ca1d7857588a493a..a0701ed1a421f861f489c4e0a7062137acfb724f 100644 --- a/ets2panda/test/runtime/ets/MathCordic.ets +++ b/ets2panda/test/runtime/ets/MathCordic.ets @@ -42,14 +42,14 @@ export class MathCordic { for (step = 0; step < 12; step++) { let newX : double ; if (targetAngle > currAngle) { - newX = x - (y as int >> step); - y = (x as int >> step) + y; + newX = x - (Double.toInt(y) >> step); + y = (Double.toInt(x) >> step) + y; x = newX; currAngle += MathCordic.ANGLES[step]; } else { - newX = x + (y as int >> step); - y = -(x as int >> step) + y; + newX = x + (Double.toInt(y) >> step); + y = -(Double.toInt(x) >> step) + y; x = newX; currAngle -= MathCordic.ANGLES[step]; } diff --git a/ets2panda/test/runtime/ets/NullishCoalescing_02.ets b/ets2panda/test/runtime/ets/NullishCoalescing_02.ets new file mode 100644 index 0000000000000000000000000000000000000000..17388223af5a8a15ccbd991a8c5c2a9afb91e79a --- /dev/null +++ b/ets2panda/test/runtime/ets/NullishCoalescing_02.ets @@ -0,0 +1,72 @@ +/* + * 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 foo1(z: long|undefined) { + let x = z ?? 10000000000; + return x; +} + +function foo2(z: int|undefined) { + let x = z ?? 10000000; + return x; +} + +function foo3(z: short|undefined) { + let x = z ?? 10000; + return x; +} + +function foo4(z: byte|undefined) { + let x = z ?? 100; + return x; +} + +function foo5(z: float|undefined) { + let x = z ?? 100000; + return x; +} + +function foo6(z: float|undefined) { + let x = z ?? 100000.0f; + return x; +} + +function foo7(z: double|undefined) { + let x = z ?? 10000000; + return x; +} + +function foo8(z: double|undefined) { + let x = z ?? 10000000.0f; + return x; +} + +function foo9(z: double|undefined) { + let x = z ?? 10000000.0; + return x; +} + + +function main() { + assertEQ(foo1(undefined), 10000000000); + assertEQ(foo2(undefined), 10000000); + assertEQ(foo3(undefined), 10000); + assertEQ(foo4(undefined), 100); + assertEQ(foo5(undefined), 100000.0f); + assertEQ(foo6(undefined), 100000.0f); + assertEQ(foo7(undefined), 10000000.0); + assertEQ(foo8(undefined), 10000000.0); + assertEQ(foo9(undefined), 10000000.0); +} diff --git a/ets2panda/test/runtime/ets/Override.ets b/ets2panda/test/runtime/ets/Override.ets index 97e201daa6a563530ec1a7b26a98f54beca97074..eeb12f88b8024f25282e2e6f721cda498ad29ce1 100644 --- a/ets2panda/test/runtime/ets/Override.ets +++ b/ets2panda/test/runtime/ets/Override.ets @@ -19,17 +19,17 @@ interface I { fn2(): Object; fn3(): Object; fn4(): Object; - fn5(): Object[]; + fn5(): FixedArray; } class A implements I { public x: int = 42; override self(): A { return this; } override fn(): String { return ""; } - override fn2(): Object[] { return [new Object()]; } - override fn3(): int[] { return [0]; } - override fn4(): int[][] { return [[0]]; } - override fn5(): String[] { return [""]; } + override fn2(): FixedArray { return [new Object()]; } + override fn3(): FixedArray { return [0]; } + override fn4(): FixedArray[] { return [[0]]; } + override fn5(): FixedArray { return [""]; } } @@ -45,9 +45,9 @@ function main(): void { // let i: I = a; // assertTrue(i.self() instanceof A) // assertEQ((i.fn() as String), "") - // assertEQ((i.fn2() as Object[])[0], new Object() - // assertEQ((i.fn3() as int[])[0], 0) - // assertEQ((i.fn4() as String[])[0], "") + // assertEQ((i.fn2() as FixedArray)[0], new Object() + // assertEQ((i.fn3() as FixedArray)[0], 0) + // assertEQ((i.fn4() as FixedArray)[0], "") } diff --git a/ets2panda/test/runtime/ets/PrimitiveCasts.ets b/ets2panda/test/runtime/ets/PrimitiveCasts.ets new file mode 100644 index 0000000000000000000000000000000000000000..6137b609a7d18d17dfe1caa707b6a56a3c996d34 --- /dev/null +++ b/ets2panda/test/runtime/ets/PrimitiveCasts.ets @@ -0,0 +1,77 @@ +/* + * 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(a: int): double { + return a.toDouble() + 10.5; +} + +function main() { + let b: byte = 1 + let c: char = c'a' + let s: short = 5 + let i: int = 25 + let l: long = 125 + let f: float = 2.71f + let d: double = 3.14 + + // byte + assertEQ(b.toChar(), c'\u0001') + assertEQ(b.toShort(), 1 as short) + assertEQ(b.toInt(), 1 as int) + assertEQ(b.toLong(), 1 as long) + assertEQ(b.toFloat(), 1.0f) + assertEQ(b.toDouble(),1.0) + + // short + assertEQ(s.toByte(), 5 as byte) + assertEQ(s.toChar(), c'\u0005') + assertEQ(s.toInt(), 5 as int) + assertEQ(s.toLong(), 5 as long) + assertEQ(s.toFloat(), 5.0f) + assertEQ(s.toDouble(),5.0) + + // int + assertEQ(i.toByte(), 25 as byte) + assertEQ(i.toChar(), c'\u0019') + assertEQ(i.toShort(), 25 as short) + assertEQ(i.toLong(), 25 as long) + assertEQ(i.toFloat(), 25.0f) + assertEQ(i.toDouble(),25.0) + + assertEQ(foo(i), 35.5) + + // long + assertEQ(l.toByte(), 125 as byte) + assertEQ(l.toChar(), c'\u007d') + assertEQ(l.toShort(), 125 as short) + assertEQ(l.toInt(), 125 as int) + assertEQ(l.toFloat(), 125.0f) + assertEQ(l.toDouble(),125.0) + + // float + assertEQ(f.toByte(), 2 as byte) + assertEQ(f.toShort(), 2 as short) + assertEQ(f.toInt(), 2 as int) + assertEQ(f.toLong(), 2.0 as long) + assertEQ(f.toDouble(),2.71f as double) + + // double + assertEQ(d.toByte(), 3 as byte) + assertEQ(d.toShort(), 3 as short) + assertEQ(d.toInt(), 3 as int) + assertEQ(d.toLong(), 3.0 as long) + assertEQ(d.toFloat(), 3.14f) +} diff --git a/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets b/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets index 1b1698448db902e3cf097378fc38c24ac268d766..8b5dee486363e42a70932bfe8f795dc91a0dc210 100644 --- a/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets +++ b/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets @@ -24,32 +24,28 @@ class A extends Numeric { this.value = value; } - public constructor(value: Int) { - this.value = value.intValue(); + public override toByte(): byte { + return Int.toByte(this.value); } - public override byteValue(): byte { - return this.value as byte; + public override toShort(): short { + return Int.toShort(this.value); } - public override shortValue(): short { - return this.value as short; - } - - public override intValue(): int { + public override toInt(): int { return this.value; } - public override longValue(): long { - return this.value as long; + public override toLong(): long { + return Int.toLong(this.value); } - public override floatValue(): float { - return this.value as float; + public override toFloat(): float { + return Int.toFloat(this.value); } - public override doubleValue(): double { - return this.value as double; + public override toDouble(): double { + return Int.toDouble(this.value); } public override toString(): String { @@ -61,4 +57,4 @@ function main(){ let r: Record = { 1: 1, } -} \ No newline at end of file +} diff --git a/ets2panda/test/runtime/ets/RecursiveTypeAlias4.ets b/ets2panda/test/runtime/ets/RecursiveTypeAlias4.ets index ce3e1451caaa216288c6035c5b732fb8d66ea77a..2212ccede87dedfaf5acde50913d5679cd2e8be7 100644 --- a/ets2panda/test/runtime/ets/RecursiveTypeAlias4.ets +++ b/ets2panda/test/runtime/ets/RecursiveTypeAlias4.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -type A = string | A[] +type A = string | FixedArray function main(): int { let a: A = "test"; @@ -22,7 +22,7 @@ function main(): int { a = [a] as A; a = [a] as A; - assertEQ((((a as A[])[0] as A[])[0] as A[])[0], "test") + assertEQ((((a as FixedArray)[0] as FixedArray)[0] as FixedArray)[0], "test") return 0; } \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/RegisterSpiller.ets b/ets2panda/test/runtime/ets/RegisterSpiller.ets index d83252e75f4306ebc383b3000c45a1326ff5bb45..ec627eae4aa2030a479be0747cd6909aef8349fb 100644 --- a/ets2panda/test/runtime/ets/RegisterSpiller.ets +++ b/ets2panda/test/runtime/ets/RegisterSpiller.ets @@ -17,7 +17,7 @@ function main(): void { let str: String = "hello\nworld\n"; assertEQ(str.charAt(2), c'l') assertEQ(str.length, 12) - assertEQ(str.charAt(str.length as int - 1), c'\n') + assertEQ(str.charAt(Double.toInt(str.length) - 1), c'\n') let a: String = "abc"; let b: String = "ace"; @@ -28,7 +28,7 @@ function main(): void { let n2: int = 41; let n3: long = 42; - let n4: float = 43.43; + let n4: float = 43.43f; let n5: double = 44.44; let n6: double = random(); let n7: double = random() + 42; diff --git a/ets2panda/test/runtime/ets/RestTuple1.ets b/ets2panda/test/runtime/ets/RestTuple1.ets new file mode 100644 index 0000000000000000000000000000000000000000..a52a0ea36c4a61955b65e2b2909fe2cd87e6a1b7 --- /dev/null +++ b/ets2panda/test/runtime/ets/RestTuple1.ets @@ -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. + */ + +function sum(...numbers: [number, number, number]): number { + return numbers[0] + numbers[1] + numbers[2] +} + +function sum2(a: int, ...numbers: [number, number, number]): number { + return a + numbers[0] + numbers[1] + numbers[2] +} + +function main() { + let tuple : [number, number, number] = [30, 40, 50] + let res = sum(10, 20, 30) + let res2 = sum2(10, 20, 30, 40) + + let res3 = sum(...tuple) + let res4 = sum2(10, ...tuple) + + let res5 = sum(...([30, 40, 50] as [number, number, number])) + let res6 = sum2(10, ...([30, 40, 50] as [number, number, number])) + + assertEQ(res, 60) + assertEQ(res2, 100) + assertEQ(res3, 120) + assertEQ(res4, 130) + assertEQ(res5, 120) + assertEQ(res6, 130) +} diff --git a/ets2panda/test/runtime/ets/RestTuple2.ets b/ets2panda/test/runtime/ets/RestTuple2.ets new file mode 100644 index 0000000000000000000000000000000000000000..0cca1c95277cd8635fdf961355469c05217c5a29 --- /dev/null +++ b/ets2panda/test/runtime/ets/RestTuple2.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 { + sum(...numbers: [number, number, number]): number { + return numbers[0] + numbers[1] + numbers[2] + } + + sum2(a: int, ...numbers: [number, number, number]): number { + return a + numbers[0] + numbers[1] + numbers[2] + } +} + +function main() { + let tuple : [number, number, number] = [30, 40, 50] + let a = new A() + + let res = a.sum(10, 20, 30) + let res2 = a.sum2(10, 20, 30, 40) + + let res3 = a.sum(...tuple) + let res4 = a.sum2(10, ...tuple) + + let res5 = a.sum(...([30, 40, 50] as [number, number, number])) + let res6 = a.sum2(10, ...([30, 40, 50] as [number, number, number])) + + assertEQ(res, 60) + assertEQ(res2, 100) + assertEQ(res3, 120) + assertEQ(res4, 130) + assertEQ(res5, 120) + assertEQ(res6, 130) +} diff --git a/ets2panda/test/runtime/ets/RestTuple3.ets b/ets2panda/test/runtime/ets/RestTuple3.ets new file mode 100644 index 0000000000000000000000000000000000000000..02bad1d566414f26b123d25feb7dbba2f680ade4 --- /dev/null +++ b/ets2panda/test/runtime/ets/RestTuple3.ets @@ -0,0 +1,44 @@ +/* + * 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 sum(...numbers: [number, number, number]): number { + return numbers[0] + numbers[1] + numbers[2] + } + + static sum2(a: int, ...numbers: [number, number, number]): number { + return a + numbers[0] + numbers[1] + numbers[2] + } +} + +function main() { + let tuple : [number, number, number] = [30, 40, 50] + + let res = A.sum(10, 20, 30) + let res2 = A.sum2(10, 20, 30, 40) + + let res3 = A.sum(...tuple) + let res4 = A.sum2(10, ...tuple) + + let res5 = A.sum(...([30, 40, 50] as [number, number, number])) + let res6 = A.sum2(10, ...([30, 40, 50] as [number, number, number])) + + assertEQ(res, 60) + assertEQ(res2, 100) + assertEQ(res3, 120) + assertEQ(res4, 130) + assertEQ(res5, 120) + assertEQ(res6, 130) +} diff --git a/ets2panda/test/runtime/ets/RestTuple4.ets b/ets2panda/test/runtime/ets/RestTuple4.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a4f8e30d9e896acc3fd66fff84c5e0e38406e23 --- /dev/null +++ b/ets2panda/test/runtime/ets/RestTuple4.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 { + public field : number + constructor(...numbers: [number, number, number]) { + this.field = numbers[0] + numbers[1] + numbers[2] + } + + constructor(a: int, ...numbers: [number, number, number]) { + this.field = a + numbers[0] + numbers[1] + numbers[2] + } +} + +function main() { + let tuple : [number, number, number] = [30, 40, 50] + + let res : A = new A(10, 20, 30) + let res2 : A = new A(10, 20, 30, 40) + + let res3 : A = new A(...tuple) + let res4 : A = new A(10, ...tuple) + + let res5 : A = new A(...([30, 40, 50] as [number, number, number])) + let res6 : A = new A(10, ...([30, 40, 50] as [number, number, number])) + + assertEQ(res.field, 60) + assertEQ(res2.field, 100) + assertEQ(res3.field, 120) + assertEQ(res4.field, 130) + assertEQ(res5.field, 120) + assertEQ(res6.field, 130) +} diff --git a/ets2panda/test/runtime/ets/RestTuple5.ets b/ets2panda/test/runtime/ets/RestTuple5.ets new file mode 100644 index 0000000000000000000000000000000000000000..888b16c712a7e5371b7d77865371df7b8fe205dd --- /dev/null +++ b/ets2panda/test/runtime/ets/RestTuple5.ets @@ -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. + */ + +class A {} +class B {} + +function foo(...p: [A, B]): boolean { + return p[0] == p[1] +} + +function moo(a:int, ...p: [A, B]): boolean { + return p[0] == p[1] +} + +function main() { + let a1: [A, B] = [new A, new B] + + assertTrue(foo(...a1) == false) + assertTrue(moo(12, ...a1) == false) + + assertTrue(foo(...[new A, new B]) == false) + assertTrue(moo(12, ...[new A, new B]) == false) + + assertTrue(foo(...[new A, new B] as [A, B]) == false) + assertTrue(moo(12, ...[new A, new B] as [A, B]) == false) + + assertTrue(foo(new A, new B) == false) + assertTrue(moo(12, new A, new B) == false) +} diff --git a/ets2panda/test/runtime/ets/RestTuple6.ets b/ets2panda/test/runtime/ets/RestTuple6.ets new file mode 100644 index 0000000000000000000000000000000000000000..5fc918e8e69eb192ae5eff4c126f84a934b47aad --- /dev/null +++ b/ets2panda/test/runtime/ets/RestTuple6.ets @@ -0,0 +1,43 @@ +/* + * 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 { + foo(...p: [A, B]): boolean { + return p[0] == p[1] + } + + moo(a:int, ...p: [A, B]): boolean { + return p[0] == p[1] + } +} + +function main() { + let a1: [A, B] = [new A, new B] + + assertTrue((new C()).foo(...a1) == false) + assertTrue((new C()).moo(12, ...a1) == false) + + assertTrue((new C()).foo(...[new A, new B]) == false) + assertTrue((new C()).moo(12, ...[new A, new B]) == false) + + assertTrue((new C()).foo(...[new A, new B] as [A, B]) == false) + assertTrue((new C()).moo(12, ...[new A, new B] as [A, B]) == false) + + assertTrue((new C()).foo(new A, new B) == false) + assertTrue((new C()).moo(12, new A, new B) == false) +} diff --git a/ets2panda/test/runtime/ets/RestTuple7.ets b/ets2panda/test/runtime/ets/RestTuple7.ets new file mode 100644 index 0000000000000000000000000000000000000000..4368052ce63d5789ba9cb8f6b79b936a9f23f793 --- /dev/null +++ b/ets2panda/test/runtime/ets/RestTuple7.ets @@ -0,0 +1,43 @@ +/* + * 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 { + static foo(...p: [A, B]): boolean { + return p[0] == p[1] + } + + static moo(a:int, ...p: [A, B]): boolean { + return p[0] == p[1] + } +} + +function main() { + let a1: [A, B] = [new A, new B] + + assertTrue(C.foo(...a1) == false) + assertTrue(C.moo(12, ...a1) == false) + + assertTrue(C.foo(...[new A, new B]) == false) + assertTrue(C.moo(12, ...[new A, new B]) == false) + + assertTrue(C.foo(...[new A, new B] as [A, B]) == false) + assertTrue(C.moo(12, ...[new A, new B] as [A, B]) == false) + + assertTrue(C.foo(new A, new B) == false) + assertTrue(C.moo(12, new A, new B) == false) +} diff --git a/ets2panda/test/runtime/ets/RestTuple8.ets b/ets2panda/test/runtime/ets/RestTuple8.ets new file mode 100644 index 0000000000000000000000000000000000000000..3a802df4085bb9eef700c01bb7a3c53b35be6039 --- /dev/null +++ b/ets2panda/test/runtime/ets/RestTuple8.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 { + public field : boolean + + constructor(...p: [A, B]) { + this.field = p[0] == p[1] + } + + constructor(a: int, ...p: [A, B]) { + this.field = p[0] == p[1] + } +} + +function main() { + let a1: [A, B] = [new A, new B] + + assertTrue((new C(...a1)).field == false) + assertTrue((new C(22, ...a1)).field == false) + + assertTrue((new C(...[new A, new B])).field == false) + assertTrue((new C(22, ...[new A, new B])).field == false) + + assertTrue((new C(...[new A, new B] as [A, B])).field == false) + assertTrue((new C(22, ...[new A, new B] as [A, B])).field == false) + + assertTrue((new C(new A, new B)).field == false) + assertTrue((new C(22, new A, new B)).field == false) +} diff --git a/ets2panda/test/runtime/ets/RestTuple9.ets b/ets2panda/test/runtime/ets/RestTuple9.ets new file mode 100644 index 0000000000000000000000000000000000000000..8f58003d8e570dc8ea75123a796f88d723887c97 --- /dev/null +++ b/ets2panda/test/runtime/ets/RestTuple9.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. + */ + +type TPL = [number, number] + +function foo(...j: TPL): number { + return j[0] + j[1] +} + +function main() { + assertTrue(foo(...[10, 20]) == 30) +} diff --git a/ets2panda/test/runtime/ets/SmartCast_15.ets b/ets2panda/test/runtime/ets/SmartCast_15.ets new file mode 100644 index 0000000000000000000000000000000000000000..707046968934c81bd0ddf0da19fa7424f3a2152b --- /dev/null +++ b/ets2panda/test/runtime/ets/SmartCast_15.ets @@ -0,0 +1,36 @@ +/* + * 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. + */ + +// Issue #22779 - smart cast in return statement +function isEmpty(text?: string): boolean { + return text === undefined || text === null || text.length === 0 +} + +// Some other examples +function foo(text?: string): boolean { + let a: boolean = (text === undefined || text === null || text.length == 0) ? true : false + let b: boolean = text === undefined || text === null || text.length == 0 + let c: boolean = !(text !== undefined) || text === null || text.length == 0 + let d: boolean = (text !== undefined && text !== null) ? text.length == 0 : true + let e: boolean = (text != undefined && text != null) ? text.length == 0 : true + return a && b && c && d && e +} + +function main(): void { + assertEQ(isEmpty(), true) + assertEQ(isEmpty(""), true) + assertEQ(isEmpty("a"), false) + assertEQ(foo(), true) +} diff --git a/ets2panda/test/runtime/ets/SmartCast_16.ets b/ets2panda/test/runtime/ets/SmartCast_16.ets new file mode 100644 index 0000000000000000000000000000000000000000..8f4a016de9bf2140c2087aacb7cec1e0a99b3c96 --- /dev/null +++ b/ets2panda/test/runtime/ets/SmartCast_16.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 C { + readonly fld: T + constructor(p: T) { + this.fld = p + } +} + +type NestedC = String | C | Error + +function main(): int { + let x: NestedC = new C>(new C(new Error())) + let ok = x instanceof C && x.fld instanceof C && x.fld.fld instanceof Error + return ok ? 0 : 1 +} diff --git a/ets2panda/test/runtime/ets/SpreadExpressionsforThisAndSuper.ets b/ets2panda/test/runtime/ets/SpreadExpressionsforThisAndSuper.ets index 629d2967ddd9b8e3e5ef5e0521a784f71e31a3d3..af04adc6914c4e411f96f743b36e57d0d87dc8e6 100644 --- a/ets2panda/test/runtime/ets/SpreadExpressionsforThisAndSuper.ets +++ b/ets2panda/test/runtime/ets/SpreadExpressionsforThisAndSuper.ets @@ -32,13 +32,19 @@ class B1 extends A1 { } class A2 { - fld: Boolean[] + private _fld: Boolean[] = [] constructor(p: Boolean[], q: Boolean[]) { this.fld = [...p, ...q] } meth() : Boolean[] { return [true, ...this.fld, false] } + get fld(): Boolean[]{ + return this._fld; + } + set fld(v: Boolean[]) { + this._fld = v; + } } class B2 extends A2 { @@ -75,5 +81,4 @@ function main() { assertTrue(arr4[0] == true && arr4[1] == false && arr4[2] == true) assertTrue(arr4[3] == false && arr4[4] == false) -} - +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/ThrowStatementCloneFunction.ets b/ets2panda/test/runtime/ets/ThrowStatementCloneFunction.ets index dc16545ec60a3c941400de496711b7157ac915ea..a17d795587f54e95ae613de33144a5a1333bd8f6 100644 --- a/ets2panda/test/runtime/ets/ThrowStatementCloneFunction.ets +++ b/ets2panda/test/runtime/ets/ThrowStatementCloneFunction.ets @@ -14,13 +14,13 @@ */ let error = new Error(); -let p = new Promise((resolve: (value: string) => void, reject: (error: Object) => void) => { +let p = new Promise((resolve: (value: string) => void, reject: (error: Error) => void) => { throw error; }); p.then((value: string): void => { console.log("Test failed. The promise should not be fulfilled."); -}, (err: Object): void => { +}, (err: Error): void => { if (err !== error) { return; } diff --git a/ets2panda/test/runtime/ets/Type_from_utility_type.ets b/ets2panda/test/runtime/ets/Type_from_utility_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..ac0bb4cbbf27871baa50b4a0e5214c29eef0bebb --- /dev/null +++ b/ets2panda/test/runtime/ets/Type_from_utility_type.ets @@ -0,0 +1,49 @@ + /* + * 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 from the specific language governing permissions and + * limitations under the License. + */ + + class A{ + } + + class B{ + } + + function main(){ + let partialA = Type.from>(); + let partialB = Type.from>(); + let partialC = Type.from>(); + assertTrue(partialA.toString() != partialB.toString()); + assertTrue(partialA.toString() == partialC.toString()); + + let requiredA = Type.from>(); + let requiredB = Type.from>(); + let requiredC = Type.from>(); + assertTrue(requiredA.toString() != requiredB.toString()); + assertTrue(requiredA.toString() == requiredC.toString()); + + let readonlyA = Type.from>(); + let readonlyB = Type.from>(); + let readonlyC = Type.from>(); + assertTrue(readonlyA.toString() != readonlyB.toString()); + assertTrue(readonlyA.toString() == readonlyC.toString()); + + let recordA = Type.from>(); + let recordB = Type.from>(); + assertTrue(recordA.toString() == recordB.toString()); + + let partialarrayA = Type.from>>(); + let partialarrayB = Type.from>>(); + assertTrue(partialarrayA.toString() == partialarrayB.toString()); + + } \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/Typeof.ets b/ets2panda/test/runtime/ets/Typeof.ets index 43a9a21f486ea8714ca484135b6bc626be58b5c7..33baa7817bdbdd77636c038890b7b887fb36485c 100644 --- a/ets2panda/test/runtime/ets/Typeof.ets +++ b/ets2panda/test/runtime/ets/Typeof.ets @@ -48,7 +48,7 @@ function main() { let x05: long let x06: float let x07: double - let x08: bigint + let x08: bigint = 123456789n assertEQ(typeof x00, "boolean") assertEQ(typeof x01, "number") assertEQ(typeof x02, "number") @@ -59,15 +59,15 @@ function main() { assertEQ(typeof x07, "number") assertEQ(typeof x08, "bigint") - let x000: Boolean - let x001: Byte - let x002: Char - let x003: Short - let x004: Int - let x005: Long - let x006: Float - let x007: Double - let x008: BigInt + let x000: Boolean = new Boolean() + let x001: Byte = new Byte() + let x002: Char = new Char() + let x003: Short = new Short() + let x004: Int = new Int() + let x005: Long = new Long() + let x006: Float = new Float() + let x007: Double = new Double() + let x008: BigInt = new BigInt() assertEQ(typeof x000, "boolean") assertEQ(typeof x001, "number") assertEQ(typeof x002, "number") @@ -134,7 +134,7 @@ function main() { assertEQ(typeof o8, "function") let e0 = Color.Red - let e1: Color + let e1: Color = Color.Green assertEQ(typeof e0, "number") assertEQ(typeof e1, "number") diff --git a/ets2panda/test/runtime/ets/UnaryExpression.ets b/ets2panda/test/runtime/ets/UnaryExpression.ets index 7ab431094301575017fa50f381bc6c3f3127b3e2..2b6bf0bc21999d647a04f375a379a7c40114de3c 100644 --- a/ets2panda/test/runtime/ets/UnaryExpression.ets +++ b/ets2panda/test/runtime/ets/UnaryExpression.ets @@ -49,7 +49,7 @@ function main(): void { a = -a; assertEQ(a, -30.0) - assertEQ(a.doubleValue(), -30.0) + assertEQ(a.toDouble(), -30.0) let c = +a; assertEQ(c, -30.0) @@ -64,7 +64,7 @@ function main(): void { a = -a; assertEQ(a, -40) - assertEQ(a.intValue(), -40) + assertEQ(a.toInt(), -40) let c = +a; assertEQ(c, -40) @@ -97,4 +97,24 @@ function main(): void { assertEQ(+c, 60.0) assertEQ(-c, -60.0) } + + { + let a = -(-1); + assertEQ(a, 1); + + let b = -(1); + assertEQ(b, -1); + + let c = - -1; + assertEQ(c, 1); + + let d = +(1); + assertEQ(d, 1); + + let e = +(-1); + assertEQ(e, -1); + + let f = + -1; + assertEQ(f, -1); + } } diff --git a/ets2panda/test/runtime/ets/UncheckedCasts.ets b/ets2panda/test/runtime/ets/UncheckedCasts.ets index 43a3bac4f420215f32f5eb3c437d6099941bbb07..d99fd216c1f34c147f9e4508601f4f617fe0fc58 100644 --- a/ets2panda/test/runtime/ets/UncheckedCasts.ets +++ b/ets2panda/test/runtime/ets/UncheckedCasts.ets @@ -49,7 +49,7 @@ function test_substitution() { assert_ccexc(() => { erase(new Object()); }) assert_ccexc(() => { erase(new C()); }) - assert_ccexc(() => { erase(new B[0]); }) + assert_ccexc(() => { erase>(new B[0]); }) } class Erased { @@ -76,7 +76,7 @@ function test_substitution_memberexpr() { assert_ccexc(() => { new Erased(new Object()).t; }) assert_ccexc(() => { new Erased(new C()).t; }) - assert_ccexc(() => { new Erased(new B[0]).t; }) + assert_ccexc(() => { new Erased>(new B[0]).t; }) } function cast_to_tparam(x: Object | null | undefined) { x as T; } diff --git a/ets2panda/test/runtime/ets/UnionArray.ets b/ets2panda/test/runtime/ets/UnionArray.ets index 507f1cd0c219a3826621c91c725074fae25eff96..23d10ccf8f7ed22a6d4f33ad1d418b0469437e16 100644 --- a/ets2panda/test/runtime/ets/UnionArray.ets +++ b/ets2panda/test/runtime/ets/UnionArray.ets @@ -23,19 +23,19 @@ class Item { } function main() { - let objectArray = []; - let boolArray = [true, false, true]; - let intArray = [1, 2, 99, 100]; - let doubleArray = [1, -2, 1.2, 9.9]; - let stringArray = ["one", "two", "three"]; - let classArray = [new Item(1), new Item(2), new Item(3)]; - let unionArray = [true, 9.99, new Item(9), "success"]; + let objectArray: FixedArray = []; + let boolArray: FixedArray = [true, false, true]; + let intArray: FixedArray = [1, 2, 99, 100]; + let doubleArray: FixedArray = [1, -2, 1.2, 9.9]; + let stringArray: FixedArray = ["one", "two", "three"]; + let classArray: FixedArray = [new Item(1), new Item(2), new Item(3)]; + let unionArray: FixedArray = [true, 9.99, new Item(9), "success"]; - assertTrue(objectArray instanceof Object[]) - assertTrue(boolArray instanceof Boolean[]) - assertTrue(intArray instanceof number[]) - assertTrue(doubleArray instanceof number[]) - assertTrue(stringArray instanceof string[]) - assertTrue(classArray instanceof Item[]) - assertTrue(unionArray instanceof (Boolean|Double|Item|String)[]) + assertTrue(objectArray instanceof FixedArray) + assertTrue(boolArray instanceof FixedArray) + assertTrue(intArray instanceof FixedArray) + assertTrue(doubleArray instanceof FixedArray) + assertTrue(stringArray instanceof FixedArray) + assertTrue(classArray instanceof FixedArray) + assertTrue(unionArray instanceof (FixedArray)) } diff --git a/ets2panda/test/runtime/ets/UpdateExpression.ets b/ets2panda/test/runtime/ets/UpdateExpression.ets index edefa184679f8e26e363ab6b9eb398b81a40139c..7c764d28ced86b510f2bf18cb9a56b7e814caa10 100644 --- a/ets2panda/test/runtime/ets/UpdateExpression.ets +++ b/ets2panda/test/runtime/ets/UpdateExpression.ets @@ -40,30 +40,30 @@ function main(): void { let a: Double = new Double(30.0); let b = ++a; assertEQ(a, 31.0) - assertEQ(a.doubleValue(), 31.0) + assertEQ(a.toDouble(), 31.0) assertEQ(b, 31.0) - assertEQ(b.doubleValue(), 31.0) + assertEQ(b.toDouble(), 31.0) - assertEQ((++a).doubleValue(), 32.0) + assertEQ((++a).toDouble(), 32.0) assertEQ(a, 32.0) - assertEQ(a.doubleValue(), 32.0) + assertEQ(a.toDouble(), 32.0) assertEQ(b, 31.0) - assertEQ(b.doubleValue(), 31.0) + assertEQ(b.toDouble(), 31.0) } { let a: Int = new Int(40); let b = a++; assertEQ(a, 41) - assertEQ(a.intValue(), 41) + assertEQ(a.toInt(), 41) assertEQ(b, 40) - assertEQ(b.intValue(), 40) + assertEQ(b.toInt(), 40) - assertEQ((a++).intValue(), 41) + assertEQ((a++).toInt(), 41) assertEQ(a, 42) - assertEQ(a.intValue(), 42) + assertEQ(a.toInt(), 42) assertEQ(b, 40) - assertEQ(b.intValue(), 40) + assertEQ(b.toInt(), 40) } { @@ -71,9 +71,9 @@ function main(): void { let a: Int = new Int(50); let b = fn(a++); assertEQ(a, 51) - assertEQ(a.intValue(), 51) + assertEQ(a.toInt(), 51) assertEQ(b, 50) - assertEQ(b.intValue(), 50) + assertEQ(b.toInt(), 50) assertEQ(fn(++a), 52) assertEQ(a, 52) diff --git a/ets2panda/test/runtime/ets/accessor_functional_declaration.ets b/ets2panda/test/runtime/ets/accessor_functional_declaration.ets new file mode 100644 index 0000000000000000000000000000000000000000..acee9091004e39af702f239eac147f6eeee48ff7 --- /dev/null +++ b/ets2panda/test/runtime/ets/accessor_functional_declaration.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A{ + a_:()=>void = ()=>{}; + get a(){ + return this.a_; + } + set a(a:()=>void){ + this.a_ = a + } + method(){ + this.a + this.a() + } +} +function main(){ + let a = new A(); + a.method() +} diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForArrayType.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForArrayType.ets index c204e03f460953d76da69ce46b90cf67a5813a3b..6176db3c9ae795c6d3ed4c429fa9fb8a9112181f 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForArrayType.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForArrayType.ets @@ -30,7 +30,7 @@ type C = MyClass // annotations for elementType of array -let array: @Message @Anno FixedArray> -let deepArray: @Message FixedArray>>>> +let array: @Message @Anno Int[][] +let deepArray: @Message Number[][][][][] function main(){} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForClass.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForClass.ets index da4fa57bcab6d639a5fcf4d83818c239d55362e7..578645313217bd0cd6ad6d13e14b9860eef4bcc9 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForClass.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForClass.ets @@ -17,9 +17,9 @@ authorName: string = "Jim" authorAge: number = 35 testBool: boolean = false - reviewers: FixedArray = ["Bob", "Jim", "Tom"] - reviewersAge: FixedArray = [18, -21, 32] - testBools: FixedArray = [false, true, false] + reviewers: string[] = ["Bob", "Jim", "Tom"] + reviewersAge: number[] = [18, -21, 32] + testBools: boolean[] = [false, true, false] } // Annotation use: diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunctionParam.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunctionParam.ets index bc6475b60a9a548c0e9f7407788071bec1d1aa0b..2958f0a5eb7c70bac0d03acf821be5d0e0267fb7 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunctionParam.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForFunctionParam.ets @@ -31,7 +31,7 @@ function foo2(@Anno() x : int, @Anno2({name: "name2"}) y : int) { } function foo3(@Anno({}) x : int, @Anno2({name: "name3"}) y : int) { } -function foo4(@Anno({}) x: int, @Anno2({name: "name3"}) ...y : FixedArray) { +function foo4(@Anno({}) x: int, @Anno2({name: "name3"}) ...y : int[]) { } function foo5(@Anno({}) x: int, @Anno2({name: "name3"}) y ?: int) { } diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForInterface.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForInterface.ets index 59af73c87e9280647ad730f46db691833fafda02..bb196754d07eb526b80acd272d841fa4142ad98b 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForInterface.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForInterface.ets @@ -33,7 +33,7 @@ interface itf0 { x4 : boolean @Anno({name : "2", id : 1}) - x5 : FixedArray + x5 : int[] } @Anno() diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForLambdaExpression.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForLambdaExpression.ets index 507ae4e107fcf7ccdb4865ffe801ee481e7b8abb..4090d529a689333fba690a7671bcff17a0f35f82 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForLambdaExpression.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForLambdaExpression.ets @@ -20,11 +20,11 @@ enum Color{RED, GREEN, BLUE} authorAge: number = 35 testBool: boolean = false favorColor: Color = Color.BLUE - color: FixedArray = [Color.RED, Color.BLUE] - reviewers: FixedArray = ["Bob", "Jim", "Tom"] - reviewersAge: FixedArray = [18, 21, 32] - testBools: FixedArray = [false, true, false] - mutiArray: FixedArray> = [ + color: Color[] = [Color.RED, Color.BLUE] + reviewers: string[] = ["Bob", "Jim", "Tom"] + reviewersAge: number[] = [18, 21, 32] + testBools: boolean[] = [false, true, false] + mutiArray: number[][] = [ [1, 2, 3], [4, -5, 6], [7, 8, -9] diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForReadonlyType.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForReadonlyType.ets index 972313697cb1897aa222643e611847c9884d3058..744f74097851bdd9c047e88edd607519569a054c 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForReadonlyType.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForReadonlyType.ets @@ -28,6 +28,7 @@ } // annotations for readonly Type -let readonlyTuple: readonly @Message @Anno1 @Anno2 [Int, String, Float, FixedArray] +let readonlyArray: readonly @Message @Anno1 Int[][] +let readonlyTuple: readonly @Message @Anno1 @Anno2 [Int, String, Float, Object[]] function main(){} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.ets index 5c5b4c8143ed66fc8c5458efc3352432f11a819f..0a88db7c52548712be6d57714bca1aa14040cb21 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypeAliaDecl.ets @@ -29,7 +29,7 @@ type t1 = int @Anno() -type t2 = FixedArray +type t2 = int[] @Anno({name : "2"}) type t3 = string @@ -44,7 +44,7 @@ type t5 = double // Annotation use: function main(): void { @Anno - type t6 = FixedArray + type t6 = int[] @Anno() type t7 = int @@ -57,5 +57,5 @@ function main(): void { @Anno({name : "2", id : 1}) @Anno2({name : "ab"}) - type t10 = FixedArray + type t10 = string[] } diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypesInArray.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypesInArray.ets index 6550ed9c00c1bca2090a5fe024bb3acb41bcd5cc..ffaad449f473d1028ea29a871ca222744015299e 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypesInArray.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationForTypesInArray.ets @@ -23,7 +23,7 @@ @interface Anno{} // annotations for elementType of array -let array: @Anno FixedArray> -let deepArray: @Anno FixedArray>>>> +let array: @Anno Int[][] +let deepArray: @Anno Number[][][][][] function main(){} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties03.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties03.ets index c0b6898a09cef9ab77a06ed244455776d341e96b..bbde2c19a4d2439dde54b346863008f684a4f059 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties03.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationNoNeedToSetProperties03.ets @@ -18,9 +18,9 @@ authorName: string = "Jim" authorAge: number = 35 testBool: boolean = false - reviewers: FixedArray = ["Bob", "Jim", "Tom"] - reviewersAge: FixedArray = [18, 21, -32] - testBools: FixedArray = [false, true, false] + reviewers: string[] = ["Bob", "Jim", "Tom"] + reviewersAge: number[] = [18, 21, -32] + testBools: boolean[] = [false, true, false] } // Annotation use: diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType03.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType03.ets index cba9e8633c68e444bf7d7992b40a9154e85ffedd..27dfdd6f2dbd2f16c643fe1ce6696ea744d27b23 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType03.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType03.ets @@ -18,9 +18,9 @@ authorName: string = "Jim" authorAge: number = 35 testBool: boolean = false - reviewers: FixedArray = ["Bob", "Jim", "Tom"] - reviewersAge: FixedArray = [18, 21, 32] - testBools: FixedArray = [false, true, false] + reviewers: string[] = ["Bob", "Jim", "Tom"] + reviewersAge: number[] = [18, 21, 32] + testBools: boolean[] = [false, true, false] } // Annotation use: diff --git a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType04.ets b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType04.ets index 1e04af9c6533aebeff0dab5496892a54b8ea4dd0..441aa0709f1ab1a94c32aeacef371b8a18121cb5 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType04.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/AnnotationsFieldType04.ets @@ -18,9 +18,9 @@ authorName: string = "Jim" authorAge: number = 35 testBool: boolean = false - reviewers: FixedArray = ["Bob", "Jim", "Tom"] - reviewersAge: FixedArray = [18, 21, 32] - testBools: FixedArray = [false, true, false] + reviewers: string[] = ["Bob", "Jim", "Tom"] + reviewersAge: number[] = [18, 21, 32] + testBools: boolean[] = [false, true, false] } @interface MyAnno { diff --git a/ets2panda/test/runtime/ets/annotation_tests/EmitAnnotationToBytecode.ets b/ets2panda/test/runtime/ets/annotation_tests/EmitAnnotationToBytecode.ets index 8b529695b23dc10a7e3cdcf56fc66dbfa968b2e9..35c24bc37e207a775a6a64b0cc4251834ae41682 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/EmitAnnotationToBytecode.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/EmitAnnotationToBytecode.ets @@ -20,11 +20,11 @@ enum Color{RED, BLUE, GREEN} authorAge: number = 35 testBool: boolean = false favorColor: Color = Color.BLUE - color: FixedArray = [Color.RED, Color.BLUE] - reviewers: FixedArray = ["Bob", "Jim", "Tom"] - reviewersAge: FixedArray = [18, 21, 32] - testBools: FixedArray = [false, true, false] - mutiArray: FixedArray> = [ + color: Color[] = [Color.RED, Color.BLUE] + reviewers: string[] = ["Bob", "Jim", "Tom"] + reviewersAge: number[] = [18, 21, 32] + testBools: boolean[] = [false, true, false] + mutiArray: number[][] = [ [1, 2, 3], [4, -5, 6], [7, 8, -9] diff --git a/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds05.ets b/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds05.ets index d825b3f4e8a83945e471cf85c31eb693daabab88..1471a0cb184855c2de57f25a63090f3f63628ab7 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds05.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds05.ets @@ -14,7 +14,7 @@ */ @interface MyValue { - size: FixedArray + size: int[] } @MyValue([1,2,-3]) class A{ diff --git a/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds06.ets b/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds06.ets index dc00caf30f018a08ddfab02d8f8cc3f858aa823e..0ebe8e183b96ee33493069151504974d85592211 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds06.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds06.ets @@ -14,7 +14,7 @@ */ @interface MyValue { - size: FixedArray + size: string[] } @MyValue(["1","2","3"]) class A{ diff --git a/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds07.ets b/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds07.ets index 82050727942e985044f24676f927f030ed8a4b07..6c844f4aa113285e3169f1a4efb4a239770e6845 100644 --- a/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds07.ets +++ b/ets2panda/test/runtime/ets/annotation_tests/annotationUsageSingleFileds07.ets @@ -15,7 +15,7 @@ enum Color {Blue, Red, Green} @interface MyValue { - size: FixedArray + size: Color[] } @MyValue([Color.Blue,]) class A{ diff --git a/ets2panda/test/runtime/ets/array-new-catched.ets b/ets2panda/test/runtime/ets/array-new-catched.ets index b4190d4d26ba49305750e260e0a440622dd5e091..ffd045de333ac865156a0af3c98a842609065301 100644 --- a/ets2panda/test/runtime/ets/array-new-catched.ets +++ b/ets2panda/test/runtime/ets/array-new-catched.ets @@ -15,13 +15,14 @@ function baz(): number { return 5.1 -} -function main(): void { + } + function main(): void { let catched = false; try { - let a = new int[baz()] + let a:FixedArray = new int[baz()] } catch (e: TypeError) { catched = true } assertTrue(catched) -} + } + \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/array-object.ets b/ets2panda/test/runtime/ets/array-object.ets index c8f34ec660f50c564410e4b722c78efce8559b72..f0555dda3625c6ec9b3f46759c461eea4a87ea39 100644 --- a/ets2panda/test/runtime/ets/array-object.ets +++ b/ets2panda/test/runtime/ets/array-object.ets @@ -14,33 +14,33 @@ */ function main(): void { - let arr1: Int[] = [1,2,3,4,5]; - let arr2: int[] = [1,2,3,4,5]; - let object_array: Object[] = arr1 as Object[]; - let object: Object = arr1 as Object; + let arr1: FixedArray = [1,2,3,4,5]; + let arr2: FixedArray = [1,2,3,4,5]; + let object_array: FixedArray = arr1 as FixedArray; + let obj: Object = arr1 as Object; // TypeError: Cannot access property of non-object or non-enum type // arr1.toString(); // arr2.toString(); // object_array.toString(); - object.toString(); + obj.toString(); // TypeError: Cannot access property of non-object or non-enum type // arr1.$_hashCode(); // arr2.$_hashCode(); // object_array.$_hashCode(); - object.$_hashCode(); + obj.$_hashCode(); assertEQ(arr1, arr1) assertEQ(arr1, object_array) - assertEQ(arr1, object) + assertEQ(arr1, obj) assertNE(arr1, arr2) // Cannot cast type 'int[]' to 'Object[]' // let object_array2: Object[] = arr2 as Object[]; -// assertEQ(object.equals(arr2 as Object), false) +// assertEQ(obj.equals(arr2 as Object), false) assertEQ(arr2, arr2) assertNE(arr2, new int[5]) diff --git a/ets2panda/test/runtime/ets/array_inf.ets b/ets2panda/test/runtime/ets/array_inf.ets index b8cc54d319a2aeab512892c01a5a32316df7ba50..bfbc5eb3795459fe1c67d33c8eaacccd6e625986 100644 --- a/ets2panda/test/runtime/ets/array_inf.ets +++ b/ets2panda/test/runtime/ets/array_inf.ets @@ -14,29 +14,30 @@ */ class A { - foo(p: Object[]): int { + foo(p: FixedArray): int { let s = 0 for (let v of p) { s += v instanceof A ? 1 : 0 } return s } - bar(p: A[]): int { + bar(p: FixedArray): int { let s = 0 for (let v of p) { s += v instanceof A ? 1 : 0 } return s } -} - - -class B extends A{} - -function main() { + } + + + class B extends A{} + + function main() { assertEQ(new A().foo([new Object(), new Long(), new Int()]), 0) assertEQ(new A().foo([new A(), new A(), new Object()]), 2) assertEQ(new A().foo(["aaa", new A(), new Object()]), 1) assertEQ(new A().foo([1, "hello", new A()]), 1) assertEQ(new A().bar([new B(), new B(), new A()]), 3) -} + } + \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/array_test1.ets b/ets2panda/test/runtime/ets/array_test1.ets new file mode 100644 index 0000000000000000000000000000000000000000..c1607466f0296dd0c4cb273c5e7395f39b385eff --- /dev/null +++ b/ets2panda/test/runtime/ets/array_test1.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. + */ + +function main() { + let a : Array = [1,2] + a[0] = 1; + a[1] = 2; + assertEQ(a.length, 2); + assertEQ(a.pop(), 2); + assertEQ(a.length, 1) + + let c : Array>> = [[[1,2,3],[4,5,6]], [[7,8],[9,10]]] + assertEQ(c[1][1][1], 10) + assertEQ(c[0][0][0], 1) + c[1][1][1] = 100 + c[0][0][0] = 5 + assertEQ(c[1][1][1], 100) + assertEQ(c[0][0][0], 5) + assertEQ(c[0][1][0], 4) + assertEQ(c[0][1][1], 5) + assertEQ(c[0][1][2], 6) + assertEQ(c[1][1][0], 9) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/array_test2.ets b/ets2panda/test/runtime/ets/array_test2.ets new file mode 100644 index 0000000000000000000000000000000000000000..f62be77d591a9fb692f41d5437e3bc9f82eb9ec2 --- /dev/null +++ b/ets2panda/test/runtime/ets/array_test2.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. + */ + +function main() { + let a : Array = new int[2] + a[0] = 1; + a[1] = 2; + assertEQ(a.length, 2); + assertEQ(a.pop(), 2); + assertEQ(a.length, 1) + + let c : Array>> = new int[2][2][2] + c[1][1][1] = 10 + c[0][0][0] = 5 + assertEQ(c[1][1][1], 10) + assertEQ(c[0][0][0], 5) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/array_test3.ets b/ets2panda/test/runtime/ets/array_test3.ets new file mode 100644 index 0000000000000000000000000000000000000000..a9dece808953c590ac3ca53862664ee889c01dc2 --- /dev/null +++ b/ets2panda/test/runtime/ets/array_test3.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. + */ + +let a : Array = [1,2,3] +function main() { + assertEQ(a.length, 3); + assertEQ(a[1], 2) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/array_type_rest_param01.ets b/ets2panda/test/runtime/ets/array_type_rest_param01.ets new file mode 100644 index 0000000000000000000000000000000000000000..9e9e9a01009c8359c9754ad44945b565cc9b51d0 --- /dev/null +++ b/ets2panda/test/runtime/ets/array_type_rest_param01.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. + */ + +function foo(a:string, ...args:Array){ + assertEQ(a, "hello") + let i = 1; + for(let e of args) { + assertEQ(i, e) + i++ + } +} + +function main() : void { + foo("hello",1,2,3,4); +} diff --git a/ets2panda/test/runtime/ets/array_type_rest_param02.ets b/ets2panda/test/runtime/ets/array_type_rest_param02.ets new file mode 100644 index 0000000000000000000000000000000000000000..53a53fdb5ba1e5a36d21132c118859047aaab6fb --- /dev/null +++ b/ets2panda/test/runtime/ets/array_type_rest_param02.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. + */ + +function foo(...args:Array):number{ + let sum = 0; + for(let e of args) { + sum+=e + } + return sum +} + +function main() : void { + assertEQ(foo(1,2,3,4),10) +} diff --git a/ets2panda/test/runtime/ets/array_type_rest_param03.ets b/ets2panda/test/runtime/ets/array_type_rest_param03.ets new file mode 100644 index 0000000000000000000000000000000000000000..4c3ad7194c51d7fd9309b561afa363392fa2e67c --- /dev/null +++ b/ets2panda/test/runtime/ets/array_type_rest_param03.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. + */ + +class A{ + name:string = "" + age:int + + constructor(name:string, age:int){ + this.name = name + this.age = age + } +} + +function foo(...args:Array):int{ + let sum = 0; + for(let a of args) { + sum+=a.age + } + return sum +} + +function main() : void { + let a = new A("a" ,1) + let b = new A("b" ,2) + let c = new A("a" ,3) + let d = new A("b" ,4) + assertEQ(foo(a,b,c,d),10) +} diff --git a/ets2panda/test/runtime/ets/array_type_rest_param04.ets b/ets2panda/test/runtime/ets/array_type_rest_param04.ets new file mode 100644 index 0000000000000000000000000000000000000000..6b691678f7dbbbeea82bb41122b3e9d45b1744ec --- /dev/null +++ b/ets2panda/test/runtime/ets/array_type_rest_param04.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. + */ + +function foo(...args:Array){ + let a = 1; + for(let e of args){ + assertEQ(a++, e); + } +} + +function main(){ + foo(1,2,3,4) +} + diff --git a/ets2panda/test/runtime/ets/array_type_rest_param05.ets b/ets2panda/test/runtime/ets/array_type_rest_param05.ets new file mode 100644 index 0000000000000000000000000000000000000000..6c38dc2e98c367a1d7229bdde273e47b5cebd734 --- /dev/null +++ b/ets2panda/test/runtime/ets/array_type_rest_param05.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. + */ + +function foo(...args:Array){ + let s:StringBuilder = new StringBuilder("a") + for(let e of args){ + assertEQ(s.toString(), e); + s.append("a") + } +} + +function main(){ + foo("a","aa","aaa","aaaa") +} + diff --git a/ets2panda/test/runtime/ets/async_function_return_type.ets b/ets2panda/test/runtime/ets/async_function_return_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..7e596a0f9ec408748f4b45c8254945189abca1a6 --- /dev/null +++ b/ets2panda/test/runtime/ets/async_function_return_type.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Person{ + name:string; + fetchData?:()=>Promise; + + constructor(name:string){ + this.name = name; + } +} + +function main(){ + const bob = new Person("Bob"); + bob.fetchData = async () => "Data fetched"; +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/await_promise_union_type.ets b/ets2panda/test/runtime/ets/await_promise_union_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4529432ca8b9210da1821429e62cb41321ffb4e --- /dev/null +++ b/ets2panda/test/runtime/ets/await_promise_union_type.ets @@ -0,0 +1,33 @@ +/* + * 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 Person{ + name:string; + fetchData?:()=>Promise; + constructor(name:string){ + this.name = name; + } +} + +async function foo():Promise{ +const bob = new Person("Bob"); +const resultPromise = bob.fetchData?.()??Promise.resolve(undefined); +const result = await resultPromise; +assertEQ(result,undefined); +} + +function main():void{ + foo(); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/big_switch.ets b/ets2panda/test/runtime/ets/big_switch.ets new file mode 100644 index 0000000000000000000000000000000000000000..af9b8b2c7563ee99123eba60ffa46458e837e190 --- /dev/null +++ b/ets2panda/test/runtime/ets/big_switch.ets @@ -0,0 +1,1224 @@ +/* + * 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 main() { + let res = false; + switch (0) { + case 0: + switch (1) { + case 1: + res = true + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + case 7: + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + break; + case 13: + break; + case 14: + break; + case 15: + break; + case 16: + break; + case 17: + break; + case 18: + break; + case 19: + break; + case 20: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 21: + break; + case 22: + break; + case 23: + break; + case 24: + break; + case 25: + break; + case 26: + break; + case 27: + break; + case 28: + break; + case 29: + break; + case 30: + break; + case 31: + break; + case 32: + break; + case 33: + break; + case 34: + break; + case 35: + break; + case 36: + break; + case 37: + break; + case 38: + break; + case 39: + break; + case 40: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 41: + break; + case 42: + break; + case 43: + break; + case 44: + break; + case 45: + break; + case 46: + break; + case 47: + break; + case 48: + break; + case 49: + break; + case 50: + break; + case 51: + break; + case 52: + break; + case 53: + break; + case 54: + break; + case 55: + break; + case 56: + break; + case 57: + break; + case 58: + break; + case 59: + break; + case 60: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 61: + break; + case 62: + break; + case 63: + break; + case 64: + break; + case 65: + break; + case 66: + break; + case 67: + break; + case 68: + break; + case 69: + break; + case 70: + break; + case 71: + break; + case 72: + break; + case 73: + break; + case 74: + break; + case 75: + break; + case 76: + break; + case 77: + break; + case 78: + break; + case 79: + break; + case 80: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 81: + break; + case 82: + break; + case 83: + break; + case 84: + break; + case 85: + break; + case 86: + break; + case 87: + break; + case 88: + break; + case 89: + break; + case 90: + break; + case 91: + break; + case 92: + break; + case 93: + break; + case 94: + break; + case 95: + break; + case 96: + break; + case 97: + break; + case 98: + break; + case 99: + break; + case 100: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 101: + break; + case 102: + break; + case 103: + break; + case 104: + break; + case 105: + break; + case 106: + break; + case 107: + break; + case 108: + break; + case 109: + break; + case 110: + break; + case 111: + break; + case 112: + break; + case 113: + break; + case 114: + break; + case 115: + break; + case 116: + break; + case 117: + break; + case 118: + break; + case 119: + break; + case 120: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 121: + break; + case 122: + break; + case 123: + break; + case 124: + break; + case 125: + break; + case 126: + break; + case 127: + break; + case 128: + break; + case 129: + break; + case 130: + break; + case 131: + break; + case 132: + break; + case 133: + break; + case 134: + break; + case 135: + break; + case 136: + break; + case 137: + break; + case 138: + break; + case 139: + break; + case 140: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 141: + break; + case 142: + break; + case 143: + break; + case 144: + break; + case 145: + break; + case 146: + break; + case 147: + break; + case 148: + break; + case 149: + break; + case 150: + break; + case 151: + break; + case 152: + break; + case 153: + break; + case 154: + break; + case 155: + break; + case 156: + break; + case 157: + break; + case 158: + break; + case 159: + break; + case 160: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 161: + break; + case 162: + break; + case 163: + break; + case 164: + break; + case 165: + break; + case 166: + break; + case 167: + break; + case 168: + break; + case 169: + break; + case 170: + break; + case 171: + break; + case 172: + break; + case 173: + break; + case 174: + break; + case 175: + break; + case 176: + break; + case 177: + break; + case 178: + break; + case 179: + break; + case 180: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 181: + break; + case 182: + break; + case 183: + break; + case 184: + break; + case 185: + break; + case 186: + break; + case 187: + break; + case 188: + break; + case 189: + break; + case 190: + break; + case 191: + break; + case 192: + break; + case 193: + break; + case 194: + break; + case 195: + break; + case 196: + break; + case 197: + break; + case 198: + break; + case 199: + break; + case 200: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 201: + break; + case 202: + break; + case 203: + break; + case 204: + break; + case 205: + break; + case 206: + break; + case 207: + break; + case 208: + break; + case 209: + break; + case 210: + break; + case 211: + break; + case 212: + break; + case 213: + break; + case 214: + break; + case 215: + break; + case 216: + break; + case 217: + break; + case 218: + break; + case 219: + break; + case 220: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 221: + break; + case 222: + break; + case 223: + break; + case 224: + break; + case 225: + break; + case 226: + break; + case 227: + break; + case 228: + break; + case 229: + break; + case 230: + break; + case 231: + break; + case 232: + break; + case 233: + break; + case 234: + break; + case 235: + break; + case 236: + break; + case 237: + break; + case 238: + break; + case 239: + break; + case 240: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 241: + break; + case 242: + break; + case 243: + break; + case 244: + break; + case 245: + break; + case 246: + break; + case 247: + break; + case 248: + break; + case 249: + break; + case 250: + break; + case 251: + break; + case 252: + break; + case 253: + break; + case 254: + break; + case 255: + break; + case 256: + break; + case 257: + break; + case 258: + break; + case 259: + break; + case 260: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 261: + break; + case 262: + break; + case 263: + break; + case 264: + break; + case 265: + break; + case 266: + break; + case 267: + break; + case 268: + break; + case 269: + break; + case 270: + break; + case 271: + break; + case 272: + break; + case 273: + break; + case 274: + break; + case 275: + break; + case 276: + break; + case 277: + break; + case 278: + break; + case 279: + break; + case 280: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 281: + break; + case 282: + break; + case 283: + break; + case 284: + break; + case 285: + break; + case 286: + break; + case 287: + break; + case 288: + break; + case 289: + break; + case 290: + break; + case 291: + break; + case 292: + break; + case 293: + break; + case 294: + break; + case 295: + break; + case 296: + break; + case 297: + break; + case 298: + break; + case 299: + break; + case 300: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 301: + break; + case 302: + break; + case 303: + break; + case 304: + break; + case 305: + break; + case 306: + break; + case 307: + break; + case 308: + break; + case 309: + break; + case 310: + break; + case 311: + break; + case 312: + break; + case 313: + break; + case 314: + break; + case 315: + break; + case 316: + break; + case 317: + break; + case 318: + break; + case 319: + break; + case 320: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 321: + break; + case 322: + break; + case 323: + break; + case 324: + break; + case 325: + break; + case 326: + break; + case 327: + break; + case 328: + break; + case 329: + break; + case 330: + break; + case 331: + break; + case 332: + break; + case 333: + break; + case 334: + break; + case 335: + break; + case 336: + break; + case 337: + break; + case 338: + break; + case 339: + break; + case 340: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 341: + break; + case 342: + break; + case 343: + break; + case 344: + break; + case 345: + break; + case 346: + break; + case 347: + break; + case 348: + break; + case 349: + break; + case 350: + break; + case 351: + break; + case 352: + break; + case 353: + break; + case 354: + break; + case 355: + break; + case 356: + break; + case 357: + break; + case 358: + break; + case 359: + break; + case 360: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 361: + break; + case 362: + break; + case 363: + break; + case 364: + break; + case 365: + break; + case 366: + break; + case 367: + break; + case 368: + break; + case 369: + break; + case 370: + break; + case 371: + break; + case 372: + break; + case 373: + break; + case 374: + break; + case 375: + break; + case 376: + break; + case 377: + break; + case 378: + break; + case 379: + break; + case 380: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 381: + break; + case 382: + break; + case 383: + break; + case 384: + break; + case 385: + break; + case 386: + break; + case 387: + break; + case 388: + break; + case 389: + break; + case 390: + break; + case 391: + break; + case 392: + break; + case 393: + break; + case 394: + break; + case 395: + break; + case 396: + break; + case 397: + break; + case 398: + break; + case 399: + break; + case 400: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 401: + break; + case 402: + break; + case 403: + break; + case 404: + break; + case 405: + break; + case 406: + break; + case 407: + break; + case 408: + break; + case 409: + break; + case 410: + break; + case 411: + break; + case 412: + break; + case 413: + break; + case 414: + break; + case 415: + break; + case 416: + break; + case 417: + break; + case 418: + break; + case 419: + break; + case 420: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 421: + break; + case 422: + break; + case 423: + break; + case 424: + break; + case 425: + break; + case 426: + break; + case 427: + break; + case 428: + break; + case 429: + break; + case 430: + break; + case 431: + break; + case 432: + break; + case 433: + break; + case 434: + break; + case 435: + break; + case 436: + break; + case 437: + break; + case 438: + break; + case 439: + break; + case 440: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 441: + break; + case 442: + break; + case 443: + break; + case 444: + break; + case 445: + break; + case 446: + break; + case 447: + break; + case 448: + break; + case 449: + break; + case 450: + break; + case 451: + break; + case 452: + break; + case 453: + break; + case 454: + break; + case 455: + break; + case 456: + break; + case 457: + break; + case 458: + break; + case 459: + break; + case 460: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 461: + break; + case 462: + break; + case 463: + break; + case 464: + break; + case 465: + break; + case 466: + break; + case 467: + break; + case 468: + break; + case 469: + break; + case 470: + break; + case 471: + break; + case 472: + break; + case 473: + break; + case 474: + break; + case 475: + break; + case 476: + break; + case 477: + break; + case 478: + break; + case 479: + break; + case 480: + switch (1) { + case 1: + break; + case 2: + break; + default: + throw Error('Bad overload'); + } + break; + case 481: + break; + case 482: + break; + case 483: + break; + case 484: + break; + case 485: + break; + case 486: + break; + case 487: + break; + case 488: + break; + case 489: + break; + case 490: + break; + case 491: + break; + case 492: + break; + case 493: + break; + case 494: + break; + case 495: + break; + case 496: + break; + case 497: + break; + case 498: + break; + case 499: + break; + default: + break; + } + assertTrue(res) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/boxingConversions3.ets b/ets2panda/test/runtime/ets/boxingConversions3.ets index 49c48b0ee196ce18a16aa3783ebebad0128306b0..b5a1ab4277ab11eaad0ab4c0cfb0f6da82956d44 100644 --- a/ets2panda/test/runtime/ets/boxingConversions3.ets +++ b/ets2panda/test/runtime/ets/boxingConversions3.ets @@ -14,8 +14,8 @@ */ function main() { - let b: byte = 1.0 - let s: Short = b + let b: byte = 1 + let s: Short = b let i: Int = b let l: Long = b let f: Float = b diff --git a/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets b/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets index 3f0f183b1f7217c37fd7c1ab42ecf0c0fae5f37d..0c0e95fb754b1c53d29f1507c67dc489a4ebf1a8 100644 --- a/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets +++ b/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets @@ -17,10 +17,6 @@ function intParam(a: int): int { return 0; } -function intParam(a: Int): int { - return 1; -} - function objParam(a: Object): int { return 2; } @@ -36,14 +32,10 @@ function retInt(a: Int): int { function main(): void { let a: int = 1; let b: Int = 2; - let c: int = intParam(a); - assertEQ(c, 0) - let d: int = intParam(b); - assertEQ(d, 1) - let e: Int = intParam(a); + let c: Int = intParam(a); assertEQ(c, 0) let f: Int = intParam(b); - assertEQ(d, 1) + assertEQ(f, 0) let g: int = objParam(a); assertEQ(g, 2) let h: int = objParam(b); diff --git a/ets2panda/test/runtime/ets/boxing_1.ets b/ets2panda/test/runtime/ets/boxing_1.ets index 4dd0b40fc810c6ffe563eac649963c4b838412f3..4a8f4492e8651222dede5555fef0c5c68411ed38 100644 --- a/ets2panda/test/runtime/ets/boxing_1.ets +++ b/ets2panda/test/runtime/ets/boxing_1.ets @@ -26,13 +26,13 @@ class A { } function main(): void { - assertEQ(global_Int_.intValue(), 2_000_000) - assertEQ((global_Object_Int_ as Int).intValue(), 2_000_001) - assertEQ(const_global_Int_.intValue(), 2_000_002) - assertEQ((const_global_Object_Int_ as Int).intValue(), 2_000_003) + assertEQ(global_Int_.toInt(), 2_000_000) + assertEQ((global_Object_Int_ as Int).toInt(), 2_000_001) + assertEQ(const_global_Int_.toInt(), 2_000_002) + assertEQ((const_global_Object_Int_ as Int).toInt(), 2_000_003) - assertEQ(A.Int_.intValue(), 2_000_004) - assertEQ((A.Object_Int_ as Int).intValue(), 2_000_005) - assertEQ(A.readonly_Int_.intValue(), 2_000_006) - assertEQ((A.readonly_Object_Int_ as Int).intValue(), 2_000_007) + assertEQ(A.Int_.toInt(), 2_000_004) + assertEQ((A.Object_Int_ as Int).toInt(), 2_000_005) + assertEQ(A.readonly_Int_.toInt(), 2_000_006) + assertEQ((A.readonly_Object_Int_ as Int).toInt(), 2_000_007) } diff --git a/ets2panda/test/runtime/ets/castSequence.ets b/ets2panda/test/runtime/ets/castSequence.ets index 23d7d88b2d8e31d16a0097c0f1105c3ae3cdfd51..bdc27764fa581056a273f4c2a22d4149acbe4311 100644 --- a/ets2panda/test/runtime/ets/castSequence.ets +++ b/ets2panda/test/runtime/ets/castSequence.ets @@ -15,12 +15,12 @@ function main(): void { let a_int : int = 2147; - let b_Num : Number = a_int as Number; + let b_Num : Number = Int.toDouble(a_int); assertTrue(b_Num instanceof Number && b_Num.unboxed() == 2147.0) let a_Short : Short = 215; - let b_double : double = a_Short as double; + let b_double : double = Short.toDouble(a_Short); assertTrue(a_Short instanceof Short) assertEQ(b_double, 215.0) diff --git a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_1.ets b/ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts similarity index 66% rename from ets2panda/test/runtime/ets/most_specific_method_with_rest_param_1.ets rename to ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts index 0612bb60a8203488ce01d95080da86c2da8abc59..ae46d04e2fc1660322c106ccba6b2a7c85f09a36 100644 --- a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_1.ets +++ b/ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts @@ -13,17 +13,23 @@ * limitations under the License. */ -class C { - public met(...p: number[]): string { - return "nR" - } - public met(...p: Number[]): string { - return "NR" - } +class A {} + +function foo(a: Float): Float { + return a; } -function main() { - let c: C = new C() - assertEQ(c.met(0.0), "nR") - assertEQ(c.met(new Number()), "NR") +function main(): int { + let c: A | Double = new Double(10.0); + let b: Int = new Int(9 as int); + c = b + if (c != 9) { + return 1; + } + let k: Int = new Int(10 as int); + let v: Float = foo(k) + if (v.isNaN()) { + return 1; + } + return 0; } diff --git a/ets2panda/test/runtime/ets/charToStringCast.ets b/ets2panda/test/runtime/ets/charToStringCast.ets index 0d4ed953f3633279c5b9522616397b5f4031a430..1226d3c2843bbe2d1777f904cbc807463b8036c1 100644 --- a/ets2panda/test/runtime/ets/charToStringCast.ets +++ b/ets2panda/test/runtime/ets/charToStringCast.ets @@ -14,7 +14,6 @@ */ function main(): void { - let s:string = c'X' as string; - + let s:string = new Char(c'X').toString(); assertEQ(s, "X") -} \ No newline at end of file +} diff --git a/ets2panda/test/runtime/ets/class-abstract-inheritance.ets b/ets2panda/test/runtime/ets/class-abstract-inheritance.ets index 9d79472b57db51e8304572fa8e48e4cf065698d8..127e926296de71d7495dd3cc952aa892ab363f24 100644 --- a/ets2panda/test/runtime/ets/class-abstract-inheritance.ets +++ b/ets2panda/test/runtime/ets/class-abstract-inheritance.ets @@ -15,15 +15,23 @@ abstract class A { str: string = "A" + + getA():string { + return this.str; + } } abstract class B extends A { + getB():string { + return this.str; + } + public get_str(): string { return this.str; } public get_super_str(): string { - return super.str; + return super.getA(); } } @@ -37,7 +45,7 @@ abstract class C extends B { } public override get_super_str(): string { - return super.str; + return super.getB(); } } diff --git a/ets2panda/test/runtime/ets/class-fields-same-name.ets b/ets2panda/test/runtime/ets/class-fields-same-name.ets index 82ae8aa38c181fcb5940a2ae2af7bf5875aedd6f..c556135949d9df2ba741884e4d13dab7bc694cea 100644 --- a/ets2panda/test/runtime/ets/class-fields-same-name.ets +++ b/ets2panda/test/runtime/ets/class-fields-same-name.ets @@ -23,9 +23,29 @@ class D extends C { public foo: int = 40 } +class E { + public static foo: int = 50 +} + +class F extends E { + public foo: int = 60 +} + +class G { + public foo: int = 70 +} + +class H extends G { + public static foo: int = 80 +} + function main(): void { assertEQ(C.foo, 10) assertEQ(new C().foo, 20) assertEQ(D.foo, 30) assertEQ(new D().foo, 40) + assertEQ(F.foo, 50) + assertEQ(new F().foo, 60) + assertEQ(H.foo, 80) + assertEQ(new H().foo, 70) } diff --git a/ets2panda/test/runtime/ets/class_implements_interface_export.ets b/ets2panda/test/runtime/ets/class_implements_interface_export.ets new file mode 100644 index 0000000000000000000000000000000000000000..585718a5fa356c33eaf2f6c05836597e798ed9cc --- /dev/null +++ b/ets2panda/test/runtime/ets/class_implements_interface_export.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. + */ + +export class A{} + +interface I { + a: boolean +} + +class B implements I { + a = false +} + diff --git a/ets2panda/test/runtime/ets/class_implements_interface_import.ets b/ets2panda/test/runtime/ets/class_implements_interface_import.ets new file mode 100644 index 0000000000000000000000000000000000000000..e779066f3cace24871b5147abf0176e5623c4d1a --- /dev/null +++ b/ets2panda/test/runtime/ets/class_implements_interface_import.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. + */ + +import { A } from "./class_implements_interface_export" \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/compoundAssignmentExpression.ets b/ets2panda/test/runtime/ets/compoundAssignmentExpression.ets index 7a6c59251f347002b2eb09559b87700fded2ca3c..2688584ce51617915ef2bec90c0bc0bd583a6281 100644 --- a/ets2panda/test/runtime/ets/compoundAssignmentExpression.ets +++ b/ets2panda/test/runtime/ets/compoundAssignmentExpression.ets @@ -14,13 +14,13 @@ */ function main() { - let s: string[] = ["s1", "s2"]; - let res: int[] = [0, 0, 0, 0, 0]; - res[0] -= s[1 % 2].length as int; + let s: FixedArray = ["s1", "s2"]; + let res: FixedArray = [0, 0, 0, 0, 0]; + res[0] -= Double.toInt(s[1 % 2].length); res[(res.length - 4) as Int] += 1; - res[2 % (res.length as int)] &= s[1].length; - res[3 % (res.length as int)] |= s[1 % 2].length as int; - res[2 % (res.length as int) + s.length] *= s[1 % 2].length as int; + res[2 % (res.length as int)] &= Double.toInt(s[1].length); + res[3 % (res.length as int)] |= Double.toInt(s[1 % 2].length); + res[2 % (res.length as int) + s.length] *= Double.toInt(s[1 % 2].length); assertEQ(res[0], -2); assertEQ(res[1], 1); diff --git a/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets b/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets index 5b40ffe6e08fc44320e24bb463101e2274a90682..e316567081ad93c4a8f28ddc33ac55fddfbc3c92 100644 --- a/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets +++ b/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets @@ -45,6 +45,10 @@ function foo(p: F): int { return 6; } +function getTrue(): boolean { + return true +} + // #15276 foo(Object|null) and foo(Object) overloads function foo7(p: Object | null): int { return 7; @@ -59,30 +63,30 @@ function main(): void { function sameTypeLUB(): void { let a : A = new A(); let b : A = new A(); - let c = true ? a : b; + let c = getTrue() ? a : b; assertEQ(foo(c), 2) } function objectLUB(): void { let a : A = new A(); let b : Int = 2; - let c = true ? a : b; + let c = getTrue() ? a : b; assertEQ(foo(c), 1) let arr : Int[] | null = null; - let d = true ? a : arr; + let d = getTrue() ? a : arr; assertEQ(foo7(d), 7) } function forkSubtypeLUB(): void { let a : F = new F(); let b : D = new D(); - let c = true ? a : b; + let c = getTrue() ? a : b; assertEQ(foo(c), 2) let d : A = new A(); - let e = true ? a : b; + let e = getTrue() ? a : b; assertEQ(foo(e), 2) let f : B = new B(); - let g = true ? a : f; + let g = getTrue() ? a : f; assertEQ(foo(g), 3) } diff --git a/ets2panda/test/runtime/ets/const_variable_in_switch_statement/code_point_at.ets b/ets2panda/test/runtime/ets/const_variable_in_switch_statement/code_point_at.ets new file mode 100644 index 0000000000000000000000000000000000000000..56021ab8dbead42c9df4e011cbfd5c6f75cfcf4d --- /dev/null +++ b/ets2panda/test/runtime/ets/const_variable_in_switch_statement/code_point_at.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. + */ + +const a = 'X'.codePointAt(0) as int +assertEQ(a, 88); +const b = 'x'.codePointAt(0) as int +assertEQ(b, 120); +let c = 88 +let d = 0 +switch (c) { + case a: + d = a; + break; + case b: + d = b; + break; + default: + break; +} + +assertEQ(d, a); +assertNE(d, b); \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/const_variable_in_switch_statement/selection_expression.ets b/ets2panda/test/runtime/ets/const_variable_in_switch_statement/selection_expression.ets new file mode 100644 index 0000000000000000000000000000000000000000..93682d2b2de4b6611587671c4e5d59b036077750 --- /dev/null +++ b/ets2panda/test/runtime/ets/const_variable_in_switch_statement/selection_expression.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 d = 1 +const a = (d == 1) ? 2 : 3; +assertEQ(a, 2); +const b = (d == 0) ? 4 : 5; +assertEQ(b, 5); +let c = 5 +let e = 0 +switch (c) { + case a: + e = a; + break; + case b: + e = b; + break; + default: + break; +} + +assertNE(e, a); +assertEQ(e, b); \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/declareTypeAlias_generic.ets b/ets2panda/test/runtime/ets/declareTypeAlias_generic.ets new file mode 100644 index 0000000000000000000000000000000000000000..02d839bc3bdc50293fb78b7fa24ed816342df41e --- /dev/null +++ b/ets2panda/test/runtime/ets/declareTypeAlias_generic.ets @@ -0,0 +1,84 @@ +/* + * 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. + */ + +// Union +export declare type type_union = T | boolean; + + +// Array +export declare type type_array_1 = Array; +declare type type_array_2 = T[]; + + +// Array + Union +export declare type type_union_array_1 = Array | Array +declare type type_union_array_2 = Array + + +// Array + Type Alias +export declare type type_array_alias_1 = Array> +declare type type_array_alias_2 = Array> | type_union +declare type type_array_alias_3 = Array> | type_array_2 + + +// Tuple +declare type type_tuple_1 = [T, U, R] +declare type type_tuple_2 = [T, Array, R] +declare type type_tuple_3 = [T, [U, R], P] +declare type type_tuple_4 = [T, U[], R] + +// Tuple + Union +declare type type_tuple_union_1 = [string, T | null, number] +declare type type_tuple_union_2 = [string, Array | boolean, number] +declare type type_tuple_union_3 = [string, T, number] | Array | [string, T, number] +declare type type_tuple_union_4 = [string, T, number] | (T | undefined)[] + +// Tuple + Type Alias +declare type type_tuple_alias_1 = [T, U | null, type_union_array_1] +declare type type_tuple_alias_2 = [string, Array | boolean, type_union_array_1] +declare type type_tuple_alias_3 = [string, U, R] | Array | [string, boolean, number] | type_tuple_union_4 +declare type type_tuple_alias_4 = [string, boolean, number] | (boolean | undefined)[] | type_tuple_union_3 + + +// Utility +interface Issue { + title : T + description : T +} + +interface Issue2 { + title?: T + description?: string +} +declare type type_utility_1 = Required>; +declare type type_utility_2 = Readonly>; +declare type type_utility_3 = Record; + + +function main() { + let type_union_var : type_union = "name" + let type_array_var : type_array_1 = new Array() + let type_union_array_var : type_union_array_1 = new Array() + let type_array_alias_var : type_array_alias_1 = new Array() + let type_tuple_var : type_tuple_1 = ["name", true, 2] + let type_tuple_union_var : type_tuple_union_2 = ["name", true, 2] + let type_tuple_alias__var : type_tuple_alias_1 = ["name", null, new Array] + let type_utility_1_var : type_utility_1 = {title: "type alias", description: "test for type alias"} + let type_utility_2_var : type_utility_2 = {title: "type alias", description: "test for type alias"} + let type_utility_3_var : type_utility_3 = { + 1 : new Object() + } +} + diff --git a/ets2panda/test/runtime/ets/declareTypeAlias_specified.ets b/ets2panda/test/runtime/ets/declareTypeAlias_specified.ets new file mode 100644 index 0000000000000000000000000000000000000000..374b81f2c6b9ef6b793c99ccd0c03e01a3103196 --- /dev/null +++ b/ets2panda/test/runtime/ets/declareTypeAlias_specified.ets @@ -0,0 +1,86 @@ +/* + * 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. + */ + +// Union +export declare type type_union = string | boolean; + + +// Array +export declare type type_array_1 = Array; +declare type type_array_2 = boolean[]; + + +// Array + Union +export declare type type_union_array_1 = Array | Array +declare type type_union_array_2 = Array + + +// Array + Type Alias +export declare type type_array_alias_1 = Array +declare type type_array_alias_2 = Array | type_union +declare type type_array_alias_3 = Array | type_array_2 + + +// Tuple +declare type type_tuple_1 = [string, boolean, number] +declare type type_tuple_2 = [string, Array, number] +declare type type_tuple_3 = [string, [string, boolean], number] +declare type type_tuple_4 = [string, boolean[], number] + +// Tuple + Union +declare type type_tuple_union_1 = [string, boolean | null, number] +declare type type_tuple_union_2 = [string, Array | boolean, number] +declare type type_tuple_union_3 = [string, boolean, number] | Array | [string, null, number] +declare type type_tuple_union_4 = [string, boolean, number] | (boolean | undefined)[] + +// Tuple + Type Alias +declare type type_tuple_alias_1 = [string, boolean | null, type_union_array_1] +declare type type_tuple_alias_2 = [string, Array | boolean, type_union_array_1] +declare type type_tuple_alias_3 = [string, boolean, number] | Array | [string, null, number] | type_tuple_union_4 +declare type type_tuple_alias_4 = [string, boolean, number] | (boolean | undefined)[] | type_tuple_union_3 + + +// Utility +interface Issue { + title : string + description : string +} +declare type type_utility_1 = Partial; + +interface Issue2 { + title?: string + description?: string +} +declare type type_utility_2 = Required; +declare type type_utility_3 = Readonly; +declare type type_utility_4 = Record; + + +function main() { + let type_union_var : type_union = "name" + let type_array_var : type_array_1 = new Array() + let type_union_array_var : type_union_array_1 = new Array() + let type_array_alias_var : type_array_alias_1 = new Array() + let type_tuple_var : type_tuple_1 = ["name", true, 2] + let type_tuple_union_var : type_tuple_union_2 = ["name", new Array, 2] + let type_tuple_alias__var : type_tuple_alias_1 = ["name", null, new Array] + let type_utility_1_var : type_utility_1 = {} + let type_utility_2_var : type_utility_2 = {title: "type alias", description: "test for type alias"} + let type_utility_3_var : type_utility_3 = {title: "type alias", description: "test for type alias"} + let type_utility_4_var : type_utility_4 = { + 1 : new Object() + } +} + diff --git a/ets2panda/test/runtime/ets/define_var_test.ets b/ets2panda/test/runtime/ets/define_var_test.ets new file mode 100644 index 0000000000000000000000000000000000000000..4de85c7aa4bf06c62d21da92b4cde318aa5b2728 --- /dev/null +++ b/ets2panda/test/runtime/ets/define_var_test.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 main() { + let Infinity: number = Double.POSITIVE_INFINITY; + let NaN: number; + assertEQ(Infinity, Double.POSITIVE_INFINITY); + assertEQ(NaN, 0); +} diff --git a/ets2panda/test/runtime/ets/division-by-zero.ets b/ets2panda/test/runtime/ets/division-by-zero.ets index 3d774e0f85c7f0451142f6efe3132830eef47f7b..2f06cf1157ad5ee8a4fc4683a48586ce3db58d8a 100644 --- a/ets2panda/test/runtime/ets/division-by-zero.ets +++ b/ets2panda/test/runtime/ets/division-by-zero.ets @@ -16,34 +16,6 @@ function main() : void { let caught_counter = 0; - try { - let result : int = 1 / 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 1) - - try { - let result : long = 1 / 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 2) - - try { - let result : int = 1 % 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 3) - - try { - let result : long = 1 % 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 4) - let INT_ONE : int = 1; let INT_ZERO : int = 0; let LONG_ONE : long = 1; @@ -54,28 +26,28 @@ function main() : void { } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 5) + assertEQ(caught_counter, 1) try { let result : long = LONG_ONE / LONG_ZERO; } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 6) + assertEQ(caught_counter, 2) try { let result : int = INT_ONE % INT_ZERO; } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 7) + assertEQ(caught_counter, 3) try { let result : long = LONG_ONE % LONG_ZERO; } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 8) + assertEQ(caught_counter, 4) let DOUBLE_ONE : double = 1.0; let DOUBLE_ZERO : double = 0.0; diff --git a/ets2panda/test/runtime/ets/enum-initialize-with-enum3.ets b/ets2panda/test/runtime/ets/enum-initialize-with-enum3.ets new file mode 100644 index 0000000000000000000000000000000000000000..5d263d01ebaec54979373dab71c4b59066cd81d8 --- /dev/null +++ b/ets2panda/test/runtime/ets/enum-initialize-with-enum3.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. + */ + +namespace NS { + export enum E { + B = 4, + C = B + 1 + } +} +enum F { + R = 1 << 1, + W = 1 << 2, + O = NS.E.C +} + +assertEQ(F.O.valueOf(), 5) diff --git a/ets2panda/test/runtime/ets/enum-initialize-with-itself.ets b/ets2panda/test/runtime/ets/enum-initialize-with-itself.ets new file mode 100644 index 0000000000000000000000000000000000000000..4c116a0eb25f354c69878a75743a6822e5bfb545 --- /dev/null +++ b/ets2panda/test/runtime/ets/enum-initialize-with-itself.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. + */ + +enum FileAccess { + None, + Read = 1 << 1, + Write = 1 << 2, + ReadWrite = Read | Write +} + +enum FileAccess2 { + None, + Read = 1 << 1, + Write = 1 << 2, + ReadWrite = Read +} + +assertEQ(FileAccess.ReadWrite.valueOf(), 6) +assertEQ(FileAccess2.ReadWrite.valueOf(), 2) \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/enum_as_expression_cast.ets b/ets2panda/test/runtime/ets/enum_as_expression_cast.ets index 6ae7f5e5cef09d389ffacd18d2f6a06af4816ffa..252dab20655ca874bd4faad9067d0db6213a440a 100644 --- a/ets2panda/test/runtime/ets/enum_as_expression_cast.ets +++ b/ets2panda/test/runtime/ets/enum_as_expression_cast.ets @@ -22,7 +22,7 @@ function main() { assertEQ(E.A.toString(), "100") // E.A.toString() assertEQ(E.A as int, 100) // cast(E.A) to int, E.A is a index assertEQ(E.B.toString(), "200") // E.B.toString() - assertEQ(E.B as number, 200) // cast(E.B) to number, E.B is a index + assertEQ(Int.toDouble(E.B), 200) // cast(E.B) to number, E.B is a index assertEQ(E.A.valueOf() as int, 100) // get value of E.A - assertEQ(E.B.valueOf() as number, 200) // get value of E.B + assertEQ(Int.toDouble(E.B.valueOf()), 200) // get value of E.B } \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/enum_as_key_of_record.ets b/ets2panda/test/runtime/ets/enum_as_key_of_record.ets new file mode 100644 index 0000000000000000000000000000000000000000..93d19bb9f681e4ddcdfa5e5659e6c11d1b7c248e --- /dev/null +++ b/ets2panda/test/runtime/ets/enum_as_key_of_record.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. + */ + + + enum StringEnum { + up = "1" + } + + enum IntEnum { + up = 1 + } + + +function foo(val1:Record, val2:Record){ + +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/enum_empty.ets b/ets2panda/test/runtime/ets/enum_empty.ets new file mode 100644 index 0000000000000000000000000000000000000000..3b7accba5095a1741e7888a435267f30ba722885 --- /dev/null +++ b/ets2panda/test/runtime/ets/enum_empty.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. + */ + +enum Empty { } + +class TestClass { } + +function main() { + let a: Empty | undefined = undefined; + let c: Empty | string | TestClass = "123" + foo(a); + foo2(c) +} + +function foo(a?: Empty) { } + +function foo2(a?: Empty | string | TestClass) { + assertEQ(a, "123") +} diff --git a/ets2panda/test/runtime/ets/enum_reference.ets b/ets2panda/test/runtime/ets/enum_reference.ets index e7951c5105aee17deb71c9efe6cb256b6fcec8f7..ec334ab5664c910b163805a109bf6760549c87e9 100644 --- a/ets2panda/test/runtime/ets/enum_reference.ets +++ b/ets2panda/test/runtime/ets/enum_reference.ets @@ -17,5 +17,5 @@ enum Color { Red } enum Color2 { Red } function main(): void { - assertNE(Color.Red, Color2.Red) + assertEQ(Color.Red, Color2.Red) } diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_in_constructor.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_in_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..28242276592a294ed6a5367a03e3941afbb5e3a0 --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_in_constructor.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + value!: string; + constructor(cond: boolean) { + if (cond) { + this.value = "init"; + } + } +} + +function main() { + try { + const obj = new A(false); + console.log(obj.value); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_in_lambda.ets.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_in_lambda.ets.ets new file mode 100644 index 0000000000000000000000000000000000000000..90bbf8e5b9514471d65d80f60052b72e45071490 --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_in_lambda.ets.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. + */ + +class ClosureDemo { + captured!: string; + constructor() { + const fn = () => this.captured.length; + this.captured = "value"; + fn(); // ok + } +} + +class ClosureError { + captured!: string; + constructor() { + const fn = () => this.captured.length; + fn(); // RTE + } +} + +function main() { + try { + new ClosureDemo(); + new ClosureError(); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_nested_field.ets.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_nested_field.ets.ets new file mode 100644 index 0000000000000000000000000000000000000000..6fcff594e6a29a15eb6269d565290579a3367553 --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_nested_field.ets.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Node { + next!: Node; +} + +function main() { + try { + const node = new Node(); + node.next = new Node(); + node.next.next; // RTE + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/empty_launch.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_base_class_extends.ets similarity index 80% rename from ets2panda/test/ast/parser/ets/empty_launch.ets rename to ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_base_class_extends.ets index efcf469eaf815f64c344b2fe6b30c728ac3890b4..021c90ecc659ba1f8ab1d99d1b7f6de67d38ba29 100644 --- a/ets2panda/test/ast/parser/ets/empty_launch.ets +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_base_class_extends.ets @@ -13,9 +13,16 @@ * limitations under the License. */ -function main(): void { - launch; +class Base { + f!:string +} + +class Derived extends Base { + } -/* @@? 17:11 Error SyntaxError: Unexpected token ';'. */ -/* @@? 17:11 Error SyntaxError: Only call expressions are allowed after 'launch'. */ +function main(): void { + let a: Base = new Derived(); + a.f = "aa"; + assertEQ( a.f,"aa" ); +} diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_base_class_extends_error.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_base_class_extends_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..96a99f0aec7a0d0b5505d9e86941a0825814c14e --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_base_class_extends_error.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. + */ + +class Base { + f!: string +} + +class Derived extends Base { + +} + +function main(): void { + try { + let a: Base = new Derived(); + assertEQ(a.f, "aa"); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_constructor.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_constructor.ets new file mode 100644 index 0000000000000000000000000000000000000000..f1d628012bfe14d811fca7da3a891bc5e51d53be --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_constructor.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 Base { + f!:string + + constructor(name: string) { + this.f = name + } +} + +function main(): void { + let a = new Base("aa"); + assertEQ( a.f,"aa" ); +} diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_constructor_error.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_constructor_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..550725b8414943432cf53cc705fc87d645429fdc --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_constructor_error.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. + */ + +class Base { + f!: string + + constructor(name: string) { + this.f = name + } + +} + +class Base2 { + g!: string + +} + +function main(): void { + let a = new Base("aa"); + assertEQ(a.f, "aa"); + + try { + let b = new Base2(); + assertEQ(b.g, "aa"); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_generic_field_01.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_generic_field_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..7bf43ad91e7cc5eb82d30ba0a6c286d41bfaf4cc --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_generic_field_01.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 Generic { + genericField!: T; +} + +function main(): void { + try { + const gen = new Generic(); + console.log(gen.genericField); + } catch (e) { + assertTrue(e instanceof ClassCastError) + } +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_generic_field_02.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_generic_field_02.ets new file mode 100644 index 0000000000000000000000000000000000000000..f66c9b348e4e004419b88204d0ba373e726531d8 --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_generic_field_02.ets @@ -0,0 +1,48 @@ +/* + * 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 (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 Generic { + genericField!: T; +} + +function main(): void { + const gen = new Generic(); + try { + console.log(gen.genericField); + } catch (e) { + assertTrue(e instanceof ClassCastError) + } + gen.genericField = "1" + assertEQ(gen.genericField, "1") + gen.genericField = new A() + assertTrue(gen.genericField instanceof A) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_object_literal.ets similarity index 82% rename from ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets rename to ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_object_literal.ets index 4d96d8de990f08633df87a01c1b9fcc6dfd9fa67..c4799c64dbac93aee7910063649bd6d539184689 100644 --- a/ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_object_literal.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 @@ -13,9 +13,12 @@ * limitations under the License. */ +class A { + f!: string +} + function main(): void { - let c:char = c'X'; - let s:string = c; + let a: A = { f: "aa" } + assertEQ(a.f, "aa"); +} - assertEQ(s, "X") -} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_object_literal_error.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_object_literal_error.ets new file mode 100644 index 0000000000000000000000000000000000000000..5625b258ddacf1d55d85594ee9c61d7ca66f1c41 --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_object_literal_error.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 A { + f!: string +} + +function main(): void { + try { + let a: A = {} + assertEQ(a.f, "aa"); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} + + diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_unionType.ets.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_unionType.ets.ets new file mode 100644 index 0000000000000000000000000000000000000000..ac5be4f5e2cd1604846ed49ad5aa83a587520f60 --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_unionType.ets.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 UnionDemo { + value!: string | number; +} + +function main() { + try { + const ud = new UnionDemo(); + ud.value.toString(); + ud.value = 10; + console.log(ud.value.toString()); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_01.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_01.ets new file mode 100644 index 0000000000000000000000000000000000000000..804149e9b10acee8f9ffb95b13e36c3a58aedd5e --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_01.ets @@ -0,0 +1,30 @@ +/* + * 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 C { + f!: string +} + + +function main(): void { + try { + let y = new C(); + assertTrue(y.f != "aa") + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} + +/* @@? 21:14 Error TypeError: Uninitialized late field f was accessed before assignment. */ diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_02.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_02.ets new file mode 100644 index 0000000000000000000000000000000000000000..e8970cc8112051efefc0a62645373e0b7d96b4ad --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_02.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 C { + prop!: string; + getProp() { + return this.prop; + } +} + +function main() { + try { + new C().getProp(); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_03.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_03.ets new file mode 100644 index 0000000000000000000000000000000000000000..22f0f2f1d7a75eff028775128af64884d5cfe4fc --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_03.ets @@ -0,0 +1,30 @@ +/* + * 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 AsyncDemo { + payload!: string; + constructor() { + setTimeout(() => { this.payload = "done"; }, 100); + } +} + +function main() { + try { + const ad = new AsyncDemo(); + ad.payload; + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_04.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_04.ets new file mode 100644 index 0000000000000000000000000000000000000000..bcfd2c503d3a4d570a3509a90b30c97d6d120b98 --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_04.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 Static3 { + data!: Object[]; + init() { this.data = []; } +} + +function main(): void { + try { + const obj = new Static3(); + console.log(obj.data); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} + diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_05.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_05.ets new file mode 100644 index 0000000000000000000000000000000000000000..77b2c08ca2fb0a53455ff506314b71651653526a --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_05.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 Parent { + parentId!: string; +} +class Child extends Parent { + childId!: number; + constructor() { + super(); + this.childId = 1; + } +} + +function main(): void { + try { + const child = new Child(); + child.parentId; + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_06.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_06.ets new file mode 100644 index 0000000000000000000000000000000000000000..919a1b3f13a0b9ec05b2255c8618b6ce5139cd22 --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_06.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 Calculator { + base!: string; + result = this.base; +} + +function main(): void { + try { + console.log(new Calculator().result) + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_07.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_07.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc243e202668e990c6d119bd873274371bece9ad --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_07.ets @@ -0,0 +1,30 @@ +/* + * 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 Parent { + parentField!: string; +} +class Child extends Parent { + childField!: number; +} + +function main(): void { + try { + const child = new Child(); + console.log(child.parentField); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_08.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_08.ets new file mode 100644 index 0000000000000000000000000000000000000000..006a1d12a1872652c519eaef87567629a2fac1eb --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_assignment_08.ets @@ -0,0 +1,33 @@ +/* + * 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{ + f!:string +} + +class A implements I{ + f!:string +} + +function main(): void { + let a = new A() + try { + console.log(a.f); + } catch (e) { + assertTrue(e instanceof NullPointerError) + } + a.f = "1" + assertEQ(a.f, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_initializer.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_initializer.ets new file mode 100644 index 0000000000000000000000000000000000000000..5b03d3caf8c5ac4b7898f6ec0b0c324914877cbe --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_without_initializer.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. + */ + +class A { + f!:string +} diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_property_late_initalization_usage.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_property_late_initalization_usage.ets new file mode 100644 index 0000000000000000000000000000000000000000..6dee1099178bfc0ceb3eee7aa7367451963903a0 --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_property_late_initalization_usage.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. + */ + +class C{ + f!:string +} + +function main() : void { + let x = new C(); + x.f = "aa" + assertEQ(x.f, "aa") +} diff --git a/ets2panda/test/runtime/ets/fields_with_late_initialization/class_property_late_initalization_usage2.ets b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_property_late_initalization_usage2.ets new file mode 100644 index 0000000000000000000000000000000000000000..0f1ff1ca4af4948724bb83b2fc0de33140dd1fdd --- /dev/null +++ b/ets2panda/test/runtime/ets/fields_with_late_initialization/class_property_late_initalization_usage2.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + f!:string +} + +class B { + g!:number +} + +function main() : void { + let y = new A(); + y.f = "ab" + assertEQ(y.f,"ab") + + let x = new B(); + x.g = 5 + assertEQ(x.g,5) +} diff --git a/ets2panda/test/parser/ets/user_defined_3.ets b/ets2panda/test/runtime/ets/forof.ets similarity index 52% rename from ets2panda/test/parser/ets/user_defined_3.ets rename to ets2panda/test/runtime/ets/forof.ets index a058258ea3247b6812e73600fe8fbc13a0927ba5..8d8d3461a0ec15cebb87aea26d66f938aa0a5950 100644 --- a/ets2panda/test/parser/ets/user_defined_3.ets +++ b/ets2panda/test/runtime/ets/forof.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * Copyright (c) 2025-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 @@ -13,22 +13,24 @@ * limitations under the License. */ - let float : float; - let boolean : boolean; - let double : double; - let byte : byte; - let short : short; - let int : int; - let char : char; - let long : long; +function sum1(...p: (Int)[]): int { + let res = 0 + for (let n: Int of p) res += n ?? 0 + return res; +} +function sum2(...p: (Int | undefined)[]): int { + let res = 0 + for (let n: Int | undefined of p) res += n ?? 0 + return res; +} +function sum3(...p: (Int | null)[]): int { + let res = 0 + for (let n: Int | null of p) res += n ?? 0 + return res; +} function main() { - let float : float; - let boolean : boolean; - let double : double; - let byte : byte; - let short : short; - let int : int; - let char : char; - let long : long; -} + assertEQ(6, sum1(1, 2, 3)) + assertEQ(3, sum2(1, 2, undefined)) + assertEQ(3, sum3(1, 2, null)) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/function_assignable.ets b/ets2panda/test/runtime/ets/function_assignable.ets new file mode 100644 index 0000000000000000000000000000000000000000..80a1638485e1d983efb02683d170a0ba5a14e49a --- /dev/null +++ b/ets2panda/test/runtime/ets/function_assignable.ets @@ -0,0 +1,68 @@ +/* + * 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 ccc(): string { + return "function ccc" +} + +let foo: () => string = () => { return "lambda foo" } + +interface AAAOp { + aa?: () => string +} + +class A { + _aa?: () => string + get aa(): () => string { + return this._aa!; + } + set aa(value: () => string) { + this._aa = value; + } + _init1(it?: AAAOp) { + this._aa = it?.aa ?? ccc; + } + _init2(it?: AAAOp) { + this.aa = it?.aa ?? ccc; + } + _init3() { + this._aa = foo ?? ccc; + } + _init4() { + this.aa = ccc ?? foo; + } + _init5(it?: AAAOp) { + this._aa = it == undefined ? ccc:it.aa; + } + _init6(it?: AAAOp) { + this._aa = it?.aa || ccc; + } +} + +function main(){ + let a = new A(); + a._init1() + assertEQ(a.aa(),"function ccc") + a._init2() + assertEQ(a.aa(),"function ccc") + a._init3() + assertEQ(a.aa(),"lambda foo") + a._init4() + assertEQ(a.aa(),"function ccc") + a._init5() + assertEQ(a.aa(),"function ccc") + a._init6() + assertEQ(a.aa(),"function ccc") +} diff --git a/ets2panda/test/runtime/ets/function_param_tuple_array_expr_infer.ets b/ets2panda/test/runtime/ets/function_param_tuple_array_expr_infer.ets new file mode 100644 index 0000000000000000000000000000000000000000..6d164f81fdcea8903ea5d0df03bfa54e46eab89e --- /dev/null +++ b/ets2panda/test/runtime/ets/function_param_tuple_array_expr_infer.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. + */ + +function foo(a: [byte, int, long]) { + assertEQ(a[0], 3) + assertEQ(a[1], 42) + assertEQ(a[2], -9223372036854775808) +} + +function main() { + // call context, tuple of primitives + foo([0b11, 42, -9223372036854775808]) +} diff --git a/ets2panda/test/runtime/ets/generic_union.ets b/ets2panda/test/runtime/ets/generic_union.ets new file mode 100644 index 0000000000000000000000000000000000000000..08d2e6444888d0938e6c678de0899e99a6f75423 --- /dev/null +++ b/ets2panda/test/runtime/ets/generic_union.ets @@ -0,0 +1,36 @@ +/* + * 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 { + foo(a : int){} + foo() { + return 1 + } +} + +class B { + foo(a : int){} + foo() { + return 2 + } +} +type AAA = A | B +function foo(a : T) { + return a.foo() +} +function main() { + assertEQ(foo(new A()), 1) + assertEQ(foo(new B()), 2) +} diff --git a/ets2panda/test/runtime/ets/greater_parse.ets b/ets2panda/test/runtime/ets/greater_parse.ets new file mode 100644 index 0000000000000000000000000000000000000000..d78e2e9b7b060a694ebbda4cafc436f7d9a7f78b --- /dev/null +++ b/ets2panda/test/runtime/ets/greater_parse.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. + */ + +let a: Array= new Array() +let b: Array>= new Array>() +let c: Array>>= new Array>>() + diff --git a/ets2panda/test/runtime/ets/import_declare_type_alias.ets b/ets2panda/test/runtime/ets/import_declare_type_alias.ets new file mode 100644 index 0000000000000000000000000000000000000000..eaf3883587b150bfcdb955f81e8c775665647130 --- /dev/null +++ b/ets2panda/test/runtime/ets/import_declare_type_alias.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. + */ + +import {type_union, type_array_1 as type_array, type_union_array_1 as type_union_array, type_array_alias_1 as type_array_alias} from './declareTypeAlias_generic.ets' + +function main() { + let type_union_var : type_union = "name" + 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() + assertEQ((typeof type_union_var), string); + assertEQ((typeof type_array_var), object); + assertEQ((typeof type_union_array_var), object); + assertEQ((typeof type_array_alias_var), object); +} + diff --git a/ets2panda/test/runtime/ets/inferTypeLambda_11.ets b/ets2panda/test/runtime/ets/inferTypeLambda_11.ets new file mode 100644 index 0000000000000000000000000000000000000000..c3222907b05e3473a3994116d9663c31af3ad41a --- /dev/null +++ b/ets2panda/test/runtime/ets/inferTypeLambda_11.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. + */ +function foo(arr:T[], f:(a:T)=>string){ + return f(arr[0]) +} + +function bar(arr:number[]){ + return foo(arr, a=>a.toString()) +} + +function main(){ + assertTrue(bar([1,2,3,4]) == "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/inferTypeLambda_12.ets b/ets2panda/test/runtime/ets/inferTypeLambda_12.ets new file mode 100644 index 0000000000000000000000000000000000000000..3599d278ce6b49a7f562f731a899eb8f5a67255f --- /dev/null +++ b/ets2panda/test/runtime/ets/inferTypeLambda_12.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. + */ +function foo(arr:T[], f:(a:T|Object)=>string){ + return f(arr[1]) +} + +function bar(arr:number[]){ + return foo(arr, a=>a.toString()) +} + +function main(){ + assertTrue(bar([1,2,3,4]) == "2") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/inferTypeLambda_13.ets b/ets2panda/test/runtime/ets/inferTypeLambda_13.ets new file mode 100644 index 0000000000000000000000000000000000000000..5c41a4301ca6c7e76758e74b928e1e169b910ae3 --- /dev/null +++ b/ets2panda/test/runtime/ets/inferTypeLambda_13.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. + */ +function foo(arr:T[], f:(a:T[])=>string){ + return f(arr) +} + +function bar(arr:number[]){ + return foo(arr, a=>a.toString()) +} + +function main(){ + assertTrue(bar([1,2,3,4]) == "1,2,3,4") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/inferTypeLambda_14.ets b/ets2panda/test/runtime/ets/inferTypeLambda_14.ets new file mode 100644 index 0000000000000000000000000000000000000000..0dfd8932a1d92cf80eefc4f5a0fb95cef58fcf85 --- /dev/null +++ b/ets2panda/test/runtime/ets/inferTypeLambda_14.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. + */ +function foo(arr:FixedArray, f:(a:FixedArray)=>string){ + return f(arr) +} + +function bar(arr:FixedArray){ + return foo(arr, a=>a.toString()) +} + +function main(){ + assertTrue(bar([1,2,3,4]) == "1,2,3,4") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/inferTypeLambda_15.ets b/ets2panda/test/runtime/ets/inferTypeLambda_15.ets new file mode 100644 index 0000000000000000000000000000000000000000..4c7191af26c5a4efaa3783f1461ee3fa833bfaca --- /dev/null +++ b/ets2panda/test/runtime/ets/inferTypeLambda_15.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. + */ +function foo(arr:T[], f:(a:[T, string])=>string){ + return f([arr[0], "1"]) +} + +function bar(arr:number[]){ + return foo(arr, a=>a.toString()) +} + +function main(){ + assertTrue(bar([1,2,3,4]) == "1,1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/infer_type_spread.ets b/ets2panda/test/runtime/ets/infer_type_spread.ets index 9a5033ef0a976b54e40c37bbcf1423b7d0a84ed2..258b4d35d4c4c5a241a6036ded310356d5600840 100644 --- a/ets2panda/test/runtime/ets/infer_type_spread.ets +++ b/ets2panda/test/runtime/ets/infer_type_spread.ets @@ -14,7 +14,8 @@ */ function main() { - let a = [c'b', c'c'] - let r = [c'a', ...a, c'd'] + let a:FixedArray = [c'b', c'c'] + let r:FixedArray = [c'a', ...a, c'd'] assertTrue(r.length == 4 && (new String(r) == "abcd")) -} + } + \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/instanceof.ets b/ets2panda/test/runtime/ets/instanceof.ets index 6068092863c511ef92bd9e9134ce734bea2f86bc..8f2560a127db0741c70f06282a0bc2365b04671c 100644 --- a/ets2panda/test/runtime/ets/instanceof.ets +++ b/ets2panda/test/runtime/ets/instanceof.ets @@ -27,7 +27,7 @@ function main(): void { assertTrue(nobj instanceof null) assertTrue(!(obj instanceof null)) - let arr: int[] = [1, 2, 3]; + let arr: FixedArray = [1, 2, 3]; assertTrue(arr instanceof Object) assertTrue(!(arr instanceof Long)) @@ -35,34 +35,36 @@ function main(): void { assertTrue(obj instanceof Boolean) assertTrue(!(obj instanceof Long)) - let intArr: int[] = [1, 2, 3]; + let intArr: FixedArray = [1, 2, 3]; - assertTrue(intArr instanceof int[]) + assertTrue(intArr instanceof FixedArray) assertTrue(intArr instanceof Object) assertTrue(!(intArr instanceof Long)) - assertTrue(!(intArr instanceof Int[])) + assertTrue(!(intArr instanceof FixedArray)) assertTrue(!(intArr instanceof Int)) - let integerArr: Int[] = new Int[10]; + let integerArr: FixedArray = new Int[10]; - assertTrue(integerArr instanceof Int[]) + assertTrue(integerArr instanceof FixedArray) assertTrue(integerArr instanceof Object) - assertTrue(!(intArr instanceof Double[])) - assertTrue(!(integerArr instanceof int[])) + assertTrue(!(intArr instanceof FixedArray)) + assertTrue(!(integerArr instanceof FixedArray)) assertTrue(!(integerArr instanceof Int)) - let integerArrArr: Int[][] = [[10], [20]]; + let integerArrArr: FixedArray> = [[10], [20]]; - assertTrue(integerArrArr instanceof Int[][]) + assertTrue(integerArrArr instanceof FixedArray>) assertTrue(integerArrArr instanceof Object) - assertTrue(!(integerArrArr instanceof Int[])) + assertTrue(!(integerArrArr instanceof FixedArray)) assertTrue(!(integerArrArr instanceof Int)) - assertTrue(!(integerArrArr instanceof Long[][])) + assertTrue(!(integerArrArr instanceof FixedArray>)) let f: () => void = foo(); assertTrue(f instanceof (() => void)) + assertTrue(bar instanceof (() => void)) + return; } diff --git a/ets2panda/test/runtime/ets/interfaceMethodWithDefaultParameter.ets b/ets2panda/test/runtime/ets/interfaceMethodWithDefaultParameter.ets new file mode 100644 index 0000000000000000000000000000000000000000..7efbf745fc190e2fd399fca9e3ee15bfa118c702 --- /dev/null +++ b/ets2panda/test/runtime/ets/interfaceMethodWithDefaultParameter.ets @@ -0,0 +1,80 @@ +/* + * 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 Composer { + getCompositions(count: int = 100): string[] + getIdentification(includeAge: boolean = true, prefix: string = "He is "): string + getChildren(count: int, excludeLast: boolean = false): string[] +} + +class JohannSebastianBach implements Composer { + getCompositions(count: int = 8): string[] { + let compositions: string[] = [ + "The Brandenburg Concertos", + "The Goldberg Variations", + "Concerto for Two Violins in D minor", + "Air on the G String", + "The Well-Tempered Clavier", + "St Matthew Passion", + "Toccata and Fugue in D minor", + "Passacaglia and Fugue in C minor" + ] + + let max: int = min(compositions.length, count) as int + return [...compositions.slice(0, max)] + } + + getIdentification(includeAge: boolean = true, prefix: string = "He is"): string { + return `${prefix} Johann Sebastian Bach, the greatest composer that has ever lived${includeAge ? " who died at the age of 65." : "."}`; + } + + getChildren(count: int, excludeLast: boolean = false): string[] { + let children: string[] = [ + "Catharina Dorothea Bach", + "Wilhelm Friedemann Bach", + "Carl Philipp Emanuel Bach", + "Johann Gottfried Bernhard Bach", + "Gottfried Heinrich Bach", + "Johann Christoph Friedrich Bach", + "Johann Christian Bach III" + ] + + let max: int = min(children.length, count) as int + return excludeLast ? [...children.slice(0, max - 1)] : [...children.slice(0, max)] + } + } + +function main() { + let bach: JohannSebastianBach = {} + let compositions_1: string[] = bach.getCompositions() + let compositions_2: string[] = bach.getCompositions(5) + let identification_1: string = bach.getIdentification() + let identification_2: string = bach.getIdentification(false) + let identification_3: string = bach.getIdentification(true, "He is the") + let children_1: string[] = bach.getChildren(3) + let children_2: string[] = bach.getChildren(7, true) + + assertEQ(compositions_1.length, 8) + assertEQ(compositions_2.length, 5) + assertEQ(compositions_1[3], "Air on the G String") + assertEQ(compositions_2[4], "The Well-Tempered Clavier") + assertEQ(identification_1, "He is Johann Sebastian Bach, the greatest composer that has ever lived who died at the age of 65.") + assertEQ(identification_2, "He is Johann Sebastian Bach, the greatest composer that has ever lived.") + assertEQ(identification_3, "He is the Johann Sebastian Bach, the greatest composer that has ever lived who died at the age of 65.") + assertEQ(children_1.length, 3) + assertEQ(children_2.length, 6) + assertEQ(children_1[0], "Catharina Dorothea Bach") + assertEQ(children_2[5], "Johann Christoph Friedrich Bach") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/interfaceObjPropertyName.ets b/ets2panda/test/runtime/ets/interfaceObjPropertyName.ets new file mode 100644 index 0000000000000000000000000000000000000000..6795270a1e508d96bbaed4c894d4668430a7cd8e --- /dev/null +++ b/ets2panda/test/runtime/ets/interfaceObjPropertyName.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. + */ + +interface A { + name:string +} +let a : A = {name:"name"} + +assertEQ(((Value.of(a)) as ClassValue).getFieldByName("name").toString(), "name") + diff --git a/ets2panda/test/runtime/ets/interfacePropertyTypeAnnotationWithParameter.ets b/ets2panda/test/runtime/ets/interfacePropertyTypeAnnotationWithParameter.ets new file mode 100644 index 0000000000000000000000000000000000000000..93321a557792f09d0bfca014b1aad588e9d87d60 --- /dev/null +++ b/ets2panda/test/runtime/ets/interfacePropertyTypeAnnotationWithParameter.ets @@ -0,0 +1,53 @@ +/* + * 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 Itf { + callback1: (temp: string) => string + callback2: (temp: Array) => Int + callback3: () => Int + callback4: ((temp: Array) => Int) | number | string + callback5: [(temp: number) => void] + p1: string + p2: Int +} + +class Test implements Itf { + public callback1: (temp: string) => string = (temp: string): string => { + return temp; + } + public callback2: (temp: Array) => Int = (temp: Array): Int => { + return 2; + } + public callback3: () => Int = (): Int => { + return 3; + } + public callback4: ((temp: Array) => Int) | number | string = 4 + public callback5: [(temp: number) => void] = [(temp: number): void => { assertEQ(temp, 5); }] + public p1: string = "p1" + public p2: Int = 2 +} + +function main() { + let a = new Test; + let b: Array = new Array("hello"); + + assertEQ(a.callback1("hello1"), "hello1"); + assertEQ(a.callback2(b), 2); + assertEQ(a.callback3(), 3); + assertEQ(a.callback4, 4); + a.callback5[0](5); + assertEQ(a.p1, "p1"); + assertEQ(a.p2, 2); +} diff --git a/ets2panda/test/runtime/ets/interface_objliteral.ets b/ets2panda/test/runtime/ets/interface_objliteral.ets new file mode 100644 index 0000000000000000000000000000000000000000..821f013ac73f6c7fbf4e03e2aacc691d8a1798db --- /dev/null +++ b/ets2panda/test/runtime/ets/interface_objliteral.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. + */ + +interface InterfaceA { + propA: string +} +interface InterfaceAA extends InterfaceA {} + +interface InterfaceB { + propB: number; +} +interface ParentInterface extends InterfaceA, InterfaceB {} +interface ChildInterface extends ParentInterface {} + +function main() { + const obj: ChildInterface = { + propA: "Hello", + propB: 42 + } + assertEQ(obj.propA, "Hello") + assertEQ(obj.propB, 42) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/invoke-with-rest.ets b/ets2panda/test/runtime/ets/invoke-with-rest.ets new file mode 100644 index 0000000000000000000000000000000000000000..99838da2fdd723e6e402ca3ac36472796dcc56e7 --- /dev/null +++ b/ets2panda/test/runtime/ets/invoke-with-rest.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 A { + x: FixedArray + constructor(x: T) { + this.x = new NullishType[1] + this.x[0] = x as NullishType + } + + static $_invoke(first: T, ...items: T[]): A { + return new A(first) + } + + public get(): T { + return this.x[0] as T + } +} + +let x = A(1) + +assertEQ(x.get(), 1) diff --git a/ets2panda/test/runtime/ets/keyof_primitive_type.ets b/ets2panda/test/runtime/ets/keyof_primitive_type.ets index fdbaed33b76f0b275ed59b5d4d40555f7197a782..bb93cec92d90ed06bafa41ad7668eaac72593687 100644 --- a/ets2panda/test/runtime/ets/keyof_primitive_type.ets +++ b/ets2panda/test/runtime/ets/keyof_primitive_type.ets @@ -18,10 +18,10 @@ function main() : void { let c2:keyof number = "toPrecision" let c3:keyof number = "toLocaleString" let c4:keyof boolean = "valueOf" - let c5:keyof byte = "byteValue" - let c6:keyof short = "shortValue" - let c7:keyof int = "intValue" - let c8:keyof long = "longValue" - let c9:keyof float = "floatValue" - let c10:keyof double = "doubleValue" + let c5:keyof byte = "toByte" + let c6:keyof short = "toShort" + let c7:keyof int = "toInt" + let c8:keyof long = "toLong" + let c9:keyof float = "toFloat" + let c10:keyof double = "toDouble" } diff --git a/ets2panda/test/runtime/ets/keyword_get_set_as_identfier.ets b/ets2panda/test/runtime/ets/keyword_get_set_as_identfier.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a1c8d7d76092ac83f1693c1ee882233851586b0 --- /dev/null +++ b/ets2panda/test/runtime/ets/keyword_get_set_as_identfier.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. + */ + +let set = 1; +set = 2; +let get = 3; +get = 5; +assertEQ(set, 2) +assertEQ(get, 5) diff --git a/ets2panda/test/runtime/ets/keyword_get_set_as_identfier2.ets b/ets2panda/test/runtime/ets/keyword_get_set_as_identfier2.ets new file mode 100644 index 0000000000000000000000000000000000000000..9c0f566066f484c56e159c4c4edf9a28a812bd5b --- /dev/null +++ b/ets2panda/test/runtime/ets/keyword_get_set_as_identfier2.ets @@ -0,0 +1,30 @@ +/* + * 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 class set { + constructor() {} + constructor(a: int){}; + get set(): int { return 1; } + $_get (index: number): set { return new set } + $_set (index: number, value: set) {} +} + +let get: set +get = new set(); + +new +set(1) + +get[get.set] = get[0] diff --git a/ets2panda/test/runtime/ets/lambda_as_param.ets b/ets2panda/test/runtime/ets/lambda_as_param.ets new file mode 100644 index 0000000000000000000000000000000000000000..c5beaf2bd590a4dccfa607b19a10182eaea9f651 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_as_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. + */ + +const foo = (str: string, func: (() => void) ) => { + func() +} + +let a:string = ""; +foo(a, () => {a = "successfully!"}); +assertEQ(a, "successfully!"); diff --git a/ets2panda/test/runtime/ets/lambda_call_base.ets b/ets2panda/test/runtime/ets/lambda_call_base.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a34d3f2445c9dae3b11315d54e280636e1a13d3 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_call_base.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. + */ + +class MyDate { + public getFullYear(): int { + return 20; + } +} + +class DateC extends MyDate { + bigY() { + let x = this.getFullYear + return x(); + } +} + +function main() { + assertEQ(new DateC().bigY(), 20) +} diff --git a/ets2panda/test/runtime/ets/lambda_with_receiver/lambda_with_receiver_as_class_fields1.ets b/ets2panda/test/runtime/ets/lambda_with_receiver/lambda_with_receiver_as_class_fields1.ets new file mode 100644 index 0000000000000000000000000000000000000000..9b3a86d87093754ba337b026968a65fafd7689c6 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_with_receiver/lambda_with_receiver_as_class_fields1.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. + */ + +// lambda with receiver is used as fields + +class A { + f = (this: A): string => { return "instance A" } + + static f = (this: A): string => { return "static A" } +} + +function main() { + let a: A = new A() + assertEQ(a.f(a), "instance A") + assertEQ(A.f(a), "static A") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/lambda_with_receiver/lambda_with_receiver_as_class_fields2.ets b/ets2panda/test/runtime/ets/lambda_with_receiver/lambda_with_receiver_as_class_fields2.ets new file mode 100644 index 0000000000000000000000000000000000000000..1f304be5ac8142965188a728a02edb0315d3e64e --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_with_receiver/lambda_with_receiver_as_class_fields2.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. + */ + +class A { + f(): string { return "A" } +} +class B { + a:A + constructor(a:A){ + this.a = a + } + f = (this: A): string => { return "A ex" } +} + +function main() { + let a: A = new A() + let b: B = new B(a) + assertEQ(b.a.f(), "A") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/lambda_with_rest_param_fixedarray.ets b/ets2panda/test/runtime/ets/lambda_with_rest_param_fixedarray.ets new file mode 100644 index 0000000000000000000000000000000000000000..fc2a0e0f7cd77ba201970df312565881b9bb9c3c --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_with_rest_param_fixedarray.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let foa:(c:string, ...args:FixedArray)=>string = (c:string, ...args:FixedArray)=>{ + return "c" +} + +let fob:(...args:FixedArray)=>number = (...args:FixedArray):number =>{ + let sum = 0 + for(let e of args){ + sum += e + } + return sum +} + + +function main(){ + assertEQ(foa("1"), "c") + assertEQ(fob(1, 2, 3, 4), 10) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/lambda_with_rest_param_resizablearray.ets b/ets2panda/test/runtime/ets/lambda_with_rest_param_resizablearray.ets new file mode 100644 index 0000000000000000000000000000000000000000..447940b4087a4eac8ff150d5499bfad933db9a71 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_with_rest_param_resizablearray.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let foa:(c:string, ...args:number[])=>string = (c:string, ...args:number[])=>{ + return "c" +} + +let fob:(...args:number[])=>number = (...args:number[]):number =>{ + let sum = 0 + for(let e of args){ + sum += e + } + return sum +} + + +function main(){ + assertEQ(foa("1"), "c") + assertEQ(fob(1, 2, 3, 4), 10) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/lambda_with_restparameter_object_fixedarray.ets b/ets2panda/test/runtime/ets/lambda_with_restparameter_object_fixedarray.ets new file mode 100644 index 0000000000000000000000000000000000000000..75d3dcf07cef5da95016081c27e9c88a22a0e01d --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_with_restparameter_object_fixedarray.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. + */ + +let f1 = (a:String, b:Number, ...args:FixedArray)=>{ + assertEQ(a,"000"); + assertEQ(args[0],"222"); +} + +function main(){ + let f2 = (a:String, b:Number, ...args:FixedArray)=>{ + assertEQ(a,"000"); + assertEQ(args[0],222); + } + f1("000",111,"222","333") + f2("000",111,222,333) +} diff --git a/ets2panda/test/runtime/ets/lambda_with_restparameter_optinal_fixedarray.ets b/ets2panda/test/runtime/ets/lambda_with_restparameter_optinal_fixedarray.ets new file mode 100644 index 0000000000000000000000000000000000000000..6d0575268d67bbae945dd808d8e5b23fff252d46 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_with_restparameter_optinal_fixedarray.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. + */ + +function main(){ + let f1 = (a?:String, b?:String, ...args:FixedArray)=>{ + if(a != undefined){ + assertEQ(a,"000"); + } + + if(args.length > 0){ + assertEQ(args[0],"222"); + } + } + f1("000","111","222","333") + f1("000","111","222") + f1("000","111") + f1("000") + f1() +} diff --git a/ets2panda/test/runtime/ets/lambda_with_restparameter_predefinedtypes_fixedarray.ets b/ets2panda/test/runtime/ets/lambda_with_restparameter_predefinedtypes_fixedarray.ets new file mode 100644 index 0000000000000000000000000000000000000000..d13aec2b206518a14257276aefc95906e385e6a8 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_with_restparameter_predefinedtypes_fixedarray.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. + */ + +let f1 = (a:number, b:number, ...args:FixedArray)=>{ + assertEQ(a,0); + assertEQ(args[0],222); +} + +function main(){ + let f2 = (a:number, b:number, ...args:FixedArray)=>{ + assertEQ(a,0); + assertEQ(args[0],222); + } + f1(0,111,222,333) + f2(0,111,222,333) +} diff --git a/ets2panda/test/runtime/ets/lambda_with_restparameter_variance_fixedarray.ets b/ets2panda/test/runtime/ets/lambda_with_restparameter_variance_fixedarray.ets new file mode 100644 index 0000000000000000000000000000000000000000..e6d3ae778ea0d631ce228fb7db1612ab712b7926 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_with_restparameter_variance_fixedarray.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. + */ + +function main(){ + let f1:(a:String, b:String, c:String, ...args:FixedArray) =>void = (a:String, b:String, ...args:FixedArray)=>{ + if(a != undefined){ + assertEQ(a,"000"); + } + + if(args.length > 0){ + assertEQ(args[0],"222"); + } + } + f1("000","111","222","333") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/literal_types_RTE.ets b/ets2panda/test/runtime/ets/literal_types_RTE.ets index 8252f62a5fbf3abf3eb83470f634857a6835772a..28e04e0aee9170e28b4db2f8443c990c63fab08a 100644 --- a/ets2panda/test/runtime/ets/literal_types_RTE.ets +++ b/ets2panda/test/runtime/ets/literal_types_RTE.ets @@ -26,39 +26,12 @@ function f2(a: "aa"): "bb" { } function main() { - let caught_counter = 0 - - try { - let s = id<"a" | "b" | "c">("d") - } catch (error: ClassCastError) { - caught_counter++; - } - + let s1 = id<"a" | "b" | "c">("d") let s = id<"a" | "b" | "c">("a") + assertEQ(s1 + s, "da") - try { - let y = s as "b" - } catch (error: ClassCastError) { - caught_counter++; - } - - try { - assertEQ(s as "c", "c") - } catch (error: ClassCastError) { - caught_counter++; - } - - try { - f1("aa"); - } catch (error: ClassCastError) { - caught_counter++; - } - - try { - f2("aa"); - } catch (error: ClassCastError) { - caught_counter++; - } - - assertEQ(caught_counter, 5) + s as "b" + assertEQ((s as "c") == "c", false) + f1("aa"); + f2("aa"); } diff --git a/ets2panda/test/runtime/ets/local-class-capture-boxing.ets b/ets2panda/test/runtime/ets/local-class-capture-boxing.ets index 0ddecafe02f2695aca1947efa51947ec1365eaab..a3ebeedea6082408a396fc7b247e33e7203d89a2 100644 --- a/ets2panda/test/runtime/ets/local-class-capture-boxing.ets +++ b/ets2panda/test/runtime/ets/local-class-capture-boxing.ets @@ -56,7 +56,7 @@ class GlobalClass let l_short : short = 3; let l_int : int = 4; let l_long : long = 5; - let l_float : float = 6.0; + let l_float : float = 6.0f; let l_double : double = 7.0; let l_boolean : boolean = false; let l_char : char = c'x'; @@ -147,7 +147,7 @@ class GlobalClass l_short = 103; l_int = 104; l_long = 105; - l_float = 106.0; + l_float = Double.toFloat(106.0); l_double = 107.0; l_boolean = true; l_char = c'y'; diff --git a/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets b/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets index b22d5bb64c4de397121cf8e3990ab6cf8d21cef2..d06cbc640e1aa21b127f71f11bd4f8456a364f48 100644 --- a/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets +++ b/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets @@ -56,7 +56,7 @@ class GlobalClass let l_short : short = 3; let l_int : int = 4; let l_long : long = 5; - let l_float : float = 6.0; + let l_float : float = 6.0f; let l_double : double = 7.0; let l_boolean : boolean = false; let l_char : char = c'x'; diff --git a/ets2panda/test/runtime/ets/looseReferenceEquality.ets b/ets2panda/test/runtime/ets/looseReferenceEquality.ets index baa9079342ad7edaf1254df3ea179cd0faacffcd..e5f1698008fbc60d916db5f1dafeb590fc16bb69 100644 --- a/ets2panda/test/runtime/ets/looseReferenceEquality.ets +++ b/ets2panda/test/runtime/ets/looseReferenceEquality.ets @@ -39,9 +39,9 @@ function test_numerics() { // NOTE(vpukhov): the same is applied to float? // NOTE(vpukhov): char == int overlow? function test_numeric_precision() { - const maxsafe = Double.MAX_SAFE_INTEGER as long + const maxsafe = Double.toLong(Double.MAX_SAFE_INTEGER) assertTrue(!eq(maxsafe * 4 + 1, maxsafe * 4)) - assertTrue(eq(maxsafe * 4 + 1, (maxsafe * 4) as double)) + assertTrue(eq(maxsafe * 4 + 1, Long.toDouble(maxsafe * 4))) } function main() { diff --git a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_2.ets b/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_2.ets index 4bec84671ee3a4564ec352f66e85ca7e2cf308d4..ada9a99ba9ca45ecebbec6aed6bae95a7d8ba601 100644 --- a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_2.ets +++ b/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_2.ets @@ -13,11 +13,11 @@ * limitations under the License. */ - function foo(...x: string[]) { + function foo(...x: FixedArray) { return 1; } -function foo(...x: int[]) { +function foo(...x: FixedArray) { return 2; } diff --git a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_4.ets b/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_4.ets index 3e1306b2ded73b5c841aaf50b142b04142e31d0b..77f0d3ba6cd05b0658d34af8cc8ae44380bd869b 100644 --- a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_4.ets +++ b/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_4.ets @@ -14,19 +14,19 @@ */ class A { - foo(...n: number[]){ + foo(...n: FixedArray){ return "A"; } } class B extends A { - foo(...n: number[]){ + foo(...n: FixedArray){ return "B"; } } class C extends B { - foo(...n: number[]){ + foo(...n: FixedArray){ return "C"; } } diff --git a/ets2panda/test/runtime/ets/multi-array-new-catched-1.ets b/ets2panda/test/runtime/ets/multi-array-new-catched-1.ets index e9623011ebf237567496cecc442e4792919d79ba..1611f8e2f649a0a6fa21bc0ec7c68dde257da522 100644 --- a/ets2panda/test/runtime/ets/multi-array-new-catched-1.ets +++ b/ets2panda/test/runtime/ets/multi-array-new-catched-1.ets @@ -14,15 +14,15 @@ */ function main(): void { - let A: Array = new Array(); - let a: Number[][][]; + let A: Array = new Array(); + let a: FixedArray>>; - let catched = false; - try { - a = new Number[A.length + 2.][4][A.length + 3.00001]; - } catch (e: TypeError) { - catched = true; - } + let catched = false; + try { + a = new Number[A.length + 2.][4][A.length + 3.00001]; + } catch (e: TypeError) { + catched = true; + } - assertTrue(catched) + assertTrue(catched) } diff --git a/ets2panda/test/runtime/ets/multi-array-new-catched-2.ets b/ets2panda/test/runtime/ets/multi-array-new-catched-2.ets index 3013f0db2b196aa376d4c8650def448e5a58c6fb..4a8928554e096d29c2df807ceecb11350e4d9b1a 100644 --- a/ets2panda/test/runtime/ets/multi-array-new-catched-2.ets +++ b/ets2panda/test/runtime/ets/multi-array-new-catched-2.ets @@ -19,8 +19,7 @@ function baz(): number { function main(): void { let A: Array = new Array(); - let a: Number[][][]; - + let a: FixedArray>>; let catched = false; try { a = new Number[baz()][4][A.length + 3.0000]; diff --git a/ets2panda/test/runtime/ets/multiple_interface_inheritance_1.sts b/ets2panda/test/runtime/ets/multiple_interface_inheritance_1.sts new file mode 100644 index 0000000000000000000000000000000000000000..90a14cbcd33d0d4f330d78b2f1e138bb8a228105 --- /dev/null +++ b/ets2panda/test/runtime/ets/multiple_interface_inheritance_1.sts @@ -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. + */ + +let res: number = 0; + +interface I { + foo(i: number) { + return 1; + } +} +interface J extends I { + foo(j: string) { + return 2; + } +} + +class A implements I, J {} + +function main(): void { + let a = new A(); + assertEQ(a.foo(1.1 as number), 1); + assertEQ(a.foo("some string"), 2); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/multiple_interface_inheritance_2.sts b/ets2panda/test/runtime/ets/multiple_interface_inheritance_2.sts new file mode 100644 index 0000000000000000000000000000000000000000..c3e5110ba0a728447206fc8529acb19af278dd04 --- /dev/null +++ b/ets2panda/test/runtime/ets/multiple_interface_inheritance_2.sts @@ -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. + */ + +let res: number = 0; + +interface I { + foo(i: number) { + return 1; + } +} +interface J extends I { + foo(j: string) { + return 2; + } +} + +class A implements J, I {} + +function main(): void { + let a = new A(); + assertEQ(a.foo(1.1 as number), 1); + assertEQ(a.foo("some string"), 2); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/multiple_interface_inheritance_3.sts b/ets2panda/test/runtime/ets/multiple_interface_inheritance_3.sts new file mode 100644 index 0000000000000000000000000000000000000000..72c606eadb055b0355cbeffc57de7daff3a14ab7 --- /dev/null +++ b/ets2panda/test/runtime/ets/multiple_interface_inheritance_3.sts @@ -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. + */ + +let res: number = 0; + +interface I { + foo(i: number) { + return 1; + } +} +interface J extends I { + foo(j: string) { + return 2; + } +} + +class B { + foo(j: string) { + return 3; + } + +} +class A extends B implements J, I { + foo(i: number) { + return 4; + } +} + +function main(): void { + let a = new A(); + assertEQ(a.foo(1.1 as number), 4); + assertEQ(a.foo("some string"), 3); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/multiple_interface_inheritance_4.sts b/ets2panda/test/runtime/ets/multiple_interface_inheritance_4.sts new file mode 100644 index 0000000000000000000000000000000000000000..4c4e82e2b4d451404b908228a939dc3c2c7923f6 --- /dev/null +++ b/ets2panda/test/runtime/ets/multiple_interface_inheritance_4.sts @@ -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. + */ + +let res: number = 0; + +interface I { + foo(i: number) { + return 1; + } +} +interface J extends I { + foo(j: string) { + return 2; + } +} + +class B { + foo(j: string) { + return 3; + } +} + +class A extends B implements J, I {} + +function main(): void { + let a = new A(); + assertEQ(a.foo(1.1 as number), 1); + assertEQ(a.foo("some string"), 3); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/multiple_typeof_operator.ets b/ets2panda/test/runtime/ets/multiple_typeof_operator.ets new file mode 100644 index 0000000000000000000000000000000000000000..6a891f640d3021dc7337034fb3d998252d252fac --- /dev/null +++ b/ets2panda/test/runtime/ets/multiple_typeof_operator.ets @@ -0,0 +1,36 @@ +/* + * 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 Y {} + +function main() { + let a : Int = 5 + + assertEQ(typeof typeof 1, "string") + assertEQ(typeof typeof typeof typeof typeof 5, "string") + assertEQ(typeof typeof typeof typeof typeof typeof 1, "string") + assertEQ(typeof typeof typeof typeof typeof typeof ++a, "string") + assertEQ(typeof typeof typeof typeof typeof typeof a++, "string") + + let y = new Y(); + + assertEQ(typeof y, "object") + + let typeof: int = 0; + let x = typeof + 1 + ++typeof; + + assertEQ(typeof typeof, "number"); +} diff --git a/ets2panda/test/runtime/ets/multisource_inheritance.ets b/ets2panda/test/runtime/ets/multisource_inheritance.ets index 25a2b6ae42cab18ade729f994eff2b55ed7654cc..0bbee68ba594c68ce47dda603fe3333ef6b13135 100644 --- a/ets2panda/test/runtime/ets/multisource_inheritance.ets +++ b/ets2panda/test/runtime/ets/multisource_inheritance.ets @@ -18,7 +18,15 @@ } abstract class Abstract { - instance_field: number = -1 + private _instance_field: number = -1 + + get instance_field(): number{ + return this._instance_field; + } + + set instance_field(v: number) { + this._instance_field = v; + } } class Base extends Abstract { diff --git a/ets2panda/test/runtime/ets/mypackage/implicit_package_import_1.ets b/ets2panda/test/runtime/ets/mypackage/implicit_package_import_1.ets index 93ab609f750af9dba535b584e909c592a1ed81c2..13cd6da22d40d14d7bd6a011cb4af63680d0191d 100644 --- a/ets2panda/test/runtime/ets/mypackage/implicit_package_import_1.ets +++ b/ets2panda/test/runtime/ets/mypackage/implicit_package_import_1.ets @@ -27,13 +27,13 @@ function main(): void { let locVar: mytype = new A(); assertEQ(locVar.aMemb, 5) assertEQ(globVar1, 7) - // NOTE (mmartin): Enable this assert, when correct initialization order of global variables is well defined for packages - // assertEQ(globVar2, 7) + assertEQ(globVar2, 7) } -// NOTE (mmartin): Merge these when correct initialization order of global variables is well defined for packages let globVar2: number; -globVar2 = globVar1; +static { + globVar2 = globVar1; +} function func2(a0: number): void { assertEQ(a0, 6) diff --git a/ets2panda/test/runtime/ets/namespace_tests/namespace_with_annotations.ets b/ets2panda/test/runtime/ets/namespace_tests/namespace_with_annotations.ets index 06541570eb90d98efb268e234219e635683721b1..b7bd11384443ed6fbaea4b175ec240ab18b24d20 100644 --- a/ets2panda/test/runtime/ets/namespace_tests/namespace_with_annotations.ets +++ b/ets2panda/test/runtime/ets/namespace_tests/namespace_with_annotations.ets @@ -24,11 +24,11 @@ enum Color{RED, BLUE, GREEN} authorAge: number = -35 testBool: boolean = false favorColor: Color = Color.BLUE - color: Color[] = [Color.RED, Color.BLUE] - reviewers: string[] = ["Bob", "Jim", "Tom"] - reviewersAge: number[] = [18, 21, 32] - testBools: boolean[] = [false, true, false] - mutiArray: number[][] = [ + color: FixedArray = [Color.RED, Color.BLUE] + reviewers: FixedArray = ["Bob", "Jim", "Tom"] + reviewersAge: FixedArray = [18, 21, 32] + testBools: FixedArray = [false, true, false] + mutiArray: FixedArray> = [ [1, 2, 3], [4, +5, 6], [7, 8, -9] diff --git a/ets2panda/test/runtime/ets/nestedLambdaLet.ets b/ets2panda/test/runtime/ets/nestedLambdaLet.ets index 4f04759e0ea2400e294c06b7890cb47281152f44..df1b075d54b171a0f22399efd7ce66c480d6ece1 100644 --- a/ets2panda/test/runtime/ets/nestedLambdaLet.ets +++ b/ets2panda/test/runtime/ets/nestedLambdaLet.ets @@ -101,7 +101,7 @@ function number4Levels(): void { function arrays(): void { force(() => { - let a0 = [1, 0, 0, 0]; + let a0 : FixedArray = [1, 0, 0, 0]; force(() => { let a1 = a0; a1[1]=a0[0]; diff --git a/ets2panda/test/runtime/ets/non-const-capture.ets b/ets2panda/test/runtime/ets/non-const-capture.ets index c9cc5905de8aab7e86dddd513b48b232e524abf6..f2eacbf0e466c58b165b8eeb19cde025accc550e 100644 --- a/ets2panda/test/runtime/ets/non-const-capture.ets +++ b/ets2panda/test/runtime/ets/non-const-capture.ets @@ -59,7 +59,7 @@ function part1() { function part2() { let l: long = 0; - let f: float = 0.0; + let f: float = Double.toFloat(0.0); let d: double = 0.0; let o = new C(0); let lam: () => void = () => { @@ -68,12 +68,12 @@ function part2() { assertEQ(d, 11.0) assertEQ(o.v, 12) l = 13; - f = 14.0; + f = Double.toFloat(14.0); d = 15.0; o = new C(16); } l = 9; - f = 10.0; + f = Double.toFloat(10.0); d = 11.0; o = new C(12); lam(); diff --git a/ets2panda/test/runtime/ets/opAssignmentWithUpdateExpression.ets b/ets2panda/test/runtime/ets/opAssignmentWithUpdateExpression.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ee3133e77e90563b4f4f8a4e198ac55c076fb2f --- /dev/null +++ b/ets2panda/test/runtime/ets/opAssignmentWithUpdateExpression.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. + */ + +let line = 0; +let pixelOffset = 0; +let weight = 1; +let output = new Array(1, 2, 3, 4); +let buffer = new Array(5, 6, 7, 8); +output[line++] += buffer[pixelOffset]; +assertEQ(line, 1); +assertEQ(output[0], 6); diff --git a/ets2panda/test/runtime/ets/optinal_lambda_argument.ets b/ets2panda/test/runtime/ets/optinal_lambda_argument.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a73c820dd3af28327a75ef523f72187efbdbc90 --- /dev/null +++ b/ets2panda/test/runtime/ets/optinal_lambda_argument.ets @@ -0,0 +1,48 @@ +/* + * 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 count = 1; +class A { + callback_?: Function; + on(callback?: Function): void { + this.callback_ = callback; + this.callback_!.unsafeCall(); + } +} + +class B { + callback1_?: Function; + callback2_?: Function; + on(callback1?: Function, callback2?: Function): void { + this.callback1_ = callback1; + this.callback1_!.unsafeCall(); + this.callback2_ = callback2; + this.callback2_!.unsafeCall(); + } +} + +function main() { + let a = new A(); + a.on(() => { count = 100 }) + assertEQ(count, 100) + + let lambda1 = () => { count = 200 }; + a.on(lambda1); + assertEQ(count, 200) + + let b = new B(); + b.on(() => { count = 300 }, () => { count = 400 }); + assertEQ(count, 400) +} diff --git a/ets2panda/test/runtime/ets/optional-chaining-lazy-evaluation.ets b/ets2panda/test/runtime/ets/optional-chaining-lazy-evaluation.ets index 4287ef31919e10b0f658a5a3c9c4a10660380a36..a8d4b83a3b89b215a96c032e3d28e3d36c5dc1e4 100644 --- a/ets2panda/test/runtime/ets/optional-chaining-lazy-evaluation.ets +++ b/ets2panda/test/runtime/ets/optional-chaining-lazy-evaluation.ets @@ -26,14 +26,14 @@ function main(): void { let x: int = 0; let potentiallyNullObj: Int[] | null = foo1(); - let number: Int | undefined = potentiallyNullObj?.[x++] ?? 2; - assertEQ(number, 2) + let numb: Int | undefined = potentiallyNullObj?.[x++] ?? 2; + assertEQ(numb, 2) assertEQ(x, 0) // 0 as x was not incremented let obj: Int[] | null = foo2(); - number = obj?.[x++]; + numb = obj?.[x++]; let a : Int = 11; - assertEQ(number, a) + assertEQ(numb, a) assertEQ(x, 1) // 1 as x was incremented } diff --git a/ets2panda/test/runtime/ets/overload-primitive-and-object.ets b/ets2panda/test/runtime/ets/overload-primitive-and-object.ets new file mode 100644 index 0000000000000000000000000000000000000000..0ac7c992a695ded3de698a970f89ba2865463e2b --- /dev/null +++ b/ets2panda/test/runtime/ets/overload-primitive-and-object.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. + */ + +let res: number = 0; +function foo(i: int, j: int): void { + res = 19; +} +function foo(i: number, j: Number): void { + res = 21; +} +function boo(x: Number, y: number) { + res = 34; +} +function boo(x: number, y: Number) { + res = 47; +} +function main(): void { + let n: Number = new Number(); + foo(1, n); + assertEQ(res, 21); + boo(6 as Number, 8); + assertEQ(res, 34); +} diff --git a/ets2panda/test/runtime/ets/overload_name_collision.ets b/ets2panda/test/runtime/ets/overload_name_collision.ets new file mode 100644 index 0000000000000000000000000000000000000000..97dcdad2f032110b9ad1ad8eb3641f6b6becccec --- /dev/null +++ b/ets2panda/test/runtime/ets/overload_name_collision.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 a { + xx: string + constructor(xx: string) { + this.xx = xx + } +} + +class b extends a { + constructor(xx: string) { + super(xx) + } + static xx() { + return new b('FOO').xx + } +} + +function main() { + assertEQ(b.xx(), "FOO") +} diff --git a/ets2panda/test/runtime/ets/param_sort.ets b/ets2panda/test/runtime/ets/param_sort.ets new file mode 100644 index 0000000000000000000000000000000000000000..4570ab4a7479c0805678e3e44a96f38442b56cf5 --- /dev/null +++ b/ets2panda/test/runtime/ets/param_sort.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 foo1(p1: int, p2?: int, p3: int = 22) { } + +function foo2(p1: int, p2: int =44 , p3: int = 55) { } + +function foo3(p1: int, p2: int = 44, p3?: int) { } + + +function main(){ + foo1(1, 1, 1); + foo2(1, 1, 1); + foo3(1, 1, 1); + +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/precedence.ets b/ets2panda/test/runtime/ets/precedence.ets index 0c3fb4064ec9dd06d15a8e70df2140016a899e2c..148c7997755973c20b8c587999a5a3858d61bd41 100644 --- a/ets2panda/test/runtime/ets/precedence.ets +++ b/ets2panda/test/runtime/ets/precedence.ets @@ -20,8 +20,8 @@ function main() : void { function testAsAndDiv() : void { let i : int = 1 let f : float - f = i as float / 2 + f = Int.toFloat(i) / 2 assertEQ(f, 0.5) - f = i / 2 as float + f = Int.toFloat(i / 2) assertEQ(f, 0.0) } diff --git a/ets2panda/test/runtime/ets/primitive_to_boxed.ets b/ets2panda/test/runtime/ets/primitive_to_boxed.ets index 15e7c37f595360e8d2e78900dd5b05ec110274a4..b81a5231214b25d8b0fa1e0549e246c22bd2bdef 100644 --- a/ets2panda/test/runtime/ets/primitive_to_boxed.ets +++ b/ets2panda/test/runtime/ets/primitive_to_boxed.ets @@ -26,7 +26,7 @@ function fooShort() : Short { } function fooChar() : Char { - return "c"; + return c'c'; } @@ -66,7 +66,7 @@ function main() { let val2 : Short = fooShort() assertEQ(val2, c2) - let c3 : Char = 'c'; + let c3 : Char = c'c'; let val3 : Char = fooChar() assertEQ(val3, c3) @@ -82,7 +82,7 @@ function main() { let val6 : Float = fooFloat() assertEQ(val6, c6) - + let c7 : Double = 1; let val7 : Double = fooDouble() assertEQ(val7, c7) @@ -90,4 +90,4 @@ function main() { let c8 : Color = Color.Green; let val8 : Color = fooEnum(); assertEQ(c8, val8) -} \ No newline at end of file +} diff --git a/ets2panda/test/runtime/ets/qualified-type-name.ets b/ets2panda/test/runtime/ets/qualified-type-name.ets new file mode 100755 index 0000000000000000000000000000000000000000..9d7434cb6632506604a16bb114d0f6d4566a3f19 --- /dev/null +++ b/ets2panda/test/runtime/ets/qualified-type-name.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. + */ + + +// This test case is meant to ensure 'foo.window' can compile successfully, + +export namespace foo { + export function check_interface(a: foo.window): void { + return; + } + + export interface window {} +} diff --git a/ets2panda/test/runtime/ets/readonly_parameter_test_2.ets b/ets2panda/test/runtime/ets/readonly_parameter_test_2.ets index bec85a4d1f230709b8013f44cdb8f1c1635a36de..17bd9ff9840c9c53c4560991606cd8a4b7cd87d8 100644 --- a/ets2panda/test/runtime/ets/readonly_parameter_test_2.ets +++ b/ets2panda/test/runtime/ets/readonly_parameter_test_2.ets @@ -44,7 +44,7 @@ function foo4 (x: readonly [int, string], x2: [int, string]) { function main() : void { foo1([1, "ab", true], [1, 2]) let x2: readonly int[] = [] - let y2: readonly [string, float] = ["a", 0.1] + let y2: readonly [string, float] = ["a", Double.toFloat(0.1)] foo2(x2, y2) let x : readonly int[] = [] diff --git a/ets2panda/test/runtime/ets/readonly_parameter_test_3.ets b/ets2panda/test/runtime/ets/readonly_parameter_test_3.ets index 193ab00d4c7c45feb5780894481a634a91480d66..6fb60b165a62241d6ef52e17a50e17b0536fc271 100644 --- a/ets2panda/test/runtime/ets/readonly_parameter_test_3.ets +++ b/ets2panda/test/runtime/ets/readonly_parameter_test_3.ets @@ -46,7 +46,7 @@ function main() : void { foo1([1, "ab", true], [1, 2]) let x2: Readonly = [] - let y2: Readonly<[string, float]> = ["a", 0.1] + let y2: Readonly<[string, float]> = ["a", Double.toFloat(0.1)] foo2(x2, y2) let x : Readonly = [] diff --git a/ets2panda/test/runtime/ets/recheck_test/recheck_test1.ets b/ets2panda/test/runtime/ets/recheck_test/recheck_test1.ets new file mode 100644 index 0000000000000000000000000000000000000000..6b983fabea36e3bc71a7f926c6c5b08f5d8bc8c6 --- /dev/null +++ b/ets2panda/test/runtime/ets/recheck_test/recheck_test1.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. + */ + +/* The test code is the lowering result of the code: + interface test { + testFoo: () => string; + } + + function ff(): string { + return "1111" + } + + class ExpectExtend { + public tst: test | null; + extendstst() { + const tst: test = { + testFoo : ff, + }; + this.tst = tst; + } +*/ + +function ff(): string { + return "1111"; +} + +interface test { + set testFoo(testFoo: (()=> string)) + get testFoo(): (()=> string) +} + +class ExpectExtend { + public tst: test; + public extendstst() { + const tst: test = { + testFoo: ff, + }; + (this).tst = tst; + } + public constructor(tst: test) { + this.tst = tst + } +} + +assertEQ(true, true); diff --git a/ets2panda/test/runtime/ets/rest_object_literal.ets b/ets2panda/test/runtime/ets/rest_object_literal.ets new file mode 100644 index 0000000000000000000000000000000000000000..5e67e1bfa5f0e1af53a354456288053aa57dbb8e --- /dev/null +++ b/ets2panda/test/runtime/ets/rest_object_literal.ets @@ -0,0 +1,44 @@ +/* + * 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 { + a1 : string = "" + a2 : number = 0 +} + + +function main() { + let r1 = new Array() + r1.push({a1:"A", a2: 1}, {a1:"B", a2: 2}); + assertEQ(r1[0].a1, "A") + assertEQ(r1[0].a2, 1) + assertEQ(r1[1].a1, "B") + assertEQ(r1[1].a2, 2) + + let r2 = new Array>(); + r2.push({"A": 1}, {"B": 2}) + let v = r2.pop() + assertEQ(v!["B"], 2) + v = r2.pop() + assertEQ(v!["A"], 1) + + let r3: [Record, Record string>] = [{1:"1", 2:"2", 3:"3"}, + {"A":(p:number):string=>"A" + p, "B":(p:number):string => "b" + p}] + assertEQ(r3[0][1], "1") + assertEQ(r3[0][2], "2") + assertEQ(r3[0][3], "3") + assertEQ(r3[1]["A"]!(123), "A123") + assertEQ(r3[1]["B"]!(123), "b123") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/return_this_type_over_child_class.ets b/ets2panda/test/runtime/ets/return_this_type_over_child_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..ad541951b8076986e68ce03221d2a52429d391e4 --- /dev/null +++ b/ets2panda/test/runtime/ets/return_this_type_over_child_class.ets @@ -0,0 +1,39 @@ +/* + * 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 IButton { + getTitle(): string; + setTitle(t: string): IButton; +} + +class Button implements IButton { + title: string = ""; + + getTitle(): string { + return this.title; + } + + setTitle(t: string): this { + this.title = t; + return this; + } +} + +function main() { + let b = new Button().setTitle("🍆"); + + assertTrue(b instanceof Button) + assertEQ(b.getTitle(), "🍆") +} diff --git a/ets2panda/test/runtime/ets/return_type inference.ets b/ets2panda/test/runtime/ets/return_type_inference.ets similarity index 100% rename from ets2panda/test/runtime/ets/return_type inference.ets rename to ets2panda/test/runtime/ets/return_type_inference.ets diff --git a/ets2panda/test/runtime/ets/signature_match_lambda.ets b/ets2panda/test/runtime/ets/signature_match_lambda.ets new file mode 100644 index 0000000000000000000000000000000000000000..54f38746a30030549843dd83dc28ed9c6756a518 --- /dev/null +++ b/ets2panda/test/runtime/ets/signature_match_lambda.ets @@ -0,0 +1,42 @@ +/* + * 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 { + catch(onRejected: () => U | PromiseLike): string { + onRejected() + return "first catch is matched" + } + catch(onRejected: (error: Error) => U | PromiseLike): string { + onRejected(new Error()) + return "second catch is matched" + } + catch(onRejected: (a: Error, b: Error) => U | PromiseLike): string { + onRejected(new Error(), new Error()) + return "third catch is matched" + } + catch(onRejected: (a: Error, b: Error, c: Error) => U | PromiseLike): string { + onRejected(new Error(), new Error(), new Error()) + return "fourth catch is matched" + } +} + +function main(){ + let a = new A() + assertEQ(a.catch(()=>{}),"first catch is matched") + assertEQ(a.catch((e:Error|undefined|null)=>{}),"second catch is matched") + assertEQ(a.catch((e:Error)=>{}),"second catch is matched") + assertEQ(a.catch((e:Error,e2:Error)=>{}),"third catch is matched") + assertEQ(a.catch((e:Error,e2:Error,e3:Error)=>{}),"fourth catch is matched") +} diff --git a/ets2panda/test/runtime/ets/skippedTest.ets b/ets2panda/test/runtime/ets/skippedTest.ets index 436327c4501077b732592ab4ca251e626b092eb6..b611bb3cbcb0eb36b135ded2fa8820fa7a3bdc84 100644 --- a/ets2panda/test/runtime/ets/skippedTest.ets +++ b/ets2panda/test/runtime/ets/skippedTest.ets @@ -20,13 +20,13 @@ function main(): void { let c: String = "abc"; let n2: int = 41; let n3: long = 42; - let n4: float = 43.43; + let n4: float = 43.43f; let n5: double = 44.44; console.print(str); console.println(); console.print(str.charAt(2)); console.println(); - console.print(str.length as int); + console.print(Double.toInt(str.length)); console.println(); console.print(a.equals(b)); console.println(); diff --git a/ets2panda/test/runtime/ets/stringliteral_to_char.ets b/ets2panda/test/runtime/ets/stringliteral_to_char.ets index 12a4d5723fd2b738a0bce33c12a459b82e8e2744..54c125597040571d9ed3c8d192043f85c1688f82 100644 --- a/ets2panda/test/runtime/ets/stringliteral_to_char.ets +++ b/ets2panda/test/runtime/ets/stringliteral_to_char.ets @@ -14,7 +14,7 @@ */ function foo() : Char { - return 'c' + return c'c' } function foo1(a: Char) : Char { @@ -26,11 +26,11 @@ function foo2() : Char { } function main() { - let c : Char = 'c'; + let c : Char = c'c'; let val : Char = foo() assertEQ(val, c) - let val1 : Char = foo1("c") + let val1 : Char = foo1("c"[0]) assertEQ(val1, c) let val2 : Char = foo2() diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets1.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets1.ets new file mode 100644 index 0000000000000000000000000000000000000000..d12ed1ddd153c5b4bd3ea9affd3b6821591a3870 --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets1.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. + */ + +function foo(a: number, b: string, f?: () => string) { + assertEQ(a, 1) + assertEQ(b, "1") + if(f != undefined) { + assertEQ(f(), "Ok") + } +} + +function main() { + foo(1, "1") { + return "Ok" + } + foo(1, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets10.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets10.ets new file mode 100644 index 0000000000000000000000000000000000000000..f9647a0f57720ec0848ed0964ec164c828166946 --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets10.ets @@ -0,0 +1,95 @@ +/* + * 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. + */ + +// State tracker +class Tracker { + static lambdaCalled = false; + static blockExecuted = false; + static reset() { + Tracker.lambdaCalled = false; + Tracker.blockExecuted = false; + } +} + +// Test class +class TestClass { + // Method with mandatory lambda + withMandatoryLambda(a: number, f: () => void) { + f(); + } + + // Method with optional lambda + withOptionalLambda(a?: number, f?: () => void) { + f?.(); + } +} + +// Test function +function testFunction(a: number, f: () => void) { + f(); +} + +function main() { + /* Scenario 1: Class method with mandatory parameter ​*/ + Tracker.reset(); + new TestClass().withMandatoryLambda(1, () => { + Tracker.lambdaCalled = true; + }) + { + Tracker.blockExecuted = true; + } + assertTrue(Tracker.lambdaCalled, "Scenario 1: Lambda should be executed"); + assertTrue(Tracker.blockExecuted, "Scenario 1: Block should be executed"); + + /* Scenario 2: Class method with optional parameter ​*/ + Tracker.reset(); + new TestClass().withOptionalLambda(1, () => { + Tracker.lambdaCalled = true; + }) + { + Tracker.blockExecuted = true; + } + assertTrue(Tracker.lambdaCalled, "Scenario 2: Lambda should be executed"); + assertTrue(Tracker.blockExecuted, "Scenario 2: Block should be executed"); + + /* Scenario 3: Function call with mandatory parameter ​*/ + Tracker.reset(); + testFunction(1, () => { + Tracker.lambdaCalled = true; + }) + { + Tracker.blockExecuted = true; + } + assertTrue(Tracker.lambdaCalled, "Scenario 3: Lambda should be executed"); + assertTrue(Tracker.blockExecuted, "Scenario 3: Block should be executed"); + + /* Scenario 4: No lambda + block ​*/ + Tracker.reset(); + new TestClass().withOptionalLambda(1) // No lambda parameter + { + Tracker.blockExecuted = true; + } + assertTrue(Tracker.blockExecuted, "Boundary Test: Block should be executed"); + assertEQ(Tracker.lambdaCalled, false) + + /* Scenario 5: only trailing lambda ​*/ + Tracker.reset(); + new TestClass().withOptionalLambda() // No lambda parameter + { + Tracker.lambdaCalled = true; + } + assertTrue(Tracker.lambdaCalled, "Boundary Test: Lambda should be executed"); + assertEQ(Tracker.blockExecuted, false) +} diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets11.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets11.ets new file mode 100644 index 0000000000000000000000000000000000000000..563b1eb019edf6b478a1cb2c45b34c5f751f6dd0 --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets11.ets @@ -0,0 +1,47 @@ +/* + * 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. + */ + +// Test scenarios with multiple lambda parameters +class B { + // Mix required and optional parameters (non-lambda first) + bar(requiredFn: () => void, optionalNum?: number, optionalFn?: () => string) { + requiredFn(); + assertEQ(optionalNum, 42); + if (optionalFn) assertEQ(optionalFn(), "optional"); + } + + // Multiple optional lambda parameters + baz(a: number, f1?: () => string, f2?: () => number) { + assertEQ(a, 10); + if (f1) assertEQ(f1(), "first"); + if (f2) assertEQ(f2(), 42); + } +} + +function main() { + const b = new B(); + + b.bar(() => { }, 42, () => "optional"); + + b.bar(() => { }, 42) { + return "optional"; + }; + + b.baz(10, () => "first", () => 42); + + b.baz(10, () => "first"){ + return 42 + } +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets12.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets12.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d7b1ee6eb096e51d7b5de59119913b73fb7da5d --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets12.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. + */ + +class A { } + +function foo(this: A, a: number, f?: () => number) { + return f?.() +} + +function main() { + assertEQ(foo(new A(), 1) { + {{ return 1; }} + }, 1) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets13.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets13.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d7b1ee6eb096e51d7b5de59119913b73fb7da5d --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets13.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. + */ + +class A { } + +function foo(this: A, a: number, f?: () => number) { + return f?.() +} + +function main() { + assertEQ(foo(new A(), 1) { + {{ return 1; }} + }, 1) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets2.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets2.ets new file mode 100644 index 0000000000000000000000000000000000000000..9806e06292604bd5cb046e51c766d9ea94108be8 --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets2.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. + */ + +function foo(a: number, b?: string, f?: () => string) { + assertEQ(a, 1) + assertEQ(b, b == undefined ? undefined : "1") + if(f != undefined) { + assertEQ(f(), "Ok") + } +} + + +function main() { + foo(1) { + return "Ok" + } + + foo(1, "1") { + return "Ok" + } + foo(1, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets3.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets3.ets new file mode 100644 index 0000000000000000000000000000000000000000..d99246d661a249baa316822ac357a046dffaef40 --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets3.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. + */ + +function foo(a?: number, b?: string, f?: () => string) { + assertEQ(a, a == undefined ? undefined : 1) + assertEQ(b, b == undefined ? undefined : "1") + if(f != undefined) { + assertEQ(f(), "Ok") + } +} + +function main() { + foo() { + return "Ok" + } + foo(1) { + return "Ok" + } + foo(1, "1") { + return "Ok" + } + foo(1, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets4.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets4.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd1a0dd9315674f617efc2534b73bbf44c742c38 --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets4.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A{ + foo(a: number, b: string, f?: () => string) { + assertEQ(a, 1) + assertEQ(b, "1") + if(f != undefined) { + assertEQ(f(), "Ok") + } + } +} + +function main() { + let a = new A() + a.foo(1, "1") { + return "Ok" + } + a.foo(1, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets5.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets5.ets new file mode 100644 index 0000000000000000000000000000000000000000..71237991efc0cdeaf1c0a64b22b96ac25f82904f --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets5.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 A{ + foo(a: number, b?: string, f?: () => string) { + assertEQ(a, 1) + assertEQ(b, b == undefined ? undefined : "1") + if(f != undefined) { + assertEQ(f(), "Ok") + } + } +} + +function main() { + let a = new A() + a.foo(1) { + return "Ok" + } + a.foo(1, "1") { + return "Ok" + } + a.foo(1, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets6.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets6.ets new file mode 100644 index 0000000000000000000000000000000000000000..638b62f9ad87aef5aa54244c004543f668d14bd5 --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets6.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A{ + foo(a?: number, b?: string, f?: () => string) { + assertEQ(a, a == undefined ? undefined : 1) + assertEQ(b, b == undefined ? undefined : "1") + if(f != undefined) { + assertEQ(f(), "Ok") + } + } +} + +function main() { + let a = new A() + a.foo() { + return "Ok" + } + a.foo(1) { + return "Ok" + } + a.foo(1, "1") { + return "Ok" + } + a.foo(1, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets7.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets7.ets new file mode 100644 index 0000000000000000000000000000000000000000..6adaf58ef812bbe521e9ee4a0f8c343ff712e796 --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets7.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. + */ + +interface I{ + foo(a: number, b: string, f?: () => string) { + assertEQ(a, 1) + assertEQ(b, "1") + if(f != undefined) { + assertEQ(f(), "Ok") + } + } +} + +class A implements I{} + +function main() { + let a = new A() + a.foo(1, "1") { + return "Ok" + } + a.foo(1, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets8.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets8.ets new file mode 100644 index 0000000000000000000000000000000000000000..a5eb47308ab483e0685de42a65aab58850b876ca --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets8.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. + */ + +interface I{ + foo(a: number, b?: string, f?: () => string) { + assertEQ(a, 1) + assertEQ(b, b == undefined ? undefined : "1") + if(f != undefined) { + assertEQ(f(), "Ok") + } + } +} + +class A implements I{} + +function main() { + let a: I = new A() + a.foo(1) { + return "Ok" + } + a.foo(1, "1") { + return "Ok" + } + a.foo(1, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets9.ets b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets9.ets new file mode 100644 index 0000000000000000000000000000000000000000..f754a91afdb8f8e554f73107b6105abf519bb30d --- /dev/null +++ b/ets2panda/test/runtime/ets/trailing_lambda_and_optional_parameterets9.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{ + foo(a?: number, b?: string, f?: () => string) { + assertEQ(a, a == undefined ? undefined : 1) + assertEQ(b, b == undefined ? undefined : "1") + if(f != undefined) { + assertEQ(f(), "Ok") + } + } +} + +class A implements I{} + +function main() { + let a: I = new A() + a.foo() { + return "Ok" + } + a.foo(1) { + return "Ok" + } + a.foo(1, "1") { + return "Ok" + } + a.foo(1, "1") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/tuple_types_runtime.ets b/ets2panda/test/runtime/ets/tuple_types_runtime.ets index 800c51c4d12902eb91d3af8e9791df07dd71f37b..f787e31f4d090f9284498b5cbd30d5ebf372a332 100644 --- a/ets2panda/test/runtime/ets/tuple_types_runtime.ets +++ b/ets2panda/test/runtime/ets/tuple_types_runtime.ets @@ -56,13 +56,10 @@ function main(): void { const sum = tup_3[0][1][0] + tup_3[1][1][0] + tup_3[1][1][1] + tup_3[2][1][0] + tup_3[2][1][1] + tup_3[2][1][2]; assertEQ(sum, 1660); - // Runs correctly, but fails on verifier - // It sees the type of `tup_3[0][0]` as an `Object`, what it really is an Array type. - - // tup_3[0][0][0]++; - // assertEQ(tup_3[0][0][0], 14) - // tup_3[0][0][0] = 4; - // assertEQ(tup_3[0][0][0], 4) + tup_3[0][0][0]++; + assertEQ(tup_3[0][0][0], 14) + tup_3[0][0][0] = 4; + assertEQ(tup_3[0][0][0], 4) let int_update: [int] = [42]; assertEQ(int_update[0], 42) @@ -80,7 +77,7 @@ function main(): void { let tup_10: [number, int, string, boolean, Object] = [1, 2, "I", false, new Object()]; let var_float: float = tup_10[1]; - let var_float_2: float = 2.0; + let var_float_2: float = 2.0f; assertEQ(var_float, var_float_2); let tup_11: [int, number, string, boolean, Object] = [6, 7, "J", true, 789]; diff --git a/ets2panda/test/runtime/ets/tuple_union.ets b/ets2panda/test/runtime/ets/tuple_union.ets new file mode 100644 index 0000000000000000000000000000000000000000..5864a616353e95ceec4830c8f23120341e241c38 --- /dev/null +++ b/ets2panda/test/runtime/ets/tuple_union.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. + */ + + +let v: [string]|null = ["A"] + diff --git a/ets2panda/test/runtime/ets/type_from_array_map_record_type.ets b/ets2panda/test/runtime/ets/type_from_array_map_record_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..3f52ee3b112f0b04e504e29060ce64ef6be07230 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_from_array_map_record_type.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 from the specific language governing permissions and + * limitations under the License. + */ + +function main(){ + let arrayA = Type.from>(); + let arrayB = Type.from>(); + let arrayC = Type.from(); + assertTrue(arrayA.toString() == arrayB.toString()) + assertTrue(arrayA.toString() == arrayC.toString()) + + let mapA = Type.from>(); + let mapB = Type.from>(); + assertTrue(mapA.toString() == mapB.toString()) + + let recordA = Type.from>(); + let recordB = Type.from>(); + assertTrue(recordA.toString() == recordB.toString()) + +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/type_from_bigint.ets b/ets2panda/test/runtime/ets/type_from_bigint.ets new file mode 100644 index 0000000000000000000000000000000000000000..3db2b5c63201e3d9013786da37eafa17beda17f6 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_from_bigint.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 from the specific language governing permissions and + * limitations under the License. + */ + function main(){ + let bigintA = Type.from(); + let bigintB = Type.from(); + let bigintC = Type.from(); + assertTrue(bigintA.toString() == bigintB.toString()); + assertTrue(bigintA.toString() == bigintC.toString()); + } \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/type_from_enum.ets b/ets2panda/test/runtime/ets/type_from_enum.ets new file mode 100644 index 0000000000000000000000000000000000000000..74f6cf0843deda54b4104e5734496883c3bba783 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_from_enum.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 from the specific language governing permissions and + * limitations under the License. + */ + +enum Color { Green = "red" , Red = "blue", Blue = "green" } +enum ColorNumber { Green = 1 , Red = 2, Blue = 3 } + + + + function main(){ + let enumColorA = Type.from(); + let enumColorB = Type.from(); + let enumColorC = Type.from(); + assertTrue(enumColorA.toString() == enumColorB.toString()); + assertTrue(enumColorA.toString() != enumColorC.toString()); + } \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/type_from_function.ets b/ets2panda/test/runtime/ets/type_from_function.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a29eb9ff31f491281a58838ce1e12edfca77674 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_from_function.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 from the specific language governing permissions and + * limitations under the License. + */ + + function main(){ + let a = Type.from<()=>number>(); + let b = Type.from<()=>number>(); + let c = Type.from<(v:string)=>number>(); + assertTrue(a.toString() == b.toString()); + assertTrue(a.toString() != c.toString()); + } \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/type_from_interface_class_type.ets b/ets2panda/test/runtime/ets/type_from_interface_class_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..6a73d375735a29e6466e6b4aaa75e0de3492c3ab --- /dev/null +++ b/ets2panda/test/runtime/ets/type_from_interface_class_type.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 from the specific language governing permissions and + * limitations under the License. + */ + class A{ + } + class B{ + + } + interface C{ + } + + interface D{ + } + function main(){ + let classA = Type.from(); + let classB = Type.from(); + let classC = Type.from(); + assertTrue(classA.toString() == classC.toString()) + assertTrue(classA.toString() != classB.toString()) + + let interfaceA = Type.from(); + let interfaceB = Type.from(); + let interfaceC = Type.from(); + assertTrue(interfaceA.toString() == interfaceC.toString()) + assertTrue(interfaceA.toString() != interfaceB.toString()) +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/type_from_primitive_type.ets b/ets2panda/test/runtime/ets/type_from_primitive_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..541460cc9598da7c83753d8678fd460312540df3 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_from_primitive_type.ets @@ -0,0 +1,81 @@ + /* + * 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 from the specific language governing permissions and + * limitations under the License. + */ + +function main(){ + let byte1 = Type.from(); + let byte2 = Type.from(); + let byte3 = Type.from(); + assertTrue(byte1 == byte2) + assertTrue(byte1 != byte3) + + let char1 = Type.from(); + let char2 = Type.from(); + let char3 = Type.from(); + assertTrue(char1 == char2) + assertTrue(char1 != char3) + + let short1 = Type.from(); + let short2 = Type.from(); + let short3 = Type.from(); + assertTrue(short1 == short2) + assertTrue(short1 != short3) + + let int1 = Type.from(); + let int2 = Type.from(); + let int3 = Type.from(); + assertTrue(int1 == int2) + assertTrue(int1 != int3) + + let long1 = Type.from(); + let long2 = Type.from(); + let long3 = Type.from(); + assertTrue(long1 == long2) + assertTrue(long1 != long3) + + let float1 = Type.from(); + let float2 = Type.from(); + let float3 = Type.from(); + assertTrue(float1 == float2) + assertTrue(float1 != float3) + + let double1 = Type.from(); + let double2 = Type.from(); + let double3 = Type.from(); + assertTrue(double1 == double2) + assertTrue(double1 != double3) + + + let number1 = Type.from(); + let number2 = Type.from(); + let number3 = Type.from(); + assertTrue(number1 == number2) + assertTrue(number1 != number3) + + + let boolean1 = Type.from(); + let boolean2 = Type.from(); + let boolean3 = Type.from(); + assertTrue(boolean1 == boolean2) + assertTrue(boolean1 != boolean3) + + let void1 = Type.from(); + let void2 = Type.from(); + let void3 = Type.from(); + assertTrue(void1 == void2) + assertTrue(void1 != void3) + + + + } diff --git a/ets2panda/test/runtime/ets/type_from_type_aliases.ets b/ets2panda/test/runtime/ets/type_from_type_aliases.ets new file mode 100644 index 0000000000000000000000000000000000000000..ed0fc056c98f347ccc380638e9df094466fb3aae --- /dev/null +++ b/ets2panda/test/runtime/ets/type_from_type_aliases.ets @@ -0,0 +1,82 @@ + /* + * 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 from the specific language governing permissions and + * limitations under the License. + */ +class A{ +} + +interface B{ +} + +namespace MyNamespace { + export interface Person { + name: string; + age: number; + } + + export type EmployeeA = Person; + export type EmployeeB = Person; + export type stringType = string; +} + +type intType = int; +type stringType = string; +type functionType = ()=>void; +type aClass = A; +type bInterface = B; +type arrayType = Array; +type mapType = Map; +type recordType = Record; + +function main(){ + let a = Type.from(); + let b = Type.from(); + assertTrue(a == b); + + let stringA = Type.from(); + let stringB = Type.from(); + assertTrue(stringA.toString() == stringB.toString()); + + let c = Type.from() + let d = Type.from() + assertTrue(c.toString() == d.toString()); + + let e = Type.from() + let f = Type.from() + assertTrue(e.toString() == f.toString()); + + let g = Type.from() + let h = Type.from>() + assertTrue(g.toString() == h.toString()); + + + let mapA = Type.from(); + let mapB = Type.from>(); + assertTrue(mapA.toString() == mapB.toString()); + + let recordA = Type.from(); + let recordB = Type.from>(); + assertTrue(recordA.toString() == recordB.toString()); + + + let functionA = Type.from(); + let functionB = Type.from<()=>void>(); + assertTrue(functionA.toString() == functionB.toString()); + + let employeeA = Type.from(); + let employeeB = Type.from(); + let employeeC = Type.from(); + assertTrue(employeeA.toString() == employeeB.toString()); + assertTrue(employeeA.toString() != employeeC.toString()); + +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/type_param_infer_in_union_1.ets b/ets2panda/test/runtime/ets/type_param_infer_in_union_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..4f9604f1155031878dd4bcbe1a24c81b757a69af --- /dev/null +++ b/ets2panda/test/runtime/ets/type_param_infer_in_union_1.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A{} +function foo1(array:Iterable|U>){ + return "foo1 should be ok" +} +function foo2(array:Iterable>){ + return "foo2 should be ok too" +} + +function main(){ + let a = [1,2,3] + assertEQ(foo1(a), "foo1 should be ok") + assertEQ(foo2(a), "foo2 should be ok too") +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/type_param_infer_in_union_2.ets b/ets2panda/test/runtime/ets/type_param_infer_in_union_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..487dfda9d383f2b60890b682f3a2c4d54ab9290b --- /dev/null +++ b/ets2panda/test/runtime/ets/type_param_infer_in_union_2.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 A { } +class B { } + +function testNested(data: A> | U): string { + return "nested passed"; +} + +function main() { + const validInput: A> = new A>(); + assertEQ(testNested(validInput), "nested passed"); + + const validValue = 42; + assertEQ(testNested(validValue), "nested passed"); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/type_param_infer_in_union_3.ets b/ets2panda/test/runtime/ets/type_param_infer_in_union_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..ced320a63b31f2d8ce232583ce034b05953224a6 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_param_infer_in_union_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. + */ + +class A { } + +function testConstraints(arg: A | U[] | U): string { + return "constraints passed"; +} + +function main() { + const valid1: A = new A(); + assertEQ(testConstraints(valid1), "constraints passed"); + + const valid2 = ["text"]; + assertEQ(testConstraints(valid2), "constraints passed"); + + const valid3 = "text"; + assertEQ(testConstraints(valid3), "constraints passed"); +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/undefined_as_default_value_for_built_in_array.ets b/ets2panda/test/runtime/ets/undefined_as_default_value_for_built_in_array.ets index 9be2531582edef414ee6afb219aefd3469e44226..1b5c0d9696e957ae50e31f00bf630d5f31453169 100644 --- a/ets2panda/test/runtime/ets/undefined_as_default_value_for_built_in_array.ets +++ b/ets2panda/test/runtime/ets/undefined_as_default_value_for_built_in_array.ets @@ -27,7 +27,7 @@ function main(): int { assertTrue(y[i] instanceof undefined, "y[i] value has to be undefined.") } - let m = new int[33] + let m : FixedArray = new int[33] for (let i = 0; i < 33; i++) { assertEQ(m[i], 0, "m[i] value has to be 0.") } diff --git a/ets2panda/test/runtime/ets/union_call.ets b/ets2panda/test/runtime/ets/union_call.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb39f1e81360872ec65c46c2e498b70011e24298 --- /dev/null +++ b/ets2panda/test/runtime/ets/union_call.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 A { + foo() { + return 1 + } +} + +final class B { + foo() { + return 2 + } +} +type AAA = A | B +function foo(a : AAA) { + return a.foo() +} +function main() { + assertEQ(foo(new A()), 1) + assertEQ(foo(new B()), 2) +} diff --git a/ets2panda/test/runtime/ets/union_generic_class.ets b/ets2panda/test/runtime/ets/union_generic_class.ets new file mode 100644 index 0000000000000000000000000000000000000000..969061f19a749babbf0118a04adb9b33150437a6 --- /dev/null +++ b/ets2panda/test/runtime/ets/union_generic_class.ets @@ -0,0 +1,43 @@ +/* + * 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 { + fld: T + constructor(p: T) { + this.fld = p + } +} + +class B { + fld: string = 'b' +} + +class C { + fld: Int = 11 +} + +let u1: A|B = new A('a') +let u2: A|B = new B + +let u3: A|C = new A(10) +let u4: A|C = new C + +function main() { + assertEQ(u1.fld, 'a') + assertEQ(u2.fld, 'b') + + assertEQ(u3.fld, 10) + assertEQ(u4.fld, 11) +} diff --git a/ets2panda/test/runtime/ets/union_type_RTE.ets b/ets2panda/test/runtime/ets/union_type_RTE.ets new file mode 100644 index 0000000000000000000000000000000000000000..18f876f8260634716981f9310a4a509554f27c18 --- /dev/null +++ b/ets2panda/test/runtime/ets/union_type_RTE.ets @@ -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. + */ + +class A { + fld: T + constructor(p: T) { + this.fld = p + } +} + +class B { + fld: string = 'b' +} + +function main() { + let caught_counter = 0 + + try { + foo(new A(11) as Object) + } catch (error: ClassCastError) { + caught_counter++ + } + + assertEQ(caught_counter, 1) +} + +function foo(obj: Object) { + return (obj as A|B).fld +} diff --git a/ets2panda/test/runtime/ets/unreachable.ets b/ets2panda/test/runtime/ets/unreachable.ets new file mode 100644 index 0000000000000000000000000000000000000000..3415a066c53d5fddeccdeff225b77117ebfc49b3 --- /dev/null +++ b/ets2panda/test/runtime/ets/unreachable.ets @@ -0,0 +1,36 @@ +/* + * 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 SwitchTest(value:int){ + let result = 0; + switch(value) { + case 0: + switch(value) { + case 0: + result += 3; + break; + default: + result += 32; + break; + } + result *= 2; + break; + result=3; + default: + result += 32; + break; + } + return result; +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/user_defined_1.ets b/ets2panda/test/runtime/ets/user_defined_1.ets index 3052f4066b5c0acc5e17929fd39b80c1efb7a555..e6371f450b30d2abbe993e52c203d8ff0c2216f6 100644 --- a/ets2panda/test/runtime/ets/user_defined_1.ets +++ b/ets2panda/test/runtime/ets/user_defined_1.ets @@ -20,11 +20,8 @@ class B { a: boolean; } -let boolean: int = 3; - let x: B = new B(true); function main() { assertEQ(x.a, true) - assertEQ(boolean, 3) } diff --git a/ets2panda/test/runtime/ets/verifier_acc_type.ets b/ets2panda/test/runtime/ets/verifier_acc_type.ets index dcf2ae93df13446630b26ca15eaa80f5d0a96b38..4133f9ef3aabe1013a4df8c3487e67d0da8719b7 100644 --- a/ets2panda/test/runtime/ets/verifier_acc_type.ets +++ b/ets2panda/test/runtime/ets/verifier_acc_type.ets @@ -23,7 +23,7 @@ class A { } } function foo(a: int, ...p: boolean[]): int { - return a + p.length + return Double.toInt(a + p.length) } function main() { diff --git a/ets2panda/test/runtime/ets/verifier_acc_type1.ets b/ets2panda/test/runtime/ets/verifier_acc_type1.ets index 78ee6bd6d76f753d7008b7ed16dc47a46c8b061a..cc3af85756a278011447c6de0b7f430e2529fcbc 100644 --- a/ets2panda/test/runtime/ets/verifier_acc_type1.ets +++ b/ets2panda/test/runtime/ets/verifier_acc_type1.ets @@ -31,7 +31,7 @@ class B extends A { } } function foo(a: int, ...p: boolean[]): int { - return a + p.length + return Double.toInt(a + p.length) } function main() { diff --git a/ets2panda/test/runtime/ets/visible_signatures.ets b/ets2panda/test/runtime/ets/visible_signatures.ets index a4201f3d8d0efa181ce2012252aebcd15e61159c..0acd2259f5149e0d16365bca709b6ac9e7c58deb 100644 --- a/ets2panda/test/runtime/ets/visible_signatures.ets +++ b/ets2panda/test/runtime/ets/visible_signatures.ets @@ -14,39 +14,37 @@ */ class A { - foo(a: Double | undefined): Int { + foo(a: Long): Int { return 1; } - private foo(a: double): Int { + private foo(a: Int): Int { return 0; } - foo2(a: Int | undefined): Int { + foo2(a: Int): Int { return 1; } - private foo2(a: int): Int { + private foo2(a: Long): Int { return 0; } - foo3(a: Number | undefined): Int { + foo3(a: Long): Int { return 1; } - private foo3(a: number): Int { + private foo3(a: Int): Int { return 0; } - - foo4(a: Number | undefined): Int { + foo4(a: Int): Int { return 1; } - protected foo4(a: number): Int { + protected foo4(a: Long): Int { return 0; } - } function main(): void { - assertEQ(new A().foo(3.0), 1) + assertEQ(new A().foo(3), 1) assertEQ(new A().foo2(3), 1) - assertEQ(new A().foo3(3.0), 1) - assertEQ(new A().foo4(3.0), 1) + assertEQ(new A().foo3(3), 1) + assertEQ(new A().foo4(3), 1) } diff --git a/ets2panda/test/srcdump/if_stmt_alternative.ets b/ets2panda/test/srcdump/if_stmt_alternative.ets new file mode 100644 index 0000000000000000000000000000000000000000..a04f53cf1d64cd092c0977d07d65cfda77fbde49 --- /dev/null +++ b/ets2panda/test/srcdump/if_stmt_alternative.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. + */ + +export class XXX { + bar: (()=>void)|undefined = undefined + foo() { + if (1) { + 17; + } else + this + this?.bar() + } +} \ No newline at end of file diff --git a/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt b/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt index bb991b21cc0e1c7221a26d21a1801bbffd551f58..2e165ab582113b71ccda1812e0ba2be2fe70ea00 100644 --- a/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt +++ b/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt @@ -76,12 +76,6 @@ ast/compiler/ets/readonlyType_5.ets # Issue: #23068 ast/parser/ets/InferTypeParamFromParam2.ets -# Issue: #23079 -ast/parser/ets/cast_expressions10.ets -ast/parser/ets/cast_expressions7.ets -ast/parser/ets/cast_expressions8.ets -ast/parser/ets/cast_expressions9.ets - # Issue: #23080 ast/parser/ets/default_parameter3.ets ast/parser/ets/default_parameters_multi_error.ets @@ -108,3 +102,7 @@ ast/compiler/ets/lambda_infer_type/lambda_param_type_cannot_be_determined.ets # Issue: #24605 incorrect column ast/parser/ets/named_types_2.ets + +# +ast/parser/ets/partialGenericInterface.ets +ast/parser/ets/partialGenericInterface_n.ets \ No newline at end of file diff --git a/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt b/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt index 78d0fde199e8752b28ccfe23aa7dc4505b791059..71f12afe4c9bb68fe73fbdc61b3869e18984e746 100644 --- a/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt +++ b/ets2panda/test/test-lists/declgenets2ts/ets-runtime/declgen-ets2ts-runtime-ignored.txt @@ -1,100 +1,20 @@ -#FailKind.SEGFAULT_FAIL - 7 tests: -StringFasta.ets -conditionalExpressionGenericLUB.ets -funcRefWithRestArguments.ets +#FailKind.SEGFAULT_FAIL - 1 tests: lambda_with_receiver/lambda_with_receiver_generics_return_this.ets -struct-identifier.ets -struct-init2.ets -type_param_in_union.ets #FailKind.ABORT_FAIL - 1 tests: -ArrowFunctionWithNestedNameSpace.ets -#FailKind.TSC_FAIL - 88 tests: -AccessNBody.ets -AliasClass.ets +type_param_in_union.ets +#FailKind.TSC_FAIL - 14 tests: ClassNewInstance.ets Enum7.ets GenericBridges_01.ets GenericBridges_02.ets -Morph3d.ets RecordKeyTypeCheck.ets -RecursiveTypeAlias8.ets -annotation_tests/AnnotationForArrayType.ets -annotation_tests/AnnotationForClass.ets -annotation_tests/AnnotationForClassProperty.ets -annotation_tests/AnnotationForInterface.ets -annotation_tests/AnnotationForMethod.ets -annotation_tests/AnnotationForTypeAliaDecl.ets -annotation_tests/AnnotationForTypesInArray.ets -annotation_tests/AnnotationForTypesInClass.ets -annotation_tests/AnnotationForTypesInInterface.ets -annotation_tests/AnnotationNoNeedToSetProperties01.ets -annotation_tests/AnnotationNoNeedToSetProperties02.ets -annotation_tests/AnnotationNoNeedToSetProperties03.ets -annotation_tests/AnnotationsFieldType01.ets -annotation_tests/AnnotationsFieldType02.ets -annotation_tests/AnnotationsFieldType03.ets -annotation_tests/AnnotationsFieldType04.ets -annotation_tests/EmitAnnotationToBytecode.ets -annotation_tests/Muti-AnnotationsDefineAndUseForClass.ets -annotation_tests/annotationForNamespace.ets -annotation_tests/annotationUsageSingleFileds01.ets -annotation_tests/annotationUsageSingleFileds02.ets -annotation_tests/annotationUsageSingleFileds03.ets -annotation_tests/annotationUsageSingleFileds04.ets -annotation_tests/annotationUsageSingleFileds05.ets -annotation_tests/annotationUsageSingleFileds06.ets -annotation_tests/annotationUsageSingleFileds07.ets -annotation_tests/annotationUsage_scope_check02.ets -annotation_tests/annotationUsage_scope_check03.ets -classGetterSetter.ets -class_implements_interface.ets -defaultTypeParam_with_qualifiedname.ets -enum_namespace.ets -enum_switch.ets -exportDefault_1.ets -exportDefault_2.ets -function_type_with_receiver/extensionFunctionTypeGeneric.ets +StringFasta.ets function_type_with_receiver/validReturnThisOfExtensionFunction.ets generic_constraint_implicit.ets generics_1.ets -getteSetterImplementation.ets -getterSetterImplementationWithConstructor.ets -implementClassPropertyFunctionOptionCall.ets -implementsClassPropertyFunctionType.ets -implementsClassPropertyFunctionType2.ets -implementsClassPropertyUnionType1.ets -implementsClassPropertyUnionType2.ets -import_self_head_tests/A/test.ets -import_self_head_tests/B/test.d.ets -inherited_getter_setter_implementation_1.ets -inherited_getter_setter_implementation_2.ets -interface_prop.ets -interface_with_optional_property_cycle_import/class_file.ets -interface_with_optional_property_cycle_import/interface_file.ets -lambda_with_receiver/lambda_with_receiver_generics1.ets lambda_with_receiver/lambda_with_receiver_generics_return_this_rotate.ets lambda_with_receiver/lambda_with_receiver_return_this3.ets lambda_with_receiver/lambda_with_receiver_trailing_in_function_return_this_rotate.ets -namespace_tests/namespace_basic.ets -namespace_tests/namespace_deeplt_nested.ets -namespace_tests/namespace_execution_statements_test01.ets -namespace_tests/namespace_execution_statements_test02.ets -namespace_tests/namespace_import_type_test/namespace_export.ets -namespace_tests/namespace_merge_test.ets -namespace_tests/namespace_merged.ets -namespace_tests/namespace_nested.ets -namespace_tests/namespace_qualified.ets -namespace_tests/namespace_with_annotations.ets -namespace_tests/nested_namespace_plus_equal.ets -nestedNameSpaceWithStaticField.ets -override_for_partial_01.ets -override_for_partial_02.ets -qualifiedNameInForOfStmt1.ets -qualifiedNameInForOfStmt2.ets -qualifierNameInTypeParam.ets -readonly_simple_form_pos.ets -record_namespace.ets -simple_form_pos.ets static-invoke.ets top_level_03.ets -declareExport.ets +multisource_inheritance.ets diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored-AOT-PGO.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored-AOT-PGO.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 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 ed76e9c73b6951a8779e7e44bc463cc44da1d3e1..bdff84c10b858546bbc682285e61754399df128c 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -1,28 +1,28 @@ # SyntaxError: Cannot find type 'Class'. -# panda#10421 +#10421 ClassNewInstance.ets # SyntaxError: Cannot find type 'HashMap'. -# panda#10422 +#10422 StringFasta.ets # SyntaxError: Cannot find type 'Class'. -# panda#10423 +#10423 generics_1.ets -# panda#11502 +#11502 nullCoalesc.ets -# panda#11104 +#11104 unboxing.ets -# panda#11326 +#11326 GenericsTest.ets -# panda#11327 +#11327 objectEquality.ets -# FailKind.ES2PANDA_FAIL # panda#19809 +#19809 FailKind.ES2PANDA_FAIL conditionalExpressionGenericLUB.ets # Failed due to lambda captures @@ -42,52 +42,40 @@ funcRefWithRestArguments.ets # Wrong type inferred for lambda type_param_in_union.ets -# 15276 +#15276 n_overrideWithNullable.ets nullableType.ets -#Issue 17949 -#SyntaxError: Cannot find type 'C'. -lambdaWithLocalClassAccess.ets - -#Issue 21065 +#21065 implementsClassPropertyUnionType1.ets implementsClassPropertyUnionType2.ets -#Issue 21834 +#21834 override_for_partial_02.ets optional_field.ets -#Issue 22384 +#22384 Object-type-in-binary-logical-expression.ets trailing-lambda.ets -unboxingBooleanConversion.ets BitwiseOperationsOnFloat.ets RecursiveTypeAlias11.ets -boxingConversions3.ets char-type.ets conversionFloatIntLong.ets -conversionFromInfinity.ets enum_const_variable.ets local_enum03.ets -non-const-capture.ets inallyCatchExecutedNormally.ets finallyTryExecutedNormally.ets finallyCatchExecutedNormally.ets enumConstExpression.ets -#Issue 48215 -implementsClassPropertyFunctionType_ObjectLiteralExpr.ets +#48215 lambda_with_receiver/lambda_with_receiver_generics_return_this_rotate.ets lambda_with_receiver/lambda_with_receiver_return_this3.ets lambda_with_receiver/lambda_with_receiver_generics_return_this.ets lambda_with_receiver/lambda_with_receiver_trailing_in_class_method_return_this_rotate.ets lambda_with_receiver/lambda_with_receiver_trailing_in_function_return_this_rotate.ets -#Issue 23074 -# instance method used as value -FunctionType.ets -function_type_inference1.ets +#23074 # generic bridges GenericBridges_01.ets GenericBridges_02.ets @@ -95,3 +83,6 @@ override_for_partial_01.ets #HEAD FILE NO NEED TO RUN import_self_head_tests/B/test.d.ets + +#Issue 25550 +enum-initialize-with-enum3.ets diff --git a/ets2panda/test/test-lists/parser/parser-ets-allowed.txt b/ets2panda/test/test-lists/parser/parser-ets-allowed.txt index 03736558ab1491ba9d139463327af9bc0b9a8c4f..dca932b87e84039854aa48681bcac5f11882f6b6 100644 --- a/ets2panda/test/test-lists/parser/parser-ets-allowed.txt +++ b/ets2panda/test/test-lists/parser/parser-ets-allowed.txt @@ -479,3 +479,5 @@ parser/ets/trailing_lambda_tests/trailing_lambda_with_throw.ets parser/ets/trailing_lambda_tests/trailing_lambda_define_lambda_in_body.ets parser/ets/override.ets parser/ets/declare_namespace.ets +parser/ets/await_priority.ets +parser/ets/await_as_priority.ets \ No newline at end of file diff --git a/ets2panda/test/test-lists/recheck/recheck-ignored.txt b/ets2panda/test/test-lists/recheck/recheck-ignored.txt new file mode 100644 index 0000000000000000000000000000000000000000..73876854b2bffa06eac101a18fba106f0600cdb4 --- /dev/null +++ b/ets2panda/test/test-lists/recheck/recheck-ignored.txt @@ -0,0 +1,1481 @@ +# New failures at #FailKind.ES2PANDA_FAIL +# Negative tests that are ignored +ast/parser/ets/import_tests/export_and_import_class.ets +ast/parser/ets/import_tests/export_and_import_top_level.ets +ast/parser/ets/too_many_expression.ets +compiler/ets/ConditionalExpressionCallVoidNeg.ets +compiler/ets/abstractNewClassInstanceExpression.ets +compiler/ets/dynamic_instanceof_error.ets +compiler/ets/func-ref-private.ets +compiler/ets/functions_with_ambiguous_rest_parameter.ets +compiler/ets/generic_arrayaslist.ets +compiler/ets/instanceof_dyndecl_dynvalue.ets +compiler/ets/instanceof_dyndecl_jsvalue.ets +compiler/ets/instanceof_dynvalue_dynvalue.ets +compiler/ets/instanceof_dynvalue_jsvalue.ets +compiler/ets/instanceof_etsobject_dynvalue.ets +compiler/ets/instanceof_etsobject_jsvalue.ets +compiler/ets/instanceof_jsvalue_dynvalue.ets +compiler/ets/instanceof_jsvalue_jsvalue.ets +compiler/ets/instanceof_object_dynvalue.ets +compiler/ets/instanceof_object_jsvalue.ets +compiler/ets/instanceof_object_long.ets +parser/ets/dynamic_import_tests/dynamic_iface_decl_bad.ets +parser/ets/import_tests/packages/var-duplication/subpackage_module_1.ets +parser/ets/import_tests/packages/var-duplication/subpackage_module_2.ets +parser/ets/interfaces.ets +parser/ets/lambda-type-inference-overloaded.ets +parser/ets/localTypeAlias.ets +parser/ets/re_export/import_10.ets +parser/ets/re_export/re_export_4.ets +parser/ets/test_type_alias6.ets +parser/ets/type_alias_1.ets +runtime/ets/ClassNewInstance.ets +runtime/ets/GenericsTest.ets +runtime/ets/Object-type-in-binary-logical-expression.ets +runtime/ets/StringFasta.ets +runtime/ets/conditionalExpressionGenericLUB.ets +runtime/ets/funcRefWithRestArguments.ets +runtime/ets/generics_1.ets +runtime/ets/implementsClassPropertyUnionType1.ets +runtime/ets/implementsClassPropertyUnionType2.ets +runtime/ets/lambda_with_receiver/lambda_with_receiver_generics_return_this_rotate.ets +runtime/ets/lambda_with_receiver/lambda_with_receiver_return_this3.ets +runtime/ets/lambda_with_receiver/lambda_with_receiver_trailing_in_class_method_return_this_rotate.ets +runtime/ets/lambda_with_receiver/lambda_with_receiver_trailing_in_function_return_this_rotate.ets +runtime/ets/n_overrideWithNullable.ets +runtime/ets/nullCoalesc.ets +runtime/ets/nullableType.ets +runtime/ets/objectEquality.ets +runtime/ets/optional_field.ets +runtime/ets/override_for_partial_01.ets +runtime/ets/override_for_partial_02.ets +runtime/ets/struct-identifier.ets +runtime/ets/struct-init.ets +runtime/ets/struct-init2.ets +runtime/ets/struct_implements.ets +runtime/ets/top_level_03.ets +runtime/ets/type_param_in_union.ets + +# New failures at #FailKind.ABORT_FAIL +runtime/ets/lambda_with_receiver/lambda_with_receiver_generics_return_this.ets + +# Negative tests that should be ignored +ast/parser/multi_returnstatement_typeerror.ets +ast/parser/ets/spreadexpr_in_newexpr_neg02.ets +ast/parser/ets/multiple_fields.ets +ast/parser/ets/enum18.ets +ast/parser/ets/async_ctor.ets +ast/parser/ets/special_signatures.ets +ast/parser/ets/local-class-access-modifier-private.ets +ast/parser/ets/generic_error.ets +ast/parser/ets/getterOverrideGen_n.ets +ast/parser/ets/unexpected_token_3.ets +ast/parser/ets/unexpected_token_34.ets +ast/parser/ets/partialGenericInterface_n.ets +ast/parser/ets/spreadExpressionNotArrayType.ets +ast/parser/ets/method_modifier_check_6.ets +ast/parser/ets/interfaceMethodNativeModifier.ets +ast/parser/ets/interfaceMethodPrivatePrivate.ets +ast/parser/ets/ambient_indexer_4.ets +ast/parser/ets/genericDefaultParam_4.ets +ast/parser/ets/inheritance-cyclic.ets +ast/parser/ets/lambda-type-inference-bad-arrow.ets +ast/parser/ets/non_constant_expression.ets +ast/parser/ets/function_decl.ets +ast/parser/ets/undefinedNullNotObject.ets +ast/parser/ets/unexpected_token_59.ets +ast/parser/ets/switch_alive_2.ets +ast/parser/ets/recordKeyTypeCheck01.ets +ast/parser/ets/static_func_call_10.ets +ast/parser/ets/local-class-member-access-modifier-private1.ets +ast/parser/ets/unexpected_token_52.ets +ast/parser/ets/cast_expressions7.ets +ast/parser/ets/async_method_bad.ets +ast/parser/ets/recordKeyTypeCheck04.ets +ast/parser/ets/struct_with_annotations.ets +ast/parser/ets/launch_super_ctor.ets +ast/parser/ets/declare_namespace_5.ets +ast/parser/ets/class_keyword.ets +ast/parser/ets/function_implicit_return_type2.ets +ast/parser/ets/nonIntegralIndex.ets +ast/parser/ets/missing_in_for_statement_2.ets +ast/parser/ets/accessor_void.ets +ast/parser/ets/unexpected_token_20.ets +ast/parser/ets/async_lambda_bad.ets +ast/parser/ets/unexpected_token_33.ets +ast/parser/ets/method_modifier_check_7.ets +ast/parser/ets/wrong_context_function_3.ets +ast/parser/ets/getter_native.ets +ast/parser/ets/lambda-type-inference-neg2.ets +ast/parser/ets/ambient_indexer_8.ets +ast/parser/ets/async_function_bad.ets +ast/parser/ets/increment-on-nullish-type-undefined-invalid.ets +ast/parser/ets/circulary_interface_declaration.ets +ast/parser/ets/ambiguous_call_1.ets +ast/parser/ets/function_implicit_return_type7.ets +ast/parser/ets/unexpected_token_7.ets +ast/parser/ets/nonPublicInterfaceProp.ets +ast/parser/ets/struct_keywords2.ets +ast/parser/ets/unexpected_token_30.ets +ast/parser/ets/invalidEnums.ets +ast/parser/ets/InvalidExpressions1.ets +ast/parser/ets/interface_member_initialization.ets +ast/parser/ets/constant_expression_divide_zero.ets +ast/parser/ets/default_parameter1.ets +ast/parser/ets/method_modifier_check_4.ets +ast/parser/ets/typeparameter_constraint_circular-neg_0.ets +ast/parser/ets/class_interface_enum_only_top_level_5.ets +ast/parser/ets/namespace_badtoken03.ets +ast/parser/ets/enum24.ets +ast/parser/ets/for_of_02.ets +ast/parser/ets/method_modifier_check_3.ets +ast/parser/ets/unexpected_token_31.ets +ast/parser/ets/array_2.ets +ast/parser/ets/invalid_type.ets +ast/parser/ets/visible_signatures_1.ets +ast/parser/multierror_switchcases.ets +ast/parser/ets/method_modifier_check_9.ets +ast/parser/ets/TypeInferFunc.ets +ast/parser/ets/non_proper_iterator_method.ets +ast/parser/ets/thisInConstructor.ets +ast/parser/ets/keyof_type_parameter.ets +ast/parser/ets/local-interface-access-modifier-public.ets +ast/parser/ets/rest_parameter_03.ets +ast/parser/ets/unexpected_token_50.ets +ast/parser/ets/assignment_non-functional_variable_to_functional_type.ets +ast/parser/ets/access_modifier_4.ets +ast/parser/ets/class-static-field-redeclaration.ets +ast/parser/ets/method_modifier_check_5.ets +ast/parser/ets/enum23.ets +ast/parser/ets/arrow_1.ets +ast/parser/ets/readonlyGetterSetterReassignment2.ets +ast/parser/ets/StructTest3.ets +ast/parser/ets/trailing_comma_1.ets +ast/parser/ets/invalid_access_static.ets +ast/parser/ets/interfaces2.ets +ast/parser/ets/for_with_empty_body.ets +ast/parser/ets/generics_type_param_no_typeargs_no_default_2.ets +ast/parser/ets/namespace_badtoken04.ets +ast/parser/ets/InvalidStatements1.ets +ast/parser/ets/wrong-union-array-assignment.ets +ast/parser/ets/optional_field_interfaceUnionNotCompatible.ets +ast/parser/ets/struct_invalid_nested2.ets +ast/parser/ets/distinguishable-decl-1.ets +ast/parser/ets/class_interface_enum_only_top_level_2.ets +ast/parser/ets/for_of_loop_variable.ets +ast/parser/ets/single_statement_2.ets +ast/parser/ets/switch_readonly_member_different_enum_2.ets +ast/parser/ets/unexpected_token_44.ets +ast/parser/ets/tryBlockOnly.ets +ast/parser/ets/test_type_alias2.ets +ast/parser/ets/switch_readonly_member_enum.ets +ast/parser/ets/nested_function_in_method.ets +ast/parser/ets/main_entry_point_4.ets +ast/parser/ets/enum12.ets +ast/parser/ets/n_returnNullFromMethod.ets +ast/parser/ets/enum28.ets +ast/parser/ets/unexpected_token_17.ets +ast/parser/ets/try_catch_alive_5.ets +ast/parser/ets/SmartCast_2.ets +ast/parser/ets/user_defined_20.ets +ast/parser/ets/enum13.ets +ast/parser/ets/cycle_constructor.ets +ast/parser/ets/unexpected_token_25.ets +ast/parser/ets/test_type_alias4.ets +ast/parser/ets/missing_in_for_statement_1.ets +ast/parser/ets/multi_typeerror_function_implicit_return_value.ets +ast/parser/ets/anonymous_class.ets +ast/parser/ets/ambient_indexer_7.ets +ast/parser/ets/for_of_03.ets +ast/parser/ets/rest_parameter_04.ets +ast/parser/ets/invalid_access_static2.ets +ast/parser/ets/class_property_access.ets +ast/parser/ets/tuple_type_3_neg.ets +ast/parser/ets/readonly_reference_CTE_err_elimilate.ets +ast/parser/ets/setter_native.ets +ast/parser/ets/missing_implementation_1.ets +ast/parser/ets/user_defined_14.ets +ast/parser/ets/static_func_call_9.ets +ast/parser/ets/enum2.ets +ast/parser/ets/method_modifier_check_1.ets +ast/parser/ets/dynmicImportUnimplemented.ets +ast/parser/ets/try_catch_alive_8.ets +ast/parser/ets/partialGenericInterface_2.ets +ast/parser/ets/lambda_infer_type_neg_2.ets +ast/parser/ets/local_interface_already_class.ets +ast/parser/ets/calls.ets +ast/parser/ets/this_type_lambda_declaration_return_invalid.ets +ast/parser/ets/static_field_2.ets +ast/parser/ets/invalidEnums1.ets +ast/parser/ets/static_func_call_2.ets +ast/parser/ets/record_object_value.ets +ast/parser/ets/operator_logical_nullish_equal.ets +ast/parser/ets/user_defined_24.ets +ast/parser/ets/unexpected_token_41.ets +ast/parser/ets/typeinference_function_generic.ets +ast/parser/ets/n_assignNullableFromFunctionToNonNullable.ets +ast/parser/ets/local-interface-member-access-modifier-private2.ets +ast/parser/ets/keyof_annotation.ets +ast/parser/ets/unexpected_token_37.ets +ast/parser/ets/cast_expressions8.ets +ast/parser/ets/unexpected_token_35.ets +ast/parser/ets/static_func_call_1.ets +ast/parser/ets/class_interface_enum_only_top_level_1.ets +ast/parser/ets/this_type_class_static_method_return_invalid.ets +ast/parser/ets/unexpected_token_36.ets +ast/parser/ets/struct_export1.ets +ast/parser/ets/local_interface_already_variable..ets +ast/parser/ets/enum_default_negative.ets +ast/parser/ets/struct_in_class.ets +ast/parser/ets/switch_enum.ets +ast/parser/ets/InterfaceWithDefaultFunction2.ets +ast/parser/ets/enum8.ets +ast/parser/ets/struct_invalid_abstract.ets +ast/parser/ets/partialPrimitiveConversion_n.ets +ast/parser/ets/superInConstructor3.ets +ast/parser/ets/primitive_type_method_2.ets +ast/parser/ets/method_modifier_check_11.ets +ast/parser/ets/this_type_lambda_declaration_return_in_class_invalid.ets +ast/parser/ets/interfaceAbstract.ets +ast/parser/ets/non-ambient_call_signature.ets +ast/parser/ets/await_promise_bad.ets +ast/parser/ets/class_interface_enum_only_top_level_3.ets +ast/parser/ets/forOfType.ets +ast/parser/ets/SmartCast_1.ets +ast/parser/ets/lambda-type-inference-overloaded-1.ets +ast/parser/ets/superInConstructor1.ets +ast/parser/ets/assign_bad.ets +ast/parser/ets/topLevelStaticClass.ets +ast/parser/ets/InvalidParserImpl.ets +ast/parser/ets/privateSuperConstructorCall.ets +ast/parser/ets/declare_class_neg.ets +ast/parser/ets/unexpected_token_10.ets +ast/parser/ets/method_modifier_check_16.ets +ast/parser/ets/keyof_applied_to_other.ets +ast/parser/ets/ambient_indexer_9.ets +ast/parser/ets/enum15.ets +ast/parser/ets/async_abstract_bad.ets +ast/parser/ets/typeparameter_constraint_circular-neg_1.ets +ast/parser/ets/user_defined_17.ets +ast/parser/ets/class_composite_1.ets +ast/parser/ets/unclosed_loop.ets +ast/parser/ets/static_field_3.ets +ast/parser/ets/missing_implementation_2.ets +ast/parser/ets/object_literal_withfunc.ets +ast/parser/ets/default_parameters_multi_error.ets +ast/parser/ets/unexpected_token_13.ets +ast/parser/ets/functionTypeRethrows.ets +ast/parser/ets/type_param_contraint_override.ets +ast/parser/ets/namespace_badtoken02.ets +ast/parser/ets/return_null_and_type_not_match.ets +ast/parser/ets/union_static_method.ets +ast/parser/ets/unexpected_token_28.ets +ast/parser/ets/overrideFuncWithGetter_n.ets +ast/parser/ets/operator_logical_or_equal.ets +ast/parser/ets/type_references.ets +ast/parser/ets/fields.ets +ast/parser/ets/generic_defined_before_use_neg_5.ets +ast/parser/ets/constructor_functionbody_nullptr.ets +ast/parser/ets/switch_enum_case_duplicate.ets +ast/parser/ets/lambda-arrow-after-braces.ets +ast/parser/ets/variable_throw_function_2.ets +ast/parser/ets/interfaceMethodPrivateStaticModifier.ets +ast/parser/ets/user_defined_7.ets +ast/parser/ets/optional_chaining_invalid_property.ets +ast/parser/ets/string_literal_const_cast.ets +ast/parser/ets/InvalidClasses.ets +ast/parser/ets/interfaceExtendInterfaces1.ets +ast/parser/ets/method_modifier_check_17.ets +ast/parser/ets/invalid_decorator_usage.ets +ast/parser/ets/operator_logical_and_euqal.ets +ast/parser/ets/ambient_indexer_5.ets +ast/parser/ets/declare_class_bad_2.ets +ast/parser/ets/wrong_context_function_2.ets +ast/parser/ets/enum22.ets +ast/parser/ets/test_type_alias1.ets +ast/parser/ets/unexpected_token_21.ets +ast/parser/ets/enum17.ets +ast/parser/ets/superStaticCall.ets +ast/parser/ets/unexpected_token_8.ets +ast/parser/ets/reserved_type.ets +ast/parser/ets/SmartCast_3.ets +ast/parser/ets/types_decls.ets +ast/parser/ets/partialInterface_n1.ets +ast/parser/ets/keyof_never.ets +ast/parser/ets/empty_launch.ets +ast/parser/ets/increment-on-nullish-type-undefined.ets +ast/parser/ets/generics_type_param_no_typeargs_no_default.ets +ast/parser/ets/lambda_infer_type_neg_1.ets +ast/parser/ets/readonlyFunctionTypeAnnotation.ets +ast/parser/ets/readonlyGetterSetterReassignment1.ets +ast/parser/ets/interface_instantiation.ets +ast/parser/ets/Dollar_doller_invalid2.ets +ast/parser/ets/enum3.ets +ast/parser/ets/static_field_5.ets +ast/parser/ets/unexpected_token_5.ets +ast/parser/ets/new_object_undefined.ets +ast/parser/ets/unexpected_token_40.ets +ast/parser/ets/string_literal_01.ets +ast/parser/ets/wrong_context_function_4.ets +ast/parser/ets/struct_extends_class.ets +ast/parser/ets/keyof_union.ets +ast/parser/ets/for_await_of_loop.ets +ast/parser/ets/keyof_private_and_protected.ets +ast/parser/ets/local-class-member-access-modifier-protected1.ets +ast/parser/ets/MultipleClassErrors.ets +ast/parser/ets/unexpected_token_15.ets +ast/parser/ets/arrAsArray.ets +ast/parser/ets/ambient_indexer_2.ets +ast/parser/ets/method_modifier_check_10.ets +ast/parser/ets/switch_num_compare_char_duplicate.ets +ast/parser/ets/static_func_call_8.ets +ast/parser/ets/InvalidLexer.ets +ast/parser/ets/local_class_already_class.ets +ast/parser/ets/illegal_break_statement.ets +ast/parser/ets/user_defined_13.ets +ast/parser/ets/unexpected_token_22.ets +ast/parser/ets/SmartCast_4.ets +ast/parser/ets/static_func_call_3.ets +ast/parser/ets/generics_1.ets +ast/parser/ets/unexpected_token_56.ets +ast/parser/ets/index_not_support_such_type.ets +ast/parser/ets/unexpected_token_45.ets +ast/parser/ets/unexpected_token_26.ets +ast/parser/ets/this_type_function_return_invalid.ets +ast/parser/ets/InvalidStatements2.ets +ast/parser/ets/user_defined_18.ets +ast/parser/ets/array_new_failed.ets +ast/parser/ets/trailing_comma_2.ets +ast/parser/ets/this_type_lambda_declaration_parameter_invalid.ets +ast/parser/ets/static_field_1.ets +ast/parser/ets/struct_with_component_annotation.ets +ast/parser/ets/InferTypeParamFromParam2.ets +ast/parser/ets/interface.ets +ast/parser/ets/namespace_badtoken01.ets +ast/parser/ets/recordKeyTypeCheck02.ets +ast/parser/ets/user_defined_15.ets +ast/parser/ets/ambient_iterable_declaration.ets +ast/parser/ets/lambda_omit_parentheses_parameter_neg_1.ets +ast/parser/ets/object_literal_dup_keys_0.ets +ast/parser/ets/global_const_vars1.ets +ast/parser/ets/partialType_4.ets +ast/parser/ets/function_implicit_return_type4.ets +ast/parser/ets/lambda_optional_param_3.ets +ast/parser/ets/type_variance3.ets +ast/parser/ets/partial_interface.ets +ast/parser/ets/wrong_context_class_3.ets +ast/parser/ets/try_catch_alive_2.ets +ast/parser/ets/enum14.ets +ast/parser/ets/UnexpectedToken.ets +ast/parser/ets/unexpected_token_4.ets +ast/parser/ets/setter_with_non_void.ets +ast/parser/ets/local_class_already_interface.ets +ast/parser/ets/returntype_override_object.ets +ast/parser/ets/class_optional_property.ets +ast/parser/ets/unexpected_token_60.ets +ast/parser/ets/illegal_line_after_throw.ets +ast/parser/ets/enum5.ets +ast/parser/ets/new_object_2.ets +ast/parser/ets/unexpected_token_51.ets +ast/parser/ets/constructors.ets +ast/parser/ets/static_func_call_7.ets +ast/parser/ets/constructor_with_return_3.ets +ast/parser/ets/unexpected_token_18.ets +ast/parser/ets/interfaceMethodReadonlyModifier.ets +ast/parser/ets/switch_enum2.ets +ast/parser/ets/declare_class_bad_5.ets +ast/parser/ets/async_func_return_type_bad.ets +ast/parser/ets/method_modifier_check_2.ets +ast/parser/ets/main_entry_point_2.ets +ast/parser/ets/ambiguous_call_3.ets +ast/parser/ets/method_modifier_check_13.ets +ast/parser/ets/differentTypeCompare.ets +ast/parser/ets/Interface_variable_identifier.ets +ast/parser/ets/interface_with_different_type.ets +ast/parser/ets/enum16.ets +ast/parser/ets/function_implicit_return_type3.ets +ast/parser/ets/class_as_object_1.ets +ast/parser/ets/tuple_trailing_comma.ets +ast/parser/ets/lambda_omit_parentheses_type_alias_neg_1.ets +ast/parser/ets/unexpected_token_2.ets +ast/parser/ets/getter_setter_modifier_diff.ets +ast/parser/ets/forOfCustomIterator1.ets +ast/parser/ets/property-access-method-2.ets +ast/parser/ets/switch_readonly_member_number_duplicate.ets +ast/parser/ets/declare_class_bad_3.ets +ast/parser/ets/launch_unresolved.ets +ast/parser/ets/call_expression_for_non_functional_type.ets +ast/parser/ets/keyof_array_tuple.ets +ast/parser/ets/user_defined_23.ets +ast/parser/ets/generic_defined_before_use_neg_4.ets +ast/parser/ets/this_type_lambda_declaration_parameter_in_class_invalid.ets +ast/parser/ets/double_parenthesis_invocation_supposed_to_fail.ets +ast/parser/ets/functionTypeWithDefaultParam1.ets +ast/parser/ets/cast_expressions9.ets +ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets +ast/parser/ets/interface_private_function_1.ets +ast/parser/ets/unexpected_token_39.ets +ast/parser/ets/cast_expressions2.ets +ast/parser/ets/unexpected_token_58.ets +ast/parser/ets/unexpected_token_11.ets +ast/parser/ets/constructor_with_return_1.ets +ast/parser/ets/lambda-type-inference-neg.ets +ast/parser/ets/genericDefaultParam_2.ets +ast/parser/ets/MultipleFunctionErrors.ets +ast/parser/ets/unexpected_token_49.ets +ast/parser/ets/unexpected_token_43.ets +ast/parser/ets/static_func_call_6.ets +ast/parser/ets/iterator_override_next.ets +ast/parser/ets/user_defined_10.ets +ast/parser/ets/tuple_type_4_neg.ets +ast/parser/ets/unexpected_token_24.ets +ast/parser/ets/wrong_context_class_4.ets +ast/parser/ets/property-access-method-1.ets +ast/parser/ets/record_dup_key_02.ets +ast/parser/ets/switch_readonly_member_different_enum.ets +ast/parser/ets/user_defined_25.ets +ast/parser/ets/partialInterface_n0.ets +ast/parser/ets/unexpected_token_9.ets +ast/parser/ets/static_field_4.ets +ast/parser/ets/local-interface-member-access-modifier-private1.ets +ast/parser/ets/class-instance-field-redeclaration.ets +ast/parser/ets/enum11.ets +ast/parser/ets/user_defined_11.ets +ast/parser/ets/InvalidTyped.ets +ast/parser/ets/invalid_type_assignment.ets +ast/parser/ets/DeclareAsyncFunction.ets +ast/parser/ets/unexpected_token_1.ets +ast/parser/ets/InvalidStatements3.ets +ast/parser/ets/enum20.ets +ast/parser/ets/struct_in_interface.ets +ast/parser/ets/this_type_function_parameter_invalid.ets +ast/parser/ets/declare_func_bad.ets +ast/parser/ets/assignment_with_wrong_type.ets +ast/parser/ets/functionTypeWithDefaultParam2.ets +ast/parser/ets/method_modifier_check_12.ets +ast/parser/ets/generics_type_param_constraint_8.ets +ast/parser/ets/local-class-member-access-modifier-public1.ets +ast/parser/ets/enum7.ets +ast/parser/ets/InterfacePrivateMethod.ets +ast/parser/ets/switch_const_int_compare_char_duplicate.ets +ast/parser/ets/Dollar_doller_invalid3.ets +ast/parser/ets/try_catch_alive_3.ets +ast/parser/ets/local_class_already_variable.ets +ast/parser/ets/static_function_override_4.ets +ast/parser/ets/await_argument_null.ets +ast/parser/ets/native_constructor_non_empty_body.ets +ast/parser/ets/primitive_type_method_1.ets +ast/parser/ets/Multiline_string_escape_char.ets +ast/parser/ets/missing_in_if_statement_1.ets +ast/parser/ets/user_defined_9.ets +ast/parser/ets/unexpected_token_12.ets +ast/parser/ets/methods.ets +ast/parser/ets/nested_function.ets +ast/parser/ets/returntype_override_primitive.ets +ast/parser/ets/lambda_optional_param_2.ets +ast/parser/ets/ambient_indexer_3.ets +ast/parser/ets/required_multiple_fields.ets +ast/parser/ets/user_defined_5.ets +ast/parser/ets/object_literal_dup_keys_2.ets +ast/parser/ets/main_entry_point_3.ets +ast/parser/ets/local_interface_already_interface.ets +ast/parser/ets/generic_defined_before_use_neg_2.ets +ast/parser/ets/type_decution_unnecessary_boxing.ets +ast/parser/ets/ets_never_type_without_affect_other.ets +ast/parser/ets/return_type_non_match.ets +ast/parser/ets/nested_function_1.ets +ast/parser/ets/interfaces3.ets +ast/parser/ets/tuple_type_2_neg.ets +ast/parser/ets/interfaceExtendInterfaces2.ets +ast/parser/ets/this_type_lambda_definition_parameter_invalid.ets +ast/parser/ets/abstract_class_modidier.ets +ast/parser/ets/unexpected_token_47.ets +ast/parser/ets/wrongReadonlyUtilityType.ets +ast/parser/ets/assign-func-iface.ets +ast/parser/ets/labeled.ets +ast/parser/ets/array_missing_element.ets +ast/parser/ets/constFloatInSwitch.ets +ast/parser/ets/getter_setter_access_modifiers_2.ets +ast/parser/ets/global_scope_string.ets +ast/parser/ets/static_func_call_4.ets +ast/parser/ets/unexpected_token_23.ets +ast/parser/ets/null_invalid.ets +ast/parser/ets/static_func_call_5.ets +ast/parser/ets/keyof_predefined_type.ets +ast/parser/ets/loops.ets +ast/parser/ets/generic_defined_before_use_neg_3.ets +ast/parser/ets/user_defined_21.ets +ast/parser/ets/ambiguous_call_2.ets +ast/parser/ets/generic_defined_before_use_neg_1.ets +ast/parser/ets/local_class_in_classfunction.ets +ast/parser/ets/unexpected_token_42.ets +ast/parser/ets/local-class-member-access-modifier-private2.ets +ast/parser/ets/required_multiple_fields_2.ets +ast/parser/ets/accessor_call.ets +ast/parser/ets/this_type_class_method_parameter_invalid.ets +ast/parser/ets/unexpected_token_61.ets +ast/parser/ets/property-access-field-1.ets +ast/parser/ets/switch_readonly_member_enum_duplicate.ets +ast/parser/ets/superInConstructor2.ets +ast/parser/ets/unexpected_token_53.ets +ast/parser/ets/invalidTypes.ets +ast/parser/ets/swtich_not_const.ets +ast/parser/ets/keyof_smartcast.ets +ast/parser/ets/struct_extends_struct.ets +ast/parser/ets/try_catch_alive_7.ets +ast/parser/ets/declare_class_bad_4.ets +ast/parser/ets/this_type_class_static_method_parameter_invalid.ets +ast/parser/ets/array_type.ets +ast/parser/ets/global_const_vars4.ets +ast/parser/ets/AllowSequence.ets +ast/parser/ets/declare_class_bad_1.ets +ast/parser/ets/InterfaceWithDefaultFunction1.ets +ast/parser/ets/partial_not_reference_type.ets +ast/parser/ets/assert_with_not_boolean_type_1.ets +ast/parser/ets/test_type_alias10.ets +ast/parser/ets/windows_multiline_comments.ets +ast/parser/ets/override_method.ets +ast/parser/ets/wrong_context_class_1.ets +ast/parser/ets/new_object_1.ets +ast/parser/ets/unexpected_token_6.ets +ast/parser/ets/native_function_without_return_type.ets +ast/parser/ets/spreadexpr_in_newexpr_neg01.ets +ast/parser/ets/unexpected_token_38.ets +ast/parser/ets/single_statement_1.ets +ast/parser/ets/StructTest2.ets +ast/parser/ets/struct_keywords1.ets +ast/parser/ets/this_type_class_field_invalid.ets +ast/parser/ets/n_nullableTypeMissingNull.ets +ast/parser/ets/this_type_lambda_definition_parameter_in_class_invalid.ets +ast/parser/ets/non_proper_index_method.ets +ast/parser/ets/type_argument_conversion.ets +ast/parser/ets/local-interface-access-modifier-private.ets +ast/parser/ets/unexpected_token_57.ets +ast/parser/ets/staticFunctionCallOfObject.ets +ast/parser/ets/functionTypeParam_neg2.ets +ast/parser/ets/instanceof_with_not_object_type.ets +ast/parser/ets/InvalidExpressions.ets +ast/parser/ets/n_returnNullFromFunction.ets +ast/parser/ets/local-interface-access-modifier-protected.ets +ast/parser/ets/Dollar_doller_invalid1.ets +ast/parser/ets/local-class-member-access-modifier-protected2.ets +ast/parser/ets/generic_defined_before_use_neg_6.ets +ast/parser/ets/default_parameter3.ets +ast/parser/ets/try_catch_alive_9.ets +ast/parser/ets/struct_keywords3.ets +ast/parser/ets/test_type_alias3.ets +ast/parser/ets/namespace_bad_token.ets +ast/parser/ets/optional_field_variable_forof.ets +ast/parser/ets/StructTest1.ets +ast/parser/ets/n_arrayHoldingNullValue.ets +ast/parser/ets/local-class-access-modifier-protected.ets +ast/parser/ets/unexpected_token_32.ets +ast/parser/ets/assert_with_not_boolean_type_2.ets +ast/parser/ets/switch_enum_string_case_duplicate.ets +ast/parser/ets/instantied_abstract_class_with_array_creation_expression.ets +ast/parser/ets/unexpected_token_54.ets +ast/parser/ets/local-interface-member-access-modifier-protected1.ets +ast/parser/ets/array_union_type_not_contains_nullish_type.ets +ast/parser/ets/illegal_union_member_exp.ets +ast/parser/ets/struct_in_struct.ets +ast/parser/ets/this_type_lambda_definition_return_invalid.ets +ast/parser/ets/unexpected_token_19.ets +ast/parser/ets/unexpected_token_16.ets +ast/parser/ets/labeledBlockStatement.ets +ast/parser/ets/enum6.ets +ast/parser/ets/struct_extends_interface.ets +ast/parser/ets/instantied_interface_with_array_creation_expression.ets +ast/parser/ets/lexer002.ets +ast/parser/ets/function_implicit_return_type.ets +ast/parser/ets/lexer001.ets +ast/parser/ets/spreadArrayInTuple.ets +ast/parser/ets/enum27.ets +ast/parser/ets/recordKeyTypeCheck03.ets +ast/parser/ets/await_object_bad.ets +ast/parser/ets/unexpected_token_29.ets +ast/parser/ets/null-coalesc-negative.ets +ast/parser/ets/recordIndexing.ets +ast/parser/ets/record_dup_key_01.ets +ast/parser/ets/try_catch_alive_6.ets +ast/parser/ets/global_scope_boolean.ets +ast/parser/ets/interfaceMethodStaticModifier.ets +ast/parser/ets/wrong_context_class_2.ets +ast/parser/ets/unexpected_token_48.ets +ast/parser/ets/default_parameter2.ets +ast/parser/ets/lambdaWithWrongOptionalParameter.ets +ast/parser/ets/tupleIndexWithLargeInt.ets +ast/parser/ets/struct_invalid_local.ets +ast/parser/ets/enum26.ets +ast/parser/ets/forOfCustomIterator2.ets +ast/parser/ets/launch_non_callable.ets +ast/parser/ets/missing_in_if_statement_2.ets +ast/parser/ets/unexpected_token_14.ets +ast/parser/ets/lambda_omit_parentheses_parameter_neg_3.ets +ast/parser/ets/for_of_04.ets +ast/parser/ets/cast_expressions10.ets +ast/parser/ets/named_types.ets +ast/parser/ets/native_constructor_empty_body.ets +ast/parser/ets/user_defined_19.ets +ast/parser/ets/accessor_with_this_param.ets +ast/parser/ets/constructor_super_call2.ets +ast/parser/ets/constructor_default_super.ets +ast/parser/ets/global_const_vars2.ets +ast/parser/ets/user_defined_8.ets +ast/parser/ets/main_entry_point_5.ets +ast/parser/ets/record_init_check.ets +ast/parser/ets/property-access-field-2.ets +ast/parser/ets/functionTypeParam_neg.ets +ast/parser/ets/interface-override-function.ets +ast/parser/ets/FunctionalTypeAsArrayElement.ets +ast/parser/ets/this_type_lambda_definition_return_in_class_invalid.ets +ast/parser/ets/user_defined_12.ets +ast/parser/ets/unexpected_token_27.ets +ast/parser/ets/localTypeAlias_n.ets +ast/parser/ets/access_modifier_1.ets +ast/parser/ets/method_modifier_check_15.ets +ast/parser/ets/user_defined_16.ets +ast/parser/ets/enum_default_invalid_value_type.ets +ast/parser/ets/struct_implements_interface.ets +ast/parser/ets/constructor_type_inference_crash.ets +ast/parser/ets/wrong_context_function_1.ets +ast/parser/ets/empty_array_map_inference_fail.ets +ast/parser/ets/illegal_continue_statement.ets +ast/parser/ets/minus_sign_as_index_1.ets +ast/parser/ets/export_after_statement.ets +ast/parser/ets/unreachable_fuzz_error.ets +ast/parser/ets/interface_parser_error_1.ets +ast/parser/ets/interface_parser_error_2.ets +ast/parser/ets/overloaded_method_as_value_neg.ets +ast/parser/ets/lambda_function_index_access_neg.ets +ast/compiler/ets/union_string_literals_5.ets +ast/compiler/ets/annotation_tests/annotation_for_type_parameter01.ets +ast/compiler/ets/readonlyType_4.ets +ast/compiler/ets/annotation_tests/annotationUsage_excessive_param02.ets +ast/compiler/ets/ambient_indexer_2.ets +ast/compiler/ets/annotation_tests/annotation_for_types_in_interface.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_arguements01.ets +ast/compiler/ets/method-resolution-class-and-interface-in-signatures_4.ets +ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets +ast/compiler/ets/mostSpecificMethod1.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_on_class.ets +ast/compiler/ets/function_subtyping_3.ets +ast/compiler/ets/annotation_tests/annotationUsage_bad_param10.ets +ast/compiler/ets/readonlyType_5.ets +ast/compiler/ets/annotation_tests/annotation_for_array_type02.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_type_alias.ets +ast/compiler/ets/objectLiteralBadKey.ets +ast/compiler/ets/annotation_tests/annotation_for_types_in_annotation.ets +ast/compiler/ets/lambda_type_mismatch.ets +ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_classproperty.ets +ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets +ast/compiler/ets/annotation_tests/annotation_for_type_parameter02.ets +ast/compiler/ets/readonlyType_3.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_classproperty.ets +ast/compiler/ets/etsObjectToString0.ets +ast/compiler/ets/annotation_tests/annotation_for_tuple_type.ets +ast/compiler/ets/void_as_value_neg_3.ets +ast/compiler/ets/annotation_tests/annotation_for_boxing_type.ets +ast/compiler/ets/nullable_type_in_stringconcat_func.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_on_function.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_interface.ets +ast/compiler/ets/tuple_types_1_neg.ets +ast/compiler/ets/annotation_tests/ambient_annotations_bad_type03.ets +ast/compiler/ets/invalidPrivateAccess1.ets +ast/compiler/ets/annotation_tests/annotation_for_types_in_variance.ets +ast/compiler/ets/identifierReference11.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfacemethod.ets +ast/compiler/ets/readonlyField_2.ets +ast/compiler/ets/annotation_tests/annotation_for_array_type01.ets +ast/compiler/ets/recursive_interface_neg_1.ets +ast/compiler/ets/annotation_tests/annotationDecl_bad_type.ets +ast/compiler/ets/ambient_namesapce07.ets +ast/compiler/ets/annotation_tests/annotation_for_types_in_class.ets +ast/compiler/ets/typeOfString.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type04.ets +ast/compiler/ets/getterNoReturn1.ets +ast/compiler/ets/annotation_tests/annotation_for_union_type.ets +ast/compiler/ets/switch_negative_5.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_classproperty.ets +ast/compiler/ets/annotation_tests/annotationUsage_conflict_for_namespace02.ets +ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type14.ets +ast/compiler/ets/setter_func_no_return_type.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets +ast/compiler/ets/genericObjectLiteral_neg_3.ets +ast/compiler/ets/annotation_tests/annotation_for_readonly_type.ets +ast/compiler/ets/variable_declaretion_neg_1.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_from_import.ets +ast/compiler/ets/requiredType_8_neg.ets +ast/compiler/ets/annotation_tests/annotation_for_types_in_function.ets +ast/compiler/ets/objectLiteral_abstract_class_2.ets +ast/compiler/ets/annotation_tests/ambient_annotations_bad_type01.ets +ast/compiler/ets/generics_implicit_lambda2.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type12.ets +ast/compiler/ets/void_as_return_type_neg_1.ets +ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_variable_decl.ets +ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_function_param.ets +ast/compiler/ets/union_types_2.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type09.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_on_extension_lambda.ets +ast/compiler/ets/namespace_export_invalid02.ets +ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets +ast/compiler/ets/readonlyType_1.ets +ast/compiler/ets/annotation_tests/annotationUsage_bad_param08.ets +ast/compiler/ets/export_and_export_type_class.ets +ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_interface.ets +ast/compiler/ets/trailing_lambda.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_variable_decl.ets +ast/compiler/ets/identifierReference9.ets +ast/compiler/ets/annotation_tests/annotation_for_other_type.ets +ast/compiler/ets/assert_bad.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_variable_decl.ets +ast/compiler/ets/null_coalescing_generic_1_neg.ets +ast/compiler/ets/annotation_tests/annotation_for_types_in_expression.ets +ast/compiler/ets/overload_equivalent_generics.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_arguements02.ets +ast/compiler/ets/variance_typeparam_class.ets +ast/compiler/ets/annotation_tests/annotation_for_function_type.ets +ast/compiler/ets/override11.ets +ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets +ast/compiler/ets/forbidden_inherit_class_3.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type01.ets +ast/compiler/ets/ObjectLiteral_neg_2.ets +ast/compiler/ets/recursive_method_neg_2.ets +ast/compiler/ets/nullable_type_in_arithmeticmult_func_w_undefined.ets +ast/compiler/ets/union_string_literals_4.ets +ast/compiler/ets/objectLiteral_abstract_class.ets +ast/compiler/ets/etsObjectToString3.ets +ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets +ast/compiler/ets/enum-to-int-conversion.ets +ast/compiler/ets/expression/this_expression/undefined_class_for_this_1.ets +ast/compiler/ets/generic_function_call_2.ets +ast/compiler/ets/expression/this_expression/undefined_class_for_this_2.ets +ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets +ast/compiler/ets/same_assembly_overload/identical_signature.ets +ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets +ast/compiler/ets/extension_accessor_tests/setterAsFunctionCall.ets +ast/compiler/ets/objectLiteralInterface3.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithInterfaceInstanceField.ets +ast/compiler/ets/variance_typeparam_super.ets +ast/compiler/ets/extension_accessor_tests/extensionGetterInWrongUsage.ets +ast/compiler/ets/recursive_method_neg_1.ets +ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets +ast/compiler/ets/thisReferenceFromStaticContext.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithInstanceField.ets +ast/compiler/ets/ambient_namesapce04.ets +ast/compiler/ets/extension_accessor_tests/getterAsMethodCall.ets +ast/compiler/ets/async_with_non_generic_return_type.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorParams.ets +ast/compiler/ets/nullable_type_in_arithmeticplus_func.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets +ast/compiler/ets/void_as_return_type_neg_2.ets +ast/compiler/ets/extension_accessor_tests/setterAsMethodCall.ets +ast/compiler/ets/FunctionType8.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithSuperMethod2.ets +ast/compiler/ets/invalidMemberExpressionFromStaticContext4.ets +ast/compiler/ets/implicit_package_import/scopes_multi_error.ets +ast/compiler/ets/recursive_union_neg_2.ets +ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets +ast/compiler/ets/generic_class_without_type_arg_1.ets +ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets +ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets +ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets +ast/compiler/ets/validate_signatures_throw_type_error.ets +ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets +ast/compiler/ets/unionCommonMember_neg.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorMissingReceiver.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithSuperInstanceField.ets +ast/compiler/ets/Non-static-private-method-used-as-val-neg.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithMethod1.ets +ast/compiler/ets/tuple_types_11_neg.ets +ast/compiler/ets/extension_accessor_tests/extensionSetCantReturnValue.ets +ast/compiler/ets/conversion_Double-to-Int_w_try_stmt_typerror.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets +ast/compiler/ets/invalidMemberExpressionFromStaticContext3.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithMethod2.ets +ast/compiler/ets/partialType_1_neg.ets +ast/compiler/ets/extension_accessor_tests/extensionGetMustReturnValue.ets +ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithSuperMethod1.ets +ast/compiler/ets/resolve_func_name_union_type_1.ets +ast/compiler/ets/extension_accessor_tests/getterAsFunctionCall.ets +ast/compiler/ets/implicit_package_import/package_test_7/package_module_1_neg.ets +ast/compiler/ets/invalidInheritance2.ets +ast/compiler/ets/implicit_package_import/package_test_7/package_module_2_neg.ets +ast/compiler/ets/variance_typeparam_union.ets +ast/compiler/ets/implicit_package_import/package_test_5/package_module_1.ets +ast/compiler/ets/staticInitializerInInnerClass.ets +ast/compiler/ets/implicit_package_import/package_test_5/package_module_2_neg.ets +ast/compiler/ets/tuple_types_3_neg.ets +ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets +ast/compiler/ets/same_name_field_err.ets +ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets +ast/compiler/ets/implicit_package_import/package_test_4/package_module_1.ets +ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets +ast/compiler/ets/implicit_package_import/package_test_3/package_module_1_neg.ets +ast/compiler/ets/implicit_package_import/package_test_3/package_module_2_neg.ets +ast/compiler/ets/union_string_literals_2.ets +ast/compiler/ets/union_array_declaration.ets +ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets +ast/compiler/ets/tuple_types_2_neg.ets +ast/compiler/ets/FixedArray/array_indexing_without_chaining_nullish.ets +ast/compiler/ets/generic_typealias_3_neg.ets +ast/compiler/ets/FixedArray/for_of_missing_iterator_type.ets +ast/compiler/ets/namespace_export_invalid01.ets +ast/compiler/ets/FixedArray/tuple_types_5_neg.ets +ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets +ast/compiler/ets/implicit_package_import/package_test_8/import_multi_error.ets +ast/compiler/ets/return_missing_argument.ets +ast/compiler/ets/type_error_processing/not_constructible_types.ets +ast/compiler/ets/export_type_variable_at_definition.ets +ast/compiler/ets/type_error_processing/var_without_def.ets +ast/compiler/ets/objectLiteralInaccessibleKey.ets +ast/compiler/ets/type_error_processing/type_handlers.ets +ast/compiler/ets/identifierReference3.ets +ast/compiler/ets/lambda_with_receiver_tests/extensionFuncTypeAsParamsNameDuplicated2.ets +ast/compiler/ets/objectLiteralNoContextType.ets +ast/compiler/ets/lambda_with_receiver_tests/MakeNormalFunctypeAsMethodCall.ets +ast/compiler/ets/lambda_with_receiver_tests/extensionFuncTypeAsParamsNameDuplicated3.ets +ast/compiler/ets/inferTypeOfArrayNegative2.ets +ast/compiler/ets/lambda_with_receiver_tests/extensionFuncTypeAsParamsNameDuplicated.ets +ast/compiler/ets/TypeError_recursive_parameter_2.ets +ast/compiler/ets/lambda_with_receiver_tests/ExtensionFunctypeUncompatible.ets +ast/compiler/ets/genericObjectLiteral_neg_2.ets +ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets +ast/compiler/ets/FixedArray/annotation_tests/ambient_annotations_bad_type02.ets +ast/compiler/ets/method-resolution-class-and-interface-in-signatures_1.ets +ast/compiler/ets/FixedArray/union_string_literals_7.ets +ast/compiler/ets/FixedArray/setArrayLength3.ets +ast/compiler/ets/FunctionType9.ets +ast/compiler/ets/namespace_tests/namespace_as_type03.ets +ast/compiler/ets/setArrayLength3.ets +ast/compiler/ets/namespace_tests/namespace_as_type07.ets +ast/compiler/ets/variance_typeparam.ets +ast/compiler/ets/FixedArray/setArrayLength1.ets +ast/compiler/ets/recursive_union_neg_1.ets +ast/compiler/ets/FixedArray/annotation_tests/annotation_for_array_type01.ets +ast/compiler/ets/tuple_types_5_neg.ets +ast/compiler/ets/namespace_tests/namespace_bad_merged01.ets +ast/compiler/ets/objectLiteralWrongValueType.ets +ast/compiler/ets/namespace_tests/src01.ets +ast/compiler/ets/method-resolution-class-and-interface-in-signatures_2.ets +ast/compiler/ets/superReferenceFromStaticContext.ets +ast/compiler/ets/namespace_tests/namespace_bad_merged02.ets +ast/compiler/ets/string_tuple_type_neg.ets +ast/compiler/ets/FixedArray/lambda_type_mismatch.ets +ast/compiler/ets/invalidMemberExpressionFromStaticContext7.ets +ast/compiler/ets/FixedArray/tuple_types_1_neg.ets +ast/compiler/ets/variance_typeparam_tuple.ets +ast/compiler/ets/FixedArray/unionCommonMember_neg.ets +ast/compiler/ets/invalidMemberExpressionFromStaticContext8.ets +ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets +ast/compiler/ets/namespace_tests/namespace_as_type02.ets +ast/compiler/ets/generic_typealias_4_neg.ets +ast/compiler/ets/namespace_tests/namespace_access_violation.ets +ast/compiler/ets/invalidMemberExpressionFromStaticContext2.ets +ast/compiler/ets/FixedArray/union_array_declaration.ets +ast/compiler/ets/overloadMethodNoReturn0.ets +ast/compiler/ets/FixedArray/setArrayLength2.ets +ast/compiler/ets/recordWithLambdaFunction1.ets +ast/compiler/ets/FixedArray/annotation_tests/annotation_for_readonly_type.ets +ast/compiler/ets/invalidPrivateAccess5.ets +ast/compiler/ets/etsObjectToString5.ets +ast/compiler/ets/namespace_tests/namespace_access_violation_nested_scopes.ets +ast/compiler/ets/partialType_2_neg.ets +ast/compiler/ets/namespace_tests/namespace_access_violation_scope_resolution.ets +ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets +ast/compiler/ets/invalidPrivateAccess2.ets +ast/compiler/ets/FixedArray/unresolved_reference.ets +ast/compiler/ets/tuple_types_9_neg.ets +ast/compiler/ets/FixedArray/annotation_tests/ambient_annotations_bad_type01.ets +ast/compiler/ets/identifierReference16.ets +ast/compiler/ets/namespace_tests/namespace_access_violation_exports.ets +ast/compiler/ets/ambient_namesapce02.ets +ast/compiler/ets/FixedArray/iterabletypes_with_protected_iterator_neg.ets +ast/compiler/ets/lambdaFunction3.ets +ast/compiler/ets/FixedArray/newClassInstanceExpression.ets +ast/compiler/ets/export_same_type_at_decl_and_selective_binding.ets +ast/compiler/ets/namespace_tests/namespace_merge_conflicts.ets +ast/compiler/ets/invalidPrivateAccess6.ets +ast/compiler/ets/namespace_tests/namespace_as_type05.ets +ast/compiler/ets/invalidInheritanceFromClass.ets +ast/compiler/ets/FunctionType5.ets +ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets +ast/compiler/ets/invalidPrivateAccess3.ets +ast/compiler/ets/namespace_tests/namespace_access_violation_circular_dependencies.ets +ast/compiler/ets/invalidProtectedAccess3.ets +ast/compiler/ets/export_and_export_type_interface.ets +ast/compiler/ets/FixedArray/tuple_types_9_neg.ets +ast/compiler/ets/FunctionType3.ets +ast/compiler/ets/namespace_tests/namespace_access_violation_undefined_scopes.ets +ast/compiler/ets/nullable_type_in_arithmeticmult_func.ets +ast/compiler/ets/namespace_tests/namespace_as_type12.ets +ast/compiler/ets/genericObjectLiteral_neg_1.ets +ast/compiler/ets/void_as_typeAnnotation_neg_1.ets +ast/compiler/ets/namespace_tests/namespace_as_type01.ets +ast/compiler/ets/tryCatchErrorIncorrectParamType.ets +ast/compiler/ets/namespace_tests/namespace_as_type09.ets +ast/compiler/ets/generic_typealias_5_neg.ets +ast/compiler/ets/namespace_tests/namespace_access_violation_conflicts.ets +ast/compiler/ets/generics_primitive_type_param_neg_2.ets +ast/compiler/ets/namespace_tests/namespace_as_type11.ets +ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets +ast/compiler/ets/namespace_tests/namespace_default_import.ets +ast/compiler/ets/inferTypeOfArrayNegative3.ets +ast/compiler/ets/namespace_tests/namespace_as_type06.ets +ast/compiler/ets/FixedArray/variance_typeparam_array.ets +ast/compiler/ets/etsObjectToString2.ets +ast/compiler/ets/identifierReference10.ets +ast/compiler/ets/FixedArray/implicit_package_import/scopes_multi_error.ets +ast/compiler/ets/identifierReference2.ets +ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets +ast/compiler/ets/requiredType_6.ets +ast/compiler/ets/objectLiteralNoSuchKey.ets +ast/compiler/ets/FixedArray/extension_function_tests/array_extension_func_dupicated_name_with_builtin.ets +ast/compiler/ets/invalidProtectedAccess1.ets +ast/compiler/ets/infinityNarrowing.ets +ast/compiler/ets/generic_variance_4.ets +ast/compiler/ets/FixedArray/extension_function_tests/extension_function_return_this_neg2.ets +ast/compiler/ets/union_string_literals_1.ets +ast/compiler/ets/namespace_tests/namespace_as_type10.ets +ast/compiler/ets/invalidMemberExpressionFromStaticContext1.ets +ast/compiler/ets/default_export/export_default_bad2.ets +ast/compiler/ets/ambient_namesapce06.ets +ast/compiler/ets/identifierReference13.ets +ast/compiler/ets/generics_primitive_type_param_neg_1.ets +ast/compiler/ets/selective-export-multiple/import_ambient_const_neg.ets +ast/compiler/ets/tryCatchFlow.ets +ast/compiler/ets/switchcaseDuplicate.ets +ast/compiler/ets/setArrayLength2.ets +ast/compiler/ets/import_type_with_invalid_syntax.ets +ast/compiler/ets/tryCatchMissingParam.ets +ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets +ast/compiler/ets/forbidden_inherit_class_1.ets +ast/compiler/ets/namespace_tests/namespace_as_type08.ets +ast/compiler/ets/identifierReference1.ets +ast/compiler/ets/default_export/export_default_bad1.ets +ast/compiler/ets/readonlyType_6.ets +ast/compiler/ets/forbidden_inherit_class_2.ets +ast/compiler/ets/objectLiteralPrimitiveContextType.ets +ast/compiler/ets/lambdaFunction5.ets +ast/compiler/ets/array_with_type_parameter.ets +ast/compiler/ets/readonlyIntfObjectLiteral_neg_1.ets +ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets +ast/compiler/ets/tryCatchErrorFlow.ets +ast/compiler/ets/export_type_enum.ets +ast/compiler/ets/union_string_literals_6.ets +ast/compiler/ets/namespace_tests/namespace_as_type04.ets +ast/compiler/ets/FunctionType1.ets +ast/compiler/ets/invalidInheritance1.ets +ast/compiler/ets/absent_return_statement.ets +ast/compiler/ets/unresolved_reference.ets +ast/compiler/ets/generic_variance_5.ets +ast/compiler/ets/iterabletypes_with_protected_iterator_neg.ets +ast/compiler/ets/UnresolvedReferenceInCamparison.ets +ast/compiler/ets/invalidMemberExpressionFromStaticContext5.ets +ast/compiler/ets/override7.ets +ast/compiler/ets/invalidProtectedAccess2.ets +ast/compiler/ets/recordWithLambdaFunction2.ets +ast/compiler/ets/variance_typeparam_array.ets +ast/compiler/ets/spreadExpressionAsPropertyInObjectLiteral.ets +ast/compiler/ets/export_type_variable.ets +ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentType.ets +ast/compiler/ets/interfaceMethodNotOverridden.ets +ast/compiler/ets/lambda_infer_type/lambda_param_type_cannot_be_determined.ets +ast/compiler/ets/extension_function_tests/extension_function_return_this_union2.ets +ast/compiler/ets/extension_function_tests/extension_function_params_neg2.ets +ast/compiler/ets/extension_function_tests/normal_function_with_extension_style_signature.ets +ast/compiler/ets/namespace_tests/namespace_access_violation_non_exported_merge.ets +ast/compiler/ets/mostSpecificMethod2.ets +ast/compiler/ets/privateMethodOverride.ets +ast/compiler/ets/import_tests/export_multi_error.ets +ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets +ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets +ast/compiler/ets/extension_function_tests/extension_function_called_by_class.ets +ast/compiler/ets/extension_function_tests/extension_function_return_this_union3.ets +ast/compiler/ets/generic_typealias_2_neg.ets +ast/compiler/ets/tuple_types_4_neg.ets +ast/compiler/ets/annotation_tests/annotationUsage_excessive_param01.ets +ast/compiler/ets/import_tests/dynamic_import_interop_neg.ets +ast/compiler/ets/import_tests/selective_export_tests/import_function_wrong_name.ets +ast/compiler/ets/import_tests/selective_export_tests/import_interface_wrong_name.ets +ast/compiler/ets/import_tests/selective_export_tests/namespace_import_wrong_access_name.ets +ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_1.ets +ast/compiler/ets/extension_function_tests/array_extension_func_dupicated_name_with_builtin.ets +ast/compiler/ets/extension_function_tests/extension_function_not_for_class_type.ets +ast/compiler/ets/extension_function_tests/extension_function_duplication.ets +ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets +ast/compiler/ets/extension_function_tests/extension_function_return_this_neg3.ets +ast/compiler/ets/extension_function_tests/extension_function_shadowed_by_member_function.ets +ast/compiler/ets/extension_function_tests/put_this_as_method_params.ets +ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets +ast/compiler/ets/extension_function_tests/extension_function_access_private_field.ets +ast/compiler/ets/extension_function_tests/extension_function_shadowed_by_different_return_type_interface_function.ets +ast/compiler/ets/extension_function_tests/normal_function_duplicated_with_extension_function.ets +ast/compiler/ets/extension_function_tests/extension_function_return_this_neg2.ets +ast/compiler/ets/extension_function_tests/extension_function_params_neg1.ets +ast/compiler/ets/extension_function_tests/extension_function_return_this_union.ets +ast/compiler/ets/extension_function_tests/extension_function_for_unresolved_type.ets +ast/compiler/ets/extension_function_tests/extension_function_primitive.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_on_method.ets +ast/compiler/ets/this_type_invalid_return_type.ets +ast/compiler/ets/annotation_tests/annotation_for_object_type.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type08.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_namespace01.ets +ast/compiler/ets/variance_typeparam_transmit.ets +ast/compiler/ets/requiredType_2_neg.ets +ast/compiler/ets/generic_function_call_6.ets +ast/compiler/ets/enum_not_constant_var.ets +ast/compiler/ets/union_string_literals_8.ets +ast/compiler/ets/nullable_type_in_arithmeticplus_w_undefined.ets +ast/compiler/ets/override14.ets +ast/compiler/ets/tuple_types_10_neg.ets +ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interfaceproperty.ets +ast/compiler/ets/ambient_indexer_1.ets +ast/compiler/ets/namespace_tests/namespace_access_violation_merge_conflicts.ets +ast/compiler/ets/newClassInstanceExpression.ets +ast/compiler/ets/n_assignGenericWithNullableTypeParamToNonNullable.ets +ast/compiler/ets/overrideModifierNotOverriding.ets +ast/compiler/ets/tryCatchIncorrectParamType.ets +ast/compiler/ets/circular_variable_init.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_namespace02.ets +ast/compiler/ets/ambient_namesapce05.ets +ast/compiler/ets/identifierReference8.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_variable_decl.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type11.ets +ast/compiler/ets/annotation_tests/Retentions_missing_arguments.ets +ast/compiler/ets/method-resolution-class-and-interface-in-signatures_3.ets +ast/compiler/ets/void_as_value_neg_2.ets +ast/compiler/ets/readonlyIntfObjectLiteral_neg_2.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_interface.ets +ast/compiler/ets/annotation_tests/annotationUsage_excessive_param_for_type_alias.ets +ast/compiler/ets/generic_variance_2.ets +ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type05.ets +ast/compiler/ets/requiredType_3_neg.ets +ast/compiler/ets/etsObjectToString1.ets +ast/compiler/ets/objectLiteralPrivateConstructor.ets +ast/compiler/ets/invalidMemberExpressionFromStaticContext6.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_param_for_function_param.ets +ast/compiler/ets/void_as_value_neg_4.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_interface.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_AT01.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_AT02.ets +ast/compiler/ets/annotation_tests/annotation_for_annotation.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type06.ets +ast/compiler/ets/annotation_tests/annotationUsage_missing_AT_for_type_alias.ets +ast/compiler/ets/annotation_tests/annotation_without_source_policy.ets +ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type07.ets +ast/compiler/ets/annotation_tests/annotationUsage_duplicate_for_type_alias.ets +ast/compiler/ets/annotation_tests/annotation_for_string_literal.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type02.ets +ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer07.ets +ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_4.ets +ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_3.ets +ast/compiler/ets/import_tests/selective_export_tests/selective_export_clashing_exports_2.ets +ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets +ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets +ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets +ast/compiler/ets/import_tests/import_distant_package/master_file.ets +ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_2.ets +ast/compiler/ets/import_tests/import_distant_package/package_with_errors/package_with_errors_1.ets +ast/compiler/ets/identifierReference6.ets +ast/compiler/ets/conversion_Double-to-Int_typeerror.ets +ast/compiler/ets/ambient_namesapce03.ets +ast/compiler/ets/export_type_class_multiple_times.ets +ast/compiler/ets/TypeError_recursive_parameter_1.ets +ast/compiler/ets/FunctionType10.ets +ast/compiler/ets/recursive_interface_neg_2.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type03.ets +ast/compiler/ets/annotation_tests/annotationUsage_as_type13.ets +ast/compiler/ets/annotation_tests/annotation_for_named_type.ets +ast/compiler/ets/annotation_tests/annotationUsage_conflict_for_namespace01.ets +ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.ets +ast/compiler/ets/import_tests/import_distant_package/package_with_errors/inner_package_with_errors/distant_package.ets +ast/compiler/ets/annotation_tests/ambient_annotations_bad_type02.ets +ast/compiler/ets/constant_variable_import_tests/enum_import_constant.ets +ast/parser/ets/classAsFunctionParam.ets +ast/parser/ets/double_parenthesis_invocation_setter_supposed_to_fail.ets +ast/parser/ets/keyof_constraint.ets +ast/parser/ets/enum_default_negative1.ets +ast/parser/ets/predefined_non_primitive_types.ets +ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets +ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets +ast/parser/ets/dynamic_import_tests/dynamic_func_decl_import_bad.ets +ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets +ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets +ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param01.ets +ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token03.ets +ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token03.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_lambda.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets +ast/parser/ets/annotations_tests/annotation_rename_export.ets +ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token04.ets +ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token05.ets +ast/parser/ets/annotations_tests/annotationDecl_bad_initializer03.ets +ast/parser/ets/annotations_tests/annotationDecl_redefined.ets +ast/parser/ets/annotations_tests/annotation_export_type.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfacemethod.ets +ast/parser/ets/annotations_tests/annotationDecl_field_with_modifiers01.ets +ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token04.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_local_variable_decl.ets +ast/parser/ets/annotations_tests/annotationDecl_with_method.ets +ast/parser/ets/annotations_tests/annotationDecl_missing_typeAnnotation03.ets +ast/parser/ets/annotations_tests/annotationUsage_on_annotationDecl.ets +ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token05.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param05.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_type_alias.ets +ast/parser/ets/annotations_tests/annotationDecl_with_innerclass.ets +ast/parser/ets/annotations_tests/annotation_default_export.ets +ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token07.ets +ast/parser/ets/annotations_tests/annotationDecl_field_with_modifiers04.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_classproperty.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param07.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_global_variable_decl.ets +ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token01.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param06.ets +ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_function_param.ets +ast/parser/ets/annotations_tests/annotationDecl_bad_initializer02.ets +ast/parser/ets/annotations_tests/annotationDecl_field_with_modifiers03.ets +ast/parser/ets/annotations_tests/annotationDecl_classDecl_conflict.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interface.ets +ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token02.ets +ast/parser/ets/annotations_tests/annotationDecl_enum_conflict.ets +ast/parser/ets/annotations_tests/annotationUsage_tmp.ets +ast/parser/ets/annotations_tests/annotationDecl_field_with_modifiers02.ets +ast/parser/ets/annotations_tests/annotationDecl_bad_initializer06.ets +ast/parser/ets/annotations_tests/annotationUsage_on_abstract_class.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_function_param.ets +ast/parser/ets/annotations_tests/annotationDecl_missing_typeAnnotation01.ets +ast/parser/ets/annotations_tests/annotationUsage_on_abstract_method.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param_for_interfaceproperty.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param02.ets +ast/parser/ets/annotations_tests/annotationUsage_missing_AT_for_classproperty.ets +ast/parser/ets/annotations_tests/annotationDecl_bad_initializer01.ets +ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier01.ets +ast/parser/ets/annotations_tests/annotation_rename_import.ets +ast/parser/ets/annotations_tests/annotationDecl_bad_initializer04.ets +ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token06.ets +ast/parser/ets/annotations_tests/annotationDecl_parser_bad_token02.ets +ast/parser/ets/annotations_tests/annotationUsage_parser_bad_token01.ets +ast/parser/ets/annotations_tests/annotationDecl_interface_conflict.ets +ast/parser/ets/annotations_tests/annotationUsage_bad_param03.ets +ast/parser/ets/annotations_tests/annotationUsage_for_invalid_expr.ets +ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier03.ets +ast/parser/ets/annotations_tests/annotationUsage_missing_initializer01.ets +ast/parser/ets/annotations_tests/annotationDecl_with_access_modifier02.ets +ast/parser/ets/annotations_tests/annotationDecl_missing_typeAnnotation02.ets +ast/parser/ets/annotations_tests/annotationDecl_bad_initializer05.ets +ast/parser/ets/annotations_tests/annotationDecl_locally.ets +ast/parser/ets/import_tests/import_type_error_top_level.ets +ast/parser/ets/import_tests/import_name_conflict_4.ets +ast/parser/ets/import_tests/Import_error_token_1.ets +ast/parser/ets/import_tests/import_all_2.ets +ast/parser/ets/import_tests/import_all_alias_neg.ets +ast/parser/ets/import_tests/import_name_alias_2.ets +ast/parser/ets/import_tests/import_name_conflict_5.ets +ast/parser/ets/import_tests/import_name_3.ets +ast/parser/ets/import_tests/import_name_conflict_11.ets +ast/parser/ets/import_tests/import_name_conflict_8.ets +ast/parser/ets/import_tests/default_import3.ets +ast/parser/ets/import_tests/check_exported_1.ets +ast/parser/ets/import_tests/import_name_conflict_9.ets +ast/parser/ets/import_tests/import_name_conflict_1.ets +ast/parser/ets/import_tests/import_all_alias_2.ets +ast/parser/ets/import_tests/import_name_conflict_6.ets +ast/parser/ets/import_tests/export_no_comma.ets +ast/parser/ets/import_tests/default_import2.ets +ast/parser/ets/import_tests/import_folder_n.ets +ast/parser/ets/import_tests/import_name_conflict_10.ets +ast/parser/ets/import_tests/import_name_conflict_7.ets +ast/parser/ets/import_tests/export_trailing_comma.ets +ast/parser/ets/import_tests/import_name_2.ets +ast/parser/ets/import_tests/import_name_conflict_2.ets +ast/parser/ets/import_tests/import_type_error_in_class.ets +ast/parser/ets/import_tests/import_name_conflict_12.ets +ast/parser/ets/import_tests/import_no_comma.ets +ast/parser/ets/import_tests/packages/different-header/subpackage_module_1.ets +ast/parser/ets/import_tests/packages/different-header/subpackage_module_2.ets +ast/parser/ets/import_tests/invalid_default_export/default_export_invalid_syntax_3.ets +ast/parser/ets/import_tests/modules/too_many_default_exports_2.ets +ast/parser/ets/import_tests/modules/too_many_default_exports.ets +ast/parser/ets/import_tests/modules/invalid_namespace_import.ets +ast/parser/ets/import_tests/invalid_default_export/default_export_invalid_syntax_4.ets +ast/parser/ets/import_tests/import_alias/import_alias_3.ets +ast/parser/ets/import_tests/import_alias/import_alias_2.ets +ast/parser/ets/import_tests/import_alias/import_alias_4.ets +ast/parser/ets/import_tests/import_name_conflicts/main_1.ets +ast/parser/ets/import_tests/import_name_conflicts/main_6.ets +ast/parser/ets/import_tests/import_name_conflicts/main_4.ets +ast/parser/ets/import_tests/import_name_conflicts/main_7.ets +ast/parser/ets/import_tests/wrong_import_decl_placement/import_decl_in_block_n.ets +ast/parser/ets/import_tests/wrong_import_decl_placement/import_decl_after_decl_n.ets +ast/parser/ets/import_tests/import_name_conflicts/main_5.ets +ast/parser/ets/import_tests/import_name_conflicts/main_8.ets +ast/parser/ets/import_tests/import_name_conflicts/main_3.ets +ast/parser/ets/import_tests/import_name_conflicts/main_2.ets +ast/parser/ets/import_tests/type/import_type_1.ets +ast/parser/ets/import_tests/type/type_2.ets +ast/parser/ets/import_tests/type/type_3.ets +ast/parser/ets/import_tests/type/import_type_2.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test6.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test1.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-and-Readonly-test2.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test3.ets +ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test1.ets +ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test1.ets +ast/parser/ets/trailing_lambda_tests/trailing_lambda_mismatch_lambda_signature_1.ets +ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_1.ets +ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_3.ets +ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_5.ets +ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_2.ets +ast/parser/ets/trailing_lambda_tests/trailing_lambda_not_transform_trailing_block_4.ets +ast/parser/ets/trailing_lambda_tests/trailing_lambda_omit_call_parentheses.ets +ast/parser/ets/re_export/import_5.ets +ast/parser/ets/type_variance2.ets +ast/parser/ets/type_variance4.ets +ast/parser/ets/MultipleParserErrors.ets +ast/parser/ets/local-class-member-access-modifier-public2.ets +ast/parser/ets/local-class-access-modifier-public.ets +ast/parser/ets/setter_with_more_than_one_formal_parameter.ets +ast/parser/ets/keyof_parameter.ets +ast/parser/ets/method_full.ets +ast/parser/ets/try_catch_alive_4.ets +ast/parser/ets/class_variable_empty.ets +ast/parser/ets/unexpected_token_46.ets +ast/parser/ets/StringFasta.ets +ast/parser/ets/unexpected_token_55.ets +ast/parser/ets/re_export/import_17.ets +ast/parser/ets/FixedArray/main_entry_point_3.ets +ast/parser/ets/FixedArray/for_of_02.ets +ast/parser/ets/FixedArray/unexpected_token_31.ets +ast/parser/ets/FixedArray/main_entry_point_4.ets +ast/parser/ets/FixedArray/spreadexpr_in_newexpr_neg02.ets +ast/parser/ets/extension_function_tests/extension_function_not_in_toplevel.ets +ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test4.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test4.ets +ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets +ast/parser/ets/static_invoke_tests/static_invoke_mismatch_signature_1.ets +ast/parser/ets/static_invoke_tests/static_invoke_coexist_invoke_method.ets +ast/parser/ets/static_invoke_tests/static_invoke_mismatch_signature.ets +ast/parser/ets/static_invoke_tests/static_invoke_mismatch_signature_2.ets +ast/parser/ets/single_export/single_export_n.ets +ast/parser/ets/single_export/single_export_from_n.ets +ast/parser/ets/single_export/single_export_lambda.ets +ast/parser/ets/single_export/single_export_expression.ets +ast/parser/ets/single_export/single_export_default_lambda.ets +ast/parser/ets/single_export/single_export_as_n.ets +ast/compiler/ets/generic_variance_3.ets +ast/compiler/ets/recursive_function_neg_1.ets +ast/compiler/ets/readonlyType_2.ets +ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets +ast/compiler/ets/identifierReference12.ets +ast/parser/ets/enum_multi_error/enum_not_pair_brackets.ets +ast/parser/ets/enum_multi_error/enum_with_identifier.ets +ast/parser/ets/enum_multi_error/enum_empty.ets +ast/parser/ets/FixedArray/wrong-union-array-assignment.ets +ast/parser/ets/FixedArray/array_2.ets +ast/compiler/ets/lambdaFunction4.ets +ast/compiler/ets/spreadMultiArrayInTuple.ets +ast/compiler/ets/union_string_literals_3.ets +ast/parser/ets/FixedArray/nonIntegralIndex.ets +ast/compiler/ets/boxingConversion1.ets +ast/compiler/ets/ObjectLiteral_neg_1.ets +ast/compiler/ets/invalidPrivateAccess4.ets +ast/compiler/ets/invalidInheritanceFromInterface.ets +ast/compiler/ets/override3.ets +ast/compiler/ets/recursive_class_neg.ets +ast/compiler/ets/ambient_namesapce01.ets +ast/compiler/ets/variance_typeparam_lambda.ets +ast/compiler/ets/union_types_4.ets +ast/compiler/ets/function_subtyping_2.ets +ast/compiler/ets/override15.ets +ast/compiler/ets/identifierReference7.ets +ast/compiler/ets/tuple_types_6_neg.ets +ast/compiler/ets/etsObjectToString4.ets +ast/compiler/ets/DeclareCheckAssign.ets +ast/compiler/ets/invalidInheritance4.ets +ast/compiler/ets/overloadMethodNoReturn1.ets +ast/compiler/ets/array_indexing_without_chaining_nullish.ets +ast/compiler/ets/async_import_3.ets +ast/compiler/ets/for_of_missing_iterator_type.ets +ast/compiler/ets/generic_class_without_type_arg_2.ets +ast/compiler/ets/most_specific_method_with_empty_rest_param.ets +ast/compiler/ets/voidTypeInBinaryOperation.ets +ast/compiler/ets/export_type_interface_multiple_times.ets +ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets +ast/parser/ets/FixedArray/rest_parameter_04.ets +ast/parser/ets/FixedArray/unclosed_loop.ets +ast/parser/ets/FixedArray/trailing_comma_1.ets +ast/parser/ets/FixedArray/record_object_value.ets +ast/parser/ets/FixedArray/for_of_03.ets +ast/parser/ets/FixedArray/superInConstructor3.ets +ast/parser/ets/FixedArray/static_field_3.ets +ast/parser/ets/FixedArray/forOfCustomIterator1.ets +ast/parser/ets/FixedArray/tuple_type_2_neg.ets +ast/parser/ets/FixedArray/array_missing_element.ets +ast/parser/ets/FixedArray/forOfCustomIterator2.ets +ast/compiler/ets/partialType_3_neg.ets +ast/compiler/ets/math_const_as_identifier.ets +ast/compiler/ets/call_for_method_never_exist.ets +ast/compiler/ets/requiredType_7_neg.ets +ast/parser/ets/FixedArray/static_func_call_8.ets +ast/parser/ets/FixedArray/unexpected_token_26.ets +ast/parser/ets/re_export/re_export_4.ets +ast/parser/ets/re_export/import_16.ets +ast/parser/ets/FixedArray/unexpected_token_42.ets +ast/parser/ets/FixedArray/invalidTypes.ets +ast/parser/ets/FixedArray/unexpected_token_38.ets +ast/parser/ets/FixedArray/type_argument_conversion.ets +ast/parser/ets/FixedArray/functionTypeParam_neg2.ets +ast/parser/ets/FixedArray/MultipleParserErrors.ets +ast/parser/ets/FixedArray/method_full.ets +ast/parser/ets/FixedArray/StringFasta.ets +ast/parser/ets/FixedArray/predefined_non_primitive_types.ets +ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test4.ets +ast/parser/ets/FixedArray/readonly-parameter-test/Readonly-with-ArrayType-test1.ets +ast/parser/ets/selective_export/selective_export_bad.ets +ast/parser/ets/static_invoke_tests/static_invoke_coexist_invoke_method_1.ets +ast/compiler/ets/variance_typeparam_overload.ets +ast/compiler/ets/identifierReference15.ets +ast/compiler/ets/identifierReference5.ets +ast/compiler/ets/requiredType_10_neg.ets +ast/compiler/ets/union_string_literals_7.ets +ast/compiler/ets/objectLiteralNoParameterlessConstructor.ets +ast/compiler/ets/export_type_function.ets +ast/compiler/ets/readonlyField.ets +ast/compiler/ets/typeVarReferenceFromStaticContext.ets +ast/compiler/ets/generic_typealias_10_neg.ets +ast/compiler/ets/invalidIndirectInheritanceFromClass.ets +ast/compiler/ets/getterNoReturn0.ets +ast/compiler/ets/void_as_value_neg_1.ets +ast/compiler/ets/setArrayLength1.ets +ast/compiler/ets/boxingConversion4.ets +ast/compiler/ets/resolve_func_name_union_type.ets +ast/parser/ets/FixedArray/InvalidStatements3.ets +ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets +ast/parser/ets/FixedArray/array_type.ets +ast/parser/ets/FixedArray/spreadexpr_in_newexpr_neg01.ets +ast/parser/ets/FixedArray/n_arrayHoldingNullValue.ets +ast/parser/ets/FixedArray/spreadArrayInTuple.ets +ast/parser/ets/FixedArray/FunctionalTypeAsArrayElement.ets +ast/parser/ets/FixedArray/illegal_union_member_exp.ets +ast/parser/ets/FixedArray/unexpected_token_36.ets +ast/parser/ets/FixedArray/enum11.ets +ast/parser/ets/FixedArray/unexpected_token_47.ets +ast/parser/ets/FixedArray/function_decl.ets +ast/parser/ets/FixedArray/main_entry_point_5.ets +ast/parser/ets/FixedArray/unexpected_token_39.ets + +# Failures with plugin recheck that should be fixed (Issue #24651) +ast/compiler/ets/ambiguous_signature01.ets +ast/compiler/ets/ambiguous_signature02.ets +ast/compiler/ets/async_import_2.ets +ast/compiler/ets/interface_ambient_call_signature_1.ets +ast/compiler/ets/interface_ambient_indexer_3.ets +ast/compiler/ets/optionalClassProperty1.ets +ast/compiler/ets/static_index_function1.ets +ast/compiler/ets/static_index_function2.ets +ast/compiler/ets/static_index_function3.ets +ast/parser/ets/enum29.ets +ast/parser/ets/enum31.ets +ast/parser/ets/enum32.ets +ast/parser/ets/interface_ambient_call_signature.ets +ast/parser/ets/interface_ambient_call_signature_1.ets +ast/parser/ets/interface_ambient_indexer_1.ets +ast/parser/ets/interface_ambient_indexer_2.ets +ast/parser/ets/interface_ambient_iterable.ets +ast/parser/ets/named_types_1.ets +ast/parser/ets/named_types_2.ets +ast/parser/ets/readonly-parameter-test/Readonly-Array-test1.ets +ast/parser/ets/readonly-parameter-test/Readonly-Array-test2.ets +ast/parser/ets/readonly-parameter-test/Readonly-Array-test3.ets +compiler/ets/dynamic-equality.ets +compiler/ets/dynamicJsImport.ets +compiler/ets/dynamicLambda.ets +compiler/ets/dynamicLambdaJSValue.ets +compiler/ets/dynamicObjectLiteral.ets +compiler/ets/dynamic_call.ets +compiler/ets/import_tests/asyncfun_lambda_lib.ets +compiler/ets/instanceof_x_dyndecl.ets +compiler/ets/instanceof_x_etstype.ets +compiler/ets/instanceof_x_object.ets +parser/ets/async_function.ets +parser/ets/async_overload.ets +parser/ets/async_with_lambda.ets +parser/ets/await_keyword.ets +parser/ets/dynamic_import_tests/dynamic_decl_import.ets +parser/ets/dynamic_import_tests/dynamic_optional_decl.ets +parser/ets/re_export/diamond/D.ets +parser/ets/re_export/diamond/D2.ets +parser/ets/re_export/import_14.ets +parser/ets/re_export/import_2.ets +runtime/ets/async-func-overload-and-type-infer.ets +runtime/ets/async_and_instance_method_with_same_name01.ets +runtime/ets/async_and_instance_method_with_same_name02.ets +runtime/ets/async_method_with_same_name01.ets +runtime/ets/async_method_with_same_name02.ets +runtime/ets/async_optional.ets +runtime/ets/async_return_void_1.ets +runtime/ets/async_return_void_2.ets +runtime/ets/async_return_void_3.ets +runtime/ets/async_scope_fix.ets +runtime/ets/extension_function_tests/extensionFunctionReturnThis2.ets +runtime/ets/getteSetterImplementation.ets +runtime/ets/getterSetterImplementationWithConstructor.ets +runtime/ets/implementsClassPropertyFunctionType.ets +runtime/ets/implementsClassPropertyFunctionType2.ets +runtime/ets/lambda_with_receiver/lambda_with_receiver_return_this2.ets +runtime/ets/readonly_simple_form_pos.ets +ast/compiler/ets/declareNameSpace.ets +ast/compiler/ets/multiple_inheritance_neg.ets +ast/compiler/ets/multiple_inheritance_neg_2.ets +ast/compiler/ets/namespaceExport_neg.ets +ast/parser/ets/invalid_object_literal.ets +ast/parser/ets/static_block.ets +runtime/ets/GenericBridges_01.ets +ast/compiler/ets/tuple_union_neg.ets +ast/compiler/ets/union_method_4.ets +ast/parser/ets/rest_parameter_05.ets +ast/parser/ets/rest_parameter_06.ets +ast/parser/ets/rest_parameter_07.ets +ast/parser/ets/rest_parameter_08.ets +ast/parser/ets/user_defined_27.ets +ast/compiler/ets/interface_ambient_iterable_1.ets +ast/parser/ets/implement_interface1.ets +compiler/ets/lowering-interaction.ets +runtime/ets/Function.ets +runtime/ets/IterableTypesWithProtectedIterator.ets +runtime/ets/ObjectIterable_1.ets +runtime/ets/ObjectIterable_2.ets +runtime/ets/extension_accessor/extensionAccessorAlone.ets +runtime/ets/extension_accessor/extensionAccessorAsClassPropertyValue.ets +runtime/ets/extension_accessor/extensionAccessorAsExprOfStatementExpr.ets +runtime/ets/extension_accessor/extensionAccessorAsMemberExprObject.ets +runtime/ets/extension_accessor/extensionAccessorAsMemberExprProperty.ets +runtime/ets/extension_accessor/extensionAccessorInCallArgs.ets +runtime/ets/extension_accessor/extensionAccessorInCallArgs2.ets +runtime/ets/extension_accessor/extensionAccessorInFunction.ets +runtime/ets/extension_accessor/extensionAccessorInOpAssignment.ets +runtime/ets/extension_accessor/extensionAccessorInOpAssignment2.ets +runtime/ets/extension_accessor/extensionAccessorInherited1.ets +runtime/ets/extension_accessor/extensionAccessorInherited2.ets +runtime/ets/extension_accessor/extensionAccessorWithNewExpr1.ets +runtime/ets/extension_accessor/extensionAccessorWithNewExpr2.ets +runtime/ets/extension_accessor/extensionGetterAndOriginalSetter.ets +runtime/ets/extension_accessor/extensionSetterAndOriginalGetter.ets +runtime/ets/forOfCustomIterator1.ets +runtime/ets/forOfCustomIterator2.ets +runtime/ets/objectLiteral-2.ets +runtime/ets/objectLiteral.ets +runtime/ets/objectLiteralInterfaceType.ets +runtime/ets/objectLiteral_abstract_class_object.ets +runtime/ets/rest_object_literal.ets +ast/parser/ets/while_with_empty_body.ets +ast/parser/ets/de_while_with_empty_body.ets diff --git a/ets2panda/test/test-lists/srcdumper/srcdumper-ets-ignored.txt b/ets2panda/test/test-lists/srcdumper/srcdumper-ets-ignored.txt index adc6db3358d259440640289117d17320dbcccc93..218f40820457e3d35cead6f6e3f96a73df23a911 100644 --- a/ets2panda/test/test-lists/srcdumper/srcdumper-ets-ignored.txt +++ b/ets2panda/test/test-lists/srcdumper/srcdumper-ets-ignored.txt @@ -11,11 +11,14 @@ runtime/ets/annotation_tests/AnnotationForDifferentTypes.ets runtime/ets/annotation_tests/AnnotationForTypesInDifferentCase.ets ast/compiler/ets/async_import_1.ets ast/compiler/ets/optionalClassProperty1.ets +ast/compiler/ets/ambient_interface/use_interface.ets ast/parser/ets/import_tests/enum/import.ets ast/parser/ets/import_tests/export_and_import_class.ets ast/parser/ets/import_tests/export_and_import_top_level.ets ast/parser/ets/re_export/import_11.ets ast/parser/ets/re_export/import_12.ets +ast/parser/ets/re_export/export_5.ets +ast/parser/ets/re_export/export_6.ets ast/parser/ets/re_export/re_export_11.ets ast/parser/ets/re_export/re_export_12.ets ast/parser/ets/re_export/re_export_5.ets @@ -53,13 +56,13 @@ runtime/ets/newArrayCreationUnionType.ets runtime/ets/type_param_in_union.ets ast/parser/ets/re_export/import_18.ets ast/parser/ets/re_export/import_19.ets +ast/parser/ets/re_export/import_20.ets ast/parser/ets/re_export/re_export_13.ets ast/parser/ets/re_export/re_export_14.ets ast/parser/ets/re_export/re_export_15.ets +ast/parser/ets/re_export/re_export_16.ets parser/ets/ambient_indexer_1.ets parser/ets/ambient_indexer_6.ets -parser/ets/class_init.ets -parser/ets/class_static_initializer.ets parser/ets/conversions.ets parser/ets/declare_namespace.ets runtime/ets/namespace_tests/namespace_import_type_test/namespace_export.ets @@ -95,7 +98,6 @@ parser/ets/labeledSwitchStatement.ets parser/ets/labeledWhileStatement.ets parser/ets/lambda_import_alias_1-2.ets parser/ets/lambda_import_alias_1.ets -parser/ets/localClassIsPermitted.ets parser/ets/promiseCasting.ets parser/ets/re_export/diamond/B.ets parser/ets/re_export/diamond/B2.ets @@ -151,6 +153,12 @@ parser/ets/array_creation_expression.ets runtime/ets/re_export/export/reexport_elements1.ets runtime/ets/re_export/export/reexport_elements2.ets runtime/ets/re_export/import.ets +ast/compiler/ets/package_initializer_warning/P3/P3.ets +ast/compiler/ets/package_initializer_warning/main_test.ets +runtime/ets/import_declare_type_alias.ets +ast/compiler/ets/import_type_without_export.ets +ast/compiler/ets/type_binding_01.ets +ast/compiler/ets/type_binding_02.ets # FailKind.ES2PANDA_FAIL runtime/ets/StringFasta.ets @@ -180,6 +188,8 @@ runtime/ets/exportDefault_1.ets runtime/ets/exportDefault_2.ets runtime/ets/declareExport.ets runtime/ets/implicit_stringliteral_init.ets +runtime/ets/mypackage/implicit_package_import_1.ets +runtime/ets/class_implements_interface_import.ets # #21051 should be log warnings, but there aren't ast/compiler/ets/not_initialized_variable/import_types.ets diff --git a/ets2panda/test/tsconfig/CMakeLists.txt b/ets2panda/test/tsconfig/CMakeLists.txt index 55190eb980f558603e341e1bab4a41ec95e9f2e4..11f275f856c62b5ddfad0e8f5d6efd626e4c3e2d 100644 --- a/ets2panda/test/tsconfig/CMakeLists.txt +++ b/ets2panda/test/tsconfig/CMakeLists.txt @@ -17,3 +17,4 @@ endif() add_subdirectory(test-config) add_subdirectory(test-build) +add_subdirectory(test-decl) diff --git a/ets2panda/test/tsconfig/test-decl/CMakeLists.txt b/ets2panda/test/tsconfig/test-decl/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ad2b8fdf97bdc0138aadbf3e6bdbd7c399818fac --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/CMakeLists.txt @@ -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. + +function(add_test project) + set(PROJECT_TARGET_NAME es2panda-tsconfig-test-decl-${project}) + set(ETS_CONFIG_DECL ${CMAKE_CURRENT_BINARY_DIR}/${project}/arktsconfig_decl.json) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${project}/arktsconfig.in.decl.json ${ETS_CONFIG_DECL}) + add_custom_target(${PROJECT_TARGET_NAME} + COMMENT "Testing tsconfig for: ${project}" + DEPENDS es2panda + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + COMMAND python3 test.py + --es2panda '${PANDA_RUN_PREFIX} $' + --arktsconfig ${CMAKE_CURRENT_BINARY_DIR}/${project}/arktsconfig_decl.json + --stdlib ${PANDA_ROOT}/plugins/ets/stdlib + --target ${project}/main.ets + ) + add_dependencies(es2panda_tests ${PROJECT_TARGET_NAME}) +endfunction() + +add_test(resolve-dynamic-paths) +add_test(check-decl-path) +add_test(check-export-decl) +add_test(check-extend-dynamic) +add_test(typecheck-decl) \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/check-decl-path/arktsconfig.in.decl.json b/ets2panda/test/tsconfig/test-decl/check-decl-path/arktsconfig.in.decl.json new file mode 100644 index 0000000000000000000000000000000000000000..abc17863c978e711115757a7bcdf7bdbd756f431 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-decl-path/arktsconfig.in.decl.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "baseUrl": "${CMAKE_CURRENT_SOURCE_DIR}", + "paths": { + "escompat": ["${PANDA_ROOT}/plugins/ets/stdlib/escompat"], + "std": ["${PANDA_ROOT}/plugins/ets/stdlib/std"] + }, + "dynamicPaths": { + "js": { "language": "js", "declPath": "${CMAKE_CURRENT_SOURCE_DIR}/wrong-path/js/index.ets", "ohmUrl": "${CMAKE_CURRENT_SOURCE_DIR}/${project}/js/index" } + } + } +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/check-decl-path/expected.json b/ets2panda/test/tsconfig/test-decl/check-decl-path/expected.json new file mode 100644 index 0000000000000000000000000000000000000000..64e8f0d4060a32709449fba318dd342e7bfd4924 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-decl-path/expected.json @@ -0,0 +1,4 @@ +{ + "returncode": 1, + "stderr": "" +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/check-decl-path/main.ets b/ets2panda/test/tsconfig/test-decl/check-decl-path/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..a4d48e61d2ac3abef7390b3d93d4725514bb1249 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-decl-path/main.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. + */ + +import { A } from "js" + +function main() : void { + let myclass = new A(); +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/check-export-decl/arktsconfig.in.decl.json b/ets2panda/test/tsconfig/test-decl/check-export-decl/arktsconfig.in.decl.json new file mode 100644 index 0000000000000000000000000000000000000000..3e875c427d9787a2f9e6a5456b96b0c9e17b5e21 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-export-decl/arktsconfig.in.decl.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "baseUrl": "${CMAKE_CURRENT_SOURCE_DIR}", + "paths": { + "escompat": ["${PANDA_ROOT}/plugins/ets/stdlib/escompat"], + "std": ["${PANDA_ROOT}/plugins/ets/stdlib/std"] + }, + "dynamicPaths": { + "js": { "language": "js", "declPath": "${CMAKE_CURRENT_SOURCE_DIR}/${project}/js/index.ets", "ohmUrl": "${CMAKE_CURRENT_SOURCE_DIR}/${project}/js/index" } + } + } +} diff --git a/ets2panda/test/tsconfig/test-decl/check-export-decl/expected.json b/ets2panda/test/tsconfig/test-decl/check-export-decl/expected.json new file mode 100644 index 0000000000000000000000000000000000000000..bf996e3c554d26e9477c168b68ebc4d5eb400287 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-export-decl/expected.json @@ -0,0 +1,5 @@ +{ + "returncode": 1, + "stdout": "SyntaxError: Export keyword without declare shouldn't be used in declaration module. [index.ets:16:8]\n", + "stderr": "" +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/check-export-decl/js/index.ets b/ets2panda/test/tsconfig/test-decl/check-export-decl/js/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e54da183dd30de49f847bafe6112fec75503aa0 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-export-decl/js/index.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. + */ + +export class A { + name: string; + age: double; + location: string; + myfoo() : void {}; +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/check-export-decl/js/index.js b/ets2panda/test/tsconfig/test-decl/check-export-decl/js/index.js new file mode 100644 index 0000000000000000000000000000000000000000..e5251ce71152a73f22afe703396a4bd25b5d9747 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-export-decl/js/index.js @@ -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. + */ +'use strict'; + +class A { + name; + age; + location; +} + +exports.A = A; diff --git a/ets2panda/test/tsconfig/test-decl/check-export-decl/main.ets b/ets2panda/test/tsconfig/test-decl/check-export-decl/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..6f6df014a73bd7eb7a7dcc1d7e464affa95f6c47 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-export-decl/main.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. + */ + +import { A } from "js" + +function Test1(): int { + let a: A = { location: "string"}; + + if (a.location != "string") { + return 3; + } + return 0; +} + + diff --git a/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/arktsconfig.in.decl.json b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/arktsconfig.in.decl.json new file mode 100644 index 0000000000000000000000000000000000000000..3e875c427d9787a2f9e6a5456b96b0c9e17b5e21 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/arktsconfig.in.decl.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "baseUrl": "${CMAKE_CURRENT_SOURCE_DIR}", + "paths": { + "escompat": ["${PANDA_ROOT}/plugins/ets/stdlib/escompat"], + "std": ["${PANDA_ROOT}/plugins/ets/stdlib/std"] + }, + "dynamicPaths": { + "js": { "language": "js", "declPath": "${CMAKE_CURRENT_SOURCE_DIR}/${project}/js/index.ets", "ohmUrl": "${CMAKE_CURRENT_SOURCE_DIR}/${project}/js/index" } + } + } +} diff --git a/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/expected.json b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/expected.json new file mode 100644 index 0000000000000000000000000000000000000000..cb2d2fb848428f68098158800f6380c1984663cb --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/expected.json @@ -0,0 +1,5 @@ +{ + "returncode": 1, + "stdout": "TypeError: Class D shouldn't extend dynamic class. [main.ets:18:19]\n", + "stderr": "" +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/js/index.ets b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/js/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..aca7e89390964b661c7053170cc3f4df32ea9a86 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/js/index.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. + */ + +export declare class A { + name: string; + age: double; + location: string; +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/js/index.js b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/js/index.js new file mode 100644 index 0000000000000000000000000000000000000000..e5251ce71152a73f22afe703396a4bd25b5d9747 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/js/index.js @@ -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. + */ +'use strict'; + +class A { + name; + age; + location; +} + +exports.A = A; diff --git a/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/main.ets b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..8f6fd79207f9e4c93df901c9ee7041f0027d6c1d --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/check-extend-dynamic/main.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. + */ + +import { A } from "js" + +class D extends A { + direction: string = 'south'; +} + +function main () : void { + let myclass = new D(); +} + + diff --git a/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/arktsconfig.in.decl.json b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/arktsconfig.in.decl.json new file mode 100644 index 0000000000000000000000000000000000000000..3e875c427d9787a2f9e6a5456b96b0c9e17b5e21 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/arktsconfig.in.decl.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "baseUrl": "${CMAKE_CURRENT_SOURCE_DIR}", + "paths": { + "escompat": ["${PANDA_ROOT}/plugins/ets/stdlib/escompat"], + "std": ["${PANDA_ROOT}/plugins/ets/stdlib/std"] + }, + "dynamicPaths": { + "js": { "language": "js", "declPath": "${CMAKE_CURRENT_SOURCE_DIR}/${project}/js/index.ets", "ohmUrl": "${CMAKE_CURRENT_SOURCE_DIR}/${project}/js/index" } + } + } +} diff --git a/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/expected.json b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/expected.json new file mode 100644 index 0000000000000000000000000000000000000000..b494dfffa637712055145189eb74b541f1db1abc --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/expected.json @@ -0,0 +1,5 @@ +{ + "returncode": 0, + "stdout": "", + "stderr": "" +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/js/index.ets b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/js/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..aca7e89390964b661c7053170cc3f4df32ea9a86 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/js/index.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. + */ + +export declare class A { + name: string; + age: double; + location: string; +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/js/index.js b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/js/index.js new file mode 100644 index 0000000000000000000000000000000000000000..e5251ce71152a73f22afe703396a4bd25b5d9747 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/js/index.js @@ -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. + */ +'use strict'; + +class A { + name; + age; + location; +} + +exports.A = A; diff --git a/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/main.ets b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..3366977426345800d8d72ab7d0f4f6bc2bb89839 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/resolve-dynamic-paths/main.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. + */ + +import { A } from "js" + +function main(): void { + let myclass = new A(); + + console.log(myclass["location"]); +} + + diff --git a/ets2panda/test/tsconfig/test-decl/test.py b/ets2panda/test/tsconfig/test-decl/test.py new file mode 100644 index 0000000000000000000000000000000000000000..213042f5b2ae94458609189191dfdacd8fe76da1 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/test.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +# coding=utf-8 +# +# 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 argparse +import os +import json +import subprocess + + +def ensure_exists(path): + if not os.path.exists(path): + raise RuntimeError(f'The file {path} cannot be found') + + +def es2panda_command(es2panda_path, stdlib_path, arktsconfig_path, target_path): + return [ + *str(es2panda_path).split(), + '--opt-level=2', + '--thread=0', + '--extension=ets', + '--stdlib', stdlib_path, + '--arktsconfig', arktsconfig_path, + '--ets-unnamed', + target_path + ] + + +def compare_output(lhs, rhs): + for k in rhs: + attr = getattr(lhs, k) + if attr != rhs[k]: + message = "\n".join([f'In {k} field', + f'Expected: {rhs[k]}', + f'Got: {attr}']) + raise RuntimeError(message) + + +parser = argparse.ArgumentParser() +parser.add_argument('--es2panda', required=True, + help='Path to es2panda executable, could be prefixed') +parser.add_argument('--arktsconfig', required=True, help='Path to project arktsconfig') +parser.add_argument('--stdlib', required=True, help='Path to es2panda stdlib') +parser.add_argument('--target', required=True, help='Path to .sts to compile it to .abc') + +args = parser.parse_args() + +project_dir = os.path.dirname(args.target) +expected_path = os.path.join(project_dir, 'expected.json') + +[ensure_exists(f) for f in [ + str(args.es2panda).split()[-1], args.arktsconfig, expected_path]] + +cmd = es2panda_command(args.es2panda, args.stdlib, args.arktsconfig, args.target) + + +actual = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding='utf-8') + +with open(expected_path, "r", encoding="utf-8") as expected_file: + expected = json.load(expected_file) + compare_output(actual, expected) diff --git a/ets2panda/test/tsconfig/test-decl/typecheck-decl/arktsconfig.in.decl.json b/ets2panda/test/tsconfig/test-decl/typecheck-decl/arktsconfig.in.decl.json new file mode 100644 index 0000000000000000000000000000000000000000..3e875c427d9787a2f9e6a5456b96b0c9e17b5e21 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/typecheck-decl/arktsconfig.in.decl.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "baseUrl": "${CMAKE_CURRENT_SOURCE_DIR}", + "paths": { + "escompat": ["${PANDA_ROOT}/plugins/ets/stdlib/escompat"], + "std": ["${PANDA_ROOT}/plugins/ets/stdlib/std"] + }, + "dynamicPaths": { + "js": { "language": "js", "declPath": "${CMAKE_CURRENT_SOURCE_DIR}/${project}/js/index.ets", "ohmUrl": "${CMAKE_CURRENT_SOURCE_DIR}/${project}/js/index" } + } + } +} diff --git a/ets2panda/test/tsconfig/test-decl/typecheck-decl/expected.json b/ets2panda/test/tsconfig/test-decl/typecheck-decl/expected.json new file mode 100644 index 0000000000000000000000000000000000000000..49f23180a3e6a7c6ac3421a36a9a1d2dfb3be958 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/typecheck-decl/expected.json @@ -0,0 +1,5 @@ +{ + "returncode": 1, + "stdout": "TypeError: Type 'int' is not compatible with type 'String' at property 'location' [main.ets:19:28]\nTypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. [main.ets:21:9]\n", + "stderr": "" +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/typecheck-decl/js/index.ets b/ets2panda/test/tsconfig/test-decl/typecheck-decl/js/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..aca7e89390964b661c7053170cc3f4df32ea9a86 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/typecheck-decl/js/index.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. + */ + +export declare class A { + name: string; + age: double; + location: string; +} \ No newline at end of file diff --git a/ets2panda/test/tsconfig/test-decl/typecheck-decl/js/index.js b/ets2panda/test/tsconfig/test-decl/typecheck-decl/js/index.js new file mode 100644 index 0000000000000000000000000000000000000000..e5251ce71152a73f22afe703396a4bd25b5d9747 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/typecheck-decl/js/index.js @@ -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. + */ +'use strict'; + +class A { + name; + age; + location; +} + +exports.A = A; diff --git a/ets2panda/test/tsconfig/test-decl/typecheck-decl/main.ets b/ets2panda/test/tsconfig/test-decl/typecheck-decl/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..04f0fc99448cb0bbbd652d1ba74b0bb6ab85c881 --- /dev/null +++ b/ets2panda/test/tsconfig/test-decl/typecheck-decl/main.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. + */ + +import { A } from "js" + +function Test1(): int { + let a: A = { location: 3}; + + if (a.location != 2) { + return 3; + } + return 0; +} + + diff --git a/ets2panda/test/unit/CMakeLists.txt b/ets2panda/test/unit/CMakeLists.txt index a0b496400e877dd4a6d6886dabe5d61c70263174..07663a9a29d1e6c30a20f130b26d8cab1ce87f37 100644 --- a/ets2panda/test/unit/CMakeLists.txt +++ b/ets2panda/test/unit/CMakeLists.txt @@ -1,4 +1,4 @@ -# 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 @@ -25,6 +25,7 @@ add_subdirectory(plugin_conversion_rule) add_subdirectory(arktsconfig-parser) add_subdirectory(annotations) add_subdirectory(lsp) +add_subdirectory(relative_path) ets2panda_add_gtest(es2panda_astdumper_tests CPP_SOURCES ast_dumper_test.cpp @@ -39,6 +40,13 @@ ets2panda_add_gtest(es2panda_union_normalization_tests_2 ets2panda_add_gtest(es2panda_globalETSObjectType_tests CPP_SOURCES globalETSObjectType_test.cpp ) + +if (PANDA_TARGET_LINUX AND PANDA_TARGET_64) + ets2panda_add_gtest(sizeof_node_tests + CPP_SOURCES sizeof_node_test.cpp + ) +endif() + # NOTE: es2panda_rest_parameter_flag test runs a lot of time on qemu, so let's disable it if (NOT PANDA_QEMU_BUILD) ets2panda_add_gtest(es2panda_rest_parameter_flag diff --git a/ets2panda/test/unit/annotations/CMakeLists.txt b/ets2panda/test/unit/annotations/CMakeLists.txt index ece2c840832c0359f18290cb25bcc3bd9ca0d61d..be1ef9eb43a3bb01ff098bf171908a57f9ee4966 100644 --- a/ets2panda/test/unit/annotations/CMakeLists.txt +++ b/ets2panda/test/unit/annotations/CMakeLists.txt @@ -34,4 +34,10 @@ ets2panda_add_gtest(annotations_retention_policy ) ets2panda_add_gtest(annotations_for_namespace CPP_SOURCES annotations_for_namespace.cpp -) \ No newline at end of file +) +ets2panda_add_gtest(annotations_module + CPP_SOURCES annotations_module.cpp +) +ets2panda_add_gtest(annotations_for_functional_objects + CPP_SOURCES annotations_for_functional_objects.cpp +) diff --git a/ets2panda/test/unit/annotations/annotations_for_function.cpp b/ets2panda/test/unit/annotations/annotations_for_function.cpp index d152dab6dd74caf2025a20a7cbe4f570ab557b4b..8f1424a4d8526197f09bc4744acfa1e5d6bb3d3a 100644 --- a/ets2panda/test/unit/annotations/annotations_for_function.cpp +++ b/ets2panda/test/unit/annotations/annotations_for_function.cpp @@ -65,7 +65,7 @@ public: const AnnotationMap expectedFuncAnnotations1 = { {"Anno", {{"a", "1.000000"}}}, }; - const std::string funcName2 = "A.bar:f64;FixedArray;void;"; + const std::string funcName2 = "A.bar:f64;f64[];void;"; // Index 0 is the parameter 'this' const uint32_t paramIndex2 = 1; const uint32_t paramIndex3 = 2; @@ -106,7 +106,7 @@ TEST_F(AnnotationsforFunction, DISABLED_annotations_for_function) function foo(@Anno a ?: number) {} class A { - bar(@Anno(2) a : number, @Anno(3) ...rest : FixedArray) {} + bar(@Anno(2) a : number, @Anno(3) ...rest : number[]) {} })"; RunAnnotationEmitTest(text); diff --git a/ets2panda/test/unit/annotations/annotations_for_functional_objects.cpp b/ets2panda/test/unit/annotations/annotations_for_functional_objects.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49fb6a853f5ea1242a659e9c6bdc716cc0ed6719 --- /dev/null +++ b/ets2panda/test/unit/annotations/annotations_for_functional_objects.cpp @@ -0,0 +1,73 @@ +/* + * 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 +#include +#include +#include +#include +#include "assembly-program.h" +#include "test/unit/annotations/annotations_emit_test.h" + +namespace ark::es2panda::compiler::test { + +class AnnotationsforFunctionalObjects : public AnnotationEmitTest { +public: + AnnotationsforFunctionalObjects() = default; + + ~AnnotationsforFunctionalObjects() override = default; + + void RunAnnotationEmitTest(const std::string_view text) + { + auto program = GetCurrentProgram(text); + ASSERT_NE(program, nullptr); + + CheckAnnotations(program.get()); + CheckClassAnnotations(program.get()); + } + + void CheckAnnotations(pandasm::Program *program) + { + const std::string annoName = "std.annotations.InterfaceObjectLiteral"; + AnnotationEmitTest::CheckAnnoDecl(program, annoName, {}); + } + + void CheckClassAnnotations(pandasm::Program *program) + { + const std::string recordName = "Iface$ObjectLiteral"; + const AnnotationMap expectedClassAnnotations = { + {"std.annotations.InterfaceObjectLiteral", {}}, + }; + AnnotationEmitTest::CheckRecordAnnotations(program, recordName, expectedClassAnnotations); + } + +private: + NO_COPY_SEMANTIC(AnnotationsforFunctionalObjects); + NO_MOVE_SEMANTIC(AnnotationsforFunctionalObjects); +}; + +// #22952 +TEST_F(AnnotationsforFunctionalObjects, annotations_for_functional_objects) +{ + std::string_view text = R"( + interface Iface { a: number } + + function bar() { + let tif: Iface = { a: 42 } + })"; + + RunAnnotationEmitTest(text); +} + +} // namespace ark::es2panda::compiler::test diff --git a/ets2panda/test/unit/annotations/annotations_module.cpp b/ets2panda/test/unit/annotations/annotations_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9039c308a02bbcafb0538cc503002e86a469288b --- /dev/null +++ b/ets2panda/test/unit/annotations/annotations_module.cpp @@ -0,0 +1,82 @@ +/* + * 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 +#include +#include +#include +#include "assembly-program.h" +#include "test/unit/annotations/annotations_emit_test.h" + +namespace ark::es2panda::compiler::test { + +class ModuleAnnotations : public AnnotationEmitTest { +public: + ModuleAnnotations() = default; + + ~ModuleAnnotations() override = default; + + void RunAnnotationEmitTest(const std::string_view text, const std::function &test) + { + auto program = GetCurrentProgram(text); + ASSERT_NE(program, nullptr); + + test(program.get()); + } + +private: + NO_COPY_SEMANTIC(ModuleAnnotations); + NO_MOVE_SEMANTIC(ModuleAnnotations); +}; + +TEST_F(ModuleAnnotations, module_annotation) +{ + std::string_view text = R"( + class A {} + export class ExportedClass {} + namespace B {} + export namespace ExportedNamespace {} + )"; + + auto test = [this](pandasm::Program *program) { + AnnotationEmitTest::CheckModuleAnnotation(program, "ETSGLOBAL", true, {"ExportedClass", "ExportedNamespace"}); + AnnotationEmitTest::CheckModuleAnnotation(program, "ExportedClass", false); + AnnotationEmitTest::CheckModuleAnnotation(program, "ExportedNamespace", true, {}); + }; + RunAnnotationEmitTest(text, test); +} + +TEST_F(ModuleAnnotations, module_annotation_nested) +{ + std::string_view text = R"( + export namespace ExportedNamespace { + class A {} + export class B {} + namespace C {} + export namespace D { + export class A {} + } + } + )"; + + auto test = [this](pandasm::Program *program) { + AnnotationEmitTest::CheckModuleAnnotation(program, "ETSGLOBAL", true, {"ExportedNamespace"}); + AnnotationEmitTest::CheckModuleAnnotation(program, "ExportedNamespace", true, + {"ExportedNamespace.B", "ExportedNamespace.D"}); + AnnotationEmitTest::CheckModuleAnnotation(program, "ExportedNamespace.D", true, {"ExportedNamespace.D.A"}); + }; + RunAnnotationEmitTest(text, test); +} + +} // namespace ark::es2panda::compiler::test \ No newline at end of file diff --git a/ets2panda/test/unit/annotations/mutiple_annotations_for_class.cpp b/ets2panda/test/unit/annotations/mutiple_annotations_for_class.cpp index 767178473f94631a4ee4cdca899eea3ec5ed5f6c..4e7ef99a40eaa92134fff763275814ce845eeeca 100644 --- a/ets2panda/test/unit/annotations/mutiple_annotations_for_class.cpp +++ b/ets2panda/test/unit/annotations/mutiple_annotations_for_class.cpp @@ -116,14 +116,14 @@ TEST_F(MutipleAnnotationsforClass, mutiple_annotations_for_class) @interface Anno2 { favorColor: Color = Color.BLUE - color: FixedArray = [Color.RED, Color.BLUE] - reviewers: FixedArray = ["Bob", "Jim", "Tom"] + color: Color[] = [Color.RED, Color.BLUE] + reviewers: string[] = ["Bob", "Jim", "Tom"] } @interface Anno3 { - reviewersAge: FixedArray - testBools: FixedArray - mutiArray: FixedArray> + reviewersAge: number[] + testBools: boolean[] + mutiArray: number[][] } @Anno1({ diff --git a/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp b/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp index caa9dac40d8fc3b896659010982f1359af53e46a..523d4aaba144219e95810aceddb2dde43af87fc2 100644 --- a/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp +++ b/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp @@ -146,11 +146,11 @@ TEST_F(MutipleAnnotationsforFunction, mutiple_annotations_for_function) } @interface Anno2 { - param: FixedArray = [1, 2, 3, 4] + param: int[] = [1, 2, 3, 4] } @interface Anno3 { - param: FixedArray>> = [[[1], [2]], [[2], [3]], [[3], [4]]] + param: int[][][] = [[[1], [2]], [[2], [3]], [[3], [4]]] } @Anno1(2) diff --git a/ets2panda/test/unit/annotations/standard_test.cpp b/ets2panda/test/unit/annotations/standard_test.cpp index 0acf3ea0e6852831e3f4485cb3c66d96839ef372..fde486b3b678fc4af093a84f3856c6d7c26f7060 100644 --- a/ets2panda/test/unit/annotations/standard_test.cpp +++ b/ets2panda/test/unit/annotations/standard_test.cpp @@ -165,11 +165,11 @@ TEST_F(StandardEmitTest, standard_test) authorAge: number = 35 testBool: boolean = false favorColor: Color = Color.BLUE - color: FixedArray = [Color.RED, Color.BLUE] - reviewers: FixedArray = ["Bob", "Jim", "Tom"] - reviewersAge: FixedArray = [18, 21, 32] - testBools: FixedArray = [false, true, false] - mutiArray: FixedArray> = [ + color: Color[] = [Color.RED, Color.BLUE] + reviewers: string[] = ["Bob", "Jim", "Tom"] + reviewersAge: number[] = [18, 21, 32] + testBools: boolean[] = [false, true, false] + mutiArray: number[][] = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] diff --git a/ets2panda/test/unit/ast_dumper_test.cpp b/ets2panda/test/unit/ast_dumper_test.cpp index 19ad7c92e8f043d4deaf2d87e36e93f7f7a79c49..f7e590006198100678f9644e1c3154b0c02eb02e 100644 --- a/ets2panda/test/unit/ast_dumper_test.cpp +++ b/ets2panda/test/unit/ast_dumper_test.cpp @@ -66,7 +66,7 @@ TestParams DumpJsonSimple() { static constexpr std::string_view SRC = "\ - function main(args: String[]): int {\ + function main(args: FixedArray): int {\ let a: int = 2;\ let b: int = 3;\ return a + b;\ @@ -79,7 +79,7 @@ TestParams DumpJsonUTF16Char() { static constexpr std::string_view SRC = "\ - function main(args: String[]): int {\ + function main(args: FixedArray): int {\ let a: char = c'\\uDBFF';\ let b: char = c'\\uDC00';\ console.log(a);\ @@ -94,7 +94,7 @@ TestParams DumpEtsSrcSimple() { static constexpr std::string_view SRC = "\ - function main(args: String[]): int {\ + function main(args: FixedArray): int {\ let a: int = 2;\ let b: int = 3;\ return a + b;\ @@ -105,8 +105,6 @@ TestParams DumpEtsSrcSimple() "--dump-ets-src-before-phases=plugins-after-parse,plugins-after-check,plugins-after-lowering"}}; } -} // namespace - class ASTDumperTest : public testing::TestWithParam { public: ASTDumperTest() @@ -156,3 +154,5 @@ TEST_F(ASTDumperTest, CheckSrcDump) ASSERT(program); ASSERT(!dumpStr.str().empty()); } + +} // namespace diff --git a/ets2panda/test/unit/globalETSObjectType_test.cpp b/ets2panda/test/unit/globalETSObjectType_test.cpp index 42c96dd96cc2911bd073ec78353fd7f0ad77e9b9..9100fabbe57acc8e3f563cbbcea65f48b62343fb 100644 --- a/ets2panda/test/unit/globalETSObjectType_test.cpp +++ b/ets2panda/test/unit/globalETSObjectType_test.cpp @@ -84,13 +84,13 @@ TEST_F(GlobalETSObjectTypeTest, ETSArrayContainGlobalETSObject) << " private readonly prop: number;\n" << " constructor() {\n" << " this.prop = 0.0;}\n" - << " constructor(a: K[]) {\n" + << " constructor(a: FixedArray) {\n" << " this.prop = 1.0;}\n}" << "class B {\n" << " private readonly prop: number;\n" << " constructor() {\n" << " this.prop = 0.0;}\n" - << " constructor(a: readonly K[]) {\n" + << " constructor(a: readonly FixedArray) {\n" << " this.prop = 1.0;}\n}" << "let a = new A();\n let b = new B();"; diff --git a/ets2panda/test/unit/lowerings/CMakeLists.txt b/ets2panda/test/unit/lowerings/CMakeLists.txt index fdcf9b2fe8d069007d96a573fa94074fb94a82fc..c63c1298fa7c36e8295a8d37f110c97becc0ef41 100644 --- a/ets2panda/test/unit/lowerings/CMakeLists.txt +++ b/ets2panda/test/unit/lowerings/CMakeLists.txt @@ -27,3 +27,14 @@ ets2panda_add_gtest(const_expression_test ets2panda_add_gtest(top_level_statements_test CPP_SOURCES top_level_statements.cpp ) +ets2panda_add_gtest(node_history_test + CPP_SOURCES node_history.cpp +) + +ets2panda_add_gtest(convert_primitive_cast_method_call + CPP_SOURCES convert_primitive_cast_method_call.cpp +) + +ets2panda_add_gtest(interface_object_literal_test + CPP_SOURCES interface_object_literal.cpp +) diff --git a/ets2panda/test/unit/lowerings/convert_primitive_cast_method_call.cpp b/ets2panda/test/unit/lowerings/convert_primitive_cast_method_call.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4fbe3cdc2171384a86782bd5d633c6b420061c5 --- /dev/null +++ b/ets2panda/test/unit/lowerings/convert_primitive_cast_method_call.cpp @@ -0,0 +1,63 @@ +/** + * 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 "lowering_test.h" + +namespace ark::es2panda { + +TEST_F(LoweringTest, TestConvertPrimitiveCastMethodCall) +{ + char const *text = R"( + let d: double = 3.14 + let b: byte = d.toByte() + let s: short = d.toShort() + let i: int = d.toInt() + let l: long = d.toLong() + let f: float= d.toFloat() + )"; + + static std::array castMethods {{ + "toChar", + "toByte", + "toShort", + "toInt", + "toLong", + "toFloat", + "toDouble", + }}; + + CONTEXT(ES2PANDA_STATE_LOWERED, text) + { + const auto *const ast = GetAst(); + ASSERT_FALSE(ast->IsAnyChild([](ir::AstNode *const node) { + if (!node->IsCallExpression()) { + return false; + } + auto call = node->AsCallExpression(); + if (!call->Callee()->IsMemberExpression()) { + return false; + } + auto me = node->AsCallExpression()->Callee()->AsMemberExpression(); + auto prop = me->Property(); + if (!prop->IsIdentifier()) { + return false; + } + auto m = prop->AsIdentifier()->Name().Utf8(); + return std::find(castMethods.begin(), castMethods.end(), m) != castMethods.end(); + })); + } +} + +} // namespace ark::es2panda diff --git a/ets2panda/test/unit/lowerings/interface_object_literal.cpp b/ets2panda/test/unit/lowerings/interface_object_literal.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f7700eacf974a38bd606a9534f759078a850574 --- /dev/null +++ b/ets2panda/test/unit/lowerings/interface_object_literal.cpp @@ -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. + */ + +#include +#include "lowering_test.h" +#include "compiler/lowering/ets/topLevelStmts/topLevelStmts.h" + +namespace ark::es2panda { + +TEST_F(LoweringTest, TestInterfaceObjectLiteral) +{ + char const *text = R"( + interface I1 { + a: number + } + + interface I2 { + a: string + } + + function foo1(a: I1) { } + function foo2(a: I2) { } + + function main() { + foo1({ a: 1 }) + foo2({ a: "2" }) + })"; + + CONTEXT(ES2PANDA_STATE_LOWERED, text) + { + const auto *const ast = GetAst(); + [[maybe_unused]] auto *classDef1 = ast->FindChild([](ir::AstNode *child) { + return child->IsClassDefinition() && + (child->AsClassDefinition()->InternalName().Mutf8() == "dummy.dummy$I1$ObjectLiteral"); + }); + ASSERT_TRUE(classDef1 != nullptr); + [[maybe_unused]] auto *classDef2 = ast->FindChild([](ir::AstNode *child) { + return child->IsClassDefinition() && + (child->AsClassDefinition()->InternalName().Mutf8() == "dummy.dummy$I2$ObjectLiteral"); + }); + ASSERT_TRUE(classDef1 != nullptr); + } +} + +} // namespace ark::es2panda diff --git a/ets2panda/test/unit/lowerings/node_history.cpp b/ets2panda/test/unit/lowerings/node_history.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a8e6911a8048bac1f53c8fe6b9f8345a3a0eae8 --- /dev/null +++ b/ets2panda/test/unit/lowerings/node_history.cpp @@ -0,0 +1,379 @@ +/** + * 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 +#include "compiler/lowering/phase.h" +#include "ir/astNodeHistory.h" + +namespace ark::es2panda { + +class NodeHistoryTest : public testing::Test { +public: + ~NodeHistoryTest() override = default; + + static void SetUpTestCase() + { + ark::mem::MemConfig::Initialize(0, 0, ark::es2panda::COMPILER_SIZE, 0, 0, 0); + ark::PoolManager::Initialize(); + } + + NodeHistoryTest() + { + allocator_ = std::make_unique(SpaceType::SPACE_TYPE_COMPILER); + phaseManager_ = std::make_unique(ScriptExtension::ETS, Allocator()); + compiler::SetPhaseManager(phaseManager_.get()); + ir::EnableContextHistory(); + } + + NO_COPY_SEMANTIC(NodeHistoryTest); + NO_MOVE_SEMANTIC(NodeHistoryTest); + + ArenaAllocator *Allocator() const + { + return allocator_.get(); + } + + compiler::PhaseManager *PhaseManager() const + { + return phaseManager_.get(); + } + +private: + std::unique_ptr allocator_; + std::unique_ptr phaseManager_; +}; + +constexpr compiler::PhaseId PARSER_PHASE_ID = {0, compiler::PARSER_PHASE_ID}; +constexpr compiler::PhaseId PHASE_ID_0 = {0, 0}; +constexpr compiler::PhaseId PHASE_ID_1 = {0, 1}; +constexpr compiler::PhaseId PHASE_ID_2 = {0, 2}; +constexpr compiler::PhaseId PHASE_ID_3 = {0, 3}; +constexpr compiler::PhaseId PHASE_ID_4 = {0, 4}; +constexpr compiler::PhaseId PHASE_ID_5 = {0, 5}; + +constexpr int32_t INDEX_0 = 0; +constexpr int32_t INDEX_1 = 1; +constexpr int32_t INDEX_2 = 2; +constexpr int32_t INDEX_3 = 3; +constexpr int32_t INDEX_4 = 4; + +constexpr int32_t VALUE_0 = 0; +constexpr int32_t VALUE_1 = 1; +constexpr int32_t VALUE_2 = 2; +constexpr int32_t VALUE_3 = 3; +constexpr int32_t VALUE_4 = 4; + +constexpr int32_t SIZE_5 = 5; + +// CC-OFFNXT(huge_method, G.FUN.01-CPP, G.FUD.05) solid logic +TEST_F(NodeHistoryTest, DoubleLinkedList) +{ + util::ArenaDoubleLinkedList list {Allocator()}; + + ASSERT_EQ(list.Head(), nullptr); + ASSERT_EQ(list.Tail(), nullptr); + ASSERT_TRUE(list.Empty()); + + // Make list: (1,2,4,0,3) + std::array data = {VALUE_0, VALUE_1, VALUE_2, VALUE_3, VALUE_4}; + + auto item4 = list.Append(data[INDEX_4]); + auto item0 = list.Append(data[INDEX_0]); + auto item3 = list.Insert(item0, data[INDEX_3]); + auto item1 = list.Prepend(data[INDEX_1]); + auto item2 = list.Insert(item1, data[INDEX_2]); + + ASSERT_FALSE(list.Empty()); + + ASSERT_EQ(item0->data, data[INDEX_0]); + ASSERT_EQ(item1->data, data[INDEX_1]); + ASSERT_EQ(item2->data, data[INDEX_2]); + ASSERT_EQ(item3->data, data[INDEX_3]); + ASSERT_EQ(item4->data, data[INDEX_4]); + + ASSERT_EQ(list.Head(), item1); + ASSERT_EQ(item1->next, item2); + ASSERT_EQ(item2->next, item4); + ASSERT_EQ(item4->next, item0); + ASSERT_EQ(item0->next, item3); + ASSERT_EQ(item3, list.Tail()); + ASSERT_EQ(list.Tail()->next, nullptr); + + ASSERT_EQ(item3->prev, item0); + ASSERT_EQ(item0->prev, item4); + ASSERT_EQ(item4->prev, item2); + ASSERT_EQ(item2->prev, item1); + ASSERT_EQ(item1->prev, nullptr); + + ASSERT_EQ(item2->prev->next, item2); + ASSERT_EQ(item4->prev->next, item4); + ASSERT_EQ(item0->prev->next, item0); + + ASSERT_EQ(item2->next->prev, item2); + ASSERT_EQ(item4->next->prev, item4); + ASSERT_EQ(item0->next->prev, item0); + + list.Erase(item4); + ASSERT_EQ(item2->next, item0); + ASSERT_EQ(item0->prev, item2); + + list.Erase(item0); + ASSERT_EQ(item2->next, item3); + ASSERT_EQ(item3->prev, item2); + + list.Erase(list.Tail()); + ASSERT_EQ(list.Tail(), item2); + ASSERT_EQ(item2->next, nullptr); + ASSERT_EQ(item2->prev, item1); + + list.Erase(list.Head()); + ASSERT_EQ(list.Head(), item2); + ASSERT_EQ(item2->next, nullptr); + ASSERT_EQ(item2->prev, nullptr); + + list.Erase(item2); + ASSERT_EQ(list.Head(), nullptr); + ASSERT_EQ(list.Tail(), nullptr); + ASSERT_TRUE(list.Empty()); +} + +TEST_F(NodeHistoryTest, HistoryAt) +{ + ASSERT_EQ(PhaseManager()->CurrentPhaseId(), PARSER_PHASE_ID); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_0.minor); + auto identifier = Allocator()->New(Allocator())->AsIdentifier(); + auto history = Allocator()->New(identifier, PhaseManager()->CurrentPhaseId(), Allocator()); + + ASSERT_EQ(history->At(PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->At(PHASE_ID_0), identifier); + ASSERT_EQ(history->At(PHASE_ID_1), nullptr); +} + +TEST_F(NodeHistoryTest, HistoryGet) +{ + ASSERT_EQ(PhaseManager()->CurrentPhaseId(), PARSER_PHASE_ID); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_0.minor); + auto identifier = Allocator()->New(Allocator())->AsIdentifier(); + auto history = Allocator()->New(identifier, PhaseManager()->CurrentPhaseId(), Allocator()); + + ASSERT_EQ(history->Get(PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_0), identifier); + ASSERT_EQ(history->Get(PHASE_ID_1), identifier); + ASSERT_EQ(history->Get(PHASE_ID_2), identifier); + ASSERT_EQ(history->Get(PHASE_ID_3), identifier); +} + +// CC-OFFNXT(huge_method, G.FUN.01-CPP, G.FUD.05) solid logic +TEST_F(NodeHistoryTest, HistorySet) +{ + ASSERT_EQ(PhaseManager()->CurrentPhaseId(), PARSER_PHASE_ID); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_0.minor); + auto identifier0 = Allocator()->New(Allocator())->AsIdentifier(); + auto history = Allocator()->New(identifier0, PhaseManager()->CurrentPhaseId(), Allocator()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_1.minor); + auto identifier1 = Allocator()->New(Allocator())->AsIdentifier(); + history->Set(identifier1, PhaseManager()->CurrentPhaseId()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_2.minor); + auto identifier2 = Allocator()->New(Allocator())->AsIdentifier(); + history->Set(identifier2, PhaseManager()->CurrentPhaseId()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_3.minor); + history->Set(nullptr, PhaseManager()->CurrentPhaseId()); + + // Search forward + ASSERT_EQ(history->Get(PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_0), identifier0); + ASSERT_EQ(history->Get(PHASE_ID_1), identifier1); + ASSERT_EQ(history->Get(PHASE_ID_2), identifier2); + ASSERT_EQ(history->Get(PHASE_ID_3), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_4), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_5), nullptr); + + // Search backward + ASSERT_EQ(history->Get(PHASE_ID_5), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_4), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_3), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_2), identifier2); + ASSERT_EQ(history->Get(PHASE_ID_1), identifier1); + ASSERT_EQ(history->Get(PHASE_ID_0), identifier0); + ASSERT_EQ(history->Get(PARSER_PHASE_ID), nullptr); + + // Search random + ASSERT_EQ(history->Get(PHASE_ID_1), identifier1); + ASSERT_EQ(history->Get(PHASE_ID_5), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_2), identifier2); + ASSERT_EQ(history->Get(PHASE_ID_4), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_0), identifier0); + ASSERT_EQ(history->Get(PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_3), nullptr); + + // Search precise + ASSERT_EQ(history->At(PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->At(PHASE_ID_0), identifier0); + ASSERT_EQ(history->At(PHASE_ID_1), identifier1); + ASSERT_EQ(history->At(PHASE_ID_2), identifier2); + ASSERT_EQ(history->At(PHASE_ID_3), nullptr); + ASSERT_EQ(history->At(PHASE_ID_4), nullptr); + ASSERT_EQ(history->At(PHASE_ID_5), nullptr); +} + +TEST_F(NodeHistoryTest, HistoryReplace) +{ + ASSERT_EQ(PhaseManager()->CurrentPhaseId(), PARSER_PHASE_ID); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_0.minor); + auto identifier0Orig = Allocator()->New(Allocator())->AsIdentifier(); + auto history = Allocator()->New(identifier0Orig, PhaseManager()->CurrentPhaseId(), Allocator()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_1.minor); + auto identifier1Orig = Allocator()->New(Allocator())->AsIdentifier(); + history->Set(identifier1Orig, PhaseManager()->CurrentPhaseId()); + + ASSERT_EQ(history->Get(PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_0), identifier0Orig); + ASSERT_EQ(history->Get(PHASE_ID_1), identifier1Orig); + ASSERT_EQ(history->Get(PHASE_ID_2), identifier1Orig); + ASSERT_EQ(history->Get(PHASE_ID_3), identifier1Orig); + + ASSERT_EQ(history->At(PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->At(PHASE_ID_0), identifier0Orig); + ASSERT_EQ(history->At(PHASE_ID_1), identifier1Orig); + ASSERT_EQ(history->At(PHASE_ID_2), nullptr); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_0.minor); + auto identifier0New = Allocator()->New(Allocator())->AsIdentifier(); + history->Set(identifier0New, PhaseManager()->CurrentPhaseId()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_1.minor); + auto identifier1New = Allocator()->New(Allocator())->AsIdentifier(); + history->Set(identifier1New, PhaseManager()->CurrentPhaseId()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_2.minor); + history->Set(nullptr, PhaseManager()->CurrentPhaseId()); + + ASSERT_EQ(history->Get(PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->Get(PHASE_ID_0), identifier0Orig); + ASSERT_EQ(history->Get(PHASE_ID_1), identifier1Orig); + ASSERT_EQ(history->Get(PHASE_ID_2), identifier1Orig); + ASSERT_EQ(history->Get(PHASE_ID_3), identifier1Orig); + ASSERT_EQ(history->Get({1, PHASE_ID_0.minor}), identifier0New); + ASSERT_EQ(history->Get({1, PHASE_ID_1.minor}), identifier1New); + ASSERT_EQ(history->Get({1, PHASE_ID_2.minor}), nullptr); + ASSERT_EQ(history->Get({1, PHASE_ID_3.minor}), nullptr); + + ASSERT_EQ(history->At(PARSER_PHASE_ID), nullptr); + ASSERT_EQ(history->At(PHASE_ID_0), identifier0Orig); + ASSERT_EQ(history->At(PHASE_ID_1), identifier1Orig); + ASSERT_EQ(history->At(PHASE_ID_2), nullptr); + ASSERT_EQ(history->At({1, PHASE_ID_0.minor}), identifier0New); + ASSERT_EQ(history->At({1, PHASE_ID_1.minor}), identifier1New); + ASSERT_EQ(history->At(PHASE_ID_2), nullptr); +} + +ir::ClassDefinition *NewClassDefinition(ArenaAllocator *allocator) +{ + ArenaVector body {allocator->Adapter()}; + return allocator + ->New(allocator, nullptr, std::move(body), ir::ClassDefinitionModifiers::NONE, + ir::ModifierFlags::NONE, Language::Id::ETS) + ->AsClassDefinition(); +} + +/// NOTE(mivanov): To be enabled after #24153/#24424 implemented +TEST_F(NodeHistoryTest, UpdateField) +{ + ASSERT_EQ(PhaseManager()->CurrentPhaseId(), PARSER_PHASE_ID); + + auto definition = NewClassDefinition(Allocator()); + ASSERT_FALSE(definition->IsAbstract()); + definition->ClearModifier(ir::ModifierFlags::ABSTRACT); + ASSERT_FALSE(definition->IsAbstract()); + definition->AddModifier(ir::ModifierFlags::FINAL); + ASSERT_TRUE(definition->IsFinal()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_0.minor); + definition->AddModifier(ir::ModifierFlags::ABSTRACT); + ASSERT_TRUE(definition->IsAbstract()); + definition->ClearModifier(ir::ModifierFlags::FINAL); + ASSERT_FALSE(definition->IsFinal()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_1.minor); + definition->ClearModifier(ir::ModifierFlags::ABSTRACT); + ASSERT_FALSE(definition->IsAbstract()); + definition->AddModifier(ir::ModifierFlags::FINAL); + ASSERT_TRUE(definition->IsFinal()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_2.minor); + definition->ClearModifier(ir::ModifierFlags::FINAL); + ASSERT_FALSE(definition->IsFinal()); + + PhaseManager()->Reset(); + ASSERT_FALSE(definition->IsAbstract()); + ASSERT_TRUE(definition->IsFinal()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_0.minor); + ASSERT_TRUE(definition->IsAbstract()); + ASSERT_FALSE(definition->IsFinal()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_1.minor); + ASSERT_FALSE(definition->IsAbstract()); + ASSERT_TRUE(definition->IsFinal()); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_2.minor); + ASSERT_FALSE(definition->IsAbstract()); + ASSERT_FALSE(definition->IsFinal()); +} + +/// NOTE(mivanov): To be enabled after #24153/#24424 implemented +TEST_F(NodeHistoryTest, DISABLED_UpdateChild) +{ + ASSERT_EQ(PhaseManager()->CurrentPhaseId(), PARSER_PHASE_ID); + + auto declaration = + Allocator()->New(NewClassDefinition(Allocator()), Allocator())->AsClassDeclaration(); + ASSERT_EQ(declaration->Definition()->Ident(), nullptr); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_0.minor); + auto identifier0 = Allocator()->New(Allocator())->AsIdentifier(); + declaration->Definition()->SetIdent(identifier0); + ASSERT_EQ(declaration->Definition()->Ident(), identifier0); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_1.minor); + auto identifier1 = Allocator()->New(Allocator())->AsIdentifier(); + declaration->Definition()->SetIdent(identifier1); + ASSERT_EQ(declaration->Definition()->Ident(), identifier1); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_2.minor); + declaration->Definition()->SetIdent(nullptr); + ASSERT_EQ(declaration->Definition()->Ident(), nullptr); + + PhaseManager()->Reset(); + ASSERT_EQ(declaration->Definition()->Ident(), nullptr); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_0.minor); + ASSERT_EQ(declaration->Definition()->Ident(), identifier0); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_1.minor); + ASSERT_EQ(declaration->Definition()->Ident(), identifier1); + + PhaseManager()->SetCurrentPhaseId(PHASE_ID_2.minor); + ASSERT_EQ(declaration->Definition()->Ident(), nullptr); +} +} // namespace ark::es2panda diff --git a/ets2panda/test/unit/lowerings/scopes_initialization.cpp b/ets2panda/test/unit/lowerings/scopes_initialization.cpp index 472da09d9329ca691410ca30ae0c73809329f96a..1c82aeed87a9433ae34306838724b64a7aea4296 100644 --- a/ets2panda/test/unit/lowerings/scopes_initialization.cpp +++ b/ets2panda/test/unit/lowerings/scopes_initialization.cpp @@ -30,11 +30,12 @@ public: ~ScopesInitPhaseTest() override = default; ScopesInitPhaseTest() - : allocator_(std::make_unique(SpaceType::SPACE_TYPE_COMPILER)), nodeGen_(allocator_.get()) + : allocator_(std::make_unique(SpaceType::SPACE_TYPE_COMPILER, nullptr, true)), + nodeGen_(allocator_.get()) { } - ArenaAllocator *Allocator() + ark::ThreadSafeArenaAllocator *Allocator() { return allocator_.get(); } @@ -48,7 +49,7 @@ public: NO_MOVE_SEMANTIC(ScopesInitPhaseTest); private: - std::unique_ptr allocator_; + std::unique_ptr allocator_; gtests::NodeGenerator nodeGen_; }; diff --git a/ets2panda/test/unit/lowerings/top_level_statements.cpp b/ets2panda/test/unit/lowerings/top_level_statements.cpp index a971de722545745fc18376a9cbef5b0bc74a5eb0..88ef6174435d25f407c07ac835c14045599c0ae1 100644 --- a/ets2panda/test/unit/lowerings/top_level_statements.cpp +++ b/ets2panda/test/unit/lowerings/top_level_statements.cpp @@ -27,16 +27,12 @@ TEST_F(LoweringTest, TestTopLevelStmtsSyntheticModuleGlobalClass) CONTEXT(ES2PANDA_STATE_LOWERED, text) { const auto *const ast = GetAst(); - auto *classDef = ast->FindChild( - [](ir::AstNode *child) { return child->IsClassDefinition() && child->AsClassDefinition()->IsGlobal(); }); + [[maybe_unused]] auto *classDef = ast->FindChild([](ir::AstNode *child) { + return child->IsClassDefinition() && + (child->AsClassDefinition()->InternalName().Mutf8() == "dummy.ETSGLOBAL"); + }); ASSERT(classDef != nullptr); - bool foundModuleAnnotation = false; - for (auto *anno : classDef->AsClassDefinition()->Annotations()) { - if (anno->Expr()->AsIdentifier()->Name() == "Module") { - foundModuleAnnotation = true; - } - } - ASSERT_TRUE(foundModuleAnnotation); + ASSERT(classDef->AsClassDefinition()->IsGlobalInitialized()); } } @@ -51,18 +47,84 @@ TEST_F(LoweringTest, TestTopLevelStmtsSyntheticModuleClass) CONTEXT(ES2PANDA_STATE_LOWERED, text) { const auto *const ast = GetAst(); - auto *classDef = ast->FindChild([](ir::AstNode *child) { - return child->IsClassDefinition() && - ((child->AsClassDefinition()->Modifiers() & ir::ClassDefinitionModifiers::CLASS_DECL) != 0U); + [[maybe_unused]] auto *classDef = ast->FindChild([](ir::AstNode *child) { + return child->IsClassDefinition() && (child->AsClassDefinition()->InternalName().Mutf8() == "dummy.X"); }); ASSERT(classDef != nullptr); - bool foundModuleAnnotation = false; - for (auto *anno : classDef->AsClassDefinition()->Annotations()) { - if (anno->Expr()->AsIdentifier()->Name() == "Module") { - foundModuleAnnotation = true; - } + ASSERT(classDef->AsClassDefinition()->IsNamespaceTransformed()); + } +} + +TEST_F(LoweringTest, TestTopLevelStmtsExportedClass) +{ + char const *text = R"( + export class A {} + class B {} + )"; + + CONTEXT(ES2PANDA_STATE_LOWERED, text) + { + const auto *const ast = GetAst(); + auto *classDef = ast->FindChild([](ir::AstNode *child) { + return child->IsClassDefinition() && child->AsClassDefinition()->IsGlobalInitialized(); + }); + ASSERT_NE(classDef, nullptr); + + const auto &exportedClasses = classDef->AsClassDefinition()->ExportedClasses(); + ASSERT_EQ(exportedClasses.size(), 1); + ASSERT_TRUE(exportedClasses[0]->IsExported()); + ASSERT_EQ(exportedClasses[0]->Definition()->InternalName().Mutf8(), "dummy.A"); + } +} + +TEST_F(LoweringTest, TestTopLevelStmtsExportedNamespace) +{ + char const *text = R"( + export namespace A {} + namespace B {} + )"; + + CONTEXT(ES2PANDA_STATE_LOWERED, text) + { + const auto *const ast = GetAst(); + auto *classDef = ast->FindChild([](ir::AstNode *child) { + return child->IsClassDefinition() && child->AsClassDefinition()->IsGlobalInitialized(); + }); + ASSERT_NE(classDef, nullptr); + + const auto &exportedClasses = classDef->AsClassDefinition()->ExportedClasses(); + ASSERT_EQ(exportedClasses.size(), 1); + ASSERT_TRUE(exportedClasses[0]->IsExported()); + ASSERT_EQ(exportedClasses[0]->Definition()->InternalName().Mutf8(), "dummy.A"); + } +} + +TEST_F(LoweringTest, TestTopLevelStmtsExportedNamespaceNested) +{ + char const *text = R"( + export namespace A { + export namespace B {} + namespace C {} + export class D {} + class E {} } - ASSERT_TRUE(foundModuleAnnotation); + )"; + + CONTEXT(ES2PANDA_STATE_LOWERED, text) + { + const auto *const ast = GetAst(); + auto *classDef = ast->FindChild([](ir::AstNode *child) { + return child->IsClassDefinition() && child->AsClassDefinition()->IsNamespaceTransformed(); + }); + ASSERT(classDef != nullptr); + + const auto &exportedClasses = classDef->AsClassDefinition()->ExportedClasses(); + constexpr uint32_t EXPORTED_CLASSES_NUM = 2; + ASSERT_EQ(exportedClasses.size(), EXPORTED_CLASSES_NUM); + ASSERT_TRUE(exportedClasses[0]->IsExported()); + ASSERT_TRUE(exportedClasses[1]->IsExported()); + ASSERT_EQ(exportedClasses[0]->Definition()->InternalName().Mutf8(), "dummy.A.B"); + ASSERT_EQ(exportedClasses[1]->Definition()->InternalName().Mutf8(), "dummy.A.D"); } } diff --git a/ets2panda/test/unit/lsp/CMakeLists.txt b/ets2panda/test/unit/lsp/CMakeLists.txt index a722e3b903097de467d9fe3d75b995c51411a051..6f10ba2d98243e607e9afc7d78b3e7e29980dbef 100644 --- a/ets2panda/test/unit/lsp/CMakeLists.txt +++ b/ets2panda/test/unit/lsp/CMakeLists.txt @@ -11,30 +11,98 @@ # See the License for the specific language governing permissions and # limitations under the License. -ets2panda_add_gtest(lsp_api_test_1 CPP_SOURCES +ets2panda_add_gtest(lsp_get_definition_at_position_test CPP_SOURCES get_definition_at_position_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_get_applicable_refactors CPP_SOURCES + refactors_convert_function_test.cpp +) + +ets2panda_add_gtest(lsp_get_file_references_test CPP_SOURCES get_file_references_test.cpp +) + +ets2panda_add_gtest(lsp_api_script_element_kind CPP_SOURCES + script_element_kind_test.cpp +) + +ets2panda_add_gtest(lsp_get_references_at_position_test CPP_SOURCES get_references_at_position_test.cpp +) + +ets2panda_add_gtest(lsp_document_highlights_test CPP_SOURCES document_highlights.cpp ) -ets2panda_add_gtest(lsp_api_test CPP_SOURCES - lsp_api_test.cpp +ets2panda_add_gtest(lsp_diagnostic_test CPP_SOURCES + diagnostic_test.cpp +) + +ets2panda_add_gtest(lsp_isolated_declaration_test CPP_SOURCES + isolated_declaration.cpp +) + +ets2panda_add_gtest(lsp_cancellation_token_test CPP_SOURCES cancellation_token_test.cpp +) + +ets2panda_add_gtest(lsp_get_span_of_enclosing_comment_test CPP_SOURCES get_span_of_enclosing_comment_test.cpp +) + +ets2panda_add_gtest(lsp_user_preferences_test CPP_SOURCES user_preferences.cpp +) + +ets2panda_add_gtest(lsp_keyword_completion_data_test CPP_SOURCES keyword_completion_data_test.cpp +) + +ets2panda_add_gtest(lsp_rename_test CPP_SOURCES lsp_rename_test.cpp ) +ets2panda_add_gtest(lsp_get_current_token_value_test CPP_SOURCES + get_current_token_value_test.cpp +) + +ets2panda_add_gtest(lsp_get_file_references_impl_test CPP_SOURCES + get_file_references_impl_test.cpp +) + +ets2panda_add_gtest(lsp_get_preceding_token_test CPP_SOURCES + get_preceding_token_test.cpp +) + +ets2panda_add_gtest(lsp_get_touching_token_test CPP_SOURCES + get_touching_token_test.cpp +) + +ets2panda_add_gtest(lsp_get_type_of_symbol_at_location_test CPP_SOURCES + get_type_of_symbol_at_location_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_organize_imports CPP_SOURCES + organize_imports_test.cpp +) + ets2panda_add_gtest(lsp_quick_info_api_test CPP_SOURCES quick_info_test.cpp ) +ets2panda_add_gtest(lsp_api_completions_entry_details_test CPP_SOURCES + get_completions_entry_details.cpp +) + ets2panda_add_gtest(lsp_api_classifier_test CPP_SOURCES classifier_test.cpp ) +ets2panda_add_gtest(lsp_api_test_class_hierarchies CPP_SOURCES + class_hierarchys_test.cpp +) + ets2panda_add_gtest(lsp_api_diagnostics_test CPP_SOURCES get_compiler_options_diagnostics_test.cpp get_diagnostics.cpp @@ -44,6 +112,14 @@ ets2panda_add_gtest(lsp_api_get_adjusted_location_test CPP_SOURCES get_adjusted_location_test.cpp ) +ets2panda_add_gtest(lsp_api_test_class_hierarchy CPP_SOURCES + class_hierarchy_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_find_safe_delete_location CPP_SOURCES + find_safe_delete_location_test.cpp +) + ets2panda_add_gtest(lsp_api_test_find_references CPP_SOURCES find_references_test.cpp ) @@ -56,6 +132,10 @@ ets2panda_add_gtest(lsp_api_test_suggestion_diagnostics CPP_SOURCES suggestion_diagnostics_test.cpp ) +ets2panda_add_gtest(lsp_api_test_get_class_property_info CPP_SOURCES + get_class_property_info_test.cpp +) + ets2panda_add_gtest(lsp_api_test_brace_matching CPP_SOURCES brace_matching_test.cpp ) @@ -64,6 +144,10 @@ ets2panda_add_gtest(lsp_api_completions_test CPP_SOURCES get_completions.cpp ) +ets2panda_add_gtest(lsp_api_test_get_class_hierarchy_info CPP_SOURCES + class_hierarchy_info_test.cpp +) + ets2panda_add_gtest(lsp_api_gilap_test CPP_SOURCES get_implementation_location.cpp ) @@ -72,6 +156,10 @@ ets2panda_add_gtest(lsp_api_lco_test CPP_SOURCES line_column_offset_test.cpp ) +ets2panda_add_gtest(lsp_api_get_constructor_test CPP_SOURCES + get_constructor_test.cpp +) + ets2panda_add_gtest(lsp_api_test_auto_completion CPP_SOURCES get_auto_completion_test.cpp ) @@ -83,3 +171,42 @@ ets2panda_add_gtest(lsp_api_test_inlay_hints CPP_SOURCES ets2panda_add_gtest(lsp_api_test_find_rename_locations CPP_SOURCES find_rename_locations_test.cpp ) + +ets2panda_add_gtest(lsp_api_test_change_tracker CPP_SOURCES + change_tracker_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_get_safe_delete_info CPP_SOURCES + get_safe_delete_info_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_create_type_help_items CPP_SOURCES + create_type_help_items_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_signature_help_items CPP_SOURCES + signature_help_items_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_get_def_and_bound_span CPP_SOURCES + get_definition_and_bound_span_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_formatting_context CPP_SOURCES + formatting_context_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_formatting CPP_SOURCES + formatting_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_todo_comments CPP_SOURCES + todo_comments_test.cpp +) + +ets2panda_add_gtest(lsp_api_test_navigate_to CPP_SOURCES + navigate_to_test.cpp +) +ets2panda_add_gtest(lsp_api_test_code_fix_registration CPP_SOURCES + code_fix_registration_test.cpp +) diff --git a/ets2panda/test/unit/lsp/change_tracker_test.cpp b/ets2panda/test/unit/lsp/change_tracker_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1726d6b4563b6c66ac88352ab5ce6c8e7a3d80ff --- /dev/null +++ b/ets2panda/test/unit/lsp/change_tracker_test.cpp @@ -0,0 +1,513 @@ +/** + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "lsp_api_test.h" +#include "lsp/include/class_hierarchy.h" +#include "lsp/include/internal_api.h" +#include "lsp/include/services/text_change/change_tracker.h" +#include "public/es2panda_lib.h" +#include + +namespace { + +class LspClassChangeTracker : public LSPAPITests {}; + +const size_t START_POS = 0; +const size_t END_POS = 9; +const auto C6 = 6; + +bool g_hasTextChange = false; +bool g_hasNodeChange = false; + +ark::es2panda::lsp::ChangeTracker GetTracker() +{ + const std::string defaultNewLine = "\n"; + ark::es2panda::lsp::FormatCodeSettings settings; + auto formatContext = ark::es2panda::lsp::GetFormatContext(settings); + TextChangesContext changeText {{}, formatContext, {}}; + auto tracker = ark::es2panda::lsp::ChangeTracker::FromContext(changeText); + return tracker; +} + +TEST_F(LspClassChangeTracker, PushRaw_AddsChangeCorrectly) +{ + const char *source = R"( +function add(a: number, b: number) { + return a + b; +} +)"; + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = + initializer.CreateContext("pushRaw_AddsChangeCorrectly.ets", ES2PANDA_STATE_CHECKED, source); + auto *context = reinterpret_cast(ctx); + auto sourceFile = context->sourceFile; + + const auto *returnNode = + context->parserProgram->Ast()->FindChild([](const auto *node) { return node->IsReturnStatement(); }); + ASSERT_NE(returnNode, nullptr); + + auto spanStart = returnNode->Start().index; + auto spanLength = strlen("return a + b;"); + TextSpan span = {spanStart, spanLength}; + std::string retStr = "return a - b;"; + TextChange change = {span, retStr}; + FileTextChanges fileChange = {"pushRaw_AddsChangeCorrectly.ets", {change}}; + auto tracker = GetTracker(); + tracker.PushRaw(sourceFile, fileChange); + + auto list = tracker.GetChanges(); + EXPECT_FALSE(list.empty()); + EXPECT_EQ(list.size(), 1); + + const auto variant = list[0]; + const auto changeText = variant.textChanges; + ASSERT_EQ(changeText[0].newText, retStr); + + EXPECT_EQ(variant.fileName, fileChange.fileName); + + const auto &textChange = changeText; + EXPECT_EQ(textChange[0].span.start, spanStart); +} + +TEST_F(LspClassChangeTracker, DeleteMethods_BasicTest1) +{ + const char *source = R"( +function test() { + const a = 1; + const b = 2; +} +)"; + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext("deleteMethods_BasicTest1.ets", ES2PANDA_STATE_CHECKED, source); + auto *context = reinterpret_cast(ctx); + const auto sourceFile = context->sourceFile; + ark::es2panda::ir::AstNode *ast = context->parserProgram->Ast(); + ASSERT_NE(ast, nullptr); + const auto ca = "a"; + const auto c0 = 0; + const auto c1 = 1; + const auto c2 = 2; + ark::es2panda::ir::AstNode *aDecl; + ast->FindChild([&ca, &aDecl](ark::es2panda::ir::AstNode *node) { + if (node->IsVariableDeclaration() && + node->AsVariableDeclaration()->Declarators()[c0]->Id()->AsIdentifier()->Name() == ca) { + aDecl = node; + } + return false; + }); + ASSERT_NE(aDecl, nullptr); + auto tracker = GetTracker(); + std::variant> + nodeVariant = aDecl; + tracker.Delete(sourceFile, nodeVariant); + const auto &deletedNodes = tracker.GetDeletedNodesList(); + EXPECT_EQ(deletedNodes.size(), c1); + ark::es2panda::lsp::TextRange range = {aDecl->Start().index, aDecl->End().index}; + tracker.DeleteRange(sourceFile, range); + const auto &changes = tracker.GetChangeList(); + EXPECT_EQ(changes.size(), c1); + auto &change = std::get(changes[c0]); + EXPECT_EQ(change.kind, ark::es2panda::lsp::ChangeKind::REMOVE); + EXPECT_EQ(change.range.pos, range.pos); + EXPECT_EQ(change.range.end, range.end); + tracker.DeleteNode(ctx, sourceFile, aDecl); + EXPECT_EQ(tracker.GetChangeList().size(), c2); + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, DeleteHelpers_BasicTest2) +{ + const char *source = "export async function test() { \n let a = 1; \n let b = 2; \n let c = 3; \n}"; + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext("deleteHelpers_BasicTest2.ets", ES2PANDA_STATE_CHECKED, source); + auto *context = reinterpret_cast(ctx); + auto *ast = context->parserProgram->Ast(); + ASSERT_NE(ast, nullptr); + const auto *sourceFile = context->sourceFile; + auto tracker = GetTracker(); + ark::es2panda::ir::AstNode *aDecl; + ark::es2panda::ir::AstNode *bDecl; + ark::es2panda::ir::AstNode *cDecl; + const auto c3 = 3; + + ast->FindChild([&aDecl, &bDecl, &cDecl](ark::es2panda::ir::AstNode *node) { + if (node->IsVariableDeclaration() && + node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name() == "a") { + aDecl = node; + } + if (node->IsVariableDeclaration() && + node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name() == "b") { + bDecl = node; + } + if (node->IsVariableDeclaration() && + node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name() == "c") { + cDecl = node; + } + return false; + }); + ASSERT_NE(aDecl, nullptr); + ASSERT_NE(bDecl, nullptr); + ASSERT_NE(cDecl, nullptr); + tracker.DeleteNode(ctx, sourceFile, aDecl); + tracker.DeleteNodeRange(ctx, bDecl, cDecl); + tracker.DeleteNodeRangeExcludingEnd(ctx, const_cast(aDecl), bDecl); + const auto &changes = tracker.GetChangeList(); // varsayalım internal erişim var + EXPECT_EQ(changes.size(), c3); + for (const auto &c : changes) { + if (const auto *removeNode = std::get_if(&c)) { + EXPECT_EQ(removeNode->kind, ark::es2panda::lsp::ChangeKind::REMOVE); + EXPECT_LT(removeNode->range.pos, removeNode->range.end); + } + } + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, ReplaceHelpers_BasicTest1) +{ + const char *source = "function test() {\nlet a = 1;\nlet b = 2;\n}"; + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext("replaceHelpers_BasicTest1.ets", ES2PANDA_STATE_CHECKED, source); + auto *context = reinterpret_cast(ctx); + auto *ast = context->parserProgram->Ast(); + auto *sourceFile = context->sourceFile; + auto tracker = GetTracker(); + ark::es2panda::ir::AstNode *aDecl; + ark::es2panda::ir::AstNode *bDecl; + ast->FindChild([&aDecl, &bDecl](ark::es2panda::ir::AstNode *node) { + if (node->IsVariableDeclaration() && + node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name() == "a") { + aDecl = node; + } + if (node->IsVariableDeclaration() && + node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name() == "b") { + bDecl = node; + } + return false; + }); + const char *textReplace = "// replaced\n"; + const char *replaceNode = "let x = 100;"; + ark::es2panda::ir::AstNode *bClone = bDecl->Clone(context->allocator, nullptr); + ark::es2panda::lsp::ChangeNodeOptions options = {}; + tracker.ReplaceNode(ctx, aDecl, bClone, options); + ark::es2panda::ir::AstNode *fnNode = + ast->FindChild([](ark::es2panda::ir::AstNode *node) { return node->IsFunctionExpression(); }); + tracker.ReplaceNodeRange(ctx, bClone, fnNode, bClone); + std::vector bCloneVec {bClone}; + tracker.ReplaceNodeWithNodes(ctx, aDecl, bCloneVec); + tracker.ReplaceNodeWithText(ctx, bClone, replaceNode); + tracker.ReplaceRangeWithText(sourceFile, {START_POS, END_POS}, textReplace); + tracker.ReplaceNodeRangeWithNodes(ctx, bClone, bClone, bCloneVec); + const auto &changes = tracker.GetChangeList(); // Internal erişim + EXPECT_EQ(changes.size(), C6); + for (const auto &change : changes) { + if (std::get_if(&change) != nullptr) { + g_hasTextChange = true; + } + if (std::get_if(&change) != nullptr) { + g_hasNodeChange = true; + } + } + EXPECT_TRUE(g_hasTextChange); + EXPECT_TRUE(g_hasNodeChange); + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, ReplacePropertyAssignment_BasicTest) +{ + const char *source = R"( +let obj = { + foo: 1 +};)"; + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = + initializer.CreateContext("replacePropertyAssignment_BasicTest.ets", ES2PANDA_STATE_CHECKED, source); + auto *context = reinterpret_cast(ctx); + auto *ast = context->parserProgram->Ast(); + ASSERT_NE(ast, nullptr); + auto *propertyNode = ast->FindChild([](const ark::es2panda::ir::AstNode *node) { + return node->IsProperty() && node->AsProperty()->Key()->AsIdentifier()->Name() == "foo"; + }); + ASSERT_NE(propertyNode, nullptr); + ark::es2panda::ir::AstNode *newProperty = propertyNode->Clone(context->allocator, nullptr); + ASSERT_NE(newProperty, nullptr); + auto *prop = const_cast(newProperty->AsProperty()); + auto *ident = const_cast(prop->Key()->AsIdentifier()); + ident->SetName("bar"); + ark::es2panda::lsp::ChangeTracker tracker = GetTracker(); + tracker.ReplacePropertyAssignment(ctx, propertyNode, newProperty); + const auto &changes = tracker.GetChangeList(); + const size_t c1 = 1; + const auto bar = "bar"; + const auto newLine = ",\n"; + ASSERT_EQ(changes.size(), c1); + const auto &change = changes[0]; + const auto *replace = std::get_if(&change); + ASSERT_NE(replace, nullptr); + EXPECT_EQ(replace->kind, ark::es2panda::lsp::ChangeKind::REPLACEWITHSINGLENODE); + EXPECT_EQ(replace->node->AsProperty()->Key()->AsIdentifier()->Name(), bar); + EXPECT_EQ(replace->options->suffix, newLine); + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, ReplaceConstructorBody_BasicTest) +{ + const char *source = "class MyClass {\nconstructor() {\nlet a = 1;\n}\n}"; + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = + initializer.CreateContext("replaceConstructorBody_BasicTest.ets", ES2PANDA_STATE_CHECKED, source); + auto *context = reinterpret_cast(ctx); + auto *ast = context->parserProgram->Ast(); + ASSERT_NE(ast, nullptr); + ark::es2panda::ir::AstNode *ctrNode; + ast->FindChild([&ctrNode](ark::es2panda::ir::AstNode *node) { + if (node->IsFunctionExpression() && node->AsFunctionExpression()->Function()->Id()->Name() == "constructor") { + ctrNode = node; + } + return false; + }); + ASSERT_NE(ctrNode, nullptr); + std::vector dummyStatements; + ark::es2panda::lsp::ChangeTracker tracker = GetTracker(); + tracker.ReplaceConstructorBody(ctx, ctrNode, dummyStatements); + const auto &changes = tracker.GetChangeList(); + const size_t c1 = 1; + ASSERT_EQ(changes.size(), c1); + const auto &change = changes[0]; + const auto *replace = std::get_if(&change); + ASSERT_NE(replace, nullptr); + EXPECT_EQ(replace->kind, ark::es2panda::lsp::ChangeKind::REPLACEWITHSINGLENODE); + EXPECT_EQ(replace->node, nullptr); + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, InsertHelpers_BasicTest1) +{ + const char *source = "function test() {\nlet a = 1;\nlet b = 2;\n}"; + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext("insertHelpers_BasicTest1.ets", ES2PANDA_STATE_CHECKED, source); + auto *context = reinterpret_cast(ctx); + auto *ast = context->parserProgram->Ast(); + ASSERT_NE(ast, nullptr); + ark::es2panda::lsp::ChangeTracker tracker = GetTracker(); + ark::es2panda::ir::AstNode *aDecl; + ark::es2panda::ir::AstNode *bDecl; + ast->FindChild([&aDecl, &bDecl](ark::es2panda::ir::AstNode *node) { + if (node->IsVariableDeclaration() && + node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name() == "a") { + aDecl = node; + } + if (node->IsVariableDeclaration() && + node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name() == "b") { + bDecl = node; + } + return false; + }); + ASSERT_NE(aDecl, nullptr); + ASSERT_NE(bDecl, nullptr); + ark::es2panda::ir::AstNode *bClone = bDecl->Clone(context->allocator, nullptr); + ark::es2panda::lsp::InsertNodeOptions options; + ASSERT_NE(bClone, nullptr); + auto *ident = const_cast( + bClone->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()); + ident->SetName("bar"); + tracker.InsertNodeAt(ctx, aDecl->Start().index, bClone, options); + ident->SetName("top"); + tracker.InsertNodeAtTopOfFile(ctx, bClone, false); + ident->SetName("before"); + tracker.InsertNodeBefore(ctx, aDecl, bClone, false); + ident->SetName("modify"); + tracker.InsertModifierAt(ctx, aDecl->End().index, bClone, options); + ident->SetName("modifBefore"); + tracker.InsertModifierBefore(ctx, aDecl, bClone); + const size_t c5 = 5; + ASSERT_EQ(tracker.GetChangeList().size(), c5); + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, InsertTextTest) +{ + const std::string sourceText = "const a = 1;"; + const std::string file = "insertTextTest_1.ets"; + auto filePaths = CreateTempFile({file}, {sourceText}); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = initializer.CreateContext(file.c_str(), ES2PANDA_STATE_CHECKED, sourceText.c_str()); + auto context = reinterpret_cast(ctx); + + ark::es2panda::lsp::ChangeTracker tracker = GetTracker(); + const size_t insertPosition = 0; + const size_t c1 = 1; + const std::string textToInsert = "// Inserted text\n"; + tracker.InsertText(context->sourceFile, insertPosition, textToInsert); + ASSERT_EQ(tracker.GetChangeList().size(), c1); + const auto &changeVariant = tracker.GetChangeList(); + const auto &change = std::get(changeVariant[0]); + ASSERT_EQ(change.kind, ark::es2panda::lsp::ChangeKind::TEXT); + EXPECT_EQ(change.range.pos, insertPosition); + EXPECT_EQ(change.text, textToInsert); + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, TryInsertTypeAnnotationTest) +{ + const std::string sourceText = "const a = 1;"; + const std::string file = "tryInsertTypeAnnotationTest.ets"; + auto filePaths = CreateTempFile({file}, {sourceText}); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = initializer.CreateContext(file.c_str(), ES2PANDA_STATE_CHECKED, sourceText.c_str()); + auto context = reinterpret_cast(ctx); + + ark::es2panda::lsp::ChangeTracker tracker = GetTracker(); + auto ast = reinterpret_cast(context->parserProgram->Ast()); + ark::es2panda::ir::AstNode *aDecl; + ast->FindChild([&aDecl](ark::es2panda::ir::AstNode *node) { + if (node->IsClassProperty() && node->AsClassProperty()->Id()->AsIdentifier()->Name() == "a") { + aDecl = node; + } + return false; + }); + ASSERT_NE(aDecl, nullptr); + const size_t c1 = 1; + const auto prefix = ": "; + ark::es2panda::ir::AstNode *aClone = aDecl->Clone(context->allocator, nullptr); + tracker.TryInsertTypeAnnotation(ctx, aDecl, aClone); + ASSERT_EQ(tracker.GetChangeList().size(), c1); + const auto change = std::get(tracker.GetChangeList()[0]); + ASSERT_EQ(change.kind, ark::es2panda::lsp::ChangeKind::REPLACEWITHSINGLENODE); + EXPECT_EQ(change.range.pos, aDecl->End().index); + EXPECT_EQ(change.options->prefix, prefix); + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, TryInsertThisTypeAnnotationTest) +{ + const std::string sourceText = "function foo() {}"; + const std::string file = "tryInsertThisTypeAnnotationTest.ets"; + auto filePaths = CreateTempFile({file}, {sourceText}); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = initializer.CreateContext(file.c_str(), ES2PANDA_STATE_CHECKED, sourceText.c_str()); + auto context = reinterpret_cast(ctx); + ark::es2panda::lsp::ChangeTracker tracker = GetTracker(); + auto ast = reinterpret_cast(context->parserProgram->Ast()); + ark::es2panda::ir::AstNode *funcDecl; + ast->FindChild([&funcDecl](ark::es2panda::ir::AstNode *node) { + if (node->IsFunctionExpression() && + node->AsFunctionExpression()->Function()->Id()->AsIdentifier()->Name() == "foo") { + funcDecl = node; + } + return false; + }); + ASSERT_NE(funcDecl, nullptr); + ark::es2panda::ir::AstNode *aClone = funcDecl->Clone(context->allocator, nullptr); + tracker.TryInsertThisTypeAnnotation(ctx, funcDecl, aClone); + const auto c1 = 1; + const auto prefix = "this: "; + ASSERT_EQ(tracker.GetChangeList().size(), c1); + const auto &changeVariant = tracker.GetChangeList(); + const auto &change = std::get(changeVariant[0]); + ASSERT_EQ(change.kind, ark::es2panda::lsp::ChangeKind::REPLACEWITHSINGLENODE); + EXPECT_EQ(change.range.pos, funcDecl->Start().index); + EXPECT_EQ(change.options->prefix, prefix); + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, InsertTypeParametersTest) +{ + const std::string sourceText = "function foo(a: number) {}"; + const std::string file = "insertTypeParametersTest.ets"; + auto filePaths = CreateTempFile({file}, {sourceText}); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = initializer.CreateContext(file.c_str(), ES2PANDA_STATE_CHECKED, sourceText.c_str()); + auto context = reinterpret_cast(ctx); + ark::es2panda::lsp::ChangeTracker tracker = GetTracker(); + auto ast = reinterpret_cast(context->parserProgram->Ast()); + ark::es2panda::ir::AstNode *funcDecl; + ark::es2panda::ir::AstNode *param; + ast->FindChild([&funcDecl](ark::es2panda::ir::AstNode *node) { + if (node->IsFunctionExpression() && + node->AsFunctionExpression()->Function()->Id()->AsIdentifier()->Name() == "foo") { + funcDecl = node; + } + return false; + }); + ast->FindChild([¶m](ark::es2panda::ir::AstNode *node) { + if (node->IsETSParameterExpression()) { + param = node; + } + return false; + }); + ASSERT_NE(funcDecl, nullptr); + const auto param1 = param->Clone(context->allocator, nullptr); + const auto param2 = param->Clone(context->allocator, nullptr); + std::vector typeParams {param1, param2}; + tracker.InsertTypeParameters(ctx, funcDecl, typeParams); + const auto c1 = 1; + const auto prefix = "<"; + const auto suffix = ">"; + const auto joiner = ", "; + ASSERT_EQ(tracker.GetChangeList().size(), c1); + const auto &changeVariant = tracker.GetChangeList(); + const auto &change = std::get(changeVariant[0]); + ASSERT_EQ(change.kind, ark::es2panda::lsp::ChangeKind::REPLACEWITHMULTIPLENODES); + EXPECT_EQ(change.range.pos, funcDecl->End().index); // This may be wrong + EXPECT_EQ(change.options->prefix, prefix); + EXPECT_EQ(change.options->suffix, suffix); + EXPECT_EQ(change.options->joiner, joiner); + initializer.DestroyContext(ctx); +} + +TEST_F(LspClassChangeTracker, InsertExportModifier_BasicTest) +{ + const char *source = R"( + class ETSGLOBAL { + public static foo() { + let x = 10; + } + } + )"; + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = + initializer.CreateContext("insertExportModifier_BasicTest.ets", ES2PANDA_STATE_CHECKED, source); + auto *context = reinterpret_cast(ctx); + ASSERT_NE(context->parserProgram->Ast(), nullptr); + auto *sourceFile = context->sourceFile; + ark::es2panda::lsp::ChangeTracker tracker = GetTracker(); + ark::es2panda::ir::AstNode *classNode = context->parserProgram->Ast()->FindChild( + [](ark::es2panda::ir::AstNode *node) { return node->IsClassDeclaration(); }); + ASSERT_NE(classNode, nullptr); + auto *statementNode = classNode->AsStatement(); + ASSERT_NE(statementNode, nullptr); + tracker.InsertExportModifier(sourceFile, statementNode); + const auto c1 = 1; + const auto expText = "export "; + ASSERT_EQ(tracker.GetChangeList().size(), c1); + const auto &changeVariant = tracker.GetChangeList(); + const auto &change = std::get(changeVariant[0]); + ASSERT_NE(&change, nullptr); + EXPECT_EQ(change.text, expText); + EXPECT_EQ(change.range.pos, statementNode->Start().index); + EXPECT_EQ(change.range.pos, change.range.end); // Insert olduğu için boş aralık + + initializer.DestroyContext(ctx); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/class_hierarchy_info_test.cpp b/ets2panda/test/unit/lsp/class_hierarchy_info_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6d2466a99b55152b430fea42e2e18c50e2d20183 --- /dev/null +++ b/ets2panda/test/unit/lsp/class_hierarchy_info_test.cpp @@ -0,0 +1,193 @@ +/** + * 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/class_hierarchy_info.h" +#include "lsp_api_test.h" +#include "lsp/include/internal_api.h" +#include + +using ark::es2panda::lsp::Initializer; + +namespace { + +class LspScriptElementKindTests : public LSPAPITests {}; + +TEST_F(LSPAPITests, GetClassHierarchyInfo_1) +{ + LSPAPI const *lspApi = GetImpl(); + ASSERT_TRUE(lspApi != nullptr); + const std::string text = R"(class Parent { +private privateMethod(): void { + console.log("Parent method"); +} + public publicMethod(): void { + console.log("Parent method"); +} + protected action(fileName: string, position: number): number { + return position; +} + static staticMethod(): void { + console.log("Parent static method"); + } +} + class Child extends Parent { + public display(): void { + console.log("need display"); + } +})"; + + auto pos = text.find("Child"); + ASSERT_NE(pos, std::string::npos); + Initializer initializer = Initializer(); + auto context = initializer.CreateContext("class_hierarchy_info_1.ets", ES2PANDA_STATE_CHECKED, text.c_str()); + auto classHierarchy = lspApi->getClassHierarchyInfo(context, pos); + + ASSERT_EQ(classHierarchy.size(), 1); + ASSERT_EQ(classHierarchy[0].GetClassName(), "Parent"); + auto methods = classHierarchy[0].GetMethodList(); + auto it = methods.find("publicMethod()"); + ASSERT_TRUE(it != methods.end()); + ASSERT_TRUE(it->second != nullptr); + ASSERT_EQ(it->second->GetSetterStyle(), ark::es2panda::lsp::SetterStyle::METHOD); + ASSERT_EQ(it->second->GetAccessModifierStyle(), ark::es2panda::lsp::AccessModifierStyle::PUBLIC); + it = methods.find("action(fileName: string, position: number): number"); + ASSERT_TRUE(it != methods.end()); + ASSERT_TRUE(it->second != nullptr); + ASSERT_EQ(it->second->GetSetterStyle(), ark::es2panda::lsp::SetterStyle::METHOD); + ASSERT_EQ(it->second->GetAccessModifierStyle(), ark::es2panda::lsp::AccessModifierStyle::PROTECTED); + initializer.DestroyContext(context); +} + +TEST_F(LSPAPITests, GetClassHierarchyInfo_2) +{ + LSPAPI const *lspApi = GetImpl(); + ASSERT_TRUE(lspApi != nullptr); + const std::string text = R"(class Animal { +private body_: string = ''; + + protected action(): void { + console.log("need Animal action"); + } + protected sleep(): void { + console.log("need Animal sleep"); + } +} + +class Bird extends Animal { + action(): void { + console.log("need action"); + } + + Drink(): void { + console.log("need Drink"); + } +} + +class Magpie extends Bird { + public action(): void {} + Drink(): void { + console.log("need Drink"); + } +})"; + + auto pos = text.find("Magpie"); + ASSERT_NE(pos, std::string::npos); + Initializer initializer = Initializer(); + auto context = initializer.CreateContext("class_hierarchy_info_2.ets", ES2PANDA_STATE_CHECKED, text.c_str()); + auto classHierarchy = lspApi->getClassHierarchyInfo(context, pos); + ASSERT_EQ(classHierarchy.size(), 1); + ASSERT_EQ(classHierarchy[0].GetClassName(), "Animal"); + + auto methods = classHierarchy[0].GetMethodList(); + auto it = methods.find("sleep()"); + ASSERT_TRUE(it != methods.end()); + ASSERT_TRUE(it->second != nullptr); + ASSERT_EQ(it->second->GetSetterStyle(), ark::es2panda::lsp::SetterStyle::METHOD); + ASSERT_EQ(it->second->GetAccessModifierStyle(), ark::es2panda::lsp::AccessModifierStyle::PROTECTED); + initializer.DestroyContext(context); +} + +TEST_F(LSPAPITests, GetClassHierarchyInfo_3) +{ + LSPAPI const *lspApi = GetImpl(); + ASSERT_TRUE(lspApi != nullptr); + const std::string text = R"(class Animal { + private body_: string = ''; + + protected action(): void { + console.log("need action"); + } + protected sleep(): void { + console.log("need sleep"); + } +})"; + + auto pos = text.find("Animal"); + ASSERT_NE(pos, std::string::npos); + Initializer initializer = Initializer(); + auto context = initializer.CreateContext("class_hierarchy_info_3.ets", ES2PANDA_STATE_CHECKED, text.c_str()); + auto classHierarchy = lspApi->getClassHierarchyInfo(context, pos); + ASSERT_TRUE(classHierarchy.empty()); + initializer.DestroyContext(context); +} + +TEST_F(LSPAPITests, GetClassHierarchyInfo_4) +{ + LSPAPI const *lspApi = GetImpl(); + ASSERT_TRUE(lspApi != nullptr); + const std::string text = R"(class ii { + private body_: string = ''; + + action(): void { + console.log("need sleep"); + } + + set Body(value: string) { + this.body_ = value; + } + get Body(): string { + return this.body_; + } +} + + class jj extends ii { + private age_: number = 18; + public action(): void { + console.log("need sleep and fly"); + } +})"; + + auto pos = text.find("jj"); + ASSERT_NE(pos, std::string::npos); + Initializer initializer = Initializer(); + auto context = initializer.CreateContext("class_hierarchy_info_4.ets", ES2PANDA_STATE_CHECKED, text.c_str()); + auto classHierarchy = lspApi->getClassHierarchyInfo(context, pos); + ASSERT_EQ(classHierarchy.size(), 1); + ASSERT_EQ(classHierarchy[0].GetClassName(), "ii"); + + auto methods = classHierarchy[0].GetMethodList(); + auto it = methods.find("Body(): string"); + ASSERT_TRUE(it != methods.end()); + ASSERT_TRUE(it->second != nullptr); + ASSERT_EQ(it->second->GetSetterStyle(), ark::es2panda::lsp::SetterStyle::GETTER); + ASSERT_EQ(it->second->GetAccessModifierStyle(), ark::es2panda::lsp::AccessModifierStyle::PUBLIC); + it = methods.find("Body(value: string)"); + ASSERT_TRUE(it != methods.end()); + ASSERT_TRUE(it->second != nullptr); + ASSERT_EQ(it->second->GetSetterStyle(), ark::es2panda::lsp::SetterStyle::SETTER); + ASSERT_EQ(it->second->GetAccessModifierStyle(), ark::es2panda::lsp::AccessModifierStyle::PUBLIC); + initializer.DestroyContext(context); +} +} // namespace diff --git a/ets2panda/test/unit/lsp/class_hierarchy_test.cpp b/ets2panda/test/unit/lsp/class_hierarchy_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83062873edceddcb6bd5333497be1437416425ec --- /dev/null +++ b/ets2panda/test/unit/lsp/class_hierarchy_test.cpp @@ -0,0 +1,205 @@ +/** + * 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 +#include +#include +#include +#include +#include + +#include "lsp_api_test.h" +#include "lsp/include/class_hierarchy.h" +#include "lsp/include/internal_api.h" + +namespace { + +class LspClassHierarchyTests : public LSPAPITests {}; + +TEST_F(LspClassHierarchyTests, GetTypeHierarchiesImpl_001) +{ + std::vector fileNames = {"aa1.ets", "bb1.ets", "cc1.ets", "ii1.ets", "mm1.ets", "nn1.ets", "pp1.ets"}; + std::vector fileContents = { + R"( + export class AAA {} + )", + R"( + import { AAA } from "./aa1" + export class BBB extends AAA {} + )", + R"(import { BBB } from "./bb1" + import { NNN } from "./nn1" + import { PPP } from "./pp1" + class CCC extends BBB implements NNN, PPP {} + )", + R"(export interface III {} + )", + R"( + export interface MMM {} + )", + R"(import { III } from "./ii1" + import { MMM } from "./mm1" + export interface NNN extends III, MMM {} + export interface NNN2 extends III {} + export interface NNN3 extends NNN2 {} + export interface NNN4 extends NNN2 {} + )", + R"(export interface PPP {} + )"}; + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_TRUE(filePaths.size() == fileContents.size()); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + const int position = 120; + const int fileIndex = 2; + auto context = initializer.CreateContext(filePaths[fileIndex].c_str(), ES2PANDA_STATE_CHECKED); + auto node = ark::es2panda::lsp::GetTouchingToken(context, position, false); + auto tokenId = ark::es2panda::lsp::GetOwnerId(node); + auto tokenName = ark::es2panda::lsp::GetIdentifierName(node); + auto res = ark::es2panda::lsp::GetTypeHierarchiesImpl(context, position); + initializer.DestroyContext(context); + const size_t parentNum1 = 3; + const size_t parentNum2 = 1; + ASSERT_EQ(res.superHierarchies.subOrSuper.size(), parentNum1); + ASSERT_EQ(res.superHierarchies.subOrSuper[0].subOrSuper.size(), parentNum2); +} + +TEST_F(LspClassHierarchyTests, GetTypeHierarchiesImpl_002) +{ + std::vector fileNames = {"aa2.ets", "bb2.ets", "cc2.ets", "ii2.ets", "mm2.ets", "nn2.ets", "pp2.ets"}; + std::vector fileContents = { + R"( + export class AAA {} + )", + R"( + import { AAA } from "./aa2" + export class BBB extends AAA {} + )", + R"(import { BBB } from "./bb2" + import { NNN } from "./nn2" + import { PPP } from "./pp2" + class CCC extends BBB implements NNN, PPP {} + )", + R"(export interface III {} + )", + R"( + export interface MMM {} + )", + R"(import { III } from "./ii2" + import { MMM } from "./mm2" + export interface NNN extends III, MMM {} + export interface NNN2 extends III {} + export interface NNN3 extends NNN2 {} + export interface NNN4 extends NNN2 {} + )", + R"(export interface PPP {} + )"}; + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_TRUE(filePaths.size() == fileContents.size()); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + const int position = 94; + const int fileIndex = 5; + auto context = initializer.CreateContext(filePaths[fileIndex].c_str(), ES2PANDA_STATE_CHECKED); + auto node = ark::es2panda::lsp::GetTouchingToken(context, position, false); + auto tokenId = ark::es2panda::lsp::GetOwnerId(node); + auto tokenName = ark::es2panda::lsp::GetIdentifierName(node); + auto res = ark::es2panda::lsp::GetTypeHierarchiesImpl(context, position); + initializer.DestroyContext(context); + const size_t parentNum1 = 2; + ASSERT_EQ(res.superHierarchies.subOrSuper.size(), parentNum1); +} + +TEST_F(LspClassHierarchyTests, GetTypeHierarchiesImpl_003) +{ + std::vector fileNames = {"aa3.ets", "bb3.ets", "cc3.ets", "ii3.ets", "mm3.ets", "nn3.ets", "pp3.ets"}; + std::vector fileContents = { + R"( + export class AAA {} + )", + R"( + import { AAA } from "./aa3" + export class BBB extends AAA {} + )", + R"(import { BBB } from "./bb3" + import { NNN } from "./nn3" + import { PPP } from "./pp3" + class CCC extends BBB implements NNN, PPP {} + )", + R"(export interface III {} + )", + R"( + export interface MMM {} + )", + R"(import { III } from "./ii3" + import { MMM } from "./mm3" + export interface NNN extends III, MMM {} + export interface NNN2 extends III {} + export interface NNN3 extends NNN2 {} + export interface NNN4 extends NNN2 {} + )", + R"(export interface PPP {} + )"}; + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_TRUE(filePaths.size() == fileContents.size()); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + const int position = 20; + const int fileIndex = 3; + auto context = initializer.CreateContext(filePaths[fileIndex].c_str(), ES2PANDA_STATE_CHECKED); + auto node = ark::es2panda::lsp::GetTargetDeclarationNodeByPosition(context, position); + auto tokenId = ark::es2panda::lsp::GetOwnerId(node); + auto tokenName = ark::es2panda::lsp::GetIdentifierName(node); + const int fileIndex5 = 5; + auto context5 = initializer.CreateContext(filePaths[fileIndex5].c_str(), ES2PANDA_STATE_CHECKED); + auto res = ark::es2panda::lsp::GetTypeHierarchiesImpl(context5, position, node); + initializer.DestroyContext(context); + const size_t childNum1 = 2; + const size_t childNum2 = 2; + ASSERT_EQ(res.subHierarchies.subOrSuper.size(), childNum1); + ASSERT_EQ(res.subHierarchies.subOrSuper[1].subOrSuper.size(), childNum2); +} + +TEST_F(LspClassHierarchyTests, GetTypeHierarchiesImpl_004) +{ + std::vector fileNames = {"aa4.ets", "bb4.ets", "cc4.ets", "dd4.ets"}; + std::vector fileContents = { + R"( + export class AAA {} + )", + R"( + import { AAA } from "./aa4" + export class BBB extends AAA {} + )", + R"(import { AAA } from "./aa4" + class CCC extends AAA {} + )", + R"(import { BBB } from "./bb4" + class DDD extends BBB {} + )"}; + auto filePaths = CreateTempFile(fileNames, fileContents); + ASSERT_TRUE(filePaths.size() == fileContents.size()); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + const int position = 26; + const int fileIndex = 0; + auto context = initializer.CreateContext(filePaths[fileIndex].c_str(), ES2PANDA_STATE_CHECKED); + auto node = ark::es2panda::lsp::GetTargetDeclarationNodeByPosition(context, position); + auto tokenId = ark::es2panda::lsp::GetOwnerId(node); + auto tokenName = ark::es2panda::lsp::GetIdentifierName(node); + const int fileIndex5 = 1; + auto context5 = initializer.CreateContext(filePaths[fileIndex5].c_str(), ES2PANDA_STATE_CHECKED); + auto res = ark::es2panda::lsp::GetTypeHierarchiesImpl(context5, position, node); + initializer.DestroyContext(context); + const size_t childNum1 = 1; + ASSERT_EQ(res.subHierarchies.subOrSuper.size(), childNum1); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/class_hierarchys_test.cpp b/ets2panda/test/unit/lsp/class_hierarchys_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e946aed4748d29a5aad81ac0bc0b56fc109230f8 --- /dev/null +++ b/ets2panda/test/unit/lsp/class_hierarchys_test.cpp @@ -0,0 +1,139 @@ +/** + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "lsp_api_test.h" +#include "lsp/include/class_hierarchy.h" +#include "lsp/include/internal_api.h" + +namespace { +// NOLINTBEGIN +using ark::es2panda::lsp::Initializer; + +class LspClassHierarchiesTests : public LSPAPITests {}; + +std::vector fileNames = {"wangz_test.ets"}; +std::vector fileContents = { + R"( +interface Iaa { + name: number + name1: number + name2: number + + hello(): void + hello1(): void +} + +interface Iaaa extends Iaa { + name: number +} + +interface Iaab extends Iaa { + name: number +} + +interface Iaaaa extends Iaaa { + name: number +} + +interface Iaaab extends Iaaa { + name: number +} + +abstract class Caa implements Iaa { + name: number = 1 + name1: number = 1 + name2: number = 1 + + hello(): void { + throw new Error("Method not implemented.") + } + + age: number = 0 + age2: number = 0 + age3: number = 0 + + abstract classHello(): void + + classHello1() { + return 1 + } +} + +class Caaa extends Caa implements Iaaa { + age: number = 0 + age4: number = 0 + age5: number = 0 + + classHello(): void { + throw new Error("Method not implemented.") + } +} + +class Caab extends Caa implements Iaab { + name: number = 2 +} + +class Caaaa extends Caaa implements Iaaaa { + name: number = 3 +} + +class Caaab extends Caaa implements Iaaab { + name: number = 4 +} + +class Caaba extends Caab implements Iaaa { + name: number = 5 +} + +class Caabb extends Caab implements Iaab { + name: number = 6 +} + +export class Test extends Caabb implements Iaab { + name: number = 7 +} +)"}; + +TEST_F(LspClassHierarchiesTests, GetClassHierarchiesImpl_001) +{ + constexpr size_t expectedInfoCount = 5; + constexpr size_t tokenOffset = 600; + + auto filePaths = CreateTempFile(fileNames, fileContents); + std::vector sourceFiles; + for (size_t i = 0; i < filePaths.size(); ++i) { + sourceFiles.emplace_back(filePaths[i], fileContents[i]); + } + ASSERT_EQ(fileNames.size(), sourceFiles.size()); + Initializer initializer; + size_t sourceIndex = 0; + auto filePath = std::string {sourceFiles[sourceIndex].filePath}; + auto fileContent = std::string {sourceFiles[sourceIndex].source}; + auto context = initializer.CreateContext(filePath.c_str(), ES2PANDA_STATE_CHECKED, fileContent.c_str()); + std::vector infos = + ark::es2panda::lsp::GetClassHierarchiesImpl(context, fileNames[sourceIndex], tokenOffset); + ASSERT_EQ(expectedInfoCount, infos.size()); +} +// NOLINTEND +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/code_fix_registration_test.cpp b/ets2panda/test/unit/lsp/code_fix_registration_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c493453dba112e9a73e873418e4155888bd1b250 --- /dev/null +++ b/ets2panda/test/unit/lsp/code_fix_registration_test.cpp @@ -0,0 +1,30 @@ +/** + * 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/code_fix_provider.h" +#include "gtest/gtest.h" + +namespace { + +TEST(RefactorProviderRegistrationTest, RegistersConvertFunctionRefactor) +{ + const auto &provider = ark::es2panda::lsp::CodeFixProvider::Instance(); + const auto &errors = provider.GetErrorCodeToFixes(); + const auto &fixIdToRegistration = provider.GetFixIdToRegistration(); + EXPECT_FALSE(errors.empty()); + EXPECT_FALSE(fixIdToRegistration.empty()); + EXPECT_EQ(errors.size(), 5); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/create_type_help_items_test.cpp b/ets2panda/test/unit/lsp/create_type_help_items_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e27206f69bc2aeb7dae3c41e2f6d23c6a662d92d --- /dev/null +++ b/ets2panda/test/unit/lsp/create_type_help_items_test.cpp @@ -0,0 +1,161 @@ +/** + * 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/create_type_help_items.h" +#include "lsp_api_test.h" +#include +#include +#include +#include +#include "ir/astNode.h" +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" +#include "utils/arena_containers.h" + +namespace { + +class LSPCreateTypeHelpItems : public LSPAPITests {}; + +TEST_F(LSPCreateTypeHelpItems, GetTypeHelpItemClassTest) +{ + const auto fileClassTest = "getTypeHelpItemClassTest.ets"; + + const auto classTestText = R"( + class GenericClass { + constructor(param1: T, param2: U) {} + } +)"; + const size_t expectedTypeParamCount = 4; + const size_t index0 = 0; + std::vector files = {fileClassTest}; + std::vector texts = {classTestText}; + auto filePaths = CreateTempFile(files, texts); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = + initializer.CreateContext(files.at(index0).c_str(), ES2PANDA_STATE_CHECKED, texts.at(index0).c_str()); + auto context = reinterpret_cast(ctx); + auto astNode = reinterpret_cast(context->parserProgram->Ast()); + std::vector list; + astNode->FindChild([&list](const ark::es2panda::ir::AstNode *child) { + ark::es2panda::lsp::GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(child, list); + return false; + }); + EXPECT_EQ(list.size(), expectedTypeParamCount); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCreateTypeHelpItems, GetTypeHelpItemInterfaceTest) +{ + const auto fileInterfaceTest = "getTypeHelpItemInterfaceTest.ets"; + const auto interfaceTestText = R"( + interface GenericInterface { + method(param: T): U; + } +)"; + const size_t expectedTypeParamCount = 4; + const size_t index0 = 0; + std::vector files = {fileInterfaceTest}; + std::vector texts = {interfaceTestText}; + auto filePaths = CreateTempFile(files, texts); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = + initializer.CreateContext(files.at(index0).c_str(), ES2PANDA_STATE_CHECKED, texts.at(index0).c_str()); + auto context = reinterpret_cast(ctx); + auto astNode = reinterpret_cast(context->parserProgram->Ast()); + std::vector list; + astNode->FindChild([&list](const ark::es2panda::ir::AstNode *child) { + ark::es2panda::lsp::GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(child, list); + return false; + }); + EXPECT_EQ(list.size(), expectedTypeParamCount); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCreateTypeHelpItems, GetTypeHelpItemGenericTypeTest) +{ + const auto fileGenericTypeTest = "getTypeHelpItemGenericTypeTest.ets"; + const auto genericTypeTestText = R"( + type GenericType = { first: T; second: U }; +)"; + const size_t expectedTypeParamCount = 4; + const size_t index0 = 0; + std::vector files = {fileGenericTypeTest}; + std::vector texts = {genericTypeTestText}; + auto filePaths = CreateTempFile(files, texts); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = + initializer.CreateContext(files.at(index0).c_str(), ES2PANDA_STATE_CHECKED, texts.at(index0).c_str()); + auto context = reinterpret_cast(ctx); + auto astNode = reinterpret_cast(context->parserProgram->Ast()); + std::vector list; + astNode->FindChild([&list](const ark::es2panda::ir::AstNode *child) { + ark::es2panda::lsp::GetLocalTypeParametersOfClassOrInterfaceOrTypeAlias(child, list); + return false; + }); + EXPECT_EQ(list.size(), expectedTypeParamCount); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCreateTypeHelpItems, GetTypeHelpItemTest) +{ + const auto classTestText = R"( + class GenericClass { + constructor(param1: T, param2: U) {} + } +)"; + const auto fileClassTest = "getTypeHelpItemTest.ets"; + + const auto genericText = "GenericClass"; + const auto punctuationText = "<"; + const auto suffixText = ">"; + const auto typeText = "T"; + const auto typeText2 = "U"; + const auto expectedPrefixPartsCount = 4; // "GenericClass" and "<" + const auto expectedSuffixPartsCount = 2; // ">" + const auto expectedParametersCount = 2; // "T" and "U" + const size_t index1 = 1; + const size_t index2 = 2; + const size_t index3 = 3; + const size_t index0 = 0; + std::vector files = {fileClassTest}; + std::vector texts = {classTestText}; + auto filePaths = CreateTempFile(files, texts); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctxTypeHelp; + { + ctxTypeHelp = initializer.CreateContext(files.at(0).c_str(), ES2PANDA_STATE_CHECKED, texts.at(0).c_str()); + auto context = reinterpret_cast(ctxTypeHelp); + auto astNode = reinterpret_cast(context->parserProgram->Ast()); + SignatureHelpItem result; + std::vector typeParameters; + astNode->FindChild([&typeParameters, &result](const ark::es2panda::ir::AstNode *child) { + if (child->IsClassDeclaration()) { + ark::es2panda::lsp::GetTypeHelpItem(&typeParameters, child, result); + } + return false; + }); + ASSERT_EQ(result.GetPrefixDisplayParts().size(), expectedPrefixPartsCount); + EXPECT_EQ(result.GetPrefixDisplayParts()[index2].GetText(), genericText); + EXPECT_EQ(result.GetPrefixDisplayParts()[index3].GetText(), punctuationText); + ASSERT_EQ(result.GetSuffixDisplayParts().size(), expectedSuffixPartsCount); + EXPECT_EQ(result.GetSuffixDisplayParts()[index0].GetText(), suffixText); + ASSERT_EQ(result.GetParameters().size(), expectedParametersCount); + EXPECT_EQ(result.GetParameters()[index0].GetName(), typeText); + EXPECT_EQ(result.GetParameters()[index1].GetName(), typeText2); + } + initializer.DestroyContext(ctxTypeHelp); +} + +} // namespace diff --git a/ets2panda/test/unit/lsp/diagnostic_test.cpp b/ets2panda/test/unit/lsp/diagnostic_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..12e15c7d2251618fbc08307f215a3c52641a9a28 --- /dev/null +++ b/ets2panda/test/unit/lsp/diagnostic_test.cpp @@ -0,0 +1,189 @@ +/** + * 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_api_test.h" + +#include + +#include "ir/astNode.h" +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" +#include "public/public.h" + +namespace { + +using ark::es2panda::lsp::Initializer; + +TEST_F(LSPAPITests, DiagnosticConstructorAndField) +{ + int const errorCode = 404; + int const defaultCharacter = 10; + std::vector tags {}; + std::vector relatedInfoList {}; + Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message_); + + EXPECT_EQ(diagnostic.range_.start.line_, 1); + EXPECT_EQ(diagnostic.range_.end.character_, defaultCharacter); + EXPECT_EQ(diagnostic.message_, message_); + EXPECT_EQ(diagnostic.severity_, DiagnosticSeverity::Error); + EXPECT_EQ(std::get(diagnostic.code_), errorCode); +} + +TEST_F(LSPAPITests, DiagnosticCodeDescriptionOptional) +{ + CodeDescription codeDesc; + codeDesc.href_ = "http://example.com/error/404"; + int const errorCode = 404; + std::vector tags {}; + std::vector relatedInfoList {}; + + Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message_, codeDesc); + + const auto &codeDescription = diagnostic.codeDescription_; + EXPECT_EQ(codeDescription.href_, "http://example.com/error/404"); +} + +TEST_F(LSPAPITests, DiagnosticTagsAndRelatedInformation) +{ + std::vector tags {}; + tags.push_back(DiagnosticTag::Unnecessary); + std::vector relatedInfoList {}; + DiagnosticRelatedInformation relatedInfo; + relatedInfo.location_ = Location {"www.test.uri", range_}; + relatedInfo.message_ = "Related information message"; + relatedInfoList.push_back(relatedInfo); + int const errorCode = 200; + CodeDescription des = {}; + + Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Information, errorCode, message_, des, + "default"); + + const auto &diagnosticTags = diagnostic.tags_; + EXPECT_EQ(diagnosticTags.size(), 1); + EXPECT_EQ(diagnosticTags[0], DiagnosticTag::Unnecessary); + + const auto &relatedInformation = diagnostic.relatedInformation_; + EXPECT_EQ(relatedInformation.size(), 1); + EXPECT_EQ(relatedInformation[0].message_, "Related information message"); +} + +TEST_F(LSPAPITests, DiagnosticDataField) +{ + int const dataValue = 42; + std::variant data = dataValue; + int const errorCode = 400; + int const dataResult = 42; + std::vector tags {}; + std::vector relatedInfoList {}; + + Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message_, {}, {}, data); + + const auto &diagnosticData = diagnostic.data_; + EXPECT_EQ(std::get(diagnosticData), dataResult); +} + +TEST_F(LSPAPITests, CreateDiagnosticForNode1) +{ + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "function main() {}"); + auto astNode = GetAstFromContext(ctx); + int const dataValue = 42; + std::variant data = dataValue; + int const errorCode = 400; + std::string message = "Diagnostic"; + std::vector tags {}; + std::vector relatedInfoList {}; + + Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message, {}, {}, data); + FileDiagnostic result = ark::es2panda::lsp::CreateDiagnosticForNode(astNode, diagnostic); + + int const startLine = 0; + int const endLine = 0; + int const startChar = 0; + int const endChar = 18; + ASSERT_EQ(result.diagnostic.message_, "Diagnostic"); + ASSERT_EQ(result.diagnostic.range_.start.line_, startLine); + ASSERT_EQ(result.diagnostic.range_.end.line_, endLine); + ASSERT_EQ(result.diagnostic.range_.start.character_, startChar); + ASSERT_EQ(result.diagnostic.range_.end.character_, endChar); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, CreateDiagnosticForNode2) +{ + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "function main() {}"); + auto astNode = GetAstFromContext(ctx); + int const dataValue = 42; + std::variant data = dataValue; + int const errorCode = 400; + std::string message = "Diagnostic {0}, for the {1}, and {2}"; + std::vector args = {"Error1", "Error2", "Error3"}; + std::vector tags {}; + std::vector relatedInfoList {}; + + Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message, {}, {}, data); + FileDiagnostic result = ark::es2panda::lsp::CreateDiagnosticForNode(astNode, diagnostic, args); + + int const startLine = 0; + int const endLine = 0; + int const startChar = 0; + int const endChar = 18; + ASSERT_EQ(result.diagnostic.message_, "Diagnostic Error1, for the Error2, and Error3"); + ASSERT_EQ(result.diagnostic.range_.start.line_, startLine); + ASSERT_EQ(result.diagnostic.range_.end.line_, endLine); + ASSERT_EQ(result.diagnostic.range_.start.character_, startChar); + ASSERT_EQ(result.diagnostic.range_.end.character_, endChar); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, CreateDiagnosticForNode3) +{ + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + Initializer initializer = Initializer(); + es2panda_Context *ctx = + initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "let a = () => {\n return 1;\n}"); + auto astNode = reinterpret_cast(GetAstFromContext(ctx)); + astNode = astNode->FindChild([](ark::es2panda::ir::AstNode *child) { return child->IsArrowFunctionExpression(); }); + int const dataValue = 42; + std::variant data = dataValue; + int const errorCode = 400; + std::string message = "Diagnostic {0}, for the {1}, and {2}"; + std::vector args = {"Error1", "Error2", "Error3"}; + std::vector tags {}; + std::vector relatedInfoList {}; + + Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message, {}, {}, data); + FileDiagnostic result = + ark::es2panda::lsp::CreateDiagnosticForNode(reinterpret_cast(astNode), diagnostic, args); + + int const startLine = 0; + int const endLine = 2; + int const startChar = 12; + int const endChar = 33; + ASSERT_EQ(result.diagnostic.message_, "Diagnostic Error1, for the Error2, and Error3"); + ASSERT_EQ(result.diagnostic.range_.start.line_, startLine); + ASSERT_EQ(result.diagnostic.range_.end.line_, endLine); + ASSERT_EQ(result.diagnostic.range_.start.character_, startChar); + ASSERT_EQ(result.diagnostic.range_.end.character_, endChar); + initializer.DestroyContext(ctx); +} + +} // namespace diff --git a/ets2panda/test/unit/lsp/find_safe_delete_location_test.cpp b/ets2panda/test/unit/lsp/find_safe_delete_location_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..011731bf6a1e44b82867b8a46fd1d1a62a9aba44 --- /dev/null +++ b/ets2panda/test/unit/lsp/find_safe_delete_location_test.cpp @@ -0,0 +1,93 @@ +/** + * 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/find_safe_delete_location.h" +#include "lsp_api_test.h" +#include "lsp/include/references.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; +} // namespace + +class FindSafeDeleteLocationTests : public LSPAPITests {}; + +TEST_F(FindSafeDeleteLocationTests, FindSafeDeleteLocationBasic) +{ + std::vector files = {"safe_delete_test_basic.ets"}; + std::vector texts = {R"(function foo() {} foo(); foo();)"}; + + auto filePaths = CreateTempFile(files, texts); + + Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + constexpr size_t TOKEN_POSITION = 9; + constexpr size_t RESULT_SIZE = 3; + auto astNode = ark::es2panda::lsp::GetTouchingToken(ctx, TOKEN_POSITION, false); + + auto declInfo = ark::es2panda::lsp::GetDeclInfoImpl(astNode); + + LSPAPI const *lspApi = GetImpl(); + auto locations = lspApi->FindSafeDeleteLocation(ctx, &declInfo); + + ASSERT_EQ(locations.size(), RESULT_SIZE); + + initializer.DestroyContext(ctx); +} + +TEST_F(FindSafeDeleteLocationTests, FindSafeDeleteLocationNoResult) +{ + std::vector files = {"safe_delete_test_no_result.ets"}; + std::vector texts = {R"(let x = 1;)"}; + + auto filePaths = CreateTempFile(files, texts); + + Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + constexpr size_t TOKEN_POSITION = 4; + constexpr size_t RESULT_SIZE = 1; + auto astNode = ark::es2panda::lsp::GetTouchingToken(ctx, TOKEN_POSITION, false); + + auto declInfo = ark::es2panda::lsp::GetDeclInfoImpl(astNode); + + LSPAPI const *lspApi = GetImpl(); + auto locations = lspApi->FindSafeDeleteLocation(ctx, &declInfo); + + ASSERT_EQ(locations.size(), RESULT_SIZE); + + initializer.DestroyContext(ctx); +} + +TEST_F(FindSafeDeleteLocationTests, FindSafeDeleteLocationDeclInfoEmpty) +{ + std::vector files = {"safe_delete_test_empty.ets"}; + std::vector texts = {R"(let x: number = 1;)"}; + + auto filePaths = CreateTempFile(files, texts); + + Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + std::tuple declInfo = {"", ""}; + + LSPAPI const *lspApi = GetImpl(); + auto locations = lspApi->FindSafeDeleteLocation(ctx, &declInfo); + + ASSERT_TRUE(locations.empty()); + + initializer.DestroyContext(ctx); +} diff --git a/ets2panda/test/unit/lsp/formatting_context_test.cpp b/ets2panda/test/unit/lsp/formatting_context_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..19bb22555f524a0e191206c9b99208b3429a098b --- /dev/null +++ b/ets2panda/test/unit/lsp/formatting_context_test.cpp @@ -0,0 +1,127 @@ +/** + * 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/formatting/formatting_context.h" +#include "lsp_api_test.h" +#include +#include "ir/astNode.h" + +namespace { + +class LSPFormattingContextTests : public LSPAPITests {}; + +TEST_F(LSPFormattingContextTests, FormattingContextConstructorTest) +{ + const size_t defaultIndentSize = 4U; + const std::string defaultNewLine = "\n"; + + ark::es2panda::lsp::FormatCodeSettings settings; + settings.SetIndentSize(defaultIndentSize); + settings.SetNewLineCharacter(defaultNewLine); + settings.SetConvertTabsToSpaces(true); + + ark::es2panda::lsp::FormattingContext context(ark::es2panda::lsp::FormattingRequestKind::FORMAT_DOCUMENT, settings); + + EXPECT_EQ(context.GetformattingRequestKind(), ark::es2panda::lsp::FormattingRequestKind::FORMAT_DOCUMENT); + EXPECT_EQ(context.GetFormatCodeSettings().GetIndentSize(), defaultIndentSize); +} + +TEST_F(LSPFormattingContextTests, FormattingContextSameLineTest) +{ + const size_t firstLine = 1U; + const size_t idStart = 4U; + const size_t numStart = 8U; + const size_t semiStart = 10U; + + ark::es2panda::lsp::Initializer initializer; + auto ctx = initializer.CreateContext("sameLineTest.ets", ES2PANDA_STATE_CHECKED, "let x = 10;"); + auto contextPtr = reinterpret_cast(ctx); + auto program = contextPtr->parserProgram; + + ark::es2panda::lsp::FormatCodeSettings settings; + ark::es2panda::lsp::FormattingContext context(ark::es2panda::lsp::FormattingRequestKind::FORMAT_ON_ENTER, settings); + + ark::es2panda::lexer::SourcePosition pos1(idStart, firstLine, program); + ark::es2panda::lexer::SourcePosition pos2(numStart, firstLine, program); + ark::es2panda::lexer::SourcePosition pos3(semiStart, firstLine, program); + ark::es2panda::lsp::RangeWithKind span1(pos1, pos2, ark::es2panda::ir::AstNodeType::IDENTIFIER); + ark::es2panda::lsp::RangeWithKind span2(pos2, pos3, ark::es2panda::ir::AstNodeType::NUMBER_LITERAL); + + context.UpdateContext(ctx, span1, span2); + + EXPECT_TRUE(context.TokensAreOnSameLine()); + + initializer.DestroyContext(ctx); +} + +TEST_F(LSPFormattingContextTests, FormattingContextDifferentLinesTest) +{ + const size_t firstLine = 1U; + const size_t secondLine = 2U; + const size_t idStart = 4U; + const size_t numStart = 8U; + + ark::es2panda::lsp::Initializer initializer; + auto ctx = initializer.CreateContext("differentLinesTest.ets", ES2PANDA_STATE_CHECKED, "let x = 10;\nlet y = 20;"); + auto contextPtr = reinterpret_cast(ctx); + auto program = contextPtr->parserProgram; + + ark::es2panda::lsp::FormatCodeSettings settings; + ark::es2panda::lsp::FormattingContext context(ark::es2panda::lsp::FormattingRequestKind::FORMAT_ON_SEMICOLON, + settings); + + ark::es2panda::lexer::SourcePosition pos1(idStart, firstLine, program); + ark::es2panda::lexer::SourcePosition pos2(numStart, firstLine, program); + ark::es2panda::lexer::SourcePosition pos3(idStart, secondLine, program); + ark::es2panda::lexer::SourcePosition pos4(numStart, secondLine, program); + ark::es2panda::lsp::RangeWithKind span1(pos1, pos2, ark::es2panda::ir::AstNodeType::IDENTIFIER); + ark::es2panda::lsp::RangeWithKind span2(pos3, pos4, ark::es2panda::ir::AstNodeType::IDENTIFIER); + + context.UpdateContext(ctx, span1, span2); + + EXPECT_TRUE(context.TokensAreOnSameLine()); + + initializer.DestroyContext(ctx); +} + +TEST_F(LSPFormattingContextTests, FormattingCodeSettingsTest) +{ + const size_t indentSize = 2U; + const size_t tabSize = 4U; + const std::string newlineChar = "\r\n"; + + ark::es2panda::lsp::FormatCodeSettings settings; + + settings.SetIndentSize(indentSize); + settings.SetTabSize(tabSize); + settings.SetNewLineCharacter(newlineChar); + settings.SetConvertTabsToSpaces(true); + settings.SetInsertSpaceAfterCommaDelimiter(true); + settings.SetInsertSpaceAfterSemicolonInForStatements(true); + settings.SetInsertSpaceBeforeAndAfterBinaryOperators(true); + + ark::es2panda::lsp::FormattingContext context(ark::es2panda::lsp::FormattingRequestKind::FORMAT_DOCUMENT, settings); + + auto contextSettings = context.GetFormatCodeSettings(); + EXPECT_EQ(contextSettings.GetIndentSize(), indentSize); + EXPECT_EQ(contextSettings.GetTabSize(), tabSize); + EXPECT_EQ(contextSettings.GetNewLineCharacter(), newlineChar); + EXPECT_TRUE(contextSettings.GetConvertTabsToSpaces()); + EXPECT_TRUE(contextSettings.GetInsertSpaceAfterCommaDelimiter()); + EXPECT_TRUE(contextSettings.GetInsertSpaceAfterSemicolonInForStatements()); + EXPECT_TRUE(contextSettings.GetInsertSpaceBeforeAndAfterBinaryOperators()); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/formatting_test.cpp b/ets2panda/test/unit/lsp/formatting_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab38f7950da09931f9246385c2a73bb041f1f850 --- /dev/null +++ b/ets2panda/test/unit/lsp/formatting_test.cpp @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at* + * + * http://www.apache.org/licenses/LICENSE-2.0* + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lsp/include/formatting/formatting.h" +#include "lsp_api_test.h" +#include + +namespace { + +class LSPFormattingTests : public LSPAPITests {}; + +TEST_F(LSPFormattingTests, GetFormatContextTest) +{ + ark::es2panda::lsp::FormatCodeSettings settings; + + auto formatContext = ark::es2panda::lsp::GetFormatContext(settings); + EXPECT_NE(&formatContext, nullptr); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_adjusted_location_test.cpp b/ets2panda/test/unit/lsp/get_adjusted_location_test.cpp index 77709d658f00bb116542c6c2af3d59e6fe19220b..e8e7f4e23435ff8d22dfb0ed45b2fbe2bf3027b1 100644 --- a/ets2panda/test/unit/lsp/get_adjusted_location_test.cpp +++ b/ets2panda/test/unit/lsp/get_adjusted_location_test.cpp @@ -336,8 +336,8 @@ type NumArray = number[]; let numbers: NumArray; )"; ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); - es2panda_Context *ctx = initializer.CreateContext("test.ets", ES2PANDA_STATE_CHECKED, source); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + es2panda_Context *ctx = initializer.CreateContext("test.ets", ES2PANDA_STATE_PARSED, source); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_PARSED); auto *context = reinterpret_cast(ctx); auto *node = ark::es2panda::lsp::GetTouchingToken(ctx, ARRAY_TYPE_POS, true); ASSERT_NE(node, nullptr); diff --git a/ets2panda/test/unit/lsp/get_class_property_info_test.cpp b/ets2panda/test/unit/lsp/get_class_property_info_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b6d8c37e24a78850931124f9ab47a23d587b0d28 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_class_property_info_test.cpp @@ -0,0 +1,181 @@ +/** + * 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 +#include +#include +#include +#include +#include +#include + +#include "es2panda.h" +#include "lsp/include/api.h" +#include "lsp/include/get_class_property_info.h" +#include "lsp/include/cancellation_token.h" +#include "lsp_api_test.h" +#include + +namespace { +// NOLINTBEGIN +using ark::es2panda::lsp::Initializer; + +class LspGetClassPropertyInfoTests : public LSPAPITests {}; +std::vector fileNames = {"GetClassPropertyInfoFile.ets"}; +std::vector fileContents = { + R"( +enum BloodType { + A = 'A', + AB = 'AB' +} + +class Address { + province: string = ''; + city: string = ''; +} + +interface Control { + state: number +} + +interface SelectableControl extends Control { + select(): void +} + +class SelectableControlClass extends Address implements SelectableControl { + select(): void { + throw new Error("Method not implemented."); + } + + private state1: number = 0; + protected readonly hobbies: string[] = []; +} + +enum Sex { + Male = 'Male' +} + +export class Person extends SelectableControlClass implements SelectableControl { + static MAX_HEIGHT: number = 250; + static BLOOD_TYPES: BloodType = BloodType.AB; + static defaultAddress: Address = { + province: '北京', + city: '北京市', + }; + name: string = ''; + age: number = Person.MAX_HEIGHT; + weight: number = 0; + sex: Sex = Sex.Male; + bloodType: BloodType = BloodType.A; + address: Address = new Address(); + hobbies: string[] = []; + maritalStatus: 'single' | 'married' | 'divorced' = 'single'; + birthday: Date = new Date(); + location: [number, number] = [0, 0]; + avatar: Resource = $r('app.media.startIcon'); + attributes: Map = new Map(); + isEmployed: boolean = false; + private privateIsEmployed: boolean = false; + protected protectedIsEmployed: boolean = false; + protected readonly readonlyIsEmployed: boolean = false; + onUpdate: (() => void) | null = null; +} +)"}; +std::vector>> expectedResult = { + {"MAX_HEIGHT", 561, 585, "classField", {"public", "static"}}, + {"BLOOD_TYPES", 596, 633, "classField", {"public", "static"}}, + {"defaultAddress", 644, 722, "classField", {"public", "static"}}, + {"name", 726, 743, "classField", {"public"}}, + {"age", 747, 778, "classField", {"public"}}, + {"weight", 782, 800, "classField", {"public"}}, + {"sex", 804, 823, "classField", {"public"}}, + {"bloodType", 827, 861, "classField", {"public"}}, + {"address", 865, 898, "classField", {"public"}}, + {"hobbies", 901, 923, "classField", {"public"}}, + {"maritalStatus", 927, 986, "classField", {"public"}}, + {"birthday", 990, 1018, "classField", {"public"}}, + {"location", 1021, 1056, "classField", {"public"}}, + {"avatar", 1060, 1104, "classField", {"public"}}, + {"attributes", 1108, 1152, "classField", {"public"}}, + {"isEmployed", 1155, 1182, "classField", {"public"}}, + {"privateIsEmployed", 1194, 1228, "classField", {"private"}}, + {"protectedIsEmployed", 1242, 1278, "classField", {"protected"}}, + {"readonlyIsEmployed", 1301, 1336, "classField", {"protected", "readonly"}}, + {"onUpdate", 1340, 1376, "classField", {"public"}}}; + +void CheckClassPropertiesMatch(const std::vector &actualProperties) +{ + for (size_t i = 0; i < actualProperties.size(); ++i) { + const auto &perp = actualProperties[i]; + const auto &expected = expectedResult[i]; + + const auto &expectedName = std::get<0>(expected); + const auto expectedStart = std::get<1>(expected); + const auto expectedEnd = std::get<2>(expected); + const auto &expectedKind = std::get<3>(expected); + const auto &expectedModifiers = std::get<4>(expected); + + bool nameMatch = (perp.displayName == expectedName); + bool startMatch = (perp.start == expectedStart); + bool endMatch = (perp.end == expectedEnd); + bool kindMatch = (perp.kind == expectedKind); + + bool modifiersMatch = true; + if (perp.modifierKinds.has_value()) { + const auto &actualModifiers = perp.modifierKinds.value(); + modifiersMatch = (actualModifiers == expectedModifiers); // 严格比较顺序 + } else { + modifiersMatch = expectedModifiers.empty(); + } + + bool currentMatch = nameMatch && startMatch && endMatch && kindMatch && modifiersMatch; + ASSERT_EQ(true, currentMatch); + } +} + +TEST_F(LspGetClassPropertyInfoTests, GetClassPropertyInfoMethod1) +{ + constexpr size_t EXPECTED_CLASS_COUNT = 3; + constexpr size_t EXPECTED_CLASS_COUNT_ONE = 1; + constexpr size_t EXPECTED_PROP_COUNT = 20; + + auto filePaths = CreateTempFile(fileNames, fileContents); + std::vector sourceFiles; + + for (size_t i = 0; i < filePaths.size(); ++i) { + sourceFiles.emplace_back(filePaths[i], fileContents[i]); + } + ASSERT_EQ(fileNames.size(), sourceFiles.size()); + + Initializer initializer; + size_t sourceIndex = 0; + size_t tokenOffset = 800; + auto filePath = std::string {sourceFiles[sourceIndex].filePath}; + auto fileContent = std::string {sourceFiles[sourceIndex].source}; + auto context = initializer.CreateContext(filePath.c_str(), ES2PANDA_STATE_CHECKED, fileContent.c_str()); + + auto infos = ark::es2panda::lsp::GetClassPropertyInfo(context, tokenOffset, true); + ASSERT_EQ(EXPECTED_CLASS_COUNT, infos.size()); + + auto infos2 = ark::es2panda::lsp::GetClassPropertyInfo(context, tokenOffset); + initializer.DestroyContext(context); + ASSERT_EQ(EXPECTED_CLASS_COUNT_ONE, infos2.size()); + + FieldsInfo info = infos2[0]; + ASSERT_EQ(EXPECTED_PROP_COUNT, info.properties.size()); + ASSERT_EQ("Person", info.name); + CheckClassPropertiesMatch(info.properties); +} +// NOLINTEND +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_completions.cpp b/ets2panda/test/unit/lsp/get_completions.cpp index 42c1138a86f85ae5c774421c36a76a831e0277a9..7b5d5a22efbd2433af7ef9afe3efa910feafcef4 100644 --- a/ets2panda/test/unit/lsp/get_completions.cpp +++ b/ets2panda/test/unit/lsp/get_completions.cpp @@ -22,11 +22,14 @@ class LSPCompletionsTests : public LSPAPITests {}; using ark::es2panda::lsp::CompletionEntry; using ark::es2panda::lsp::CompletionEntryKind; using ark::es2panda::lsp::Initializer; +using ark::es2panda::lsp::sort_text::CLASS_MEMBER_SNIPPETS; using ark::es2panda::lsp::sort_text::GLOBALS_OR_KEYWORDS; +using ark::es2panda::lsp::sort_text::MEMBER_DECLARED_BY_SPREAD_ASSIGNMENT; +using ark::es2panda::lsp::sort_text::SUGGESTED_CLASS_MEMBERS; -void AssertCompletionsContainAndNotContainEntries(const std::vector &entries, - const std::vector &expectedEntries, - const std::vector &unexpectedEntries) +static void AssertCompletionsContainAndNotContainEntries(const std::vector &entries, + const std::vector &expectedEntries, + const std::vector &unexpectedEntries) { auto emptyCheck = expectedEntries.empty() && !entries.empty(); ASSERT_FALSE(emptyCheck) << "Expected empty but the result is not. Actual account: " << entries.size(); @@ -56,9 +59,387 @@ void AssertCompletionsContainAndNotContainEntries(const std::vector files = {"getCompletionsAtPosition20.ets"}; + std::vector texts = {R"delimiter( +deep +)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 5; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector { + CompletionEntry("deepcopy", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(GLOBALS_OR_KEYWORDS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition18) +{ + std::vector files = {"getCompletionsAtPosition19.ets"}; + std::vector texts = {R"delimiter( +Readonl +)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 8; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector {CompletionEntry( + "ReadonlyArray", ark::es2panda::lsp::CompletionEntryKind::INTERFACE, std::string(GLOBALS_OR_KEYWORDS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition17) +{ + std::vector files = {"getCompletionsAtPosition18.ets"}; + std::vector texts = {R"delimiter( +con +)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 4; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector { + CompletionEntry("console", ark::es2panda::lsp::CompletionEntryKind::PROPERTY, std::string(GLOBALS_OR_KEYWORDS)), + CompletionEntry("Console", ark::es2panda::lsp::CompletionEntryKind::CLASS, std::string(GLOBALS_OR_KEYWORDS)), + CompletionEntry("ConcurrentHashMap", ark::es2panda::lsp::CompletionEntryKind::CLASS, + std::string(GLOBALS_OR_KEYWORDS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition16) +{ + std::vector files = {"getCompletionsAtPosition17.ets"}; + std::vector texts = {R"delimiter( +struct MyClass { + property: string = '1' + get() { + return this._WILDCARD + } +} +)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 78; // after 'j._WILDCARD' + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector { + CompletionEntry("property", ark::es2panda::lsp::CompletionEntryKind::PROPERTY, + std::string(SUGGESTED_CLASS_MEMBERS)), + CompletionEntry("get", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition15) +{ + std::vector files = {"getCompletionsAtPosition16.ets"}; + std::vector texts = {R"delimiter( +export interface Method { + get(value: number): this; +} +export interface CommonMethod { + width(value: number): this; + height(value: number): this; +} +export interface TextAttribute extends CommonMethod { + font(value: number): this; + fontColor(value: number): this; +} +export declare function Text( + content?: string, + value?: string +): TextAttribute +Text("Hello").font()._WILDCARD +)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 385; // after 'j._WILDCARD' + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector { + CompletionEntry("font", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS)), + CompletionEntry("fontColor", ark::es2panda::lsp::CompletionEntryKind::METHOD, + std::string(CLASS_MEMBER_SNIPPETS)), + CompletionEntry("width", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS)), + CompletionEntry("height", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition14) +{ + std::vector files = {"getCompletionsAtPosition15.ets"}; + std::vector texts = {R"delimiter( +export class MyClass0 { + public property0: string = '0' + public get0() {} +} +export class MyClass extends MyClass0 { + public property: string = '1' + public get() {} +} +export class MySonClass extends MyClass { + public property2: string = '2' +} +let c = new MySonClass() +let p = c._WILDCARD +)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 292; // after 'j._WILDCARD' + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector { + CompletionEntry("property", ark::es2panda::lsp::CompletionEntryKind::PROPERTY, + std::string(SUGGESTED_CLASS_MEMBERS)), + CompletionEntry("property", ark::es2panda::lsp::CompletionEntryKind::PROPERTY, + std::string(SUGGESTED_CLASS_MEMBERS)), + CompletionEntry("property2", ark::es2panda::lsp::CompletionEntryKind::PROPERTY, + std::string(SUGGESTED_CLASS_MEMBERS)), + CompletionEntry("get", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS)), + CompletionEntry("get0", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition13) +{ + std::vector files = {"getCompletionsAtPosition14.ets"}; + std::vector texts = {R"delimiter( +export interface Method { + get(value: number): this; +} +export interface CommonMethod { + width(value: number): this; + height(value: number): this; +} +export interface TextAttribute extends CommonMethod { + font(value: number): this; + fontColor(value: number): this; +} +export declare function Text( + content?: string, + value?: string +): TextAttribute +Text("Hello")._WILDCARD +)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 378; // after 'j._WILDCARD' + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector { + CompletionEntry("font", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS)), + CompletionEntry("fontColor", ark::es2panda::lsp::CompletionEntryKind::METHOD, + std::string(CLASS_MEMBER_SNIPPETS)), + CompletionEntry("width", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS)), + CompletionEntry("height", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition12) +{ + std::vector files = {"getCompletionsAtPosition13.ets"}; + std::vector texts = {R"delimiter( +class JSON { + public static stringify(d: byte): String { + return StringBuilder.toString(d) + } +} +let j = new JSON() +let res = j._WILDCARD +)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 142; // after 'j._WILDCARD' + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector {CompletionEntry( + "stringify", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition11) +{ + std::vector files = {"getCompletionsAtPosition12.ets"}; + std::vector texts = {R"delimiter( +interface Inner { key : string; } +let i: Inner +i.k +let a = 1;)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 51; // after 'i.k' + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector { + CompletionEntry("key", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition10) +{ + std::vector files = {"getCompletionsAtPosition11.ets"}; + std::vector texts = {R"delimiter( +interface Inner { key : string; } +let i: Inner +i._WILDCARD +let a = 1;)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 59; // after 'i._WILDCARD' + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector { + CompletionEntry("key", ark::es2panda::lsp::CompletionEntryKind::METHOD, std::string(CLASS_MEMBER_SNIPPETS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition7) +{ + std::vector files = {"getCompletionsAtPosition10.ets"}; + std::vector texts = {R"delimiter( +class MyClass { + public myProp: number = 0; + public prop: number = 0; +} +let obj = new MyClass(); +let p = obj._WILDCARD +let a = 1;)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 121; // after 'obj._WILDCARD' in 'let p = obj._WILDCARD' + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = + std::vector {CompletionEntry("myProp", ark::es2panda::lsp::CompletionEntryKind::PROPERTY, + std::string(SUGGESTED_CLASS_MEMBERS)), + CompletionEntry("prop", ark::es2panda::lsp::CompletionEntryKind::PROPERTY, + std::string(SUGGESTED_CLASS_MEMBERS))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, getCompletionsAtPosition8) +{ + std::vector files = {"getCompletionsAtPosition11.ets"}; + std::vector texts = {R"delimiter( +enum Color { + Red = "red", + Blue = "blue" +} +let myColor: Color = Color._WILDCARD)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 83; // after 'Color._WILDCARD' + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto expectedEntries = std::vector { + CompletionEntry("Red", CompletionEntryKind::ENUM_MEMBER, std::string(MEMBER_DECLARED_BY_SPREAD_ASSIGNMENT)), + CompletionEntry("Blue", CompletionEntryKind::ENUM_MEMBER, std::string(MEMBER_DECLARED_BY_SPREAD_ASSIGNMENT))}; + AssertCompletionsContainAndNotContainEntries(res.GetEntries(), expectedEntries, {}); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsTests, MemberCompletionsForClassTest9) +{ + std::vector files = {"getCompletionsAtPosition12.ets"}; + std::vector texts = {R"delimiter( +namespace space { + export class classInSpace { + public c: number = 2; + } +} +let numOfSpace: space._WILDCARD)delimiter"}; + auto filePaths = CreateTempFile(files, texts); + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + LSPAPI const *lspApi = GetImpl(); + const size_t offset = 113; + auto res = lspApi->getCompletionsAtPosition(ctx, offset); + auto entries = res.GetEntries(); + std::string propertyName1 = "classInSpace"; + ASSERT_TRUE(entries.size() == 1); + CompletionEntry entry1 = + CompletionEntry(propertyName1, CompletionEntryKind::CLASS, + std::string(ark::es2panda::lsp::sort_text::MEMBER_DECLARED_BY_SPREAD_ASSIGNMENT)); + initializer.DestroyContext(ctx); + ASSERT_EQ(entry1, entries[0]); +} + TEST_F(LSPCompletionsTests, getCompletionsAtPosition6) { - std::vector files = {"getCompletionsAtPosition1.ets"}; + std::vector files = {"getCompletionsAtPosition9.ets"}; std::vector texts = {R"delimiter( let a: num )delimiter"}; @@ -79,7 +460,7 @@ let a: num TEST_F(LSPCompletionsTests, getCompletionsAtPosition5) { - std::vector files = {"getCompletionsAtPosition1.ets"}; + std::vector files = {"getCompletionsAtPosition8.ets"}; std::vector texts = {R"delimiter( class )delimiter"}; @@ -88,7 +469,7 @@ class ASSERT_EQ(filePaths.size(), expectedFileCount); LSPAPI const *lspApi = GetImpl(); - size_t const offset = 5; // after 'n' in 'let a = n' + size_t const offset = 6; // after 'ss' in 'class' Initializer initializer = Initializer(); auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); auto res = lspApi->getCompletionsAtPosition(ctx, offset); @@ -99,7 +480,7 @@ class TEST_F(LSPCompletionsTests, getCompletionsAtPosition0) { - std::vector files = {"getCompletionsAtPosition1.ets"}; + std::vector files = {"getCompletionsAtPosition7.ets"}; std::vector texts = {R"delimiter( function num1() { return 1; @@ -293,7 +674,7 @@ let prop = obj1.yp)delimiter"}; Initializer initializer = Initializer(); auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); LSPAPI const *lspApi = GetImpl(); - const size_t offset = 119; + const size_t offset = 120; auto res = lspApi->getCompletionsAtPosition(ctx, offset); auto entries = res.GetEntries(); ASSERT_TRUE(entries.size() == 1); @@ -321,7 +702,7 @@ let numOfSpace: space.classi)delimiter"}; Initializer initializer = Initializer(); auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); LSPAPI const *lspApi = GetImpl(); - const size_t offset = 109; + const size_t offset = 110; auto res = lspApi->getCompletionsAtPosition(ctx, offset); auto entries = res.GetEntries(); std::string propertyName1 = "classInSpace"; @@ -348,7 +729,7 @@ let myColor: Color = Color.R)delimiter"}; Initializer initializer = Initializer(); auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); LSPAPI const *lspApi = GetImpl(); - const size_t offset = 74; + const size_t offset = 75; auto res = lspApi->getCompletionsAtPosition(ctx, offset); auto entries = res.GetEntries(); ASSERT_TRUE(entries.size() == 1); @@ -360,3 +741,5 @@ let myColor: Color = Color.R)delimiter"}; initializer.DestroyContext(ctx); ASSERT_EQ(entry1, entries[0]); } + +} // namespace diff --git a/ets2panda/test/unit/lsp/get_completions_entry_details.cpp b/ets2panda/test/unit/lsp/get_completions_entry_details.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d55b0df0f4ba992aba6c303dd63ef955c8e83075 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_completions_entry_details.cpp @@ -0,0 +1,122 @@ +/** + * 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_api_test.h" +#include "lsp/include/completions.h" +#include "lsp/include/internal_api.h" +#include "lsp/include/api.h" +#include "lsp/include/completions_details.h" + +namespace { + +class LSPCompletionsEntryDetailsTests : public LSPAPITests {}; + +using ark::es2panda::lsp::Initializer; + +TEST_F(LSPCompletionsEntryDetailsTests, GetCompletionEntryDetails0) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("completion_entry_details.ets", ES2PANDA_STATE_CHECKED, + R"(enum MyStrings { A = 'hello' };)"); + size_t const offset = 17; + LSPAPI const *lspApi = GetImpl(); + const char *entryName = "MyStrings"; + auto completionEntryDetails = + lspApi->getCompletionEntryDetails(entryName, "completion_entry_details.ets", ctx, offset); + ASSERT_NE(completionEntryDetails, CompletionEntryDetails()); + std::vector source {}; + std::vector sourceDisplay {}; + std::vector document {}; + const std::string kind = "class"; + const std::string kindModifiers = "final"; + const std::string expectedFileName = "completion_entry_details.ets"; + + std::vector expected; + expected.emplace_back("enum", "keyword"); + expected.emplace_back(" ", "space"); + expected.emplace_back("MyStrings", "className"); + + auto expectedCompletionEntryDetails = CompletionEntryDetails(entryName, kind, kindModifiers, expected, document, + source, sourceDisplay, expectedFileName); + initializer.DestroyContext(ctx); + ASSERT_EQ(completionEntryDetails, expectedCompletionEntryDetails); +} + +TEST_F(LSPCompletionsEntryDetailsTests, GetCompletionEntryDetails1) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("completion_entry_details1.ets", ES2PANDA_STATE_CHECKED, + "class MyClass {\n public myProp: number = 0;\n}"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + size_t const offset = 9; + LSPAPI const *lspApi = GetImpl(); + const char *entryName = "MyClass"; + const std::string fileName = "completion_entry_details1.ets"; + auto completionEntryDetails = + lspApi->getCompletionEntryDetails(entryName, "completion_entry_details1.ets", ctx, offset); + ASSERT_NE(completionEntryDetails, CompletionEntryDetails()); + std::vector source {}; + std::vector sourceDisplay {}; + std::vector document {}; + const std::string kind = "class"; + const std::string kindModifiers; + const std::string expectedFileName = "completion_entry_details1.ets"; + + std::vector expected; + expected.emplace_back("class", "keyword"); + expected.emplace_back(" ", "space"); + expected.emplace_back("MyClass", "className"); + + auto expectedCompletionEntryDetails = CompletionEntryDetails(entryName, kind, kindModifiers, expected, document, + source, sourceDisplay, expectedFileName); + ASSERT_EQ(completionEntryDetails, expectedCompletionEntryDetails); + + initializer.DestroyContext(ctx); +} + +TEST_F(LSPCompletionsEntryDetailsTests, GetCompletionEntryDetails2) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = + initializer.CreateContext("completion_entry_details2.ets", ES2PANDA_STATE_CHECKED, + "interface objI { key : string; }\nlet obj : objI = { key:\"valueaaaaaaaaa,\" }"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + size_t const offset = 7; + LSPAPI const *lspApi = GetImpl(); + const char *entryName = "objI"; + const std::string fileName = "completion_entry_details2.ets"; + auto completionEntryDetails = + lspApi->getCompletionEntryDetails(entryName, "completion_entry_details2.ets", ctx, offset); + ASSERT_NE(completionEntryDetails, CompletionEntryDetails()); + std::vector source {}; + std::vector sourceDisplay {}; + std::vector document {}; + const std::string kind = "interface"; + const std::string kindModifiers = "static public"; + const std::string expectedFileName = "completion_entry_details2.ets"; + std::vector expected; + + expected.emplace_back("interface", "keyword"); + expected.emplace_back(" ", "space"); + expected.emplace_back("objI", "className"); + + auto expectedCompletionEntryDetails = CompletionEntryDetails(entryName, kind, kindModifiers, expected, document, + source, sourceDisplay, expectedFileName); + ASSERT_EQ(completionEntryDetails, expectedCompletionEntryDetails); + + initializer.DestroyContext(ctx); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_constructor_test.cpp b/ets2panda/test/unit/lsp/get_constructor_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c408c131b9811a172295ea467a69c203442bc51 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_constructor_test.cpp @@ -0,0 +1,204 @@ +/** + * 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_api_test.h" +#include "lsp/include/internal_api.h" + +namespace { + +using ark::es2panda::lsp::Initializer; + +class LSPClassInfoTests : public LSPAPITests {}; + +void AssertClassConstructorInfo(const std::vector &fileTextChanges, + const std::vector &expectedFileTextChanges) +{ + auto emptyCheck = fileTextChanges.empty(); + ASSERT_FALSE(emptyCheck) << "The result is empty."; + + auto curFileChanges = fileTextChanges.at(0); + auto expectedFileChanges = expectedFileTextChanges.at(0); + bool check = false; + if (curFileChanges.fileName != expectedFileChanges.fileName) { + check = true; + } + ASSERT_FALSE(check) << "The fileName is not expected."; + + auto textChangeEmptyCheck = curFileChanges.textChanges.empty(); + ASSERT_FALSE(textChangeEmptyCheck) << "The modified file content is empty."; + + auto curTextChange = curFileChanges.textChanges.at(0); + auto expectedTextChange = expectedFileChanges.textChanges.at(0); + if (curTextChange.span.start != expectedTextChange.span.start) { + check = true; + } + ASSERT_FALSE(check) << "The insertPosition is not expected."; + if (curTextChange.newText != expectedTextChange.newText) { + check = true; + } + ASSERT_FALSE(check) << "The newText is not expected."; +} + +TEST_F(LSPClassInfoTests, getClassConstructorInfo1) +{ + std::vector fileNames = {"getClassConstructorInfo1.ets"}; + std::vector fileContents = { + R"( +class FooParent { + f: number = 0; + str: string = "aaa"; + constructor (f: number, str: string) { + this.f = f; + this.str = str; + } +}; + +enum Colors {Red = "#FF0000", Green = "#00FF00", Blue = "#0000FF"}; +export class Foo extends FooParent { + name: string = "unassigned"; + isActive: boolean = true; + items: string[] = ["aaa", "bbb"]; + point: [number, number] = [0, 0]; + primaryColor: Colors = Colors.Blue; + optionalValue?:string|null|undefined; + x: number = 1; + static y: number = 2; + z: number = 3; +};)"}; + auto filePaths = CreateTempFile(fileNames, fileContents); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 400; + std::vector properties = {"name", "x", "z"}; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getClassConstructorInfo(ctx, offset, properties); + std::vector expectedFileTextChanges; + std::string text = + "constructor(f: number, str: string, name: string, x: number, z: number) {\n super(f, str);\n this.name = " + "name;\n this.x = x;\n this.z = z;\n}"; + size_t const insertPosition = 269; + TextSpan span(insertPosition, text.size()); + std::vector textChanges; + textChanges.emplace_back(TextChange(span, text)); + FileTextChanges textChange(filePaths.at(0), textChanges); + expectedFileTextChanges.push_back(textChange); + AssertClassConstructorInfo(res.GetFileTextChanges(), expectedFileTextChanges); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPClassInfoTests, getClassConstructorInfo2) +{ + std::vector files = {"getClassConstructorInfo2.ets"}; + std::vector texts = { + R"( +class Foo { + f: number = 0; + str: string = "aaa"; +};)"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 30; + std::vector properties = {"f", "str"}; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getClassConstructorInfo(ctx, offset, properties); + std::vector expectedFileTextChanges; + std::string text = "constructor(f: number, str: string) {\n this.f = f;\n this.str = str;\n}"; + size_t const insertPosition = 17; + TextSpan span(insertPosition, text.size()); + std::vector textChanges; + textChanges.emplace_back(TextChange(span, text)); + FileTextChanges textChange(filePaths.at(0), textChanges); + expectedFileTextChanges.push_back(textChange); + AssertClassConstructorInfo(res.GetFileTextChanges(), expectedFileTextChanges); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPClassInfoTests, getClassConstructorInfo3) +{ + std::vector files = {"getClassConstructorInfo3.ets"}; + std::vector texts = { + R"( +class Foo { +};)"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 10; + std::vector properties = {}; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getClassConstructorInfo(ctx, offset, properties); + std::vector expectedFileTextChanges; + std::string text = "constructor() {\n}"; + size_t const insertPosition = 13; + TextSpan span(insertPosition, text.size()); + std::vector textChanges; + textChanges.emplace_back(TextChange(span, text)); + FileTextChanges textChange(filePaths.at(0), textChanges); + expectedFileTextChanges.push_back(textChange); + AssertClassConstructorInfo(res.GetFileTextChanges(), expectedFileTextChanges); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPClassInfoTests, getClassConstructorInfo4) +{ + std::vector files = {"getClassConstructorInfo4.ets"}; + std::vector texts = { + R"( +namespace space { + export class classInSpace { + c: number = 2; + + function print() { + return 2; + } + } +})"}; + auto filePaths = CreateTempFile(files, texts); + + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 35; + std::vector properties = {"c"}; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto res = lspApi->getClassConstructorInfo(ctx, offset, properties); + std::vector expectedFileTextChanges; + std::string text = "constructor(c: number) {\n this.c = c;\n}"; + size_t const insertPosition = 59; + TextSpan span(insertPosition, text.size()); + std::vector textChanges; + textChanges.emplace_back(TextChange(span, text)); + FileTextChanges textChange(filePaths.at(0), textChanges); + expectedFileTextChanges.push_back(textChange); + AssertClassConstructorInfo(res.GetFileTextChanges(), expectedFileTextChanges); + initializer.DestroyContext(ctx); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_current_token_value_test.cpp b/ets2panda/test/unit/lsp/get_current_token_value_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..77160bf3e9e58240aa49abde5088c11312e3cee0 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_current_token_value_test.cpp @@ -0,0 +1,137 @@ +/** + * 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_api_test.h" + +#include +#include + +#include "ir/astNode.h" +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" + +namespace { + +using ark::es2panda::lsp::Initializer; + +TEST_F(LSPAPITests, GetCurrentTokenValue) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("current_token.ets", ES2PANDA_STATE_CHECKED, "ab"); + LSPAPI const *lspApi = GetImpl(); + size_t offset = 2; + std::string result = lspApi->getCurrentTokenValue(ctx, offset); + initializer.DestroyContext(ctx); + ASSERT_EQ(result, "ab"); +} + +TEST_F(LSPAPITests, GetCurrentTokenValue1) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "\"ab\""); + size_t offset = 3; + std::string result = ark::es2panda::lsp::GetCurrentTokenValueImpl(ctx, offset); + std::string expect = "ab"; + ASSERT_EQ(result, expect); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, GetCurrentTokenValue2) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "\'ab\'"); + size_t offset = 3; + std::string result = ark::es2panda::lsp::GetCurrentTokenValueImpl(ctx, offset); + std::string expect = "ab"; + ASSERT_EQ(result, expect); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, GetCurrentTokenValue3) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "abc"); + size_t offset = 2; + std::string result = ark::es2panda::lsp::GetCurrentTokenValueImpl(ctx, offset); + std::string expect = "ab"; + ASSERT_EQ(result, expect); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, GetTokenPosOfNode1) +{ + using ark::es2panda::ir::AstNode; + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("token-pos-identifier.ets", ES2PANDA_STATE_CHECKED, + "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto ast = GetAstFromContext(ctx); + auto targetNode = + ast->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "A"; }); + + ASSERT_NE(targetNode, nullptr); + auto result = ark::es2panda::lsp::GetTokenPosOfNode(targetNode); + size_t const pos = 51; + ASSERT_EQ(result, pos); + + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, GetTokenPosOfNode2) +{ + using ark::es2panda::ir::AstNode; + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("token-pos-expression.ets", ES2PANDA_STATE_CHECKED, + "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto ast = GetAstFromContext(ctx); + auto targetNode = ast->FindChild([](AstNode *node) { return node->IsExpressionStatement(); }); + + ASSERT_NE(targetNode, nullptr); + auto result = ark::es2panda::lsp::GetTokenPosOfNode(targetNode); + size_t const pos = 51; + ASSERT_EQ(result, pos); + + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, GetTokenPosOfNode3) +{ + using ark::es2panda::ir::AstNode; + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext( + "token-pos-literal.ets", ES2PANDA_STATE_CHECKED, + "let number_literal: number = 1234;\nlet string_literal: string = \"hello\";\nconst str_property = " + "\"foo\";\n"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto ast = GetAstFromContext(ctx); + auto targetNode = ast->FindChild( + [](AstNode *node) { return node->IsNumberLiteral() && node->AsNumberLiteral()->Str() == "1234"; }); + + ASSERT_NE(targetNode, nullptr); + auto result = ark::es2panda::lsp::GetTokenPosOfNode(targetNode); + size_t const pos = 29; + ASSERT_EQ(result, pos); + + initializer.DestroyContext(ctx); +} + +} // namespace diff --git a/ets2panda/test/unit/lsp/get_definition_and_bound_span_test.cpp b/ets2panda/test/unit/lsp/get_definition_and_bound_span_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af99f95900441c81bf160c765291950d0fe08f4f --- /dev/null +++ b/ets2panda/test/unit/lsp/get_definition_and_bound_span_test.cpp @@ -0,0 +1,102 @@ +/** + * 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 +#include +#include "lsp_api_test.h" +#include "lsp/include/get_definition_and_bound_span.h" +#include + +namespace { + +class LSPGetDefinitionAndBoundSpanTests : public LSPAPITests {}; + +TEST_F(LSPGetDefinitionAndBoundSpanTests, GetDefinitionAndBoundSpan_FunctionReference) +{ + const auto fileName = "definition1.ets"; + const auto fileContent = R"( +function sum(a: number, b: number): number { + return a + b; +} + +let total = sum(5, 10); +)"; + + const size_t offset = 79; + const size_t index0 = 0; + const size_t index3 = 3; + const size_t index13 = 13; + + std::vector files = {fileName}; + std::vector texts = {fileContent}; + auto filePaths = CreateTempFile(files, texts); + + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(files.at(index0).c_str(), ES2PANDA_STATE_CHECKED, fileContent); + + const auto result = ark::es2panda::lsp::GetDefinitionAndBoundSpan(ctx, offset); + + EXPECT_FALSE(result.definitionInfo.fileName.empty()); + EXPECT_EQ(result.definitionInfo.length, index3); + EXPECT_EQ(result.boundSpan.length, index3); + EXPECT_EQ(result.definitionInfo.start + result.definitionInfo.length, index13); + + const size_t expectedDefOffset = 10; + EXPECT_EQ(result.definitionInfo.start, expectedDefOffset); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPGetDefinitionAndBoundSpanTests, GetDefinitionAndBoundSpan_FunctionReferenceTwoFile) +{ + std::vector fileNames = {"lsp_api_test_export_1.ets", "lsp_api_test_file_1.ets"}; + std::vector texts = { + R"(export function A(a:number, b:number): number { + return a + b; +} +export function B(a:number, b:number): number { + return a + b; +})", + R"(import {A} from "./lsp_api_test_export_1"; +import {B} from "./lsp_api_test_export_1.ets"; +A(1, 2); +B(1, 2);)"}; + + auto filePaths = CreateTempFile(fileNames, texts); + int const expectedFileCount = 2; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + const size_t offset = 94; + const size_t index0 = 0; + const size_t index1 = 1; + const size_t index13 = 17; + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = + initializer.CreateContext(filePaths.at(index1).c_str(), ES2PANDA_STATE_CHECKED, texts.at(index1).c_str()); + + std::cout << "offset: " << offset << std::endl; + const auto result = ark::es2panda::lsp::GetDefinitionAndBoundSpan(ctx, offset); + + EXPECT_FALSE(result.definitionInfo.fileName.empty()); + EXPECT_EQ(result.definitionInfo.fileName, filePaths.at(index0)); + EXPECT_EQ(result.definitionInfo.length, index1); + EXPECT_EQ(result.boundSpan.length, index1); + EXPECT_EQ(result.definitionInfo.start + result.definitionInfo.length, index13); + + const size_t expectedDefOffset = 16; + EXPECT_EQ(result.definitionInfo.start, expectedDefOffset); + initializer.DestroyContext(ctx); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_file_references_impl_test.cpp b/ets2panda/test/unit/lsp/get_file_references_impl_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b43341adbfabe5fd1ef1c5db21af4dda7618168d --- /dev/null +++ b/ets2panda/test/unit/lsp/get_file_references_impl_test.cpp @@ -0,0 +1,156 @@ +/** + * 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_api_test.h" + +#include +#include + +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" +#include "public/public.h" + +namespace { + +using ark::es2panda::lsp::Initializer; + +TEST_F(LSPAPITests, GetFileReferencesImpl1) +{ + using ark::es2panda::public_lib::Context; + std::vector files = {"lsp_api_test_export_1.ets", "lsp_api_test_file_1.ets"}; + std::vector texts = { + R"(export function A(a:number, b:number): number { + return a + b; +} +export function B(a:number, b:number): number { + return a + b; +})", + R"(import {A} from "./lsp_api_test_export_1"; +import {B} from "./lsp_api_test_export_1.ets"; +A(1, 2); +B(1, 2);)"}; + auto filePaths = CreateTempFile(files, texts); + int const expectedFileCount = 2; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + char const *searchFileName = filePaths[0].c_str(); + char const *referenceFileName = filePaths[1].c_str(); + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(searchFileName, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto isPackageModule = reinterpret_cast(ctx)->parserProgram->IsPackage(); + ASSERT_FALSE(isPackageModule); + initializer.DestroyContext(ctx); + + auto ctx1 = initializer.CreateContext(referenceFileName, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(ContextState(ctx1), ES2PANDA_STATE_CHECKED); + + auto result = References(); + result = ark::es2panda::lsp::GetFileReferencesImpl(ctx1, searchFileName, isPackageModule); + auto expectedFileName1 = filePaths[1]; + size_t const expectedStartPos1 = 16; + size_t const expectedLength1 = 25; + auto expectedFileName2 = filePaths[1]; + size_t const expectedStartPos2 = 59; + size_t const expectedLength2 = 29; + ASSERT_EQ(result.referenceInfos.at(0).fileName, expectedFileName1); + ASSERT_EQ(result.referenceInfos.at(0).start, expectedStartPos1); + ASSERT_EQ(result.referenceInfos.at(0).length, expectedLength1); + ASSERT_EQ(result.referenceInfos.at(1).fileName, expectedFileName2); + ASSERT_EQ(result.referenceInfos.at(1).start, expectedStartPos2); + ASSERT_EQ(result.referenceInfos.at(1).length, expectedLength2); + initializer.DestroyContext(ctx1); +} + +TEST_F(LSPAPITests, GetFileReferencesImpl2) +{ + using ark::es2panda::public_lib::Context; + std::vector files = {"lsp_api_test_export_2.ts", "lsp_api_test_file_2.ets"}; + std::vector texts = { + R"(export function A(a:number, b:number): number { + return a + b; +} +export function B(a:number, b:number): number { + return a + b; +})", + R"(import {A} from "./lsp_api_test_export_2"; +import {B} from "./lsp_api_test_export_2.ts"; +A(1, 2); +B(1, 2);)"}; + auto filePaths = CreateTempFile(files, texts); + int const expectedFileCount = 2; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + char const *searchFileName = filePaths[0].c_str(); + char const *referenceFileName = filePaths[1].c_str(); + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(searchFileName, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto isPackageModule = reinterpret_cast(ctx)->parserProgram->IsPackage(); + ASSERT_FALSE(isPackageModule); + initializer.DestroyContext(ctx); + + auto ctx1 = initializer.CreateContext(referenceFileName, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(ContextState(ctx1), ES2PANDA_STATE_CHECKED); + + auto result = References(); + result = ark::es2panda::lsp::GetFileReferencesImpl(ctx1, searchFileName, isPackageModule); + auto expectedFileName1 = filePaths[1]; + size_t const expectedStartPos1 = 16; + size_t const expectedLength1 = 25; + auto expectedFileName2 = filePaths[1]; + size_t const expectedStartPos2 = 59; + size_t const expectedLength2 = 28; + ASSERT_EQ(result.referenceInfos.at(0).fileName, expectedFileName1); + ASSERT_EQ(result.referenceInfos.at(0).start, expectedStartPos1); + ASSERT_EQ(result.referenceInfos.at(0).length, expectedLength1); + ASSERT_EQ(result.referenceInfos.at(1).fileName, expectedFileName2); + ASSERT_EQ(result.referenceInfos.at(1).start, expectedStartPos2); + ASSERT_EQ(result.referenceInfos.at(1).length, expectedLength2); + initializer.DestroyContext(ctx1); +} + +TEST_F(LSPAPITests, GetFileReferencesImpl3) +{ + using ark::es2panda::public_lib::Context; + std::vector files = {"package-module.ets"}; + std::vector texts = {R"(import { PI } from "std/math"; +console.log(PI);)"}; + auto filePaths = CreateTempFile(files, texts); + int const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + char const *referenceFileName = filePaths[0].c_str(); + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(referenceFileName, ES2PANDA_STATE_CHECKED); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto baseUrl = reinterpret_cast(ctx)->config->options->ArkTSConfig()->BaseUrl(); + auto searchFileName = baseUrl + "/plugins/ets/stdlib/std/math/math.ets"; + auto result = References(); + result = ark::es2panda::lsp::GetFileReferencesImpl(ctx, searchFileName.c_str(), true); + auto expectedFileName = filePaths[0]; + size_t const expectedStartPos = 19; + size_t const expectedLength = 10; + + ASSERT_EQ(result.referenceInfos.at(0).fileName, expectedFileName); + ASSERT_EQ(result.referenceInfos.at(0).start, expectedStartPos); + ASSERT_EQ(result.referenceInfos.at(0).length, expectedLength); + initializer.DestroyContext(ctx); +} + +} // namespace diff --git a/ets2panda/test/unit/lsp/get_preceding_token_test.cpp b/ets2panda/test/unit/lsp/get_preceding_token_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5ad66dca25232f64fa2977075784574a3957d2bf --- /dev/null +++ b/ets2panda/test/unit/lsp/get_preceding_token_test.cpp @@ -0,0 +1,110 @@ +/** + * 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_api_test.h" + +#include +#include + +#include "ir/astNode.h" +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" + +namespace { + +using ark::es2panda::lsp::Initializer; + +TEST_F(LSPAPITests, GetPrecedingToken1) +{ + using ark::es2panda::ir::AstNode; + + LSPAPI const *lspApi = GetImpl(); + Initializer initializer = Initializer(); + es2panda_Context *context = initializer.CreateContext( + + "precedingtoken_literal.ets", ES2PANDA_STATE_CHECKED, + "let number_literal: number = 1234;\nlet string_literal: string = \"hello\";\nconst str_property = " + "\"foo\";\n"); + ASSERT_EQ(ContextState(context), ES2PANDA_STATE_CHECKED); + auto ast = GetAstFromContext(context); + + size_t const numberLiteralOffset = 31; // 31: position of '3' in '1234' + size_t const stringLiteralOffset = 96; // 96: position of first 'o' in 'foo' + auto numberLiteral = ast->FindChild([](AstNode *node) { return node->IsExpressionStatement(); }) + ->AsExpressionStatement() + ->GetExpression() + ->AsAssignmentExpression() + ->Right() + ->AsNumberLiteral(); + auto result = reinterpret_cast(lspApi->getPrecedingToken(context, numberLiteralOffset)); + ASSERT_EQ(result->DumpJSON(), numberLiteral->DumpJSON()); + ASSERT_EQ(result->Start().index, numberLiteral->Start().index); + ASSERT_EQ(result->End().index, numberLiteral->End().index); + auto stringLiteral = ast->FindChild( + [](AstNode *node) { return node->IsStringLiteral() && node->AsStringLiteral()->ToString() == "foo"; }); + result = reinterpret_cast(lspApi->getPrecedingToken(context, stringLiteralOffset)); + ASSERT_EQ(result->DumpJSON(), stringLiteral->DumpJSON()); + ASSERT_EQ(result->Start().index, stringLiteral->Start().index); + ASSERT_EQ(result->End().index, stringLiteral->End().index); + initializer.DestroyContext(context); +} + +TEST_F(LSPAPITests, GetPrecedingToken2) +{ + using ark::es2panda::ir::AstNode; + + LSPAPI const *lspApi = GetImpl(); + Initializer initializer = Initializer(); + es2panda_Context *context = initializer.CreateContext( + "precedingtoken_function.ets", ES2PANDA_STATE_CHECKED, + " \n\n\n\nfunction f() {\n le\n let a = 123;\n}\n\n\n\nconst s = \"hello\";\n\n\n"); + auto ast = GetAstFromContext(context); + + size_t const startOfFile = 0; // 0: position of start of file + size_t const secondSpaceBeforeLe = 25; // 25: position of second space before 'le' + size_t const endOfLe = 29; // 29: position of the end of 'le' identifier + size_t const secondSpaceBeforeLet = 32; // 32: position of second space before 'let' + size_t const startOfLine10 = 50; // 50: position of start of line 10 + size_t const startOfLine14 = 72; // 72: position of start of line 14 + ASSERT_EQ(lspApi->getPrecedingToken(context, startOfFile), nullptr); + ASSERT_EQ(lspApi->getPrecedingToken(context, secondSpaceBeforeLe), nullptr); + auto leIdentifier = + ast->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "le"; }); + auto result = reinterpret_cast(lspApi->getPrecedingToken(context, endOfLe)); + ASSERT_EQ(result->DumpJSON(), leIdentifier->DumpJSON()); + ASSERT_EQ(result->Start().index, leIdentifier->Start().index); + ASSERT_EQ(result->End().index, leIdentifier->End().index); + result = reinterpret_cast(lspApi->getPrecedingToken(context, secondSpaceBeforeLet)); + ASSERT_EQ(result->DumpJSON(), leIdentifier->DumpJSON()); + ASSERT_EQ(result->Start().index, leIdentifier->Start().index); + ASSERT_EQ(result->End().index, leIdentifier->End().index); + auto numberLiteral = ast->FindChild( + [](AstNode *node) { return node->IsNumberLiteral() && node->AsNumberLiteral()->Str() == "123"; }); + result = reinterpret_cast(lspApi->getPrecedingToken(context, startOfLine10)); + ASSERT_EQ(result->DumpJSON(), numberLiteral->DumpJSON()); + ASSERT_EQ(result->Start().index, numberLiteral->Start().index); + ASSERT_EQ(result->End().index, numberLiteral->End().index); + auto stringLiteral = ast->FindChild([](AstNode *node) { return node->IsClassProperty(); }) + ->AsClassProperty() + ->Value() + ->AsStringLiteral(); + result = reinterpret_cast(lspApi->getPrecedingToken(context, startOfLine14)); + ASSERT_EQ(result->DumpJSON(), stringLiteral->DumpJSON()); + ASSERT_EQ(result->Start().index, stringLiteral->Start().index); + ASSERT_EQ(result->End().index, stringLiteral->End().index); + initializer.DestroyContext(context); +} + +} // namespace diff --git a/ets2panda/test/unit/lsp/get_safe_delete_info_test.cpp b/ets2panda/test/unit/lsp/get_safe_delete_info_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac249130b62c587ccba3c2172546b7c598b1c238 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_safe_delete_info_test.cpp @@ -0,0 +1,80 @@ +/** + * 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 +#include +#include +#include +#include "lsp_api_test.h" +#include "lsp/include/internal_api.h" +#include "lsp/include/api.h" +#include "public/es2panda_lib.h" + +using ark::es2panda::lsp::Initializer; +namespace { + +class LspGetSafeDeleteInfoTest : public LSPAPITests {}; + +TEST_F(LspGetSafeDeleteInfoTest, GetSafeDeleteInfoCase1) +{ + using ark::es2panda::public_lib::Context; + + std::vector fileNames = {"firstFile.ets", "secondFile.ets"}; + std::vector fileContents = { + "const greet = (name: string) => {\n" + "return 'Hello, ${name}!';\n};\n" + "export default greet;\n", + "import greet from \"./firstFile.ets\""}; + + auto filePaths = CreateTempFile(fileNames, fileContents); + const int fileIndex = 1; + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(filePaths[fileIndex].c_str(), ES2PANDA_STATE_CHECKED); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 7; + bool result = lspApi->getSafeDeleteInfo(ctx, offset, ""); + ASSERT_EQ(result, true); + + initializer.DestroyContext(ctx); +} + +TEST_F(LspGetSafeDeleteInfoTest, GetSafeDeleteInfoCase2) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = + initializer.CreateContext("get-safe-delete-info-case2.ets", ES2PANDA_STATE_CHECKED, "class A {\n\n}"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 8; + bool result = lspApi->getSafeDeleteInfo(ctx, offset, ""); + ASSERT_EQ(result, true); + initializer.DestroyContext(ctx); +} + +TEST_F(LspGetSafeDeleteInfoTest, GetSafeDeleteInfoCase3) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("get-safe-delete-info-case3.ets", ES2PANDA_STATE_CHECKED, + "let arr: Array;\n"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + LSPAPI const *lspApi = GetImpl(); + size_t const offset = 10; + bool result = lspApi->getSafeDeleteInfo(ctx, offset, "stdlib/escompat/Array.ets"); + ASSERT_EQ(result, true); + initializer.DestroyContext(ctx); +} +} // namespace diff --git a/ets2panda/test/unit/lsp/get_span_of_enclosing_comment_test.cpp b/ets2panda/test/unit/lsp/get_span_of_enclosing_comment_test.cpp index ba4cabf781287a6e6af347ab2f38b13332a21c09..4c959d42b2cd81bbd4786343e39a8743f14dd571 100644 --- a/ets2panda/test/unit/lsp/get_span_of_enclosing_comment_test.cpp +++ b/ets2panda/test/unit/lsp/get_span_of_enclosing_comment_test.cpp @@ -17,6 +17,8 @@ #include #include +using ark::es2panda::lsp::Initializer; + class LspGetSpanTests : public LSPAPITests {}; TEST_F(LspGetSpanTests, getSpanOfEnclosingComment1) @@ -26,14 +28,17 @@ TEST_F(LspGetSpanTests, getSpanOfEnclosingComment1) auto filePaths = CreateTempFile(files, texts); LSPAPI const *lspApi = GetImpl(); size_t const offset = 60; - auto result = lspApi->getSpanOfEnclosingComment(filePaths[0].c_str(), offset, false); + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto result = lspApi->getSpanOfEnclosingComment(ctx, offset, false); size_t const startPostion = 0; size_t const length = 0; ASSERT_EQ(result.start, startPostion); ASSERT_EQ(result.length, length); - auto result1 = lspApi->getSpanOfEnclosingComment(filePaths[0].c_str(), offset, true); + auto result1 = lspApi->getSpanOfEnclosingComment(ctx, offset, true); ASSERT_EQ(result1.start, startPostion); ASSERT_EQ(result1.length, length); + initializer.DestroyContext(ctx); } TEST_F(LspGetSpanTests, getSpanOfEnclosingComment2) @@ -43,16 +48,19 @@ TEST_F(LspGetSpanTests, getSpanOfEnclosingComment2) auto filePaths = CreateTempFile(files, texts); LSPAPI const *lspApi = GetImpl(); size_t const offset = 54; - auto result = lspApi->getSpanOfEnclosingComment(filePaths[0].c_str(), offset, false); + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto result = lspApi->getSpanOfEnclosingComment(ctx, offset, false); size_t const startPostion = 50; size_t const length = 6; ASSERT_EQ(result.start, startPostion); ASSERT_EQ(result.length, length); - auto result1 = lspApi->getSpanOfEnclosingComment(filePaths[0].c_str(), offset, true); + auto result1 = lspApi->getSpanOfEnclosingComment(ctx, offset, true); size_t const startPostion1 = 0; size_t const length1 = 0; ASSERT_EQ(result1.start, startPostion1); ASSERT_EQ(result1.length, length1); + initializer.DestroyContext(ctx); } TEST_F(LspGetSpanTests, getSpanOfEnclosingComment3) @@ -62,12 +70,15 @@ TEST_F(LspGetSpanTests, getSpanOfEnclosingComment3) auto filePaths = CreateTempFile(files, texts); LSPAPI const *lspApi = GetImpl(); size_t const offset = 54; - auto result = lspApi->getSpanOfEnclosingComment(filePaths[0].c_str(), offset, false); + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto result = lspApi->getSpanOfEnclosingComment(ctx, offset, false); size_t const startPostion = 50; size_t const length = 9; ASSERT_EQ(result.start, startPostion); ASSERT_EQ(result.length, length); - auto result1 = lspApi->getSpanOfEnclosingComment(filePaths[0].c_str(), offset, true); + auto result1 = lspApi->getSpanOfEnclosingComment(ctx, offset, true); ASSERT_EQ(result1.start, startPostion); ASSERT_EQ(result1.length, length); + initializer.DestroyContext(ctx); } diff --git a/ets2panda/test/unit/lsp/get_touching_token_test.cpp b/ets2panda/test/unit/lsp/get_touching_token_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c95412b50c8b1760f245a6ac3febe0a94453f399 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_touching_token_test.cpp @@ -0,0 +1,77 @@ +/** + * 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_api_test.h" + +#include +#include + +#include "ir/astNode.h" +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" + +namespace { + +using ark::es2panda::lsp::Initializer; + +TEST_F(LSPAPITests, GetTouchingToken1) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("not-found-node.ets", ES2PANDA_STATE_CHECKED, + "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + size_t const offset = 50; + auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false); + ASSERT_EQ(result, nullptr); + + auto result1 = ark::es2panda::lsp::GetTouchingToken(ctx, offset, true); + ASSERT_EQ(result1, nullptr); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, GetTouchingToken2) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("nested-node.ets", ES2PANDA_STATE_CHECKED, + "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + size_t const offset = 51; + auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false); + auto ast = GetAstFromContext(ctx); + auto expectedNode = ast->FindChild( + [](ark::es2panda::ir::AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "A"; }); + ASSERT_EQ(result->DumpJSON(), expectedNode->DumpJSON()); + ASSERT_EQ(result->Start().index, expectedNode->Start().index); + ASSERT_EQ(result->End().index, expectedNode->End().index); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, GetTouchingToken3) +{ + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext("first-node.ets", ES2PANDA_STATE_CHECKED, + "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + size_t const offset = 51; + auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, true); + auto ast = GetAstFromContext(ctx); + auto expectedNode = ast->FindChild([](ark::es2panda::ir::AstNode *node) { return node->IsExpressionStatement(); }); + ASSERT_EQ(result->DumpJSON(), expectedNode->DumpJSON()); + ASSERT_EQ(result->Start().index, expectedNode->Start().index); + ASSERT_EQ(result->End().index, expectedNode->End().index); + initializer.DestroyContext(ctx); +} + +} // namespace diff --git a/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp b/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cfbac8e4199b2e536d3e4336d5119b8d42efda12 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp @@ -0,0 +1,149 @@ +/** + * 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_api_test.h" + +#include + +#include "ir/astNode.h" +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" +#include "public/public.h" + +namespace { + +using ark::es2panda::lsp::Initializer; + +TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation1) +{ + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + Initializer initializer = Initializer(); + es2panda_Context *ctx = + initializer.CreateContext("types.ets", ES2PANDA_STATE_CHECKED, + "let a: number;\nlet b: byte;\nlet c: short;\nlet d: int;\nlet e: long;\nlet f: " + "float;\nlet g: double;\nlet h: char;\nlet i: boolean;"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto checker = reinterpret_cast(ctx)->GetChecker()->AsETSChecker(); + auto astNode = GetAstFromContext(ctx); + auto targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "a"; }); + auto type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsDoubleType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "b"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsByteType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "c"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsShortType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "d"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsIntType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "e"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsLongType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "f"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsFloatType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "g"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsDoubleType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "h"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsCharType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "i"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSBooleanType()); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation2) +{ + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext( + "types.ets", ES2PANDA_STATE_CHECKED, + "let j: object;\nlet k: string;\nlet l: [];\nlet m: bigint;\nlet n: never;\nlet o: null;\nlet p: " + "undefined;\nlet tuple: [number, number] = [1, 2];\nlet union: int | null;"); + ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); + + auto checker = reinterpret_cast(ctx)->GetChecker()->AsETSChecker(); + auto astNode = GetAstFromContext(ctx); + auto targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "j"; }); + auto type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSObjectType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "k"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSStringType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "l"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSTupleType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "m"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSBigIntType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "n"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSNeverType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "o"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSNullType()); + + targetNode = + astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "p"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSUndefinedType()); + + targetNode = astNode->FindChild( + [](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "tuple"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSTupleType()); + + targetNode = astNode->FindChild( + [](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "union"; }); + type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); + ASSERT_TRUE(type->IsETSUnionType()); + initializer.DestroyContext(ctx); +} + +} // namespace diff --git a/ets2panda/test/unit/lsp/inlay_hints_test.cpp b/ets2panda/test/unit/lsp/inlay_hints_test.cpp index c9b480e473052680ca8d5ef136ed195e3fe94be3..91d7532befeaf109f15590aa2ed0bd7a69549ce7 100644 --- a/ets2panda/test/unit/lsp/inlay_hints_test.cpp +++ b/ets2panda/test/unit/lsp/inlay_hints_test.cpp @@ -48,7 +48,7 @@ TEST_F(LSPInlayHintsTests, VisitCallOrNewExpressionTest) preferences.SetDisableSuggestions(true); preferences.SetIncludeInlayParameterNameHints(UserPreferences::IncludeInlayParameterNameHints::ALL); - ark::es2panda::lsp::InlayHintList result = {}; + InlayHintList result = {}; ark::es2panda::lsp::Initializer initializer; const auto ctx = initializer.CreateContext(filePath[0].c_str(), ES2PANDA_STATE_CHECKED); @@ -61,7 +61,7 @@ TEST_F(LSPInlayHintsTests, VisitCallOrNewExpressionTest) parent->FindChild([&callExprNode, parent, &result](ark::es2panda::ir::AstNode *childNode) { if (childNode->IsCallExpression()) { callExprNode = childNode; - GetCallExpTypeForHints(callExprNode, parent, &result); + ark::es2panda::lsp::GetCallExpTypeForHints(callExprNode, parent, &result); } return false; }); @@ -70,9 +70,8 @@ TEST_F(LSPInlayHintsTests, VisitCallOrNewExpressionTest) const std::string p1 = "param1"; const std::string p2 = "param2"; ASSERT_NE(callExprNode, nullptr); - std::vector expectedHints = { - {p1, num1, ark::es2panda::lsp::InlayHintKind::PARAMETER, false, true}, - {p2, num2, ark::es2panda::lsp::InlayHintKind::PARAMETER, false, true}}; + std::vector expectedHints = {{p1, num1, InlayHintKind::PARAMETER, false, true}, + {p2, num2, InlayHintKind::PARAMETER, false, true}}; ASSERT_EQ(result.hints.size(), expectedHints.size()); for (size_t i = 0; i < expectedHints.size(); i++) { @@ -82,7 +81,6 @@ TEST_F(LSPInlayHintsTests, VisitCallOrNewExpressionTest) ASSERT_EQ(result.hints[i].whitespaceBefore, expectedHints[i].whitespaceBefore); ASSERT_EQ(result.hints[i].whitespaceAfter, expectedHints[i].whitespaceAfter); } - initializer.DestroyContext(ctx); } @@ -111,7 +109,7 @@ let classText = text.className; const auto filePath = CreateTempFile(files, fileContent); - ark::es2panda::lsp::InlayHintList result = {}; + InlayHintList result = {}; const size_t size = 4; const std::string enum2 = "2"; const std::string enum3 = "3"; @@ -131,7 +129,7 @@ let classText = text.className; parent->FindChild([parent, &result](ark::es2panda::ir::AstNode *childNode) { if (childNode->IsAssignmentExpression()) { - GetEnumTypeForHints(childNode, parent, &result); + ark::es2panda::lsp::GetEnumTypeForHints(childNode, parent, &result); } return false; }); @@ -171,7 +169,7 @@ TEST_F(LSPInlayHintsTests, VisitFunctionLikeForParameterTypeTest) const size_t i3 = 3; const auto filePaths = CreateTempFile(files, fileContent); ASSERT_EQ(filePaths.size(), i1); - ark::es2panda::lsp::InlayHintList result = {}; + InlayHintList result = {}; ark::es2panda::lsp::Initializer initializer; const auto ctx = initializer.CreateContext(filePaths[i0].c_str(), ES2PANDA_STATE_CHECKED); @@ -223,7 +221,7 @@ TEST_F(LSPInlayHintsTests, VisitFunctionDeclarationLikeForReturnTypeTest1) const size_t i3 = 3; const auto filePaths = CreateTempFile(files, fileContent); ASSERT_EQ(filePaths.size(), i1); - ark::es2panda::lsp::InlayHintList result; + InlayHintList result; ark::es2panda::lsp::Initializer initializer; const auto ctx = initializer.CreateContext(filePaths[i0].c_str(), ES2PANDA_STATE_CHECKED); ASSERT_NE(ctx, nullptr); @@ -268,7 +266,7 @@ TEST_F(LSPInlayHintsTests, VisitFunctionDeclarationLikeForReturnTypeTest2) const auto filePaths = CreateTempFile(files, fileContent); ASSERT_EQ(filePaths.size(), i1); - ark::es2panda::lsp::InlayHintList result; + InlayHintList result; ark::es2panda::lsp::Initializer initializer; const auto ctx = initializer.CreateContext(filePaths[i0].c_str(), ES2PANDA_STATE_CHECKED); ASSERT_NE(ctx, nullptr); @@ -310,7 +308,7 @@ TEST_F(LSPInlayHintsTests, VisitVariableLikeDeclarationTest) const size_t i2 = 2; const auto filePaths = CreateTempFile(files, fileContent); ASSERT_EQ(filePaths.size(), i1); - ark::es2panda::lsp::InlayHintList result; + InlayHintList result; ark::es2panda::lsp::Initializer initializer; const auto ctx = initializer.CreateContext(filePaths[i0].c_str(), ES2PANDA_STATE_CHECKED); ASSERT_NE(ctx, nullptr); diff --git a/ets2panda/test/unit/lsp/isolated_declaration.cpp b/ets2panda/test/unit/lsp/isolated_declaration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a0f1c776bba96cd364449bdb9ba54003c83cd59 --- /dev/null +++ b/ets2panda/test/unit/lsp/isolated_declaration.cpp @@ -0,0 +1,230 @@ +/** + * 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_api_test.h" +#include "lsp/include/isolated_declaration.h" + +namespace { +using ark::es2panda::lsp::Initializer; + +class LSPIsolatedDeclarationTests : public LSPAPITests {}; + +TEST_F(LSPIsolatedDeclarationTests, IsolatedDeclaration1) +{ + std::vector files = {"IsolatedDeclaration1_export.ets", "IsolatedDeclaration1.ets"}; + std::vector texts = {R"(export class C { + pro1: number = 123; + pro2: string = "hello"; + pro3: boolean = false; +} +)", + R"(import {C} from './IsolatedDeclaration1_export'; +export function foo(n: number) { + if (n < 3) { + return n + 2; + } + const c = new C(); + if (c.pro1 < 100) { + return c; + } + if (c.pro3) { + return c.pro3; + } + return c.pro2; +} +)"}; + auto filePaths = CreateTempFile(files, texts); + const size_t expectedFileCount = 2; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + Initializer initializer = Initializer(); + auto context = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED); + auto ctx = reinterpret_cast(context); + auto checker = reinterpret_cast(ctx->GetChecker()); + auto ast = ctx->parserProgram->Ast(); + auto id = ast->FindChild([](ark::es2panda::ir::AstNode *childNode) { + return childNode->IsIdentifier() && childNode->AsIdentifier()->Name() == "foo"; + }); + auto textChange = ark::es2panda::lsp::ProcessIdentifier(id->AsIdentifier(), checker, ctx->parserProgram); + const size_t expectedStart = 79; + ASSERT_EQ(textChange.has_value(), true); + ASSERT_EQ(textChange.value().newText, ": string | boolean | number | C"); + ASSERT_EQ(textChange.value().span.start, expectedStart); + ASSERT_EQ(textChange.value().span.length, 0); + + initializer.DestroyContext(context); +} + +TEST_F(LSPIsolatedDeclarationTests, IsolatedDeclaration2) +{ + std::vector files = {"IsolatedDeclaration2_export.ets", "IsolatedDeclaration2.ets"}; + std::vector texts = {R"(export const arr = [1, 2, 3]; +export const tuple = [1, "hello", true]; +)", + R"(import {arr, tuple} from './IsolatedDeclaration2_export'; +export function foo(n: number) { + if (n < 3) { + return n + 2; + } + if (n < 7) { + return arr; + } + return tuple; +} +)"}; + auto filePaths = CreateTempFile(files, texts); + const size_t expectedFileCount = 2; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + Initializer initializer = Initializer(); + auto context = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED); + auto ctx = reinterpret_cast(context); + auto checker = reinterpret_cast(ctx->GetChecker()); + auto ast = ctx->parserProgram->Ast(); + auto id = ast->FindChild([](ark::es2panda::ir::AstNode *childNode) { + return childNode->IsIdentifier() && childNode->AsIdentifier()->Name() == "foo"; + }); + auto textChange = ark::es2panda::lsp::ProcessIdentifier(id->AsIdentifier(), checker, ctx->parserProgram); + const size_t expectedStart = 88; + ASSERT_EQ(textChange.has_value(), true); + ASSERT_EQ(textChange.value().newText, ": [number, string, boolean] | number | number[]"); + ASSERT_EQ(textChange.value().span.start, expectedStart); + ASSERT_EQ(textChange.value().span.length, 0); + + initializer.DestroyContext(context); +} + +TEST_F(LSPIsolatedDeclarationTests, IsolatedDeclaration3) +{ + std::vector files = {"IsolatedDeclaration3_export.ets", "IsolatedDeclaration3.ets"}; + std::vector texts = {R"(export class C { + pro1: number = 123; + pro2: string = "hello"; + pro3: boolean = false; +} +)", + R"(import {C} from './IsolatedDeclaration3_export'; +export const foo = () => { + const c = new C(); + if (c.pro1 < 100) { + return c.pro1; + } + return c.pro2; +}; +)"}; + auto filePaths = CreateTempFile(files, texts); + const size_t expectedFileCount = 2; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + Initializer initializer = Initializer(); + auto context = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED); + auto ctx = reinterpret_cast(context); + auto checker = reinterpret_cast(ctx->GetChecker()); + auto ast = ctx->parserProgram->Ast(); + auto id = ast->FindChild([](ark::es2panda::ir::AstNode *childNode) { + return childNode->IsIdentifier() && childNode->AsIdentifier()->Name() == "foo"; + }); + auto textChange = ark::es2panda::lsp::ProcessIdentifier(id->AsIdentifier(), checker, ctx->parserProgram); + const size_t expectedStart = 70; + ASSERT_EQ(textChange.has_value(), true); + ASSERT_EQ(textChange.value().newText, ": number | string"); + ASSERT_EQ(textChange.value().span.start, expectedStart); + ASSERT_EQ(textChange.value().span.length, 0); + + initializer.DestroyContext(context); +} + +TEST_F(LSPIsolatedDeclarationTests, IsolatedDeclaration4) +{ + std::vector files = {"IsolatedDeclaration4_export.ets", "IsolatedDeclaration4.ets"}; + std::vector texts = {R"(export const arr = [1, 2, 3]; +export const tuple = [1, "hello", true]; +)", + R"(import {arr, tuple} from './IsolatedDeclaration4_export'; +export class A { + public foo(n: number) { + if (n < 3) { + return n + 2; + } + if (n < 7) { + return arr; + } + return tuple; + } +} +)"}; + auto filePaths = CreateTempFile(files, texts); + const size_t expectedFileCount = 2; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + Initializer initializer = Initializer(); + auto context = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED); + auto ctx = reinterpret_cast(context); + auto checker = reinterpret_cast(ctx->GetChecker()); + auto ast = ctx->parserProgram->Ast(); + auto id = ast->FindChild([](ark::es2panda::ir::AstNode *childNode) { + return childNode->IsIdentifier() && childNode->AsIdentifier()->Name() == "foo"; + }); + auto textChange = ark::es2panda::lsp::ProcessIdentifier(id->AsIdentifier(), checker, ctx->parserProgram); + const size_t expectedStart = 98; + ASSERT_EQ(textChange.has_value(), true); + ASSERT_EQ(textChange.value().newText, ": [number, string, boolean] | number | number[]"); + ASSERT_EQ(textChange.value().span.start, expectedStart); + ASSERT_EQ(textChange.value().span.length, 0); + + initializer.DestroyContext(context); +} + +TEST_F(LSPIsolatedDeclarationTests, IsolatedDeclaration5) +{ + std::vector files = {"IsolatedDeclaration5_export.ets", "IsolatedDeclaration5.ets"}; + std::vector texts = {R"(export const arr = [1, 2, 3]; +export const tuple = [1, "hello", true]; +)", + R"(import {arr, tuple} from './IsolatedDeclaration5_export'; +export class A { + public foo = (n: number) => { + if (n < 3) { + return n + 2; + } + if (n < 7) { + return arr; + } + return tuple; + } +} +)"}; + auto filePaths = CreateTempFile(files, texts); + const size_t expectedFileCount = 2; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + Initializer initializer = Initializer(); + auto context = initializer.CreateContext(filePaths[1].c_str(), ES2PANDA_STATE_CHECKED); + auto ctx = reinterpret_cast(context); + auto checker = reinterpret_cast(ctx->GetChecker()); + auto ast = ctx->parserProgram->Ast(); + auto id = ast->FindChild([](ark::es2panda::ir::AstNode *childNode) { + return childNode->IsIdentifier() && childNode->AsIdentifier()->Name() == "foo"; + }); + auto textChange = ark::es2panda::lsp::ProcessIdentifier(id->AsIdentifier(), checker, ctx->parserProgram); + const size_t expectedStart = 101; + ASSERT_EQ(textChange.has_value(), true); + ASSERT_EQ(textChange.value().newText, ": [number, string, boolean] | number | number[]"); + ASSERT_EQ(textChange.value().span.start, expectedStart); + ASSERT_EQ(textChange.value().span.length, 0); + + initializer.DestroyContext(context); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/keyword_completion_data_test.cpp b/ets2panda/test/unit/lsp/keyword_completion_data_test.cpp index 8d075c73b1f1276b268e17bf1d2065728e1c4664..98aeb6114f1b38c4e10f6304934a0b3e16d52087 100644 --- a/ets2panda/test/unit/lsp/keyword_completion_data_test.cpp +++ b/ets2panda/test/unit/lsp/keyword_completion_data_test.cpp @@ -19,6 +19,36 @@ class LspKeywordCompletionTests : public LSPAPITests {}; +static void AssertCompletionsContainAndNotContainEntries(const std::vector &entries, + const std::vector &expectedEntries, + const std::vector &unexpectedEntries) +{ + auto emptyCheck = expectedEntries.empty() && !entries.empty(); + ASSERT_FALSE(emptyCheck) << "Expected empty but the result is not. Actual account: " << entries.size(); + + for (const auto &expectedEntry : expectedEntries) { + bool found = false; + for (const auto &entry : entries) { + if (entry == expectedEntry) { + found = true; + break; + } + } + ASSERT_TRUE(found) << "Expected completion '" << expectedEntry << "' not found"; + } + + for (const auto &unexpectedEntry : unexpectedEntries) { + bool found = false; + for (const auto &entry : entries) { + if (entry == unexpectedEntry) { + found = true; + break; + } + } + ASSERT_FALSE(found) << "Unexpected completion '" << unexpectedEntry << "' found"; + } +} + TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithA) { std::string input = "a"; @@ -31,7 +61,7 @@ TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithA) actual.push_back(entry.GetName()); } - ASSERT_EQ(actual, expected); + AssertCompletionsContainAndNotContainEntries(actual, expected, {}); } TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithAs) { @@ -45,7 +75,7 @@ TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithAs) actual.push_back(entry.GetName()); } - ASSERT_EQ(actual, expected); + AssertCompletionsContainAndNotContainEntries(actual, expected, {}); } TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithAs2) { @@ -59,7 +89,7 @@ TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithAs2) actual.push_back(entry.GetName()); } - ASSERT_EQ(actual, expected); + AssertCompletionsContainAndNotContainEntries(actual, expected, {}); } TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithRe) { @@ -73,7 +103,7 @@ TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithRe) actual.push_back(entry.GetName()); } - ASSERT_EQ(actual, expected); + AssertCompletionsContainAndNotContainEntries(actual, expected, {}); } TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithRet) { @@ -87,7 +117,7 @@ TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithRet) actual.push_back(entry.GetName()); } - ASSERT_EQ(actual, expected); + AssertCompletionsContainAndNotContainEntries(actual, expected, {}); } TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithI) { @@ -103,7 +133,7 @@ TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithI) actual.push_back(entry.GetName()); } - ASSERT_EQ(actual, expected); + AssertCompletionsContainAndNotContainEntries(actual, expected, {}); } TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithInt) { @@ -117,7 +147,7 @@ TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsStartWithInt) actual.push_back(entry.GetName()); } - ASSERT_EQ(actual, expected); + AssertCompletionsContainAndNotContainEntries(actual, expected, {}); } TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsSensitiveStartWithT) { @@ -130,7 +160,7 @@ TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsSensitiveStartWithT) actual.push_back(entry.GetName()); } - ASSERT_EQ(actual, expected); + AssertCompletionsContainAndNotContainEntries(actual, expected, {}); } TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsSensitiveStartWithTy) { @@ -143,7 +173,7 @@ TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsSensitiveStartWithTy) actual.push_back(entry.GetName()); } - ASSERT_EQ(actual, expected); + AssertCompletionsContainAndNotContainEntries(actual, expected, {}); } TEST_F(LspKeywordCompletionTests, GetKeywordCompletionsInvalid) { diff --git a/ets2panda/test/unit/lsp/lsp_api_test.cpp b/ets2panda/test/unit/lsp/lsp_api_test.cpp deleted file mode 100644 index 7159d0f22666eef2251b3ecebe1d6af713176c6e..0000000000000000000000000000000000000000 --- a/ets2panda/test/unit/lsp/lsp_api_test.cpp +++ /dev/null @@ -1,670 +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. - */ - -#include "lsp_api_test.h" - -#include -#include - -#include "ir/astNode.h" -#include "lsp/include/internal_api.h" -#include "public/es2panda_lib.h" -#include "public/public.h" - -using ark::es2panda::lsp::Initializer; - -TEST_F(LSPAPITests, GetTouchingToken1) -{ - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("not-found-node.ets", ES2PANDA_STATE_CHECKED, - "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - size_t const offset = 50; - auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false); - ASSERT_EQ(result, nullptr); - - auto result1 = ark::es2panda::lsp::GetTouchingToken(ctx, offset, true); - ASSERT_EQ(result1, nullptr); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetTouchingToken2) -{ - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("nested-node.ets", ES2PANDA_STATE_CHECKED, - "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - size_t const offset = 51; - auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, false); - auto ast = GetAstFromContext(ctx); - auto expectedNode = ast->FindChild( - [](ark::es2panda::ir::AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "A"; }); - ASSERT_EQ(result->DumpJSON(), expectedNode->DumpJSON()); - ASSERT_EQ(result->Start().index, expectedNode->Start().index); - ASSERT_EQ(result->End().index, expectedNode->End().index); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetTouchingToken3) -{ - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("first-node.ets", ES2PANDA_STATE_CHECKED, - "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - size_t const offset = 51; - auto result = ark::es2panda::lsp::GetTouchingToken(ctx, offset, true); - auto ast = GetAstFromContext(ctx); - auto expectedNode = ast->FindChild([](ark::es2panda::ir::AstNode *node) { return node->IsExpressionStatement(); }); - ASSERT_EQ(result->DumpJSON(), expectedNode->DumpJSON()); - ASSERT_EQ(result->Start().index, expectedNode->Start().index); - ASSERT_EQ(result->End().index, expectedNode->End().index); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, DiagnosticConstructorAndField) -{ - int const errorCode = 404; - int const defaultCharacter = 10; - std::vector tags {}; - std::vector relatedInfoList {}; - Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message_); - - EXPECT_EQ(diagnostic.range_.start.line_, 1); - EXPECT_EQ(diagnostic.range_.end.character_, defaultCharacter); - EXPECT_EQ(diagnostic.message_, message_); - EXPECT_EQ(diagnostic.severity_, DiagnosticSeverity::Error); - EXPECT_EQ(std::get(diagnostic.code_), errorCode); -} - -TEST_F(LSPAPITests, DiagnosticCodeDescriptionOptional) -{ - CodeDescription codeDesc; - codeDesc.href_ = "http://example.com/error/404"; - int const errorCode = 404; - std::vector tags {}; - std::vector relatedInfoList {}; - - Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message_, codeDesc); - - const auto &codeDescription = diagnostic.codeDescription_; - EXPECT_EQ(codeDescription.href_, "http://example.com/error/404"); -} - -TEST_F(LSPAPITests, DiagnosticTagsAndRelatedInformation) -{ - std::vector tags {}; - tags.push_back(DiagnosticTag::Unnecessary); - std::vector relatedInfoList {}; - DiagnosticRelatedInformation relatedInfo; - relatedInfo.location_ = Location {"www.test.uri", range_}; - relatedInfo.message_ = "Related information message"; - relatedInfoList.push_back(relatedInfo); - int const errorCode = 200; - CodeDescription des = {}; - - Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Information, errorCode, message_, des, - "default"); - - const auto &diagnosticTags = diagnostic.tags_; - EXPECT_EQ(diagnosticTags.size(), 1); - EXPECT_EQ(diagnosticTags[0], DiagnosticTag::Unnecessary); - - const auto &relatedInformation = diagnostic.relatedInformation_; - EXPECT_EQ(relatedInformation.size(), 1); - EXPECT_EQ(relatedInformation[0].message_, "Related information message"); -} - -TEST_F(LSPAPITests, DiagnosticDataField) -{ - int const dataValue = 42; - std::variant data = dataValue; - int const errorCode = 400; - int const dataResult = 42; - std::vector tags {}; - std::vector relatedInfoList {}; - - Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message_, {}, {}, data); - - const auto &diagnosticData = diagnostic.data_; - EXPECT_EQ(std::get(diagnosticData), dataResult); -} - -TEST_F(LSPAPITests, CreateDiagnosticForNode1) -{ - using ark::es2panda::ir::AstNode; - using ark::es2panda::public_lib::Context; - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "function main() {}"); - auto astNode = GetAstFromContext(ctx); - int const dataValue = 42; - std::variant data = dataValue; - int const errorCode = 400; - std::string message = "Diagnostic"; - std::vector tags {}; - std::vector relatedInfoList {}; - - Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message, {}, {}, data); - FileDiagnostic result = ark::es2panda::lsp::CreateDiagnosticForNode(astNode, diagnostic); - - int const startLine = 0; - int const endLine = 0; - int const startChar = 0; - int const endChar = 18; - ASSERT_EQ(result.diagnostic.message_, "Diagnostic"); - ASSERT_EQ(result.diagnostic.range_.start.line_, startLine); - ASSERT_EQ(result.diagnostic.range_.end.line_, endLine); - ASSERT_EQ(result.diagnostic.range_.start.character_, startChar); - ASSERT_EQ(result.diagnostic.range_.end.character_, endChar); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, CreateDiagnosticForNode2) -{ - using ark::es2panda::ir::AstNode; - using ark::es2panda::public_lib::Context; - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "function main() {}"); - auto astNode = GetAstFromContext(ctx); - int const dataValue = 42; - std::variant data = dataValue; - int const errorCode = 400; - std::string message = "Diagnostic {0}, for the {1}, and {2}"; - std::vector args = {"Error1", "Error2", "Error3"}; - std::vector tags {}; - std::vector relatedInfoList {}; - - Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message, {}, {}, data); - FileDiagnostic result = ark::es2panda::lsp::CreateDiagnosticForNode(astNode, diagnostic, args); - - int const startLine = 0; - int const endLine = 0; - int const startChar = 0; - int const endChar = 18; - ASSERT_EQ(result.diagnostic.message_, "Diagnostic Error1, for the Error2, and Error3"); - ASSERT_EQ(result.diagnostic.range_.start.line_, startLine); - ASSERT_EQ(result.diagnostic.range_.end.line_, endLine); - ASSERT_EQ(result.diagnostic.range_.start.character_, startChar); - ASSERT_EQ(result.diagnostic.range_.end.character_, endChar); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, CreateDiagnosticForNode3) -{ - using ark::es2panda::ir::AstNode; - using ark::es2panda::public_lib::Context; - Initializer initializer = Initializer(); - es2panda_Context *ctx = - initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "let a = () => {\n return 1;\n}"); - auto astNode = reinterpret_cast(GetAstFromContext(ctx)); - astNode = astNode->FindChild([](ark::es2panda::ir::AstNode *child) { return child->IsArrowFunctionExpression(); }); - int const dataValue = 42; - std::variant data = dataValue; - int const errorCode = 400; - std::string message = "Diagnostic {0}, for the {1}, and {2}"; - std::vector args = {"Error1", "Error2", "Error3"}; - std::vector tags {}; - std::vector relatedInfoList {}; - - Diagnostic diagnostic(range_, tags, relatedInfoList, DiagnosticSeverity::Error, errorCode, message, {}, {}, data); - FileDiagnostic result = - ark::es2panda::lsp::CreateDiagnosticForNode(reinterpret_cast(astNode), diagnostic, args); - - int const startLine = 0; - int const endLine = 2; - int const startChar = 12; - int const endChar = 33; - ASSERT_EQ(result.diagnostic.message_, "Diagnostic Error1, for the Error2, and Error3"); - ASSERT_EQ(result.diagnostic.range_.start.line_, startLine); - ASSERT_EQ(result.diagnostic.range_.end.line_, endLine); - ASSERT_EQ(result.diagnostic.range_.start.character_, startChar); - ASSERT_EQ(result.diagnostic.range_.end.character_, endChar); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetFileReferencesImpl1) -{ - using ark::es2panda::public_lib::Context; - std::vector files = {"lsp_api_test_export_1.ets", "lsp_api_test_file_1.ets"}; - std::vector texts = { - R"(export function A(a:number, b:number): number { - return a + b; -} -export function B(a:number, b:number): number { - return a + b; -})", - R"(import {A} from "./lsp_api_test_export_1"; -import {B} from "./lsp_api_test_export_1.ets"; -A(1, 2); -B(1, 2);)"}; - auto filePaths = CreateTempFile(files, texts); - int const expectedFileCount = 2; - ASSERT_EQ(filePaths.size(), expectedFileCount); - - char const *searchFileName = filePaths[0].c_str(); - char const *referenceFileName = filePaths[1].c_str(); - Initializer initializer = Initializer(); - auto ctx = initializer.CreateContext(searchFileName, ES2PANDA_STATE_CHECKED); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - - auto isPackageModule = reinterpret_cast(ctx)->parserProgram->IsPackage(); - ASSERT_FALSE(isPackageModule); - initializer.DestroyContext(ctx); - - auto ctx1 = initializer.CreateContext(referenceFileName, ES2PANDA_STATE_CHECKED); - ASSERT_EQ(ContextState(ctx1), ES2PANDA_STATE_CHECKED); - - auto result = References(); - result = ark::es2panda::lsp::GetFileReferencesImpl(ctx1, searchFileName, isPackageModule); - auto expectedFileName1 = filePaths[1]; - size_t const expectedStartPos1 = 16; - size_t const expectedLength1 = 25; - auto expectedFileName2 = filePaths[1]; - size_t const expectedStartPos2 = 59; - size_t const expectedLength2 = 29; - ASSERT_EQ(result.referenceInfos.at(0).fileName, expectedFileName1); - ASSERT_EQ(result.referenceInfos.at(0).start, expectedStartPos1); - ASSERT_EQ(result.referenceInfos.at(0).length, expectedLength1); - ASSERT_EQ(result.referenceInfos.at(1).fileName, expectedFileName2); - ASSERT_EQ(result.referenceInfos.at(1).start, expectedStartPos2); - ASSERT_EQ(result.referenceInfos.at(1).length, expectedLength2); - initializer.DestroyContext(ctx1); -} - -TEST_F(LSPAPITests, GetFileReferencesImpl2) -{ - using ark::es2panda::public_lib::Context; - std::vector files = {"lsp_api_test_export_2.ts", "lsp_api_test_file_2.ets"}; - std::vector texts = { - R"(export function A(a:number, b:number): number { - return a + b; -} -export function B(a:number, b:number): number { - return a + b; -})", - R"(import {A} from "./lsp_api_test_export_2"; -import {B} from "./lsp_api_test_export_2.ts"; -A(1, 2); -B(1, 2);)"}; - auto filePaths = CreateTempFile(files, texts); - int const expectedFileCount = 2; - ASSERT_EQ(filePaths.size(), expectedFileCount); - - char const *searchFileName = filePaths[0].c_str(); - char const *referenceFileName = filePaths[1].c_str(); - Initializer initializer = Initializer(); - auto ctx = initializer.CreateContext(searchFileName, ES2PANDA_STATE_CHECKED); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - - auto isPackageModule = reinterpret_cast(ctx)->parserProgram->IsPackage(); - ASSERT_FALSE(isPackageModule); - initializer.DestroyContext(ctx); - - auto ctx1 = initializer.CreateContext(referenceFileName, ES2PANDA_STATE_CHECKED); - ASSERT_EQ(ContextState(ctx1), ES2PANDA_STATE_CHECKED); - - auto result = References(); - result = ark::es2panda::lsp::GetFileReferencesImpl(ctx1, searchFileName, isPackageModule); - auto expectedFileName1 = filePaths[1]; - size_t const expectedStartPos1 = 16; - size_t const expectedLength1 = 25; - auto expectedFileName2 = filePaths[1]; - size_t const expectedStartPos2 = 59; - size_t const expectedLength2 = 28; - ASSERT_EQ(result.referenceInfos.at(0).fileName, expectedFileName1); - ASSERT_EQ(result.referenceInfos.at(0).start, expectedStartPos1); - ASSERT_EQ(result.referenceInfos.at(0).length, expectedLength1); - ASSERT_EQ(result.referenceInfos.at(1).fileName, expectedFileName2); - ASSERT_EQ(result.referenceInfos.at(1).start, expectedStartPos2); - ASSERT_EQ(result.referenceInfos.at(1).length, expectedLength2); - initializer.DestroyContext(ctx1); -} - -TEST_F(LSPAPITests, GetFileReferencesImpl3) -{ - using ark::es2panda::public_lib::Context; - std::vector files = {"package-module.ets"}; - std::vector texts = {R"(import { PI } from "std/math"; -console.log(PI);)"}; - auto filePaths = CreateTempFile(files, texts); - int const expectedFileCount = 1; - ASSERT_EQ(filePaths.size(), expectedFileCount); - - char const *referenceFileName = filePaths[0].c_str(); - Initializer initializer = Initializer(); - auto ctx = initializer.CreateContext(referenceFileName, ES2PANDA_STATE_CHECKED); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - - auto baseUrl = reinterpret_cast(ctx)->config->options->ArkTSConfig()->BaseUrl(); - auto searchFileName = baseUrl + "/plugins/ets/stdlib/std/math/math.ets"; - auto result = References(); - result = ark::es2panda::lsp::GetFileReferencesImpl(ctx, searchFileName.c_str(), true); - auto expectedFileName = filePaths[0]; - size_t const expectedStartPos = 19; - size_t const expectedLength = 10; - - ASSERT_EQ(result.referenceInfos.at(0).fileName, expectedFileName); - ASSERT_EQ(result.referenceInfos.at(0).start, expectedStartPos); - ASSERT_EQ(result.referenceInfos.at(0).length, expectedLength); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetPrecedingToken1) -{ - using ark::es2panda::ir::AstNode; - - LSPAPI const *lspApi = GetImpl(); - Initializer initializer = Initializer(); - es2panda_Context *context = initializer.CreateContext( - - "precedingtoken_literal.ets", ES2PANDA_STATE_CHECKED, - "let number_literal: number = 1234;\nlet string_literal: string = \"hello\";\nconst str_property = " - "\"foo\";\n"); - ASSERT_EQ(ContextState(context), ES2PANDA_STATE_CHECKED); - auto ast = GetAstFromContext(context); - - size_t const numberLiteralOffset = 31; // 31: position of '3' in '1234' - size_t const stringLiteralOffset = 96; // 96: position of first 'o' in 'foo' - auto numberLiteral = ast->FindChild([](AstNode *node) { return node->IsExpressionStatement(); }) - ->AsExpressionStatement() - ->GetExpression() - ->AsAssignmentExpression() - ->Right() - ->AsNumberLiteral(); - auto result = reinterpret_cast(lspApi->getPrecedingToken(context, numberLiteralOffset)); - ASSERT_EQ(result->DumpJSON(), numberLiteral->DumpJSON()); - ASSERT_EQ(result->Start().index, numberLiteral->Start().index); - ASSERT_EQ(result->End().index, numberLiteral->End().index); - auto stringLiteral = ast->FindChild( - [](AstNode *node) { return node->IsStringLiteral() && node->AsStringLiteral()->ToString() == "foo"; }); - result = reinterpret_cast(lspApi->getPrecedingToken(context, stringLiteralOffset)); - ASSERT_EQ(result->DumpJSON(), stringLiteral->DumpJSON()); - ASSERT_EQ(result->Start().index, stringLiteral->Start().index); - ASSERT_EQ(result->End().index, stringLiteral->End().index); - initializer.DestroyContext(context); -} - -TEST_F(LSPAPITests, GetPrecedingToken2) -{ - using ark::es2panda::ir::AstNode; - - LSPAPI const *lspApi = GetImpl(); - Initializer initializer = Initializer(); - es2panda_Context *context = initializer.CreateContext( - "precedingtoken_function.ets", ES2PANDA_STATE_CHECKED, - " \n\n\n\nfunction f() {\n le\n let a = 123;\n}\n\n\n\nconst s = \"hello\";\n\n\n"); - auto ast = GetAstFromContext(context); - - size_t const startOfFile = 0; // 0: position of start of file - size_t const secondSpaceBeforeLe = 25; // 25: position of second space before 'le' - size_t const endOfLe = 29; // 29: position of the end of 'le' identifier - size_t const secondSpaceBeforeLet = 32; // 32: position of second space before 'let' - size_t const startOfLine10 = 50; // 50: position of start of line 10 - size_t const startOfLine14 = 72; // 72: position of start of line 14 - ASSERT_EQ(lspApi->getPrecedingToken(context, startOfFile), nullptr); - ASSERT_EQ(lspApi->getPrecedingToken(context, secondSpaceBeforeLe), nullptr); - auto leIdentifier = - ast->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "le"; }); - auto result = reinterpret_cast(lspApi->getPrecedingToken(context, endOfLe)); - ASSERT_EQ(result->DumpJSON(), leIdentifier->DumpJSON()); - ASSERT_EQ(result->Start().index, leIdentifier->Start().index); - ASSERT_EQ(result->End().index, leIdentifier->End().index); - result = reinterpret_cast(lspApi->getPrecedingToken(context, secondSpaceBeforeLet)); - ASSERT_EQ(result->DumpJSON(), leIdentifier->DumpJSON()); - ASSERT_EQ(result->Start().index, leIdentifier->Start().index); - ASSERT_EQ(result->End().index, leIdentifier->End().index); - auto numberLiteral = ast->FindChild( - [](AstNode *node) { return node->IsNumberLiteral() && node->AsNumberLiteral()->Str() == "123"; }); - result = reinterpret_cast(lspApi->getPrecedingToken(context, startOfLine10)); - ASSERT_EQ(result->DumpJSON(), numberLiteral->DumpJSON()); - ASSERT_EQ(result->Start().index, numberLiteral->Start().index); - ASSERT_EQ(result->End().index, numberLiteral->End().index); - auto stringLiteral = ast->FindChild([](AstNode *node) { return node->IsClassProperty(); }) - ->AsClassProperty() - ->Value() - ->AsStringLiteral(); - result = reinterpret_cast(lspApi->getPrecedingToken(context, startOfLine14)); - ASSERT_EQ(result->DumpJSON(), stringLiteral->DumpJSON()); - ASSERT_EQ(result->Start().index, stringLiteral->Start().index); - ASSERT_EQ(result->End().index, stringLiteral->End().index); - initializer.DestroyContext(context); -} - -TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation1) -{ - using ark::es2panda::ir::AstNode; - using ark::es2panda::public_lib::Context; - Initializer initializer = Initializer(); - es2panda_Context *ctx = - initializer.CreateContext("types.ets", ES2PANDA_STATE_CHECKED, - "let a: number;\nlet b: byte;\nlet c: short;\nlet d: int;\nlet e: long;\nlet f: " - "float;\nlet g: double;\nlet h: char;\nlet i: boolean;"); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - - auto checker = reinterpret_cast(ctx)->checker->AsETSChecker(); - auto astNode = GetAstFromContext(ctx); - auto targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "a"; }); - auto type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsDoubleType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "b"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsByteType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "c"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsShortType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "d"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsIntType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "e"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsLongType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "f"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsFloatType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "g"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsDoubleType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "h"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsCharType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "i"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSBooleanType()); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation2) -{ - using ark::es2panda::ir::AstNode; - using ark::es2panda::public_lib::Context; - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext( - "types.ets", ES2PANDA_STATE_CHECKED, - "let j: object;\nlet k: string;\nlet l: [];\nlet m: bigint;\nlet n: never;\nlet o: null;\nlet p: " - "undefined;\nlet tuple: [number, number] = [1, 2];\nlet union: int | null;"); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - - auto checker = reinterpret_cast(ctx)->checker->AsETSChecker(); - auto astNode = GetAstFromContext(ctx); - auto targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "j"; }); - auto type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSObjectType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "k"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSStringType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "l"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSTupleType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "m"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSBigIntType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "n"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSNeverType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "o"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSNullType()); - - targetNode = - astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "p"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSUndefinedType()); - - targetNode = astNode->FindChild( - [](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "tuple"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSTupleType()); - - targetNode = astNode->FindChild( - [](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "union"; }); - type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSUnionType()); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetCurrentTokenValue) -{ - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("current_token.ets", ES2PANDA_STATE_CHECKED, "ab"); - LSPAPI const *lspApi = GetImpl(); - size_t offset = 2; - std::string result = lspApi->getCurrentTokenValue(ctx, offset); - initializer.DestroyContext(ctx); - ASSERT_EQ(result, "ab"); -} - -TEST_F(LSPAPITests, GetCurrentTokenValue1) -{ - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "\"ab\""); - size_t offset = 3; - std::string result = ark::es2panda::lsp::GetCurrentTokenValueImpl(ctx, offset); - std::string expect = "ab"; - ASSERT_EQ(result, expect); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetCurrentTokenValue2) -{ - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "\'ab\'"); - size_t offset = 3; - std::string result = ark::es2panda::lsp::GetCurrentTokenValueImpl(ctx, offset); - std::string expect = "ab"; - ASSERT_EQ(result, expect); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetCurrentTokenValue3) -{ - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("file1.ets", ES2PANDA_STATE_CHECKED, "abc"); - size_t offset = 2; - std::string result = ark::es2panda::lsp::GetCurrentTokenValueImpl(ctx, offset); - std::string expect = "ab"; - ASSERT_EQ(result, expect); - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetTokenPosOfNode1) -{ - using ark::es2panda::ir::AstNode; - - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("token-pos-identifier.ets", ES2PANDA_STATE_CHECKED, - "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - - auto ast = GetAstFromContext(ctx); - auto targetNode = - ast->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "A"; }); - - ASSERT_NE(targetNode, nullptr); - auto result = ark::es2panda::lsp::GetTokenPosOfNode(targetNode); - size_t const pos = 51; - ASSERT_EQ(result, pos); - - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetTokenPosOfNode2) -{ - using ark::es2panda::ir::AstNode; - - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext("token-pos-expression.ets", ES2PANDA_STATE_CHECKED, - "function A(a:number, b:number) {\n return a + b;\n}\nA(1, 2);"); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - - auto ast = GetAstFromContext(ctx); - auto targetNode = ast->FindChild([](AstNode *node) { return node->IsExpressionStatement(); }); - - ASSERT_NE(targetNode, nullptr); - auto result = ark::es2panda::lsp::GetTokenPosOfNode(targetNode); - size_t const pos = 51; - ASSERT_EQ(result, pos); - - initializer.DestroyContext(ctx); -} - -TEST_F(LSPAPITests, GetTokenPosOfNode3) -{ - using ark::es2panda::ir::AstNode; - - Initializer initializer = Initializer(); - es2panda_Context *ctx = initializer.CreateContext( - "token-pos-literal.ets", ES2PANDA_STATE_CHECKED, - "let number_literal: number = 1234;\nlet string_literal: string = \"hello\";\nconst str_property = " - "\"foo\";\n"); - ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); - - auto ast = GetAstFromContext(ctx); - auto targetNode = ast->FindChild( - [](AstNode *node) { return node->IsNumberLiteral() && node->AsNumberLiteral()->Str() == "1234"; }); - - ASSERT_NE(targetNode, nullptr); - auto result = ark::es2panda::lsp::GetTokenPosOfNode(targetNode); - size_t const pos = 29; - ASSERT_EQ(result, pos); - - initializer.DestroyContext(ctx); -} diff --git a/ets2panda/test/unit/lsp/lsp_rename_test.cpp b/ets2panda/test/unit/lsp/lsp_rename_test.cpp index ea1af27659e22815bacc7be14489e5eb31b38aca..39ad9d38870fac53c5e9301794ffaf4090bc5902 100644 --- a/ets2panda/test/unit/lsp/lsp_rename_test.cpp +++ b/ets2panda/test/unit/lsp/lsp_rename_test.cpp @@ -441,7 +441,7 @@ TEST_F(LspRenameInfoTests, RenameInfoGetRenameInfoForNode1) ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); auto ast = GetAstFromContext(ctx); - auto checker = reinterpret_cast(ctx)->checker->AsETSChecker(); + auto checker = reinterpret_cast(ctx)->GetChecker()->AsETSChecker(); auto program = reinterpret_cast(ctx)->parserProgram; auto targetNode = ast->FindChild([](ark::es2panda::ir::AstNode *node) { diff --git a/ets2panda/test/unit/lsp/navigate_to_test.cpp b/ets2panda/test/unit/lsp/navigate_to_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46a69f87a7fa0fcfdb66d625f392e6ae501fb3ac --- /dev/null +++ b/ets2panda/test/unit/lsp/navigate_to_test.cpp @@ -0,0 +1,478 @@ +/** + * 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 +#include "lsp_api_test.h" +#include "lsp/include/navigate_to.h" + +namespace { + +using ark::es2panda::SourceFile; +using ark::es2panda::lsp::GetNavigateToItems; +using ark::es2panda::lsp::Initializer; +using std::string; +using std::vector; + +class NavigateToTest : public LSPAPITests {}; + +TEST_F(NavigateToTest, EmptySourceFiles) +{ + std::vector srcFiles; + Initializer initializer; + std::vector allResults; + const int maxResultCount = 10; + std::string searchTerm = "foo"; + + for (const auto &file : srcFiles) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto results = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false); + allResults.insert(allResults.end(), results.begin(), results.end()); + } + ASSERT_TRUE(allResults.empty()); +} + +TEST_F(NavigateToTest, ExactMatchFromSingleFile) +{ + std::vector files = {{"exatchMatch.sts", R"( + class Test { + yeke: number = 2; + method() { + let b = 3; + return b; + } + } + )"}}; + Initializer initializer; + std::vector allResults; + const int maxResultCount = 10; + const int expectedResultSize = 1; + std::string searchTerm = "yeke"; + std::string containerName = "Test"; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto results = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false); + allResults.insert(allResults.end(), results.begin(), results.end()); + } + + ASSERT_EQ(allResults.size(), expectedResultSize); + ASSERT_EQ(allResults[0].name, searchTerm); + ASSERT_EQ(allResults[0].matchKind, ark::es2panda::lsp::MatchKind::EXACT); + ASSERT_EQ(allResults[0].containerName, containerName); +} + +TEST_F(NavigateToTest, ExactPrefixAndSubstringMatch) +{ + std::vector files = {{"ExactPrefixAndSubstringMatch1.sts", R"( + function foo() { + let a = 1; + return a; + } + )"}, + {"ExactPrefixAndSubstringMatch2.sts", R"( + function foobar() { + let b = 2; + return b; + } + )"}, + {"ExactPrefixAndSubstringMatch3.sts", R"( + function my_foo() { + let c = 3; + return c; + } + )"}}; + Initializer initializer; + std::vector allResults; + const int maxResultCount = 10; + const int expectedResultSize = 3; + std::string searchTerm = "foo"; + const int thirdValueOfArray = 2; + std::string searchTermFoobar = "foobar"; + std::string searchTermMyFoo = "my_foo"; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto results = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false); + allResults.insert(allResults.end(), results.begin(), results.end()); + + initializer.DestroyContext(ctx); + } + ASSERT_EQ(allResults.size(), expectedResultSize); // "foo", "foobar", "my_foo" + ASSERT_EQ(allResults[0].name, searchTerm); + ASSERT_EQ(allResults[0].matchKind, ark::es2panda::lsp::MatchKind::EXACT); + ASSERT_EQ(allResults[1].name, searchTermFoobar); + ASSERT_EQ(allResults[1].matchKind, ark::es2panda::lsp::MatchKind::PREFIX); + ASSERT_EQ(allResults[thirdValueOfArray].name, searchTermMyFoo); + ASSERT_EQ(allResults[thirdValueOfArray].matchKind, ark::es2panda::lsp::MatchKind::SUBSTRING); +} + +TEST_F(NavigateToTest, CaseInsensitiveMatch) +{ + std::vector files = {{"caseInsensitiveMatch1.sts", R"( + function foo() { + let a = 1; + return a; + } + )"}, + {"caseInsensitiveMatch2.sts", R"( + function foobar() { + let b = 2; + return b; + } + )"}, + {"caseInsensitiveMatch3.sts", R"( + function my_foo() { + let c = 3; + return c; + } + )"}}; + Initializer initializer; + std::vector allResults; + const int maxResultCount = 10; + const int expectedResultSize = 3; + std::string searchTerm = "FOO"; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto results = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false); // case-insensitive + allResults.insert(allResults.end(), results.begin(), results.end()); + + initializer.DestroyContext(ctx); + } + ASSERT_EQ(allResults.size(), expectedResultSize); +} + +TEST_F(NavigateToTest, CaseSensitiveMismatch) +{ + std::vector files = {{"caseSensitiveMismatch1.sts", R"( + function foo() { + let a = 1; + return a; + } + )"}, + {"caseSensitiveMismatch2.sts", R"( + function foobar() { + let b = 2; + return b; + } + )"}, + {"caseSensitiveMismatch3.sts", R"( + function my_foo() { + let c = 3; + return c; + } + )"}}; + Initializer initializer; + std::vector allResults; + const int maxResultCount = 10; + std::string searchTerm = "FOO"; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto results = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, true); // case-sensitive + allResults.insert(allResults.end(), results.begin(), results.end()); + + initializer.DestroyContext(ctx); + } + ASSERT_TRUE(allResults.empty()); +} + +TEST_F(NavigateToTest, NoMatchFound) +{ + std::vector files = {{"noMatchFound1.sts", R"( + function foo() { + let a = 1; + return a; + } + )"}, + {"noMatchFound2.sts", R"( + function foobar() { + let b = 2; + return b; + } + )"}, + {"noMatchFound3.sts", R"( + function my_foo() { + let c = 3; + return c; + } + )"}}; + Initializer initializer; + std::vector allResults; + const int maxResultCount = 10; + std::string searchTerm = "nonexistent"; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto results = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false); + allResults.insert(allResults.end(), results.begin(), results.end()); + + initializer.DestroyContext(ctx); + } + ASSERT_TRUE(allResults.empty()); +} + +TEST_F(NavigateToTest, MatchLimitRespected) +{ + std::vector files = {{"matchLimitRespected1.sts", R"( + function foo() { + let a = 1; + return a; + } + )"}, + {"matchLimitRespected2.sts", R"( + function foobar() { + let b = 2; + return b; + } + )"}, + {"matchLimitRespected3.sts", R"( + function my_foo() { + let c = 3; + return c; + } + )"}}; + const int maxResultCountTwo = 2; + const int expectedResultSize = 2; + std::string searchTerm = "foo"; + + Initializer initializer; + std::vector allResults; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto matches = GetNavigateToItems(ctx, singleFile, maxResultCountTwo, searchTerm, false); + allResults.insert(allResults.end(), matches.begin(), matches.end()); + + initializer.DestroyContext(ctx); + } + + ASSERT_LE(allResults.size(), expectedResultSize); +} + +TEST_F(NavigateToTest, MultiFileSubstringMatch) +{ + std::vector files = {{"multiFileSubstringMatch1.sts", R"( + function foo() { + let a = 1; + return a; + } + )"}, + {"multiFileSubstringMatch2.sts", R"( + function foobar() { + let b = 2; + return b; + } + )"}, + {"multiFileSubstringMatch3.sts", R"( + function my_foo() { + let c = 3; + return c; + } + )"}}; + Initializer initializer; + const int maxResultCount = 10; + size_t totalMatches = 0; + std::string searchTerm = "_foo"; + const int expectedResultSize = 1; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto matches = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false); + totalMatches += matches.size(); + + initializer.DestroyContext(ctx); + } + + ASSERT_EQ(totalMatches, expectedResultSize); +} + +TEST_F(NavigateToTest, PrefixMatchOnly) +{ + std::vector files = {{"prefixMatchOnly1.sts", R"( + function foo() { + let a = 1; + return a; + } + )"}, + {"prefixMatchOnly2.sts", R"( + function foobar() { + let b = 2; + return b; + } + )"}, + {"prefixMatchOnly3.sts", R"( + function my_foo() { + let c = 3; + return c; + } + )"}}; + Initializer initializer; + const int maxResultCount = 10; + size_t prefixCount = 0; + const int expectedResultSize = 1; + std::string searchTerm = "foo"; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto matches = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false); + for (const auto &match : matches) { + if (match.matchKind == ark::es2panda::lsp::MatchKind::PREFIX) { + ++prefixCount; + } + } + + initializer.DestroyContext(ctx); + } + + ASSERT_EQ(prefixCount, expectedResultSize); // Only "foobar" is a PREFIX of "foo" +} + +TEST_F(NavigateToTest, MatchFromSecondFile) +{ + std::vector files = {{"matchFromSecondFile1.sts", R"( + function foo() { + let a = 1; + return a; + } + )"}, + {"matchFromSecondFile2.sts", R"( + function foobar() { + let b = 2; + return b; + } + )"}, + {"matchFromSecondFile3.sts", R"( + function my_foo() { + let c = 3; + return c; + } + )"}}; + Initializer initializer; + const int maxResultCount = 10; + const int expectedResultSize = 1; + std::string searchTerm = "foobar"; + std::vector matches; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto results = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false); + matches.insert(matches.end(), results.begin(), results.end()); + + initializer.DestroyContext(ctx); + } + ASSERT_EQ(matches.size(), expectedResultSize); + ASSERT_EQ(matches[0].name, searchTerm); +} + +TEST_F(NavigateToTest, MatchOnClassMember) +{ + std::vector files = {{"matchOnClassMember1.sts", R"( + class Test { + yeke: number = 2; + method() { + let b = 3; + return b; + } + } + )"}, + {"matchOnClassMember2.sts", R"( + function foobar() { + let b = 2; + return b; + } + )"}, + {"matchOnClassMember3.sts", R"( + function my_foo() { + let c = 3; + return c; + } + )"}}; + Initializer initializer; + const int maxResultCount = 10; + const int expectedResultSize = 1; + std::string searchTerm = "yeke"; + std::string containerName = "Test"; + std::vector results; + + for (const auto &file : files) { + std::string sourceStr(file.source); + es2panda_Context *ctx = + initializer.CreateContext(file.filePath.data(), ES2PANDA_STATE_CHECKED, sourceStr.c_str()); + ASSERT_NE(ctx, nullptr); + + std::vector singleFile = {{file.filePath, sourceStr}}; + auto items = GetNavigateToItems(ctx, singleFile, maxResultCount, searchTerm, false); + results.insert(results.end(), items.begin(), items.end()); + + initializer.DestroyContext(ctx); + } + + ASSERT_EQ(results.size(), expectedResultSize); + ASSERT_EQ(results[0].name, searchTerm); + ASSERT_EQ(results[0].containerName, containerName); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/organize_imports_test.cpp b/ets2panda/test/unit/lsp/organize_imports_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..573c3dc35b3be0e08e7fc924a38f0646b8637089 --- /dev/null +++ b/ets2panda/test/unit/lsp/organize_imports_test.cpp @@ -0,0 +1,168 @@ +/** + * 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 +#include "lsp/include/organize_imports.h" +#include "lsp/include/api.h" +#include "lsp/include/internal_api.h" +#include "test/unit/lsp/lsp_api_test.h" + +namespace { +using ark::es2panda::lsp::Initializer; +using ark::es2panda::lsp::OrganizeImports; +} // namespace + +class OrganizeImportsTest : public LSPAPITests {}; + +TEST_F(OrganizeImportsTest, NormalImports) +{ + std::vector files = {"normal-imports-test.ets", "mod1/organize-imports-1.ets", + "mod2/organize-imports-2.ets"}; + std::vector texts = { + R"( + import {B, C} from "./mod1/organize-imports-1"; + import { X } from "./mod2/organize-imports-2"; + const a = B; + )", + R"(const A = 1; export default A; export const B = 2; export const C = 3;)", R"(export const X = 1;)"}; + auto filePaths = CreateTempFile(files, texts); + + Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + std::vector changes = OrganizeImports::Organize(ctx, filePaths[0]); + + ASSERT_EQ(changes.size(), 1); + ASSERT_EQ(changes[0].textChanges.size(), 1); + + std::string result = changes[0].textChanges[0].newText; + + EXPECT_TRUE(result.find("import { X } from \"./mod2/organize-imports-2\";") == std::string::npos); + EXPECT_TRUE(result.find("import { B } from \"./mod1/organize-imports-1\";") != std::string::npos); + + initializer.DestroyContext(ctx); +} + +TEST_F(OrganizeImportsTest, TypeOnlyImports) +{ + std::vector files = {"typeonly-imports-test.ets", "mod1/typeonly-index.ets"}; + std::vector texts = { + R"( + import type { T } from "./mod1/typeonly-index"; + import type {T as T1} from "./mod1/typeonly-index"; + import type {T as T2} from "./mod1/typeonly-index"; + let t: T1; + function foo(arg: T2) {}; + )", + R"(export type T = string;)"}; + + auto filePaths = CreateTempFile(files, texts); + Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + std::vector changes = OrganizeImports::Organize(ctx, filePaths[0]); + + ASSERT_EQ(changes.size(), 1); + + std::string result = changes[0].textChanges[0].newText; + + EXPECT_TRUE(result.find("import type { T } from \"./mod1/typeonly-index\";") == std::string::npos); + EXPECT_TRUE(result.find("import type { T as T1 } from \"./mod1/typeonly-index\";") != std::string::npos); + EXPECT_TRUE(result.find("import type { T as T2 } from \"./mod1/typeonly-index\";") != std::string::npos); + + initializer.DestroyContext(ctx); +} + +TEST_F(OrganizeImportsTest, NamespaceImports) +{ + std::vector files = {"namespace-imports-test.ets", "mod1/namespace-imports-index.ets"}; + std::vector texts = { + R"( + import * as NS1 from "./mod1/namespace-imports-index"; + import * as NS2 from "./mod1/namespace-imports-index"; + const b = NS1.color.red; + )", + R"(export const A = 1; export const B = 2;export enum color{red, blue, yellow};)"}; + auto filePaths = CreateTempFile(files, texts); + + Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + std::vector changes = OrganizeImports::Organize(ctx, filePaths[0]); + + ASSERT_EQ(changes.size(), 1); + + std::string result = changes[0].textChanges[0].newText; + + EXPECT_TRUE(result.find("import * as NS1 from \"./mod1/namespace-imports-index\";") != std::string::npos); + EXPECT_TRUE(result.find("import * as NS2 from \"./mod1/namespace-imports-index\";") == std::string::npos); + + initializer.DestroyContext(ctx); +} + +TEST_F(OrganizeImportsTest, AliasImports) +{ + std::vector files = {"alias-imports-test.ets", "mod1/alias-imports-index.ets"}; + std::vector texts = { + R"( + import {B as B1, C} from "./mod1/alias-imports-index"; + import { B as B2 } from "./mod1/alias-imports-index"; + const b = B1; + )", + R"(export const B = 2; export const C = 3;)"}; + + auto filePaths = CreateTempFile(files, texts); + Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + std::vector changes = OrganizeImports::Organize(ctx, filePaths[0]); + + ASSERT_EQ(changes.size(), 1); + + std::string result = changes[0].textChanges[0].newText; + + EXPECT_TRUE(result.find("import { B as B1 } from \"./mod1/alias-imports-index\"") != std::string::npos); + EXPECT_TRUE(result.find("import { B as B2 } from \"./mod1/alias-imports-index\"") == std::string::npos); + + initializer.DestroyContext(ctx); +} + +TEST_F(OrganizeImportsTest, DefaultImports) +{ + std::vector files = {"default-imports-test.ets", "mod1/default-imports-index.ets"}; + std::vector texts = { + R"( + import B from "./mod1/default-imports-index"; + import {C as C1} from "./mod1/default-imports-index"; + const b = B; + const c = C1; + )", + R"(export default const B = 2; export const C = 3;)"}; + + auto filePaths = CreateTempFile(files, texts); + Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + + std::vector changes = OrganizeImports::Organize(ctx, filePaths[0]); + + ASSERT_EQ(changes.size(), 1); + + std::string result = changes[0].textChanges[0].newText; + + EXPECT_TRUE(result.find("import B from \"./mod1/default-imports-index\"") != std::string::npos); + EXPECT_TRUE(result.find("import { C as C1 } from \"./mod1/default-imports-index\"") != std::string::npos); + + initializer.DestroyContext(ctx); +} diff --git a/ets2panda/test/unit/lsp/refactors_convert_function_test.cpp b/ets2panda/test/unit/lsp/refactors_convert_function_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2688b3b2c5605f574b5afb34393d4f0a1177651c --- /dev/null +++ b/ets2panda/test/unit/lsp/refactors_convert_function_test.cpp @@ -0,0 +1,87 @@ +/** + * 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 +#include +#include +#include "lsp_api_test.h" + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetRefTests : public LSPAPITests { +public: + static constexpr std::string_view TO_NAMED_FUNCTION_KIND = "refactor.rewrite.function.named"; + static constexpr std::string_view INVALID_KIND = "aaabbbccc"; + static constexpr std::string_view TO_NAMED_FUNCTION_NAME = "Convert to named function"; +}; + +TEST_F(LspGetRefTests, ConvertFunctionRefactor1) +{ + std::vector files = {"convertFunctionRefactor1.ets"}; + std::vector texts = {R"(const add = (x: number, y: number): number => { + return x + y; + };)"}; + auto filePaths = CreateTempFile(files, texts); + size_t const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const position = 8; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto result = lspApi->getApplicableRefactors(ctx, std::string(TO_NAMED_FUNCTION_KIND).c_str(), position); + initializer.DestroyContext(ctx); + ASSERT_EQ(std::string(TO_NAMED_FUNCTION_NAME), result.action.name); +} + +TEST_F(LspGetRefTests, ConvertFunctionRefactor2) +{ + std::vector files = {"convertFunctionRefactor2.ets"}; + std::vector texts = {R"(function sub(a: number, b: number): number{ + return a - b; + };)"}; + auto filePaths = CreateTempFile(files, texts); + size_t const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const position = 11; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto result = lspApi->getApplicableRefactors(ctx, std::string(TO_NAMED_FUNCTION_KIND).c_str(), position); + initializer.DestroyContext(ctx); + ASSERT_EQ(std::string(""), result.name); +} + +TEST_F(LspGetRefTests, ConvertFunctionRefactor3) +{ + std::vector files = {"convertFunctionRefactor3.ets"}; + std::vector texts = {R"(const add = (x: number, y: number): number => { + return x + y; + };)"}; + auto filePaths = CreateTempFile(files, texts); + size_t const expectedFileCount = 1; + ASSERT_EQ(filePaths.size(), expectedFileCount); + + LSPAPI const *lspApi = GetImpl(); + size_t const position = 8; + Initializer initializer = Initializer(); + auto ctx = initializer.CreateContext(filePaths[0].c_str(), ES2PANDA_STATE_CHECKED); + auto result = lspApi->getApplicableRefactors(ctx, std::string(INVALID_KIND).c_str(), position); + initializer.DestroyContext(ctx); + ASSERT_EQ(std::string(""), result.name); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/script_element_kind_test.cpp b/ets2panda/test/unit/lsp/script_element_kind_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd461cd45da89973984963bd060d30022cf78eb5 --- /dev/null +++ b/ets2panda/test/unit/lsp/script_element_kind_test.cpp @@ -0,0 +1,90 @@ +/** + * 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/script_element_kind.h" +#include "lsp_api_test.h" +#include "lsp/include/internal_api.h" +#include + +using ark::es2panda::lsp::CompletionEntryKind; +using ark::es2panda::lsp::Initializer; + +namespace { + +class LspScriptElementKindTests : public LSPAPITests {}; + +TEST_F(LSPAPITests, GetAliasScriptElementKind_1) +{ + LSPAPI const *lspApi = GetImpl(); + ASSERT_TRUE(lspApi != nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *context = initializer.CreateContext( + "script_element_kind_1.ets", ES2PANDA_STATE_CHECKED, + "let number_literal: number = 1234;\nlet string_literal: string = \"hello\";\nconst str_property = " + "\"foo\";\n"); + + ASSERT_EQ(ContextState(context), ES2PANDA_STATE_CHECKED); + size_t const numberLiteralOffset = 31; // 31: position of '3' in '1234' + size_t const stringLiteralOffset = 96; // 96: position of first 'o' in 'foo' + + auto result = lspApi->getAliasScriptElementKind(context, numberLiteralOffset); + ASSERT_EQ(result, CompletionEntryKind::VALUE); // Literal is VALUE + result = lspApi->getAliasScriptElementKind(context, stringLiteralOffset); + ASSERT_EQ(result, CompletionEntryKind::VALUE); + initializer.DestroyContext(context); +} + +TEST_F(LSPAPITests, GetAliasScriptElementKind_2) +{ + LSPAPI const *lspApi = GetImpl(); + Initializer initializer = Initializer(); + es2panda_Context *context = + initializer.CreateContext("script_element_kind_2.ets", ES2PANDA_STATE_CHECKED, + " \nfunction f() {\n let a = 123;\n}\nconst s = \"hello\";\n"); + + size_t const startOfFile = 0; // 0: position of start of file, first space + size_t const firstleftCurlyBrance = 18; // 18:position of left curly brance after f() + size_t const numberLiteralOffset = 33; // 33: position of '2' in '123' + size_t const stringLiteralOffset = 50; // 50: position of 'h' in 'hello' + + ASSERT_EQ(lspApi->getAliasScriptElementKind(context, startOfFile), CompletionEntryKind::TEXT); + ASSERT_EQ(lspApi->getAliasScriptElementKind(context, firstleftCurlyBrance), CompletionEntryKind::SNIPPET); + ASSERT_EQ(lspApi->getAliasScriptElementKind(context, numberLiteralOffset), CompletionEntryKind::VALUE); + ASSERT_EQ(lspApi->getAliasScriptElementKind(context, stringLiteralOffset), CompletionEntryKind::VALUE); + initializer.DestroyContext(context); +} + +TEST_F(LSPAPITests, GetAliasScriptElementKind_3) +{ + LSPAPI const *lspApi = GetImpl(); + Initializer initializer = Initializer(); + + const char *statement = R"(let empty: null = null; +let notAssigned: undefined = undefined;)"; + es2panda_Context *context = + initializer.CreateContext("script_element_kind_3.ets", ES2PANDA_STATE_CHECKED, statement); + + size_t const nullLiteral = 19; // 19:position of the second null. + size_t const etsNullType = 25; // 25: position of the second let. + size_t const undefinedLiteral = 54; // 54: position of the second undefined. + + ASSERT_EQ(lspApi->getAliasScriptElementKind(context, nullLiteral), CompletionEntryKind::VALUE); + ASSERT_EQ(lspApi->getAliasScriptElementKind(context, etsNullType), CompletionEntryKind::TEXT); + ASSERT_EQ(lspApi->getAliasScriptElementKind(context, undefinedLiteral), CompletionEntryKind::VALUE); + initializer.DestroyContext(context); +} + +} // namespace diff --git a/ets2panda/test/unit/lsp/signature_help_items_test.cpp b/ets2panda/test/unit/lsp/signature_help_items_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a009e7ceecc61662e8d49b71277249916ae586d3 --- /dev/null +++ b/ets2panda/test/unit/lsp/signature_help_items_test.cpp @@ -0,0 +1,254 @@ +/** + * 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/signature_help_items.h" +#include "lsp/include/create_type_help_items.h" +#include "lsp_api_test.h" +#include +#include "lsp/include/internal_api.h" +#include "test/unit/lsp/lsp_api_test.h" +#include "checker/types/signature.h" +#include "checker/checker.h" +#include "lexer/token/sourceLocation.h" +#include "public/es2panda_lib.h" +#include "ir/astNode.h" +#include "ir/expressions/functionExpression.h" +#include "ir/statements/functionDeclaration.h" +#include +#include +#include +#include +#include "lsp/include/signature_help.h" + +namespace { + +class LSPSignatureHelpItemsTests : public LSPAPITests {}; + +ark::es2panda::ir::AstNode *FindTokenOnLeftOfPosition(es2panda_Context *context, size_t position) +{ + auto const tokenAtPosition = ark::es2panda::lsp::GetTouchingToken(context, position, false); + if (tokenAtPosition->Start().index < position && tokenAtPosition->End().index > position) { + return tokenAtPosition; + } + const auto ctx = reinterpret_cast(context); + return ark::es2panda::lsp::FindPrecedingToken(position, ctx->parserProgram->Ast(), ctx->allocator); +} + +TEST_F(LSPSignatureHelpItemsTests, GetSignatureHelpItemsTest) +{ + const auto fileName = "getSignatureHelpItemsTest.ets"; + const auto fileText = R"( + function test(a: number, b: string): void { + console.log(a); + } + test(1, "test"); +)"; + const size_t index0 = 0; + const size_t index1 = 1; + const size_t index2 = 2; + const size_t position = 10; + const size_t argumentIndex1 = 19; + const size_t argumentIndex2 = 30; + std::vector files = {fileName}; + std::vector texts = {fileText}; + auto filePaths = CreateTempFile(files, texts); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = + initializer.CreateContext(files.at(index0).c_str(), ES2PANDA_STATE_CHECKED, texts.at(index0).c_str()); + auto startingToken = FindTokenOnLeftOfPosition(ctx, position); + if (startingToken == nullptr) { + return; + } + std::vector argumentInfo; + GetArgumentOrParameterListAndIndex(startingToken, argumentInfo); + + EXPECT_EQ(argumentInfo.size(), index2); + EXPECT_EQ(argumentInfo[index0].GetArgumentIndex(), argumentIndex1); + EXPECT_EQ(argumentInfo[index1].GetArgumentIndex(), argumentIndex2); + initializer.DestroyContext(ctx); +} +TEST_F(LSPSignatureHelpItemsTests, GetResolvedSignatureForSignatureHelp) +{ + const auto fileName = "testSignature.ets"; + const auto fileText = R"( +function add(x: number, y: number): number { +return x + y; +} +let result = add(1, 2); + )"; + const size_t index0 = 0; + const size_t index2 = 3; + const size_t position = 77; + std::vector files = {fileName}; + std::vector texts = {fileText}; + auto filePaths = CreateTempFile(files, texts); + + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(files.at(index0).c_str(), ES2PANDA_STATE_CHECKED, fileText); + + auto callToken = FindTokenOnLeftOfPosition(ctx, position); + const auto callExpr = callToken->Parent(); + auto context = reinterpret_cast(ctx); + auto astNode = reinterpret_cast(context->parserProgram->Ast()); + ASSERT_NE(callExpr, nullptr); + ASSERT_NE(callExpr, nullptr); + ASSERT_TRUE(callExpr->IsCallExpression()); + std::vector candidates; + auto *sig = ark::es2panda::lsp::GetResolvedSignatureForSignatureHelp(callExpr, astNode, candidates); + + ASSERT_NE(sig, nullptr); + + ASSERT_EQ(candidates.size(), index2); + + initializer.DestroyContext(ctx); +} +TEST_F(LSPSignatureHelpItemsTests, GetCandidateOrTypeInfo) +{ + const auto fileName = "candidateOrTypeInfo.ets"; + const auto fileText = R"( +function multiply(a: number, b: number): number { +return a * b; +} +let result = multiply(10, 20); + )"; + const size_t index0 = 0; + const size_t position = 82; + + std::vector files = {fileName}; + std::vector texts = {fileText}; + auto filePaths = CreateTempFile(files, texts); + + ark::es2panda::lsp::Initializer initializer; + es2panda_Context *ctx = initializer.CreateContext(files.at(index0).c_str(), ES2PANDA_STATE_CHECKED, fileText); + + auto callToken = ark::es2panda::lsp::FindTokenOnLeftOfPosition(ctx, position); + ASSERT_NE(callToken, nullptr); + const auto callee = callToken->Parent(); + std::vector argumentInfoVec; + ark::es2panda::lsp::GetArgumentOrParameterListAndIndex(callee, argumentInfoVec); + auto context = reinterpret_cast(ctx); + auto astNode = reinterpret_cast(context->parserProgram->Ast()); + + ASSERT_FALSE(argumentInfoVec.empty()); + ark::es2panda::lsp::ArgumentListInfo info = argumentInfoVec[index0]; + auto result = ark::es2panda::lsp::GetCandidateOrTypeInfo(info, astNode, false); + ASSERT_TRUE(result.has_value()); + ASSERT_TRUE(std::holds_alternative(*result)); + auto candidateInfo = std::get(*result); + EXPECT_EQ(candidateInfo.GetKind(), ark::es2panda::lsp::CandidateOrTypeKind::CANDIDATE); + EXPECT_FALSE(candidateInfo.GetSignatures().empty()); + EXPECT_NE(candidateInfo.GetResolvedSignature(), nullptr); + + initializer.DestroyContext(ctx); +} + +TEST_F(LSPSignatureHelpItemsTests, CreateSignatureHelpItemTest) +{ + const auto fileName = "createSignatureHelpItemTest.ets"; + const auto fileText = R"( + function testFunction(param1: T, param2: U): number { + return 0; + } + testFunction(130, "test"); + )"; + const size_t index0 = 0; + const size_t index1 = 1; + const size_t position = 83; + std::vector files = {fileName}; + std::vector texts = {fileText}; + auto filePaths = CreateTempFile(files, texts); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = initializer.CreateContext(files.at(index0).c_str(), ES2PANDA_STATE_CHECKED, fileText); + auto callToken = FindTokenOnLeftOfPosition(ctx, position); + const auto callNode = callToken->Parent(); + ASSERT_NE(callNode, nullptr); + + ASSERT_TRUE(callNode->IsCallExpression()); + ark::es2panda::ir::CallExpression *callExpr = nullptr; + if (callNode->IsCallExpression()) { + callExpr = callNode->AsCallExpression(); + } + ark::es2panda::checker::Signature *signature = callExpr->Signature(); + SignatureHelpItem item = ark::es2panda::lsp::CreateSignatureHelpItem(*signature); + bool found1 = false; + bool found2 = false; + EXPECT_FALSE(item.GetPrefixDisplayParts().empty()); + for (const auto &displayPart : item.GetPrefixDisplayParts()) { + if (displayPart.GetText() == "<") { + found1 = true; + } else if (displayPart.GetText() == ">") { + found2 = true; + } + } + EXPECT_EQ(found1, true); + EXPECT_EQ(found2, true); + EXPECT_FALSE(item.GetSeparatorDisplayParts().empty()); + EXPECT_EQ(item.GetSeparatorDisplayParts().front().GetText(), ","); + EXPECT_EQ(item.GetParameters().size(), 2U); + EXPECT_EQ(item.GetParameters()[index0].GetName(), "param1"); + EXPECT_EQ(item.GetParameters()[index1].GetName(), "param2"); + item.Clear(); + initializer.DestroyContext(ctx); +} + +TEST_F(LSPSignatureHelpItemsTests, CreateSignatureHelpItemParamsTest) +{ + const auto fileName = "CreateSignatureHelpItemParamsTest.ets"; + const auto fileText = R"( + function testFunction(param1: T, param2: U): number { + return 0; + } + testFunction(130, "test"); + )"; + const size_t index0 = 0; + const size_t position = 83; + const size_t position1 = 13; + std::vector files = {fileName}; + std::vector texts = {fileText}; + auto filePaths = CreateTempFile(files, texts); + ark::es2panda::lsp::Initializer initializer = ark::es2panda::lsp::Initializer(); + es2panda_Context *ctx = initializer.CreateContext(files.at(index0).c_str(), ES2PANDA_STATE_CHECKED, fileText); + auto callToken = FindTokenOnLeftOfPosition(ctx, position); + const auto callNode = callToken->Parent(); + ASSERT_NE(callNode, nullptr); + ASSERT_TRUE(callNode->IsCallExpression()); + ark::es2panda::ir::CallExpression *callExpr = nullptr; + if (callNode->IsCallExpression()) { + callExpr = callNode->AsCallExpression(); + } + auto funcNode = FindTokenOnLeftOfPosition(ctx, position1); + funcNode = funcNode->Parent(); + ASSERT_NE(funcNode, nullptr); + ASSERT_TRUE(funcNode->IsMethodDefinition()); + ark::es2panda::ir::MethodDefinition *funcDecl = nullptr; + if (funcNode->IsMethodDefinition()) { + funcDecl = funcNode->AsMethodDefinition(); + } + std::vector signatures; + signatures.push_back(callExpr->Signature()); + signatures.push_back(funcDecl->Function()->Signature()); + ark::es2panda::lsp::ArgumentListInfo argumentListInfo; + const size_t argumentCount = 2; + const size_t argumentIndex = 1; + argumentListInfo.SetArgumentCount(argumentCount); + argumentListInfo.SetArgumentIndex(argumentIndex); + auto signatureHelpItems = + ark::es2panda::lsp::CreateSignatureHelpItems(signatures, callExpr->Signature(), argumentListInfo); + EXPECT_EQ(signatureHelpItems.GetSelectedItemIndex(), index0); + signatureHelpItems.Clear(); + initializer.DestroyContext(ctx); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/todo_comments_test.cpp b/ets2panda/test/unit/lsp/todo_comments_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..75deb939074b6f31e5d1a7706d42693bd4a4d669 --- /dev/null +++ b/ets2panda/test/unit/lsp/todo_comments_test.cpp @@ -0,0 +1,411 @@ +/** + * 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 + +#include "lsp_api_test.h" +#include "lsp/include/internal_api.h" +#include "lsp/include/todo_comments.h" + +namespace { +// NOLINTBEGIN +using ark::es2panda::lsp::Initializer; + +class TodoCommentsTest : public LSPAPITests {}; + +TEST_F(TodoCommentsTest, GetTodoCommentsSimpleTodo) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 1; + const char *const kTodoTag = "TODO"; + const char *const kFileName = "simple-todo.sts"; + const char *const kFileContent = "// TODO: Fix this"; + const char *const kExpectedMessage = "TODO: Fix this"; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsSimpleTodoWithName) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 1; + const char *const kTodoTag = "TODO"; + const char *const kFileName = "simple-todo-name.sts"; + const char *const kFileContent = "// TODO(name): Fix this"; + const char *const kExpectedMessage = "TODO(name): Fix this"; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsSimpleHack) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 1; + const char *const kHackTag = "HACK"; + const char *const kFileName = "simple-hack.sts"; + const char *const kFileContent = "// HACK: Needs work"; + const char *const kExpectedMessage = "HACK: Needs work"; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kHackTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kHackTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsBlockCommentTodo) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 1; + const char *const kTodoTag = "TODO"; + const char *const kFileName = "block-comment.sts"; + const char *const kFileContent = "/* TODO: Fix this */"; + const char *const kExpectedMessage = "TODO: Fix this "; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsMultiLineBlockComment) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 1; + const char *const kTodoTag = "TODO"; + const char *const kFileName = "multiline-block-comment.sts"; + const char *const kFileContent = "/*\n * TODO: Multi-line fix\n */"; + const char *const kExpectedMessage = "TODO: Multi-line fix"; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsIgnoresNonComments) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const char *const kTodoTag = "TODO"; + const char *const kFileName = "non-comment.sts"; + const char *const kFileContent = "let s = \"TODO: not a comment\""; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_TRUE(comments.empty()); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsMultiLineCodeMultiComments) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 2; + const char *const kTodoTag = "TODO"; + const char *const kHackTag = "HACK"; + const char *const kFileName = "multiline-multicomment.sts"; + const char *const kFileContent = + R"(export function A(a:number): number {return a;} + // TODO: this is a todo comment + + // HACK: fix me + export function B(a:number, b:number): number {return a + b;})"; + const char *const kExpectedTodoMessage = "TODO: this is a todo comment"; + const char *const kExpectedHackMessage = "HACK: fix me"; + const int kExpectedTodoPosition = 52; + const int kExpectedHackPosition = 87; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority), + ark::es2panda::lsp::TodoCommentDescriptor(kHackTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedTodoMessage); + EXPECT_EQ(comments[0].GetPosition(), kExpectedTodoPosition); + EXPECT_EQ(comments[1].GetCommentDescriptor().GetText(), kHackTag); + EXPECT_EQ(comments[1].GetMessage(), kExpectedHackMessage); + EXPECT_EQ(comments[1].GetPosition(), kExpectedHackPosition); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsMultiLineCodeSameComments) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 2; + const char *const kTodoTag = "TODO"; + const char *const kFileName = "multiline-duplicate.sts"; + const char *const kFileContent = + R"(export function A(a:number): number {return a;} + // TODO: this is a duplicate todo comment + + // TODO: this is a duplicate todo comment + export function B(a:number, b:number): number {return a + b;})"; + const char *const kExpectedMessage = "TODO: this is a duplicate todo comment"; + const int kExpectedFirstPosition = 52; + const int kExpectedSecondPosition = 97; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[1].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage); + EXPECT_EQ(comments[1].GetMessage(), kExpectedMessage); + EXPECT_EQ(comments[0].GetPosition(), kExpectedFirstPosition); + EXPECT_EQ(comments[1].GetPosition(), kExpectedSecondPosition); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsNotTodoComment) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const char *const kTodoTag = "TODO"; + const char *const kFileName = "non-comment.sts"; + const char *const kFileContent = "// TODOX not a todo comment"; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_TRUE(comments.empty()); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsBlockCommentFixMe) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 1; + const char *const kTodoTag = "FIXME"; + const char *const kFileName = "block-comment-fixme.sts"; + const char *const kFileContent = "/* FIXME: Fix this */"; + const char *const kExpectedMessage = "FIXME: Fix this "; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsSimpleFix) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 1; + const char *const kHackTag = "FIX"; + const char *const kFileName = "simple-comment-fix.sts"; + const char *const kFileContent = "// FIX: Needs to be fixed"; + const char *const kExpectedMessage = "FIX: Needs to be fixed"; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kHackTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kHackTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage); + + initializer.DestroyContext(ctx); +} + +TEST_F(TodoCommentsTest, GetTodoCommentsNoteMultiLineCodeSameComments) +{ + const time_t kDesignatedThrottleTime = 123; + const int kDescriptorPriority = 1; + const int kExpectedSize = 2; + const char *const kTodoTag = "NOTE"; + const char *const kFileName = "multiline-duplicate-note.sts"; + const char *const kFileContent = + R"(export function A(b:number): number {return c;} + // NOTE: this is a duplicate note comment + + // Comment line + + // NOTE: this is a duplicate note comment + export function B(a:number, b:number): number {return a + b;})"; + const char *const kExpectedMessage = "NOTE: this is a duplicate note comment"; + const int kExpectedFirstPosition = 52; + const int kExpectedSecondPosition = 115; + + using ark::es2panda::ir::AstNode; + using ark::es2panda::public_lib::Context; + + auto cancellationToken = ark::es2panda::lsp::CancellationToken(kDesignatedThrottleTime, nullptr); + + Initializer initializer = Initializer(); + es2panda_Context *ctx = initializer.CreateContext(kFileName, ES2PANDA_STATE_CHECKED, kFileContent); + + std::vector descriptors = { + ark::es2panda::lsp::TodoCommentDescriptor(kTodoTag, kDescriptorPriority)}; + + auto comments = ark::es2panda::lsp::GetTodoCommentsImpl(ctx, descriptors, &cancellationToken); + + ASSERT_EQ(comments.size(), kExpectedSize); + EXPECT_EQ(comments[0].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[1].GetCommentDescriptor().GetText(), kTodoTag); + EXPECT_EQ(comments[0].GetMessage(), kExpectedMessage); + EXPECT_EQ(comments[1].GetMessage(), kExpectedMessage); + EXPECT_EQ(comments[0].GetPosition(), kExpectedFirstPosition); + EXPECT_EQ(comments[1].GetPosition(), kExpectedSecondPosition); + + initializer.DestroyContext(ctx); +} +// NOLINTEND +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/plugin/CMakeLists.txt b/ets2panda/test/unit/plugin/CMakeLists.txt index 23325027200100187e3d4239835205043be6cfca..672aff08e47fc7bb6d04a499fb451dc6d7bcff1e 100644 --- a/ets2panda/test/unit/plugin/CMakeLists.txt +++ b/ets2panda/test/unit/plugin/CMakeLists.txt @@ -37,6 +37,7 @@ set(PLUGIN_TESTS "e2p_test_plugin_ets_node_types compile.ets ${RUNTIME_MODE} c ${LIBRARY_PLUGIN}" "e2p_test_plugin_ets_varibles_and_types compile.ets ${RUNTIME_MODE} c ${LIBRARY_PLUGIN}" "e2p_test_plugin_change_func runtime_change_func_call.ets ${RUNTIME_MODE} cpp ${LIBRARY_PLUGIN}" + "e2p_test_plugin_recheck compile.ets ${COMPILE_MODE} c ${LIBRARY_PLUGIN}" "e2p_test_plugin compile.ets ${EXPECTED_MODE} c ${LIBRARY_PLUGIN}" "e2p_test_plugin_is compile.ets ${EXPECTED_MODE} c ${LIBRARY_PLUGIN}" "e2p_test_plugin_after_bind compile.ets ${EXPECTED_MODE} cpp ${LIBRARY_PLUGIN}" @@ -53,12 +54,15 @@ set(PLUGIN_TESTS "plugin_proceed_to_state_find_import_declaration compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" # See #22753. # "plugin_proceed_to_state_test_number_literal compile.ets ${RUNTIME_MODE} cpp ${EXECUTABLE_PLUGIN}" - # "plugin_proceed_to_state_rerun_scopes_after_check compile.ets ${RUNTIME_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_rerun_scopes_after_check compile.ets ${RUNTIME_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_rerun_scopes_on_import import.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" # "plugin_proceed_to_state_rerun_scopes_after_lowered compile.ets ${RUNTIME_MODE} cpp ${EXECUTABLE_PLUGIN}" # "plugin_proceed_to_state_run_verifier compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" "plugin_proceed_to_state_ast_node_check compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" "plugin_proceed_to_state_resolve_path compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_arktsconfig compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" "plugin_proceed_to_state_find_method_decl compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_find_method_decl_by_name import.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" "plugin_proceed_to_state_find_identifier_decl compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" "plugin_proceed_to_state_find_import_ident_decl import.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" "plugin_proceed_to_state_test_import_external_sources import.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" @@ -92,7 +96,21 @@ set(PLUGIN_TESTS "plugin_proceed_to_state_create_interface_declaration compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" "plugin_proceed_to_state_create_import compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" "plugin_proceed_to_state_set_from_struct_modifier compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_default_access_modifier compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_dynamic_class_recheck compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_assignment_expression_set_result compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_create_diagnostic_kind compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_is_optional_declaration compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_update_function_declaration compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_update_function_expression compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_create_ets_new_expression compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_log_diagnostic_with_suggestion compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" "use_plugin_to_test_export_table compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_check_jsdoc compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_test_global_func_call_dump compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_test_interface_duplicate_setter compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_test_case_block_dump compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" + "plugin_proceed_to_state_function_dump compile.ets ${COMPILE_MODE} cpp ${EXECUTABLE_PLUGIN}" ) set(RUNTIME_ARGUMENTS diff --git a/ets2panda/test/unit/plugin/e2p_test_plugin_after_bind-expected.txt b/ets2panda/test/unit/plugin/e2p_test_plugin_after_bind-expected.txt index 9980fd7b66dd220601912f2573d3e15be210ba9d..825ed8e0f04c42c7b37c7974fcdceb7dacf52358 100644 --- a/ets2panda/test/unit/plugin/e2p_test_plugin_after_bind-expected.txt +++ b/ets2panda/test/unit/plugin/e2p_test_plugin_after_bind-expected.txt @@ -11,16 +11,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [] - }, - "properties": [] - } - ], "body": [ { "type": "MethodDefinition", @@ -615,16 +605,6 @@ }, "superClass": null, "implements": [], - "annotations": [ - { - "expr_": { - "type": "Identifier", - "name": "Module", - "decorators": [] - }, - "properties": [] - } - ], "body": [ { "type": "MethodDefinition", diff --git a/ets2panda/test/unit/plugin/e2p_test_plugin_recheck.c b/ets2panda/test/unit/plugin/e2p_test_plugin_recheck.c new file mode 100644 index 0000000000000000000000000000000000000000..15b4775e1d5f45cf447bcadb9b625f0e9aae523b --- /dev/null +++ b/ets2panda/test/unit/plugin/e2p_test_plugin_recheck.c @@ -0,0 +1,42 @@ +/** + * 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. + */ + +// No linting for pure C file +// NOLINTBEGIN + +#include +#include + +#include "public/es2panda_lib.h" + +static struct es2panda_Impl const *impl = NULL; + +void e2p_test_plugin_recheck_Initialize() +{ + impl = es2panda_GetImpl(ES2PANDA_LIB_VERSION); +} + +void e2p_test_plugin_recheck_AfterCheck(es2panda_Context *ctx) +{ + puts("Before recheck: "); + if (impl->ContextState(ctx) == ES2PANDA_STATE_ERROR) { + return; + } + es2panda_AstNode *ast = impl->ProgramAst(ctx, impl->ContextProgram(ctx)); + impl->AstNodeRecheck(ctx, ast); + puts("After recheck: "); +} + +// NOLINTEND \ No newline at end of file diff --git a/ets2panda/test/unit/plugin/export.ets b/ets2panda/test/unit/plugin/export.ets index c37edc0c5edaa58b8734de63933c3921d46e0198..b8932c008e6c4b99ae6522d1843fc66876db1094 100644 --- a/ets2panda/test/unit/plugin/export.ets +++ b/ets2panda/test/unit/plugin/export.ets @@ -21,5 +21,15 @@ export class A { foo() : int { return 2; } + too() : int { + return 2; + } b: int = 2 } + +export class B { + foo() : int { + return 5; + } + b: int = 5 +} \ No newline at end of file diff --git a/ets2panda/test/unit/plugin/export2.ets b/ets2panda/test/unit/plugin/export2.ets index 384198c4e26ce61b6908e8b88a51a8e8e0ebc39f..3f1439a17f84ab697445dbd5790810ddc99d83a4 100644 --- a/ets2panda/test/unit/plugin/export2.ets +++ b/ets2panda/test/unit/plugin/export2.ets @@ -17,12 +17,7 @@ export function foo() : int { return 2; } -export class A { - foo() : int { - return 2; - } - b: int = 2 -} +export const A0: int = 1 export class B { foo() : int { @@ -30,3 +25,5 @@ export class B { } b: int = 2 } + +hello() \ No newline at end of file diff --git a/ets2panda/test/unit/plugin/export3.ets b/ets2panda/test/unit/plugin/export3.ets new file mode 100644 index 0000000000000000000000000000000000000000..08df79d0c609a6434697e43e06134fc61a2be6cd --- /dev/null +++ b/ets2panda/test/unit/plugin/export3.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 function hello() : void { + console.log("hello arkts") +} \ No newline at end of file diff --git a/ets2panda/test/unit/plugin/import.ets b/ets2panda/test/unit/plugin/import.ets index ef92074fe3f7bb8e0962244115b48ab987a1d608..6ad3c62d494b68e060b63a1a496425ffd933f044 100644 --- a/ets2panda/test/unit/plugin/import.ets +++ b/ets2panda/test/unit/plugin/import.ets @@ -13,7 +13,9 @@ * limitations under the License. */ -import {A, foo} from "./export.ets" +import {A, B, foo} from "./export.ets" + +function goo() : int { return 2} function main() { let a: A = new A(); diff --git a/ets2panda/test/unit/plugin/plugin_check_manual_capi.cpp b/ets2panda/test/unit/plugin/plugin_check_manual_capi.cpp index 341c119d4db58e7434389b70fdbeb179e5cd4daf..72332b1a0b4aa17872bea41d618ab282404d8020 100644 --- a/ets2panda/test/unit/plugin/plugin_check_manual_capi.cpp +++ b/ets2panda/test/unit/plugin/plugin_check_manual_capi.cpp @@ -40,10 +40,10 @@ * es2panda_AstNode *(*UpdateNumberLiteral1)(es2panda_Context *ctx, es2panda_AstNode *original, int64_t value); * es2panda_AstNode *(*UpdateNumberLiteral2)(es2panda_Context *ctx, es2panda_AstNode *original, double value); * es2panda_AstNode *(*UpdateNumberLiteral3)(es2panda_Context *ctx, es2panda_AstNode *original, float value); - * bool(*SetNumberLiteralInt)(es2panda_AstNode *node, int32_t new_value); - * bool(*SetNumberLiteralLong)(es2panda_AstNode *node, int64_t new_value); - * bool(*SetNumberLiteralDouble)(es2panda_AstNode *node, double new_value); - * bool(*SetNumberLiteralFloat)(es2panda_AstNode *node, float new_value); + * bool(*NumberLiteralSetInt)(es2panda_AstNode *node, int32_t new_value); + * bool(*NumberLiteralSetLong)(es2panda_AstNode *node, int64_t new_value); + * bool(*NumberLiteralSetDouble)(es2panda_AstNode *node, double new_value); + * bool(*NumberLiteralSetFloat)(es2panda_AstNode *node, float new_value); * char *(*)(es2panda_Context *, Es2pandaEnum); * Es2pandaEnum (*)(es2panda_Context *, const char *); * void(*DestroyContext)(es2panda_Context *context); @@ -142,10 +142,10 @@ bool CheckNumberLiteral(es2panda_Context *ctx) return false; } - bool setInt32Result = g_impl->SetNumberLiteralInt(updatedInt32AstNode, 8); - bool setInt64Result = g_impl->SetNumberLiteralLong(updatedInt64AstNode, 9); - bool setDoubleResult = g_impl->SetNumberLiteralDouble(updatedDoubleAstNode, 10.0); - bool setFloatResult = g_impl->SetNumberLiteralFloat(updatedFloatAstNode, 11.0); + bool setInt32Result = g_impl->NumberLiteralSetInt(updatedInt32AstNode, 8); + bool setInt64Result = g_impl->NumberLiteralSetLong(updatedInt64AstNode, 9); + bool setDoubleResult = g_impl->NumberLiteralSetDouble(updatedDoubleAstNode, 10.0); + bool setFloatResult = g_impl->NumberLiteralSetFloat(updatedFloatAstNode, 11.0); return setInt32Result && setInt64Result && setDoubleResult && setFloatResult; } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state.cpp index aa95c1230462a62b1470ceaad0825d555a9573f5..b700c046a91a6e21bd812c47bcf96d1afc9fd211 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state.cpp @@ -39,6 +39,7 @@ int main(int argc, char **argv) std::cout << "LOAD SUCCESS" << std::endl; const char **args = const_cast(&(argv[1])); + impl->MemInitialize(); auto config = impl->CreateConfig(argc - 1, args); auto context = impl->CreateContextFromFile(config, argv[argc - 1]); if (context == nullptr) { @@ -67,6 +68,7 @@ int main(int argc, char **argv) CheckForErrors("BIN", context); impl->DestroyConfig(config); + impl->MemFinalize(); return 0; } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_arktsconfig.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_arktsconfig.cpp new file mode 100644 index 0000000000000000000000000000000000000000..13d5b32218064b800ae50d6aaf32a39e1054f761 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_arktsconfig.cpp @@ -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. + */ + +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "public/es2panda_lib.h" + +// NOLINTBEGIN + +static es2panda_Impl *impl = nullptr; +static auto source = std::string("function main() { 1 + 2 }"); + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = impl->CreateConfig(argc - 1, args); + auto context = impl->CreateContextFromString(config, source.data(), argv[argc - 1]); + if (context == nullptr) { + std::cerr << "FAILED TO CREATE CONTEXT" << std::endl; + return NULLPTR_CONTEXT_ERROR_CODE; + } + + impl->ProceedToState(context, ES2PANDA_STATE_PARSED); + CheckForErrors("PARSE", context); + + auto outDir = impl->ArkTsConfigOutDirConst( + context, + impl->OptionsUtilArkTSConfigConst(context, const_cast(impl->ConfigGetOptions(config)))); + if (strstr(outDir, "bin") == nullptr) { + return TEST_ERROR_CODE; + } + + if (impl->ContextState(context) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + impl->DestroyContext(context); + impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_assignment_expression_set_result.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_assignment_expression_set_result.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f9c2b4524b53c98e241485e7f8f7a0de36b55300 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_assignment_expression_set_result.cpp @@ -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. + */ + +#include +#include +#include "util.h" + +// NOLINTBEGIN + +static es2panda_Impl *g_impl = nullptr; +static es2panda_Context *g_ctx = nullptr; +static std::string g_source = R"( +let obj = 1; +obj = 2; +)"; + +bool Find(es2panda_AstNode *ast) +{ + if (g_impl->IsAssignmentExpression(ast)) { + auto left = g_impl->AssignmentExpressionLeft(g_ctx, ast); + g_impl->AssignmentExpressionSetResult(g_ctx, ast, left); + return g_impl->AssignmentExpressionResult(g_ctx, ast) == left; + } + return false; +} + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + g_impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = g_impl->CreateConfig(argc - 1, args); + g_ctx = g_impl->CreateContextFromString(config, g_source.data(), argv[argc - 1]); + if (g_ctx == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_PARSED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + auto ast = g_impl->ProgramAst(g_ctx, g_impl->ContextProgram(g_ctx)); + if (!g_impl->AstNodeIsAnyChildConst(g_ctx, ast, Find)) { + return TEST_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_BIN_GENERATED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + g_impl->DestroyContext(g_ctx); + g_impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_type_analyzer.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_type_analyzer.cpp index c3a467c38e6163618098a466e91540c055799d82..29a0dc42a98abd6009cc9a127c487f3076d7b6d5 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_type_analyzer.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_type_analyzer.cpp @@ -112,7 +112,7 @@ static void ProcessTSInterface(es2panda_Context *context, es2panda_AstNode *node static void ProcessNewExpression(es2panda_Context *context, es2panda_AstNode *node) { counter.newExpressionCount++; - auto *typeRef = node ? impl->ETSTypeReferencePartName(context, node) : nullptr; + auto *typeRef = node ? impl->ETSNewClassInstanceExpressionGetTypeRefConst(context, node) : nullptr; if (!typeRef) { return; } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_check_jsdoc.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_check_jsdoc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bd890b99a673fd98af063fa6f219dfe251535fee --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_check_jsdoc.cpp @@ -0,0 +1,129 @@ +/** + * 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 +#include +#include +#include + +#include "os/library_loader.h" + +#include "public/es2panda_lib.h" +#include "util.h" + +// NOLINTBEGIN + +static es2panda_Impl *impl = nullptr; +static es2panda_AstNode *targetClass = nullptr; + +static std::string g_source = R"( +/** + * @param1 {} behindStr + * @param2 preStr { p } + * @param3 preStr { p } behindStr + * @param4 preStr {} behindStr + * @returns { number } + */ +class A {} +)"; + +static std::vector nameList = {"returns", "param4", "param3", "param2", "param1"}; +static std::vector paramList = {" number", "", " p", " p", ""}; +static std::vector commentsList = {"{ number }", "preStr {} behindStr", "preStr { p } behindStr", + "preStr { p }", "{} behindStr"}; + +static void SetTargetClass(es2panda_AstNode *ast, void *context) +{ + auto ctx = reinterpret_cast(context); + if (!impl->IsClassDefinition(ast)) { + return; + } + auto *ident = impl->ClassDefinitionIdent(ctx, ast); + if (ident == nullptr) { + return; + } + auto name = impl->IdentifierName(ctx, ident); + if (std::string(name) == "A") { + targetClass = ast; + } +} + +static bool TestJSDoc(es2panda_Context *context) +{ + auto *program = impl->ContextProgram(context); + auto *ast = impl->ProgramAst(context, program); + impl->AstNodeForEach(ast, SetTargetClass, context); + if (ast == nullptr) { + std::cerr << "FAILED TO GET AST" << std::endl; + return false; + } + size_t jsDocInfoArrayLen = 0; + auto **jsDocInfoArray = impl->ClassDefinitionJsDocInformation(context, targetClass, &jsDocInfoArrayLen); + if (jsDocInfoArray == nullptr || jsDocInfoArrayLen == 0) { + std::cerr << "FAILED TO GET JsDocInfo" << std::endl; + return false; + } + for (size_t i = 0; i < jsDocInfoArrayLen; ++i) { + auto *jsDocInfo = jsDocInfoArray[i]; + if (jsDocInfo == nullptr) { + std::cerr << "FAILED TO GET JsDocInfo" << std::endl; + return false; + } + for (size_t j = 0; j < jsDocInfo->len; ++j) { + auto *jsDocRecord = jsDocInfo->jsDocRecords[j]; + if (jsDocRecord == nullptr) { + std::cerr << "FAILED TO GET JsDocRecord" << std::endl; + return false; + } + auto *name = jsDocInfo->strings[j]; + if (name == nullptr) { + std::cerr << "FAILED TO GET JsDocName" << std::endl; + return false; + } + + if (jsDocRecord->name != nameList[j]) { + std::cerr << "exact: " << jsDocRecord->name << " exp: " << nameList[j] << std::endl; + return false; + } + + if (jsDocRecord->param != paramList[j]) { + std::cerr << "exact: " << jsDocRecord->param << " exp: " << paramList[j] << std::endl; + return false; + } + + if (jsDocRecord->comment != commentsList[j]) { + std::cerr << "exact: " << jsDocRecord->comment << " exp: " << commentsList[j] << std::endl; + return false; + } + } + } + return true; +} + +int main(int argc, char **argv) +{ + std::vector newArgv(argv, argv + argc); + const char *extraArg = "--parse-jsdoc"; + newArgv.push_back(const_cast(extraArg)); + int newArgc = static_cast(newArgv.size()); + char **newArgvRaw = newArgv.data(); + + std::map>> testFunctions; + testFunctions[ES2PANDA_STATE_PARSED] = {TestJSDoc}; + ProccedToStatePluginTestData data = {newArgc, newArgvRaw, &impl, testFunctions, true, g_source}; + return RunAllStagesWithTestFunction(data); +} + +// NOLINTEND \ No newline at end of file diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_diagnostic_kind.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_diagnostic_kind.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3aeab489ea1165ca7187d2cb5c5cb672c0e51bdf --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_diagnostic_kind.cpp @@ -0,0 +1,70 @@ +/** + * 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 +#include +#include "util.h" +#include "util/diagnosticEngine.h" + +// NOLINTBEGIN + +static es2panda_Impl *g_impl = nullptr; +static es2panda_Context *g_ctx = nullptr; +static std::string g_source = R"( + function main() {} + )"; + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + + g_impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = g_impl->CreateConfig(argc - 1, args); + g_ctx = g_impl->CreateContextFromString(config, g_source.data(), argv[argc - 1]); + if (g_ctx == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_PARSED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + auto kind = reinterpret_cast( + g_impl->CreateDiagnosticKind(g_ctx, "test", ES2PANDA_PLUGIN_ERROR)); + if (strcmp(kind->Message().data(), "test") != 0 || + kind->Type() != ark::es2panda::util::DiagnosticType::PLUGIN_ERROR) { + return TEST_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_BIN_GENERATED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + g_impl->DestroyContext(g_ctx); + g_impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_new_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_new_expression.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1d8d9290aeb0d231ada09dbd7b6711a46fdb9b3 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_new_expression.cpp @@ -0,0 +1,223 @@ +/** + * 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 +#include +#include +#include "util.h" + +// NOLINTBEGIN + +static es2panda_Impl *g_impl = nullptr; +static es2panda_Context *g_ctx = nullptr; +static std::string g_source = R"( +let a = new number[5] +let b = new number[5][5] +let c = new number[5] +let d = new number[5][5] +let e = new number[5][5] +let f = new number[5][5] +)"; +static int g_count = 6; + +void FindA(es2panda_AstNode *ast, es2panda_AstNode *declarator, char *name) +{ + if (g_impl->IsETSNewArrayInstanceExpression(ast) && strcmp(name, "a") == 0) { + auto className = CreateIdentifierFromString(g_ctx, "string"); + auto part = g_impl->CreateETSTypeReferencePart1(g_ctx, className); + auto typeReference = g_impl->CreateETSTypeReference(g_ctx, part); + g_impl->AstNodeSetParent(g_ctx, part, typeReference); + g_impl->AstNodeSetParent(g_ctx, className, part); + + auto dimension = g_impl->ETSNewArrayInstanceExpressionDimension(g_ctx, ast); + auto expression = g_impl->CreateETSNewArrayInstanceExpression(g_ctx, typeReference, dimension); + g_impl->VariableDeclaratorSetInit(g_ctx, declarator, expression); + g_impl->AstNodeSetParent(g_ctx, expression, declarator); + g_impl->AstNodeSetParent(g_ctx, dimension, expression); + g_impl->AstNodeSetParent(g_ctx, typeReference, expression); + auto str = g_impl->AstNodeDumpEtsSrcConst(g_ctx, declarator); + if (strcmp(str, "a = new string[5]") == 0) { + g_count--; + } + } +} + +void FindB(es2panda_AstNode *ast, es2panda_AstNode *declarator, char *name) +{ + if (g_impl->IsETSNewMultiDimArrayInstanceExpression(ast) && strcmp(name, "b") == 0) { + auto className = CreateIdentifierFromString(g_ctx, "string"); + auto part = g_impl->CreateETSTypeReferencePart1(g_ctx, className); + auto typeReference = g_impl->CreateETSTypeReference(g_ctx, part); + g_impl->AstNodeSetParent(g_ctx, part, typeReference); + g_impl->AstNodeSetParent(g_ctx, className, part); + + size_t dimensionsLen = 0; + auto dimensions = g_impl->ETSNewMultiDimArrayInstanceExpressionDimensions(g_ctx, ast, &dimensionsLen); + auto expression = + g_impl->CreateETSNewMultiDimArrayInstanceExpression(g_ctx, typeReference, dimensions, dimensionsLen); + g_impl->VariableDeclaratorSetInit(g_ctx, declarator, expression); + g_impl->AstNodeSetParent(g_ctx, expression, declarator); + for (size_t i = 0; i < dimensionsLen; i++) { + g_impl->AstNodeSetParent(g_ctx, dimensions[i], expression); + } + g_impl->AstNodeSetParent(g_ctx, typeReference, expression); + auto str = g_impl->AstNodeDumpEtsSrcConst(g_ctx, declarator); + if (strcmp(str, "b = new string[5][5]") == 0) { + g_count--; + } + } +} + +void FindC(es2panda_AstNode *ast, es2panda_AstNode *declarator, char *name) +{ + if (g_impl->IsETSNewArrayInstanceExpression(ast) && strcmp(name, "c") == 0) { + auto className = CreateIdentifierFromString(g_ctx, "string"); + auto part = g_impl->CreateETSTypeReferencePart1(g_ctx, className); + auto typeReference = g_impl->CreateETSTypeReference(g_ctx, part); + g_impl->AstNodeSetParent(g_ctx, part, typeReference); + g_impl->AstNodeSetParent(g_ctx, className, part); + + auto dimension = g_impl->ETSNewArrayInstanceExpressionDimension(g_ctx, ast); + auto expression = g_impl->UpdateETSNewArrayInstanceExpression(g_ctx, ast, typeReference, dimension); + g_impl->VariableDeclaratorSetInit(g_ctx, declarator, expression); + g_impl->AstNodeSetParent(g_ctx, expression, declarator); + g_impl->AstNodeSetParent(g_ctx, dimension, expression); + g_impl->AstNodeSetParent(g_ctx, typeReference, expression); + auto str = g_impl->AstNodeDumpEtsSrcConst(g_ctx, declarator); + if (strcmp(str, "c = new string[5]") == 0) { + g_count--; + } + } +} + +void FindD(es2panda_AstNode *ast, es2panda_AstNode *declarator, char *name) +{ + if (g_impl->IsETSNewMultiDimArrayInstanceExpression(ast) && strcmp(name, "d") == 0) { + auto className = CreateIdentifierFromString(g_ctx, "string"); + auto part = g_impl->CreateETSTypeReferencePart1(g_ctx, className); + auto typeReference = g_impl->CreateETSTypeReference(g_ctx, part); + g_impl->AstNodeSetParent(g_ctx, part, typeReference); + g_impl->AstNodeSetParent(g_ctx, className, part); + + size_t dimensionsLen = 0; + auto dimensions = g_impl->ETSNewMultiDimArrayInstanceExpressionDimensions(g_ctx, ast, &dimensionsLen); + auto expression = + g_impl->UpdateETSNewMultiDimArrayInstanceExpression(g_ctx, ast, typeReference, dimensions, dimensionsLen); + g_impl->VariableDeclaratorSetInit(g_ctx, declarator, expression); + g_impl->AstNodeSetParent(g_ctx, expression, declarator); + for (size_t i = 0; i < dimensionsLen; i++) { + g_impl->AstNodeSetParent(g_ctx, dimensions[i], expression); + } + g_impl->AstNodeSetParent(g_ctx, typeReference, expression); + auto str = g_impl->AstNodeDumpEtsSrcConst(g_ctx, declarator); + if (strcmp(str, "d = new string[5][5]") == 0) { + g_count--; + } + } +} + +void FindE(es2panda_AstNode *ast, es2panda_AstNode *declarator, char *name) +{ + if (g_impl->IsETSNewMultiDimArrayInstanceExpression(ast) && strcmp(name, "e") == 0) { + auto typeReference = g_impl->ETSNewMultiDimArrayInstanceExpressionTypeReference(g_ctx, ast); + size_t dimensionsLen = 0; + auto dimensions = g_impl->ETSNewMultiDimArrayInstanceExpressionDimensions(g_ctx, ast, &dimensionsLen); + auto expression = g_impl->CreateETSNewMultiDimArrayInstanceExpression1(g_ctx, ast); + g_impl->VariableDeclaratorSetInit(g_ctx, declarator, expression); + g_impl->AstNodeSetParent(g_ctx, expression, declarator); + for (size_t i = 0; i < dimensionsLen; i++) { + g_impl->AstNodeSetParent(g_ctx, dimensions[i], expression); + } + g_impl->AstNodeSetParent(g_ctx, typeReference, expression); + auto str = g_impl->AstNodeDumpEtsSrcConst(g_ctx, declarator); + if (strcmp(str, "e = new number[5][5]") == 0) { + g_count--; + } + } +} + +void FindF(es2panda_AstNode *ast, es2panda_AstNode *declarator, char *name) +{ + if (g_impl->IsETSNewMultiDimArrayInstanceExpression(ast) && strcmp(name, "f") == 0) { + auto typeReference = g_impl->ETSNewMultiDimArrayInstanceExpressionTypeReference(g_ctx, ast); + size_t dimensionsLen = 0; + auto dimensions = g_impl->ETSNewMultiDimArrayInstanceExpressionDimensions(g_ctx, ast, &dimensionsLen); + auto expression = g_impl->UpdateETSNewMultiDimArrayInstanceExpression1(g_ctx, ast, ast); + g_impl->VariableDeclaratorSetInit(g_ctx, declarator, expression); + g_impl->AstNodeSetParent(g_ctx, expression, declarator); + for (size_t i = 0; i < dimensionsLen; i++) { + g_impl->AstNodeSetParent(g_ctx, dimensions[i], expression); + } + g_impl->AstNodeSetParent(g_ctx, typeReference, expression); + auto str = g_impl->AstNodeDumpEtsSrcConst(g_ctx, declarator); + if (strcmp(str, "f = new number[5][5]") == 0) { + g_count--; + } + } +} + +bool Find(es2panda_AstNode *ast) +{ + auto declarator = g_impl->AstNodeParent(g_ctx, ast); + if (g_impl->IsVariableDeclarator(declarator)) { + auto name = g_impl->IdentifierName(g_ctx, g_impl->VariableDeclaratorId(g_ctx, declarator)); + FindA(ast, declarator, name); + FindB(ast, declarator, name); + FindC(ast, declarator, name); + FindD(ast, declarator, name); + FindE(ast, declarator, name); + FindF(ast, declarator, name); + } + return g_count == 0; +} + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + g_impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = g_impl->CreateConfig(argc - 1, args); + g_ctx = g_impl->CreateContextFromString(config, g_source.data(), argv[argc - 1]); + if (g_ctx == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_PARSED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + auto ast = g_impl->ProgramAst(g_ctx, g_impl->ContextProgram(g_ctx)); + if (!g_impl->AstNodeIsAnyChildConst(g_ctx, ast, Find)) { + return TEST_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_BIN_GENERATED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + g_impl->DestroyContext(g_ctx); + g_impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND 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 8a1be20e0d8dfc91e6e0a2fd08c05fe360a456ca..d7953251363888edd9d08f7f54812ceba7388633 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 @@ -18,33 +18,148 @@ #include #include #include +#include "macros.h" #include "util.h" #include "public/es2panda_lib.h" +#include "ir/ets/etsImportDeclaration.h" #include "utils/arena_containers.h" // NOLINTBEGIN static es2panda_Impl *g_impl = nullptr; +static es2panda_Context *g_ctx = nullptr; -static void CreateImportDecl(es2panda_Context *context) +static es2panda_AstNode *CreateImportDecl(es2panda_Context *context, es2panda_Program *program, const char *importIdStr, + const char *importAliasStr, const char *importPathStr) { - char pathToResolve[] = "./export2"; - auto *importPath = g_impl->CreateStringLiteral1(context, pathToResolve); + auto *importPath = g_impl->CreateStringLiteral1(context, const_cast(importPathStr)); std::vector specifiersArray; - auto *importId = g_impl->CreateIdentifier1(context, const_cast("B")); - auto *importAlias = g_impl->CreateIdentifier1(context, const_cast("B")); + auto *importId = g_impl->CreateIdentifier1(context, const_cast(importIdStr)); + auto *importAlias = g_impl->CreateIdentifier1(context, const_cast(importAliasStr)); auto *importSpecifier = g_impl->CreateImportSpecifier(context, importId, importAlias); g_impl->AstNodeSetParent(context, importId, importSpecifier); g_impl->AstNodeSetParent(context, importAlias, importSpecifier); specifiersArray.push_back(importSpecifier); - auto *importDecl = g_impl->ETSParserBuildImportDeclaration(context, Es2pandaImportKinds::IMPORT_KINDS_ALL, - specifiersArray.data(), 1, importPath); - auto *program = g_impl->ContextProgram(context); - g_impl->InsertETSImportDeclarationAndParse(context, program, importDecl); - auto *importDeclString = g_impl->AstNodeDumpEtsSrcConst(context, importDecl); + auto *importDecl = + g_impl->ETSParserBuildImportDeclaration(context, Es2pandaImportKinds::IMPORT_KINDS_ALL, specifiersArray.data(), + 1, importPath, program, Es2pandaImportFlags::IMPORT_FLAGS_NONE); + return importDecl; +} + +void InsertStatementInFunctionBody(es2panda_Context *context, es2panda_AstNode *func) +{ + auto *blockStmt = g_impl->ScriptFunctionBody(context, func); + size_t newStmtNum = 1; + auto **statement = g_impl->ETSParserCreateStatements(context, const_cast("let a0 = A0;"), &newStmtNum); + PrependStatementToProgram(context, blockStmt, statement[0]); +} + +es2panda_AstNode *GetTargetFunc(es2panda_Context *context, es2panda_AstNode *ast) +{ + static constexpr size_t BLK_STMT_IDX = 3; + static constexpr size_t CLASS_DEF_IDX = 2; + size_t blockStmtNum = 0; + auto **blockStmt = g_impl->BlockStatementStatements(context, ast, &blockStmtNum); + auto *etsGlobal = blockStmt[BLK_STMT_IDX]; + auto *classDef = g_impl->ClassDeclarationDefinition(context, etsGlobal); + size_t blockStmtNum2 = 0; + auto *classBody = g_impl->ClassDefinitionBody(context, classDef, &blockStmtNum2); + auto *fooMethod = classBody[CLASS_DEF_IDX]; + auto *fooFunc = g_impl->MethodDefinitionFunction(context, fooMethod); + + return fooFunc; +} + +bool TestInsertImportAfterParse(es2panda_Context *context, [[maybe_unused]] es2panda_Config *config, + es2panda_Program *program) +{ + size_t externalSourceCnt {0}; + g_impl->ProgramExternalSources(context, program, &externalSourceCnt); + std::cout << "ExternalProgram Count:" << externalSourceCnt << std::endl; + auto *importDeclAfterParse = CreateImportDecl(context, program, "B", "B", "./export2"); + + g_impl->InsertETSImportDeclarationAndParse(context, program, importDeclAfterParse); + auto *importDeclString = g_impl->AstNodeDumpEtsSrcConst(context, importDeclAfterParse); std::cout << importDeclString << std::endl; + size_t externalSourceCntAfterInsert {0}; + g_impl->ProgramExternalSources(context, g_impl->ContextProgram(context), &externalSourceCntAfterInsert); + std::cout << "ExternalProgram Count:" << externalSourceCntAfterInsert << std::endl; + + if (externalSourceCntAfterInsert != externalSourceCnt + 1) { + std::cout << "Insert ETSImportDeclaration Failure." << std::endl; + g_impl->DestroyContext(context); + g_impl->DestroyConfig(config); + return false; + } + + return true; +} + +void InsertImportInHeaderAfterParse(es2panda_Context *context, [[maybe_unused]] es2panda_Config *config, + es2panda_Program *program) +{ + size_t mainProgExternalSourceCnt {0}; + auto **externalSources = g_impl->ProgramExternalSources(context, program, &mainProgExternalSourceCnt); + if (mainProgExternalSourceCnt == 0) { + std::cout << "No ExternalSource in main program." << std::endl; + return; + } + + es2panda_AstNode *importDeclInHeaderAfterParse {nullptr}; + size_t prevHeaderExternalSourceCnt {0}; + es2panda_Program *headerProgram {nullptr}; + for (size_t i = 0; i < mainProgExternalSourceCnt; ++i) { + auto *externalSource = externalSources[i]; + std::string sourceName = g_impl->ExternalSourceName(externalSource); + size_t externalSourceProgramCnt {0}; + auto **programs = g_impl->ExternalSourcePrograms(externalSource, &externalSourceProgramCnt); + if (sourceName.compare("export2") == 0) { + headerProgram = programs[0]; + g_impl->ProgramExternalSources(context, headerProgram, &prevHeaderExternalSourceCnt); + importDeclInHeaderAfterParse = CreateImportDecl(context, headerProgram, "hello", "hello", "./export3"); + g_impl->InsertETSImportDeclarationAndParse(context, headerProgram, importDeclInHeaderAfterParse); + std::cout << g_impl->AstNodeDumpEtsSrcConst(context, g_impl->ProgramAst(context, headerProgram)) + << std::endl; + auto *importDeclString = g_impl->AstNodeDumpEtsSrcConst(context, importDeclInHeaderAfterParse); + std::cout << importDeclString << std::endl; + break; + } + } +} + +bool Find(es2panda_AstNode *ast) +{ + if (g_impl->IsETSImportDeclaration(ast)) { + size_t len = 0; + auto specifiers = g_impl->ImportDeclarationSpecifiersConst(g_ctx, ast, &len); + auto source = g_impl->ImportDeclarationSource(g_ctx, ast); + auto importDeclaration = + g_impl->UpdateETSImportDeclaration(g_ctx, ast, source, specifiers, len, IMPORT_KINDS_ALL); + auto declPath = g_impl->ETSImportDeclarationDeclPathConst(g_ctx, ast); + auto ohmUrl = g_impl->ETSImportDeclarationOhmUrlConst(g_ctx, ast); + auto resolvedSource = g_impl->ETSImportDeclarationResolvedSourceConst(g_ctx, ast); + g_impl->ETSImportDeclarationSetImportMetadata(g_ctx, importDeclaration, IMPORT_FLAGS_NONE, ID_ETS, + resolvedSource, declPath, ohmUrl); + for (size_t i = 0; i < len; i++) { + g_impl->AstNodeSetParent(g_ctx, specifiers[i], importDeclaration); + } + g_impl->AstNodeSetParent(g_ctx, source, importDeclaration); + auto parent = g_impl->AstNodeParent(g_ctx, ast); + if (g_impl->AstNodeIsProgramConst(g_ctx, parent)) { + size_t sizeOfStatements = 0; + auto *statements = g_impl->BlockStatementStatements(g_ctx, parent, &sizeOfStatements); + statements[0] = 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)); + if (str.find("import { A as A } from \"./export\"") != std::string::npos) { + return true; + } + } + } + return false; } int main(int argc, char **argv) @@ -68,33 +183,38 @@ int main(int argc, char **argv) std::cerr << "FAILED TO CREATE CONTEXT" << std::endl; return NULLPTR_CONTEXT_ERROR_CODE; } + g_ctx = context; g_impl->ProceedToState(context, ES2PANDA_STATE_PARSED); CheckForErrors("PARSE", context); - size_t externalSourceCnt {0}; - g_impl->ProgramExternalSources(context, g_impl->ContextProgram(context), &externalSourceCnt); - std::cout << "ExternalProgram Count:" << externalSourceCnt << std::endl; - CreateImportDecl(context); - size_t externalSourceCntAfterInsert {0}; - g_impl->ProgramExternalSources(context, g_impl->ContextProgram(context), &externalSourceCntAfterInsert); - std::cout << "ExternalProgram Count:" << externalSourceCntAfterInsert << std::endl; - if (externalSourceCntAfterInsert != externalSourceCnt + 1) { - std::cout << "Insert ETSImportDeclaration Failure." << std::endl; - g_impl->DestroyContext(context); - g_impl->DestroyConfig(config); + + auto *program = g_impl->ContextProgram(context); + auto ast = g_impl->ProgramAst(context, program); + if (!g_impl->AstNodeIsAnyChildConst(context, ast, Find)) { + return TEST_ERROR_CODE; + } + + if (!TestInsertImportAfterParse(context, config, program)) { 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); - g_impl->ProceedToState(context, ES2PANDA_STATE_LOWERED); - CheckForErrors("LOWERED", 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); + InsertStatementInFunctionBody(context, tagetFunc); + std::cout << g_impl->AstNodeDumpEtsSrcConst(context, rootAst) << std::endl; - g_impl->ProceedToState(context, ES2PANDA_STATE_ASM_GENERATED); - CheckForErrors("ASM", context); + g_impl->AstNodeRecheck(context, rootAst); g_impl->ProceedToState(context, ES2PANDA_STATE_BIN_GENERATED); CheckForErrors("BIN", context); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_default_access_modifier.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_default_access_modifier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..913e5da01e584539a9d500723c0dd1a4167fc1e0 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_default_access_modifier.cpp @@ -0,0 +1,102 @@ +/** + * 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 +#include +#include "util.h" + +// NOLINTBEGIN + +static es2panda_Impl *g_impl = nullptr; +static es2panda_Context *g_ctx = nullptr; +static int g_count = 4; +static std::string g_source = R"( +class A { + x: number + public y: number + foo1() {} + public foo2() {} +} +)"; + +bool Find(es2panda_AstNode *ast) +{ + if (g_impl->IsClassProperty(ast) && + strcmp(g_impl->IdentifierName(g_ctx, g_impl->ClassElementId(g_ctx, ast)), "x") == 0) { + if (g_impl->ClassPropertyIsDefaultAccessModifierConst(g_ctx, ast)) { + g_count--; + } + } + if (g_impl->IsClassProperty(ast) && + strcmp(g_impl->IdentifierName(g_ctx, g_impl->ClassElementId(g_ctx, ast)), "y") == 0) { + if (!g_impl->ClassPropertyIsDefaultAccessModifierConst(g_ctx, ast)) { + g_count--; + } + } + if (g_impl->IsMethodDefinition(ast) && + strcmp(g_impl->IdentifierName(g_ctx, g_impl->ClassElementId(g_ctx, ast)), "foo1") == 0) { + if (g_impl->MethodDefinitionIsDefaultAccessModifierConst(g_ctx, ast)) { + g_count--; + } + } + if (g_impl->IsMethodDefinition(ast) && + strcmp(g_impl->IdentifierName(g_ctx, g_impl->ClassElementId(g_ctx, ast)), "foo2") == 0) { + if (!g_impl->MethodDefinitionIsDefaultAccessModifierConst(g_ctx, ast)) { + g_count--; + } + } + return g_count == 0; +} + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + + g_impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = g_impl->CreateConfig(argc - 1, args); + g_ctx = g_impl->CreateContextFromString(config, g_source.data(), argv[argc - 1]); + if (g_ctx == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_PARSED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + auto ast = g_impl->ProgramAst(g_ctx, g_impl->ContextProgram(g_ctx)); + if (!g_impl->AstNodeIsAnyChildConst(g_ctx, ast, Find)) { + return TEST_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_BIN_GENERATED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + g_impl->DestroyContext(g_ctx); + g_impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_dynamic_class_recheck.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_dynamic_class_recheck.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4355b52e6417937e0cfaff909ce291fa500662e2 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_dynamic_class_recheck.cpp @@ -0,0 +1,116 @@ +/** + * 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 +#include +#include +#include +#include + +#include "os/library_loader.h" + +#include "public/es2panda_lib.h" +#include "util.h" + +// NOLINTBEGIN +static std::string source = R"( +class $jscall {} +class $jsnew {} +)"; + +static es2panda_Impl *impl = nullptr; +es2panda_Context *context = nullptr; +static es2panda_AstNode *targetAfterCheck = nullptr; +static es2panda_AstNode *targetAfterReCheck = nullptr; + +static void SetTargetClass(es2panda_AstNode *ast, void *inputCtx) +{ + auto ctx = reinterpret_cast(inputCtx); + if (!impl->IsClassDeclaration(ast)) { + return; + } + + auto *def = impl->ClassDeclarationDefinition(ctx, ast); + if (def == nullptr) { + return; + } + + auto *ident = impl->ClassDefinitionIdent(ctx, def); + if (ident == nullptr) { + return; + } + auto name = impl->IdentifierName(ctx, ident); + if (std::string(name) == "$jscall") { + if (targetAfterCheck == nullptr) { + targetAfterCheck = ast; + return; + } + targetAfterReCheck = ast; + } +} + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return INVALID_ARGC_ERROR_CODE; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + impl = GetImpl(); + std::cout << "LOAD SUCCESS" << std::endl; + + const char **args = const_cast(&(argv[1])); + auto config = impl->CreateConfig(argc - 1, args); + context = impl->CreateContextFromString(config, source.data(), argv[argc - 1]); + if (context == nullptr) { + std::cerr << "FAILED TO CREATE CONTEXT" << std::endl; + return NULLPTR_CONTEXT_ERROR_CODE; + } + + impl->ProceedToState(context, ES2PANDA_STATE_CHECKED); + auto *program = impl->ContextProgram(context); + auto *ast = impl->ProgramAst(context, program); + impl->AstNodeForEach(ast, SetTargetClass, context); + if (targetAfterCheck == nullptr) { + std::cerr << "FAILED TO GET NODE" << std::endl; + return NULLPTR_CONTEXT_ERROR_CODE; + } + size_t len; + auto **stmts = impl->BlockStatementStatements(context, ast, &len); + auto *newStmts = static_cast(impl->AllocMemory(context, len + 1, sizeof(es2panda_AstNode *))); + for (size_t idx = 0; idx < len; ++idx) { + if (stmts[idx] != targetAfterCheck) { + newStmts[idx] = stmts[idx]; + continue; + } + + auto *def = impl->ClassDeclarationDefinition(context, targetAfterCheck); + targetAfterCheck = impl->UpdateClassDeclaration(context, targetAfterCheck, def); + newStmts[idx] = targetAfterCheck; + } + impl->BlockStatementSetStatements(context, ast, newStmts, len); + + impl->AstNodeRecheck(context, ast); + impl->AstNodeForEach(ast, SetTargetClass, context); + // the orignal class declaration named "jscall" or "jsnew" should be removed. + int res = targetAfterReCheck == nullptr ? 0 : TEST_ERROR_CODE; + impl->DestroyConfig(config); + + return res; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_error.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_error.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e4ebb2a0f5fd0308db6e30a9cfcc2a97fe8b4bbd --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_error.cpp @@ -0,0 +1,56 @@ +/** + * 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 "public/es2panda_lib.h" +#include "util.h" + +constexpr int PROCEED_ERROR_PARSER = NULLPTR_CONTEXT_ERROR_CODE + 1; +constexpr int PROCEED_ERROR_BOUND = PROCEED_ERROR_PARSER + 1; +constexpr int TEST_ERROR_PARSER = PROCEED_ERROR_BOUND + 1; +constexpr int TEST_ERROR_BOUND = TEST_ERROR_PARSER + 1; +constexpr int TEST_ERROR_CHECKED = TEST_ERROR_BOUND + 1; + +int main() +{ + es2panda_Impl *impl = GetImpl(); + const char *arg1 = "es2panda"; + const char *arg2 = "test.ets"; + char const *const args[] = {arg1, arg2}; + auto config = impl->CreateConfig(2, args); + auto context = impl->CreateContextFromString(config, "fn main() { println!(\"Hello, Rust!\") }", arg2); + if (context == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + impl->ProceedToState(context, ES2PANDA_STATE_PARSED); + if (impl->ContextState(context) != ES2PANDA_STATE_PARSED) { // Parsed, but + return PROCEED_ERROR_PARSER; + } + if (!impl->IsAnyError(context)) { // have errors reported + return TEST_ERROR_PARSER; + } + impl->ProceedToState(context, ES2PANDA_STATE_BOUND); + if (impl->ContextState(context) != ES2PANDA_STATE_BOUND) { // Bound, but + return PROCEED_ERROR_BOUND; + } + if (!impl->IsAnyError(context)) { // have errors reported + return TEST_ERROR_BOUND; + } + impl->ProceedToState(context, ES2PANDA_STATE_CHECKED); + // Will not proceed after checker if there are errors reported + if (impl->ContextState(context) != ES2PANDA_STATE_ERROR) { + return TEST_ERROR_CHECKED; + } + return 0; +} diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_import_declaration.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_import_declaration.cpp index 3cbc8d25db12c56f0a19fa25c741c252882f40c3..7d7f575528f3c2992d9ff13dd471bf470cb1c3bb 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_import_declaration.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_import_declaration.cpp @@ -35,7 +35,7 @@ void CheckForImportDeclaration(es2panda_AstNode *node, void *arg) return; } size_t n = 0; - auto specifiers = impl->ImportDeclarationSpecifiers(context, node, &n); + auto specifiers = impl->ImportDeclarationSpecifiersConst(context, node, &n); for (size_t i = 0; i < n; i++) { if (!impl->IsImportSpecifier(specifiers[i])) { std::cout << impl->IsImportSpecifier(specifiers[i]) << std::endl; diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_method_decl_by_name.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_method_decl_by_name.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f76e9b5847317397a3184f8cf8b786c1dbe94228 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_find_method_decl_by_name.cpp @@ -0,0 +1,102 @@ +/** + * 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 +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "public/es2panda_lib.h" + +// NOLINTBEGIN + +static es2panda_Impl *impl = nullptr; + +static bool NotNullAndPresentsInFoundAll(es2panda_AstNode *current, es2panda_AstNode **all, size_t all_len) +{ + if (current == nullptr || all == nullptr) { + return false; + } + + for (size_t i = 0; i < all_len; ++i) { + if (current == all[i]) { + return true; + } + } + + return false; +} + +static int TestFindMethodDeclByName(es2panda_Context *context) +{ + auto program = impl->ContextProgram(context); + auto Ast = impl->ProgramAst(context, program); + + size_t len = 0; + es2panda_AstNode **all_found = impl->AllDeclarationsByNameFromNode(context, Ast, "goo", &len); + es2panda_AstNode *found = impl->FirstDeclarationByNameFromNode(context, Ast, "goo"); + if (!NotNullAndPresentsInFoundAll(found, all_found, len)) { + std::cerr << "CANT FIND METHOD IN AST: goo" << std::endl; + return TEST_ERROR_CODE; + } + + std::vector names = {"too", "foo", "goo"}; + for (auto &name : names) { + all_found = impl->AllDeclarationsByNameFromProgram(context, program, name.c_str(), &len); + found = impl->FirstDeclarationByNameFromProgram(context, program, name.c_str()); + if (!NotNullAndPresentsInFoundAll(found, all_found, len)) { + std::cerr << "CANT FIND METHOD IN PROGRAM: " << name << std::endl; + return TEST_ERROR_CODE; + } + } + + return 0; +} + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = impl->CreateConfig(argc - 1, args); + auto context = impl->CreateContextFromFile(config, argv[argc - 1]); + if (context == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + + impl->ProceedToState(context, ES2PANDA_STATE_PARSED); + CheckForErrors("PARSE", context); + + impl->ProceedToState(context, ES2PANDA_STATE_BOUND); + CheckForErrors("BOUND", context); + + int result = TestFindMethodDeclByName(context); + + impl->DestroyContext(context); + impl->DestroyConfig(config); + + return result; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_function_dump.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_function_dump.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b04f4e7b42499db679f80b3da671c60437757c15 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_function_dump.cpp @@ -0,0 +1,48 @@ +/** + * 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 +#include "public/es2panda_lib.h" +#include "util.h" + +static es2panda_Impl *g_impl = nullptr; +static const char *const G_SOURCE = "export function foo(x?: int) {}"; +static std::string *g_dumpedSource = nullptr; + +int main(int argc, char **argv) +{ + auto dumpTest = [](es2panda_Context *context) -> bool { + const char *dumpedSourceInArenaMemory = + g_impl->AstNodeDumpEtsSrcConst(context, g_impl->ProgramAst(context, g_impl->ContextProgram(context))); + g_dumpedSource = new std::string(dumpedSourceInArenaMemory); + return g_dumpedSource->find(G_SOURCE) != std::string::npos; + }; + + std::map>> testFunctions1; + testFunctions1[ES2PANDA_STATE_CHECKED] = {dumpTest}; + ProccedToStatePluginTestData data1 = {argc, argv, &g_impl, testFunctions1, true, G_SOURCE, ES2PANDA_STATE_CHECKED}; + int result = RunAllStagesWithTestFunction(data1); + if (result != 0) { + delete g_dumpedSource; + return result; + } + + std::map>> testFunctions2; + ProccedToStatePluginTestData data2 = {argc, argv, &g_impl, testFunctions2, true, *g_dumpedSource}; + result = RunAllStagesWithTestFunction(data2); + delete g_dumpedSource; + g_dumpedSource = nullptr; + return result; +} diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_is_accessor-expected.txt b/ets2panda/test/unit/plugin/plugin_proceed_to_state_is_accessor-expected.txt index 6b6f349861b1b77fa7b60f2d12a35d4674224ce9..5f87b4030e8c41ba44451a366b7df97e47e3ea3a 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_is_accessor-expected.txt +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_is_accessor-expected.txt @@ -2,12 +2,12 @@ LOAD SUCCESS PROCEED TO PARSE SUCCESS SETTER: public set member(value: number) { - (this).m = value; + this.m = value; } GETTER: public get member() { - return (this).m; + return this.m; } PROCEED TO BOUND SUCCESS diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_is_optional_declaration.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_is_optional_declaration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46a0c140a131e3230f74da8327af01c5cafa143d --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_is_optional_declaration.cpp @@ -0,0 +1,79 @@ +/** + * 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 +#include +#include "util.h" + +// NOLINTBEGIN + +static es2panda_Impl *g_impl = nullptr; +static es2panda_Context *g_ctx = nullptr; +static std::string g_source = R"( + class A { + xx?:int + } + )"; + +bool Find(es2panda_AstNode *ast) +{ + if (g_impl->IsClassProperty(ast) && + !strcmp(g_impl->IdentifierName(g_ctx, g_impl->ClassElementId(g_ctx, ast)), "xx") && + g_impl->AstNodeIsOptionalDeclarationConst(g_ctx, ast)) { + return true; + } + return false; +} + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + + g_impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = g_impl->CreateConfig(argc - 1, args); + g_ctx = g_impl->CreateContextFromString(config, g_source.data(), argv[argc - 1]); + if (g_ctx == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_PARSED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + auto ast = g_impl->ProgramAst(g_ctx, g_impl->ContextProgram(g_ctx)); + if (!g_impl->AstNodeIsAnyChildConst(g_ctx, ast, Find)) { + return TEST_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_BIN_GENERATED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + g_impl->DestroyContext(g_ctx); + g_impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_log_diagnostic_with_suggestion.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_log_diagnostic_with_suggestion.cpp new file mode 100644 index 0000000000000000000000000000000000000000..246373f2dfe09b09f701f3f7b990b09c5191302c --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_log_diagnostic_with_suggestion.cpp @@ -0,0 +1,92 @@ +/** + * 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 +#include +#include "util.h" +#include "util/diagnosticEngine.h" + +// NOLINTBEGIN + +static es2panda_Impl *g_impl = nullptr; +static es2panda_Context *g_ctx = nullptr; +static std::string g_source = R"( +function main() {} +)"; + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + + g_impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = g_impl->CreateConfig(argc - 1, args); + g_ctx = g_impl->CreateContextFromString(config, g_source.data(), argv[argc - 1]); + if (g_ctx == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_PARSED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + auto suggestionkind = g_impl->CreateDiagnosticKind(g_ctx, "origin {}", ES2PANDA_PLUGIN_SUGGESTION); + const char *params[] = { + "a", + }; + auto suggestionInfo = g_impl->CreateSuggestionInfo(g_ctx, suggestionkind, params, 1, "replace b"); + auto diagnostikind = g_impl->CreateDiagnosticKind(g_ctx, "error", ES2PANDA_PLUGIN_ERROR); + auto diagnosticInfo = g_impl->CreateDiagnosticInfo(g_ctx, diagnostikind, nullptr, 0); + + es2panda_SourcePosition *left = g_impl->CreateSourcePosition(g_ctx, 0, 0); + es2panda_SourcePosition *right = g_impl->CreateSourcePosition(g_ctx, 7, 0); + es2panda_SourceRange *range = g_impl->CreateSourceRange(g_ctx, left, right); + + g_impl->LogDiagnosticWithSuggestion(g_ctx, diagnosticInfo, suggestionInfo, range); + + auto errors = g_impl->GetPluginErrors(g_ctx); + auto diagnosticStorage = reinterpret_cast(errors); + if (diagnosticStorage->size() != 1 || strcmp((*diagnosticStorage)[0]->Message().data(), "error") != 0) { + return TEST_ERROR_CODE; + } + + const size_t startLine = 0; + const size_t endLine = 0; + const size_t startIndex = 0; + const size_t endIndex = 7; + + auto diagnostic = reinterpret_cast(&(*(*diagnosticStorage)[0])); + auto suggestion = (diagnostic->Suggestion())[0]; + if (strcmp(suggestion->SubstitutionCode().data(), "replace b") != 0 || + strcmp(suggestion->Message().data(), "origin a") != 0 || suggestion->SourceRange()->start.line != startLine || + suggestion->SourceRange()->end.line != endLine || suggestion->SourceRange()->start.index != startIndex || + suggestion->SourceRange()->end.index != endIndex) { + return TEST_ERROR_CODE; + } + + g_impl->DestroyContext(g_ctx); + g_impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_new_expression-expected.txt b/ets2panda/test/unit/plugin/plugin_proceed_to_state_new_expression-expected.txt index b91d3a12192adb989f2d6820fcaa55d59b8f4feb..25232bbd38687a9419c8476be798bdc4dfef0467 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_new_expression-expected.txt +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_new_expression-expected.txt @@ -20,6 +20,4 @@ let a = new A() PROCEED TO BOUND SUCCESS PROCEED TO CHECKED SUCCESS -PROCEED TO LOWERED SUCCESS -PROCEED TO ASM SUCCESS PROCEED TO BIN SUCCESS diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_new_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_new_expression.cpp index 40cb095f9ccaebc1a10dffc9cb207d6e25cb3091..9f20032bec1d727dbdf1520fb2c468df664e55df 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_new_expression.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_new_expression.cpp @@ -103,6 +103,23 @@ static es2panda_AstNode *CreateNewExpr() return newExpr; } +bool Find(es2panda_AstNode *ast) +{ + if (impl->IsETSTypeReference(ast)) { + auto part = impl->ETSTypeReferencePart(context, ast); + auto newTypeReference = impl->UpdateETSTypeReference(context, ast, part); + auto property = impl->AstNodeParent(context, ast); + impl->ClassPropertySetTypeAnnotation(context, property, newTypeReference); + impl->AstNodeSetParent(context, newTypeReference, property); + impl->AstNodeSetParent(context, part, newTypeReference); + std::string str(impl->AstNodeDumpEtsSrcConst(context, property)); + if (str.find("public name: string = \"a\"") != std::string::npos) { + return true; + } + } + return false; +} + int main(int argc, char **argv) { if (argc < MIN_ARGC) { @@ -128,6 +145,10 @@ int main(int argc, char **argv) es2panda_AstNode *programNode = impl->ProgramAst(context, impl->ContextProgram(context)); + if (!impl->AstNodeIsAnyChildConst(context, programNode, Find)) { + return TEST_ERROR_CODE; + } + impl->AstNodeIterateConst(context, programNode, FindClass); impl->AstNodeIterateConst(context, programNode, FindVariableDeclaration); @@ -155,12 +176,6 @@ int main(int argc, char **argv) impl->AstNodeRecheck(context, programNode); - impl->ProceedToState(context, ES2PANDA_STATE_LOWERED); - CheckForErrors("LOWERED", context); - - impl->ProceedToState(context, ES2PANDA_STATE_ASM_GENERATED); - CheckForErrors("ASM", context); - impl->ProceedToState(context, ES2PANDA_STATE_BIN_GENERATED); CheckForErrors("BIN", context); impl->DestroyConfig(config); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_rerun_scopes_after_check.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_rerun_scopes_after_check.cpp index 06c7be9a966cffc12c1385d19d476125d9d0ea50..d577d30ebd3a38c872fc96af8ef0b983cc4ff946 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_rerun_scopes_after_check.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_rerun_scopes_after_check.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "util.h" #include "public/es2panda_lib.h" @@ -26,31 +27,18 @@ static es2panda_Impl *impl = nullptr; static auto source = std::string("function main() { \nlet a = 5;\n assertEQ(a, 5);\n }"); +constexpr int NUM_OF_CHANGE_IDENTIFIERS = 2; -static es2panda_AstNode *letStatement = nullptr; -static es2panda_AstNode *assertStatement = nullptr; static es2panda_AstNode *mainScriptFunc = nullptr; +static std::vector changeIdentifiers {}; static es2panda_Context *ctx = nullptr; -es2panda_AstNode *parNode; -es2panda_Context *newCtx; - -static void FindLet(es2panda_AstNode *ast) +static void FindChangeIdentifiers(es2panda_AstNode *ast) { - if (!impl->IsVariableDeclaration(ast)) { - impl->AstNodeIterateConst(ctx, ast, FindLet); - return; + if (impl->IsIdentifier(ast) && std::string(impl->IdentifierName(ctx, ast)) == "a") { + changeIdentifiers.emplace_back(ast); } - letStatement = ast; -} - -static void FindAssert(es2panda_AstNode *ast) -{ - if (!IsAssertCall(ast)) { - impl->AstNodeIterateConst(ctx, ast, FindAssert); - return; - } - assertStatement = ast; + impl->AstNodeIterateConst(ctx, ast, FindChangeIdentifiers); } static void FindMainDef(es2panda_AstNode *ast) @@ -68,112 +56,37 @@ static void FindMainDef(es2panda_AstNode *ast) mainScriptFunc = scriptFunc; } -static void changeParent(es2panda_AstNode *child) -{ - impl->AstNodeSetParent(newCtx, child, parNode); -} - -static void SetRightParent(es2panda_AstNode *node, void *arg) +static bool ChangeAst(es2panda_Context *context) { - es2panda_Context *context = static_cast(arg); - newCtx = context; - parNode = node; - impl->AstNodeIterateConst(context, node, changeParent); -} - -static bool ChangeAst(es2panda_Context *context, es2panda_AstNode *ast) -{ - std::cout << impl->AstNodeDumpJSONConst(context, ast) << std::endl; - size_t n = 0; + auto Ast = impl->ProgramAst(context, impl->ContextProgram(context)); ctx = context; - impl->AstNodeIterateConst(context, ast, FindLet); - impl->AstNodeIterateConst(context, ast, FindAssert); - impl->AstNodeIterateConst(context, ast, FindMainDef); - if (mainScriptFunc == nullptr || letStatement == nullptr || assertStatement == nullptr) { + impl->AstNodeIterateConst(context, Ast, FindMainDef); + if (mainScriptFunc == nullptr) { + return false; + } + impl->AstNodeIterateConst(context, mainScriptFunc, FindChangeIdentifiers); + if (changeIdentifiers.size() != NUM_OF_CHANGE_IDENTIFIERS) { return false; } - auto mainFuncBody = impl->ScriptFunctionBody(context, mainScriptFunc); - std::cout << impl->AstNodeDumpJSONConst(context, mainScriptFunc) << std::endl; - auto assertStatementTest = AssertStatementTest(context, assertStatement); - std::cout << impl->AstNodeDumpJSONConst(context, letStatement) << std::endl; - std::cout << impl->AstNodeDumpJSONConst(context, assertStatementTest) << std::endl; std::string className = std::string("b"); auto *memForName = static_cast(impl->AllocMemory(context, className.size() + 1, 1)); std::copy_n(className.c_str(), className.size() + 1, memForName); - auto varIdent = impl->CreateIdentifier1(context, memForName); - auto assertIdent = impl->CreateIdentifier1(context, memForName); - auto declarator = impl->CreateVariableDeclarator1( - context, Es2pandaVariableDeclaratorFlag::VARIABLE_DECLARATOR_FLAG_LET, varIdent, - impl->VariableDeclaratorInit(context, impl->VariableDeclarationDeclaratorsConst(context, letStatement, &n)[0])); - auto declaration = impl->CreateVariableDeclaration( - context, Es2pandaVariableDeclarationKind::VARIABLE_DECLARATION_KIND_LET, &declarator, 1); - - impl->BinaryExpressionSetLeft(context, assertStatementTest, assertIdent); - auto newAssertStatement = CreateAssertStatement(context, assertStatementTest, nullptr); - - es2panda_AstNode *newMainStatements[2] = {declaration, newAssertStatement}; - impl->BlockStatementSetStatements(context, mainFuncBody, newMainStatements, 2U); - impl->AstNodeForEach(ast, SetRightParent, context); - std::cout << impl->AstNodeDumpJSONConst(context, ast) << std::endl; - - impl->AstNodeRecheck(context, declaration); - impl->AstNodeRecheck(context, newAssertStatement); - - std::cout << impl->AstNodeDumpEtsSrcConst(context, ast) << std::endl; + for (auto ident : changeIdentifiers) { + impl->IdentifierSetName(context, ident, memForName); + } + std::cout << impl->AstNodeDumpEtsSrcConst(context, Ast) << std::endl; + impl->AstNodeRecheck(context, Ast); return true; } int main(int argc, char **argv) { - if (argc < MIN_ARGC) { - return INVALID_ARGC_ERROR_CODE; - } - - if (GetImpl() == nullptr) { - return NULLPTR_IMPL_ERROR_CODE; - } - impl = GetImpl(); - std::cout << "LOAD SUCCESS" << std::endl; - const char **args = const_cast(&(argv[1])); - auto config = impl->CreateConfig(argc - 1, args); - auto context = impl->CreateContextFromString(config, source.data(), argv[argc - 1]); - if (context == nullptr) { - std::cerr << "FAILED TO CREATE CONTEXT" << std::endl; - return NULLPTR_CONTEXT_ERROR_CODE; - } - - impl->ProceedToState(context, ES2PANDA_STATE_PARSED); - CheckForErrors("PARSE", context); - - impl->ProceedToState(context, ES2PANDA_STATE_BOUND); - CheckForErrors("BOUND", context); - - impl->ProceedToState(context, ES2PANDA_STATE_CHECKED); - CheckForErrors("CHECKED", context); - - auto ast = impl->ProgramAst(context, impl->ContextProgram(context)); - if (!ChangeAst(context, ast)) { - return TEST_ERROR_CODE; - } - - impl->AstNodeRecheck(context, ast); - - impl->ProceedToState(context, ES2PANDA_STATE_LOWERED); - CheckForErrors("LOWERED", context); - - impl->ProceedToState(context, ES2PANDA_STATE_ASM_GENERATED); - CheckForErrors("ASM", context); - - impl->ProceedToState(context, ES2PANDA_STATE_BIN_GENERATED); - CheckForErrors("BIN", context); - if (impl->ContextState(context) == ES2PANDA_STATE_ERROR) { - return PROCEED_ERROR_CODE; - } - impl->DestroyConfig(config); - - return 0; + std::map>> testFunctions; + testFunctions[ES2PANDA_STATE_CHECKED] = {ChangeAst}; + ProccedToStatePluginTestData data = {argc, argv, &impl, testFunctions, true, source}; + return RunAllStagesWithTestFunction(data); } // NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_rerun_scopes_on_import.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_rerun_scopes_on_import.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d97f84739b81c9a90920c3ac0d6be87dcfd74d2 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_rerun_scopes_on_import.cpp @@ -0,0 +1,110 @@ +/** + * 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 +#include +#include +#include +#include +#include +#include "util.h" +#include "public/es2panda_lib.h" + +// NOLINTBEGIN + +static es2panda_Impl *impl = nullptr; + +static es2panda_AstNode *letStatement = nullptr; +static std::vector *typeRefs = nullptr; +static es2panda_Context *ctx = nullptr; + +es2panda_AstNode *parNode; +es2panda_Context *newCtx; + +static void FindLet(es2panda_AstNode *ast) +{ + if (!impl->IsVariableDeclaration(ast)) { + impl->AstNodeIterateConst(ctx, ast, FindLet); + return; + } + letStatement = ast; +} + +static void FindEtsTypeReferencesInLet(es2panda_AstNode *ast) +{ + if (!impl->IsETSTypeReferencePart(ast)) { + impl->AstNodeIterateConst(ctx, ast, FindEtsTypeReferencesInLet); + return; + } + typeRefs->push_back(ast); + impl->AstNodeIterateConst(ctx, ast, FindEtsTypeReferencesInLet); +} + +static void changeParent(es2panda_AstNode *child) +{ + impl->AstNodeSetParent(newCtx, child, parNode); +} + +static void SetRightParent(es2panda_AstNode *node, void *arg) +{ + es2panda_Context *context = static_cast(arg); + newCtx = context; + parNode = node; + impl->AstNodeIterateConst(context, node, changeParent); +} + +static bool ChangeAst(es2panda_Context *context) +{ + auto Ast = impl->ProgramAst(context, impl->ContextProgram(context)); + ctx = context; + impl->AstNodeIterateConst(context, Ast, FindLet); + if (letStatement == nullptr) { + return false; + } + impl->AstNodeIterateConst(context, letStatement, FindEtsTypeReferencesInLet); + if (typeRefs == nullptr) { + return false; + } + + std::string className = std::string("B"); + auto *memForName = static_cast(impl->AllocMemory(context, className.size() + 1, 1)); + std::copy_n(className.c_str(), className.size() + 1, memForName); + + for (auto typeRef : *typeRefs) { + auto identifier = impl->ETSTypeReferencePartGetIdent(context, typeRef); + impl->IdentifierSetName(context, identifier, memForName); + } + impl->AstNodeForEach(Ast, SetRightParent, context); + impl->AstNodeRecheck(context, Ast); + return true; +} + +int main(int argc, char **argv) +{ + auto recheckTest = [&](es2panda_Context *context) -> bool { + typeRefs = new std::vector(); + auto testResult = ChangeAst(context); + delete typeRefs; + typeRefs = nullptr; + return testResult; + }; + + std::map>> testFunctions; + testFunctions[ES2PANDA_STATE_CHECKED] = {recheckTest}; + ProccedToStatePluginTestData data = {argc, argv, &impl, testFunctions, false, ""}; + return RunAllStagesWithTestFunction(data); +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_case_block_dump.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_case_block_dump.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c603bfc94fbae9a72bf767911c298c4da3b4e0c8 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_case_block_dump.cpp @@ -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. + */ + +#include +#include +#include +#include +#include "public/es2panda_lib.h" +#include "util.h" + +// NOLINTBEGIN +static std::string source = R"( +class C { + f(v: int) { + switch (v) { + case 1: { + const x = 1; + break; + } + case 2: { + const x = 1; + break; + } + default: { + const x = 1; + break; + } + } + } +} +)"; + +static es2panda_Impl *impl = nullptr; + +int main(int argc, char **argv) +{ + std::map>> testFunctions; + std::string dumpedSource {}; + testFunctions[ES2PANDA_STATE_CHECKED] = {[&dumpedSource](es2panda_Context *ctx) { + dumpedSource = impl->AstNodeDumpEtsSrcConst(ctx, impl->ProgramAst(ctx, impl->ContextProgram(ctx))); + std::cout << dumpedSource << std::endl; + return true; + }}; + ProccedToStatePluginTestData data = {argc, argv, &impl, testFunctions, true, source}; + auto testResult = RunAllStagesWithTestFunction(data); + if (testResult != 0) { + return testResult; + } + data.source = dumpedSource; + data.testFunctions = {}; + // Rerun test on dumped source + return RunAllStagesWithTestFunction(data); +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_global_func_call_dump.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_global_func_call_dump.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aebb296a910eb3056699f5865daa3d72cfaa8615 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_global_func_call_dump.cpp @@ -0,0 +1,86 @@ +/** + * 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 +#include +#include "util.h" +#include "public/es2panda_lib.h" + +// NOLINTBEGIN + +static es2panda_Impl *impl = nullptr; +static constexpr int NUMBER_OF_COMPILATION = 5; + +static std::string source = R"( +function foo() { + main(); +} +let c: number = 2; +function main() { + foo(); + console.log(c); + let b: number = c + 1; + let a: () => void = foo; + let d: number = b + 1; +} +class A { + goo() { + foo(); + } +} +)"; + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + es2panda_Config *config; + es2panda_Context *context; + + for (int i = 0; i < NUMBER_OF_COMPILATION; i++) { + config = impl->CreateConfig(argc - 1, args); + context = impl->CreateContextFromString(config, source.data(), argv[argc - 1]); + if (context == nullptr) { + return TEST_ERROR_CODE; + } + + impl->ProceedToState(context, ES2PANDA_STATE_CHECKED); + CheckForErrors("CHECKED", context); + + // Run es2panda on new source(src dump) + source = std::string( + impl->AstNodeDumpEtsSrcConst(context, impl->ProgramAst(context, impl->ContextProgram(context)))); + std::cout << source << std::endl; + impl->ProceedToState(context, ES2PANDA_STATE_BIN_GENERATED); + if (impl->ContextState(context) == ES2PANDA_STATE_ERROR) { + impl->DestroyContext(context); + impl->DestroyConfig(config); + return TEST_ERROR_CODE; + } + impl->DestroyContext(context); + impl->DestroyConfig(config); + } + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_interface_duplicate_setter.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_interface_duplicate_setter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66cacf08fea22ef1439331d275775a39f4222915 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_test_interface_duplicate_setter.cpp @@ -0,0 +1,106 @@ +/** + * 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 +#include +#include +#include +#include "util.h" +#include "public/es2panda_lib.h" + +// NOLINTBEGIN + +static es2panda_Impl *impl = nullptr; + +static std::string source = R"( +interface I { + p: number; +} + +interface J { + p: number; +} + +class A implements I { + private prop: number = 4.0; + + get p(): number { + return this.prop; + } + + set p(value: number) { + this.prop = value; + } +} + +class B implements J { + private prop: number = 4.0; + public p: number = 5.0; +} +)"; + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + impl = GetImpl(); + std::cout << "LOAD SUCCESS" << std::endl; + const char **args = const_cast(&(argv[1])); + auto config = impl->CreateConfig(argc - 1, args); + auto context = impl->CreateContextFromString(config, source.data(), argv[argc - 1]); + if (context != nullptr) { + std::cout << "CREATE CONTEXT SUCCESS" << std::endl; + } + + impl->ProceedToState(context, ES2PANDA_STATE_CHECKED); + CheckForErrors("CHECKED", context); + + std::string dump = impl->AstNodeDumpEtsSrcConst(context, impl->ProgramAst(context, impl->ContextProgram(context))); + std::cout << dump << std::endl; + + impl->ProceedToState(context, ES2PANDA_STATE_BIN_GENERATED); + if (impl->ContextState(context) == ES2PANDA_STATE_ERROR) { + impl->DestroyContext(context); + impl->DestroyConfig(config); + return PROCEED_ERROR_CODE; + } + impl->DestroyContext(context); + impl->DestroyConfig(config); + + // Rerun es2panda on dumped source + config = impl->CreateConfig(argc - 1, args); + context = impl->CreateContextFromString(config, dump.data(), argv[argc - 1]); + if (context != nullptr) { + std::cout << "CREATE CONTEXT SUCCESS" << std::endl; + } + + impl->ProceedToState(context, ES2PANDA_STATE_BIN_GENERATED); + if (impl->ContextState(context) == ES2PANDA_STATE_ERROR) { + impl->DestroyContext(context); + impl->DestroyConfig(config); + return PROCEED_ERROR_CODE; + } + impl->DestroyContext(context); + impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method-expected.txt b/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method-expected.txt index 22cfc8cabcadb520b662cfb5564dbd4b7c16aed2..2aab17eed0e70b75eaafe35e2b152735441446c7 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method-expected.txt +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method-expected.txt @@ -7,7 +7,7 @@ class A { public foo() { if (true) { - (this).x = 2; + this.x = 2; } } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_declaration.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_declaration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..29507dc4ff0aa1ebe232ccf8eefb220723b0a8f3 --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_declaration.cpp @@ -0,0 +1,169 @@ +/** + * 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 +#include +#include +#include "util.h" + +// NOLINTBEGIN + +static es2panda_Impl *g_impl = nullptr; +static es2panda_Context *g_ctx = nullptr; +static std::string g_source = R"( +interface A {} +class B { + get x() { return 1; } +} +function C() { + let a = 1; +} +)"; +static int g_count = 6; + +void FindFunctionDeclaration(es2panda_AstNode *ast) +{ + if (g_impl->IsFunctionDeclaration(ast)) { + auto scriptFunc = g_impl->FunctionDeclarationFunction(g_ctx, ast); + size_t len = 0; + auto params = g_impl->ScriptFunctionParams(g_ctx, scriptFunc, &len); + auto typeParams = g_impl->ScriptFunctionTypeParams(g_ctx, scriptFunc); + auto returnType = g_impl->ScriptFunctionReturnTypeAnnotation(g_ctx, scriptFunc); + auto signature = g_impl->CreateFunctionSignature(g_ctx, typeParams, params, len, returnType, false); + auto body = g_impl->ScriptFunctionBody(g_ctx, const_cast(scriptFunc)); + auto newScriptFunc = g_impl->CreateScriptFunction(g_ctx, body, signature, 0, 0); + auto name = g_impl->CreateIdentifier1(g_ctx, const_cast("D")); + g_impl->ScriptFunctionSetIdent(g_ctx, newScriptFunc, name); + auto funcDeclaration = g_impl->UpdateFunctionDeclaration(g_ctx, ast, newScriptFunc, nullptr, 0, false); + auto parent = g_impl->AstNodeParent(g_ctx, ast); + auto statements = g_impl->BlockStatementStatements(g_ctx, parent, &len); + const size_t position = 2; + statements[position] = funcDeclaration; + g_impl->AstNodeSetParent(g_ctx, scriptFunc, body); + g_impl->AstNodeSetParent(g_ctx, body, newScriptFunc); + g_impl->AstNodeSetParent(g_ctx, newScriptFunc, funcDeclaration); + g_impl->AstNodeSetParent(g_ctx, funcDeclaration, parent); + g_impl->BlockStatementSetStatements(g_ctx, parent, statements, len); + std::string str(g_impl->AstNodeDumpEtsSrcConst(g_ctx, funcDeclaration)); + if (str.find("function D()") != std::string::npos) { + g_count--; + } + } +} + +void FindVariableDeclaration(es2panda_AstNode *ast) +{ + if (g_impl->IsVariableDeclaration(ast)) { + size_t n = 0; + auto varIdent = g_impl->CreateIdentifier1(g_ctx, const_cast("b")); + auto declarator = g_impl->CreateVariableDeclarator1( + g_ctx, Es2pandaVariableDeclaratorFlag::VARIABLE_DECLARATOR_FLAG_LET, varIdent, + g_impl->VariableDeclaratorInit(g_ctx, g_impl->VariableDeclarationDeclaratorsConst(g_ctx, ast, &n)[0])); + auto stmt = g_impl->UpdateVariableDeclaration( + g_ctx, ast, Es2pandaVariableDeclarationKind::VARIABLE_DECLARATION_KIND_LET, &declarator, 1); + auto **stmts = static_cast(g_impl->AllocMemory(g_ctx, 1, sizeof(es2panda_AstNode *))); + stmts[0] = stmt; + g_impl->AstNodeSetParent(g_ctx, declarator, stmt); + g_impl->AstNodeSetParent(g_ctx, varIdent, declarator); + auto block = g_impl->AstNodeParent(g_ctx, ast); + if (g_impl->IsBlockStatement(block)) { + auto newBlock = g_impl->UpdateBlockStatement(g_ctx, block, stmts, 1); + g_impl->AstNodeSetParent(g_ctx, stmt, newBlock); + g_impl->ScriptFunctionSetBody(g_ctx, g_impl->AstNodeParent(g_ctx, block), newBlock); + std::string str(g_impl->AstNodeDumpEtsSrcConst(g_ctx, stmt)); + if (str.find("let b = 1;") != std::string::npos) { + g_count--; + } + } + } +} + +bool Find(es2panda_AstNode *ast) +{ + if (g_impl->IsTSInterfaceDeclaration(ast) && (g_impl->AstNodeModifiers(g_ctx, ast) & MODIFIER_FLAGS_PUBLIC)) { + g_count--; + } + FindFunctionDeclaration(ast); + FindVariableDeclaration(ast); + if (g_impl->MethodDefinitionIsGetterConst(g_ctx, ast)) { + g_count--; + } + if (g_impl->IsReturnStatement(ast)) { + auto arg = g_impl->CreateNumberLiteral(g_ctx, 2); + auto returnStmt = g_impl->UpdateReturnStatement(g_ctx, ast); + g_impl->ReturnStatementSetArgument(g_ctx, returnStmt, arg); + auto **stmts = static_cast(g_impl->AllocMemory(g_ctx, 1, sizeof(es2panda_AstNode *))); + stmts[0] = returnStmt; + std::string str(g_impl->AstNodeDumpEtsSrcConst(g_ctx, returnStmt)); + if (g_impl->IsBlockStatement(g_impl->AstNodeParent(g_ctx, ast)) && str.find("return 2;") != std::string::npos) { + g_impl->BlockStatementSetStatements(g_ctx, g_impl->AstNodeParent(g_ctx, ast), stmts, 1); + g_count--; + } + } + if (g_impl->IsIdentifier(ast) && strcmp(g_impl->IdentifierName(g_ctx, ast), "A") == 0) { + auto range = g_impl->AstNodeRangeConst(g_ctx, ast); + auto start = g_impl->SourceRangeStart(g_ctx, const_cast(range)); + auto end = g_impl->SourceRangeEnd(g_ctx, const_cast(range)); + const size_t startIndex = 11; + const size_t startLine = 1; + const size_t endIndex = 12; + const size_t endLine = 1; + if (startIndex == g_impl->SourcePositionIndex(g_ctx, start) && + startLine == g_impl->SourcePositionLine(g_ctx, start) && + endIndex == g_impl->SourcePositionIndex(g_ctx, end) && endLine == g_impl->SourcePositionLine(g_ctx, end)) { + g_count--; + } + } + return g_count == 0; +} + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + g_impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = g_impl->CreateConfig(argc - 1, args); + g_ctx = g_impl->CreateContextFromString(config, g_source.data(), argv[argc - 1]); + if (g_ctx == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_PARSED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + auto ast = g_impl->ProgramAst(g_ctx, g_impl->ContextProgram(g_ctx)); + if (!g_impl->AstNodeIsAnyChildConst(g_ctx, ast, Find)) { + return TEST_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_BIN_GENERATED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + g_impl->DestroyContext(g_ctx); + g_impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_expression.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0c3d8ab3583bf5d49001bbde692299c97ec8f9ab --- /dev/null +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_function_expression.cpp @@ -0,0 +1,99 @@ +/** + * 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 +#include +#include "util.h" + +// NOLINTBEGIN + +static es2panda_Impl *g_impl = nullptr; +static es2panda_Context *g_ctx = nullptr; +static std::string g_source = R"( +class A { + get x() { return 1; } +} +let add = () => { return 1;} +)"; +static int g_count = 2; + +bool Find(es2panda_AstNode *ast) +{ + if (g_impl->IsArrowFunctionExpression(ast)) { + auto scriptFunc = g_impl->ArrowFunctionExpressionFunction(g_ctx, ast); + auto newFunction = g_impl->UpdateArrowFunctionExpression(g_ctx, ast, scriptFunc); + auto parent = g_impl->AstNodeParent(g_ctx, ast); + g_impl->AstNodeSetParent(g_ctx, newFunction, parent); + g_impl->ClassElementSetValue(g_ctx, parent, newFunction); + std::string str(g_impl->AstNodeDumpEtsSrcConst(g_ctx, parent)); + if (str.find("add = (() => {") != std::string::npos) { + g_count--; + } + } + if (g_impl->IsFunctionExpression(ast)) { + auto scriptFunc = g_impl->FunctionExpressionFunction(g_ctx, ast); + if (strcmp(g_impl->IdentifierName(g_ctx, g_impl->ScriptFunctionId(g_ctx, scriptFunc)), "x") == 0) { + auto newFunction = g_impl->UpdateFunctionExpression(g_ctx, ast, scriptFunc); + auto parent = g_impl->AstNodeParent(g_ctx, ast); + g_impl->AstNodeSetParent(g_ctx, newFunction, parent); + g_impl->ClassElementSetValue(g_ctx, parent, newFunction); + std::string str(g_impl->AstNodeDumpEtsSrcConst(g_ctx, ast)); + if (str.find("() {\n return 1;") != std::string::npos) { + g_count--; + } + } + } + + return g_count == 0; +} + +int main(int argc, char **argv) +{ + if (argc < MIN_ARGC) { + return 1; + } + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + g_impl = GetImpl(); + const char **args = const_cast(&(argv[1])); + auto config = g_impl->CreateConfig(argc - 1, args); + g_ctx = g_impl->CreateContextFromString(config, g_source.data(), argv[argc - 1]); + if (g_ctx == nullptr) { + return NULLPTR_CONTEXT_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_PARSED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + auto ast = g_impl->ProgramAst(g_ctx, g_impl->ContextProgram(g_ctx)); + if (!g_impl->AstNodeIsAnyChildConst(g_ctx, ast, Find)) { + return TEST_ERROR_CODE; + } + + g_impl->ProceedToState(g_ctx, ES2PANDA_STATE_BIN_GENERATED); + if (g_impl->ContextState(g_ctx) == ES2PANDA_STATE_ERROR) { + return PROCEED_ERROR_CODE; + } + + g_impl->DestroyContext(g_ctx); + g_impl->DestroyConfig(config); + + return 0; +} + +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_declaration.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_declaration.cpp index 196032aedec0527dc7b63b1e08281687b81c4d0d..ae305d87f8a05031185ad48ea0c77a6033ce2051 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_declaration.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_update_import_declaration.cpp @@ -56,7 +56,7 @@ static std::string originalSourceCode = R"( import { PI as PI } from "std/math" )"; -void UpdateImportDeclaration(es2panda_Context *context) +bool UpdateImportDeclaration(es2panda_Context *context) { size_t sizeOfStatements = 0; auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); @@ -76,12 +76,22 @@ void UpdateImportDeclaration(es2panda_Context *context) impl->IdentifierSetName(context, newLocal, memForName); impl->IdentifierSetName(context, newImported, memForName); auto newSpecifier = impl->CreateImportSpecifier(context, newLocal, newImported); + if (impl->ImportSpecifierIsRemovableConst(context, newSpecifier)) { + return false; + } + impl->ImportSpecifierSetRemovable(context, newSpecifier, true); impl->AstNodeSetParent(context, newLocal, newSpecifier); impl->AstNodeSetParent(context, newImported, newSpecifier); auto newNode = impl->UpdateImportDeclaration(context, importNode, newSource, &newSpecifier, 1, Es2pandaImportKinds::IMPORT_KINDS_ALL); + if (newNode == nullptr) { + return false; + } + if (impl->ImportSpecifierIsRemovableConst(context, newSpecifier) == false) { + return false; + } impl->AstNodeSetParent(context, newSource, newNode); impl->AstNodeSetParent(context, newSpecifier, newNode); @@ -95,6 +105,7 @@ void UpdateImportDeclaration(es2panda_Context *context) impl->BlockStatementSetStatements(context, program, newStatements, sizeOfStatements); impl->AstNodeSetParent(context, newNode, program); + return true; } int main(int argc, char **argv) @@ -115,7 +126,9 @@ int main(int argc, char **argv) CheckForErrors("CHECKED", context); program = impl->ProgramAst(context, impl->ContextProgram(context)); - UpdateImportDeclaration(context); + if (UpdateImportDeclaration(context) == false) { + return 1; + } const char *src = impl->AstNodeDumpEtsSrcConst(context, program); const char *expected = "import { E as E } from \"new/std/math\""; diff --git a/ets2panda/test/unit/plugin/use_plugin_to_test_export_table.cpp b/ets2panda/test/unit/plugin/use_plugin_to_test_export_table.cpp index 855161adab04c3280f3e108b78898979eb5c062f..1bfb5a30effa8c3c2fcb7d418bc7b2b046e4f4c1 100644 --- a/ets2panda/test/unit/plugin/use_plugin_to_test_export_table.cpp +++ b/ets2panda/test/unit/plugin/use_plugin_to_test_export_table.cpp @@ -57,7 +57,7 @@ const std::string SOURCE_CODE = const std::string EXPECTED_CLASS_DEFINITION = "class A {\n public constructor() {}\n \n}\n"; -const std::string EXPECTED_METHOD_DEFINITION = "public static foo(): void {}\n"; +const std::string EXPECTED_METHOD_DEFINITION = "function foo(): void {}\n"; int CheckLiteralValues(ark::es2panda::public_lib::Context *ctx, const ark::pandasm::Program &prog) { diff --git a/ets2panda/test/unit/plugin/util.cpp b/ets2panda/test/unit/plugin/util.cpp index 8bf72741920887c4ad8e685f4bed785fc1ee1b31..e5709c5b75bff83da4e8214af53f6a76d584c81b 100644 --- a/ets2panda/test/unit/plugin/util.cpp +++ b/ets2panda/test/unit/plugin/util.cpp @@ -19,6 +19,7 @@ #include #include #include +#include "macros.h" static es2panda_Impl *g_implPtr = nullptr; @@ -39,7 +40,7 @@ es2panda_Impl *GetImpl() auto library = std::move(libraryRes.Value()); auto getImpl = ark::os::library_loader::ResolveSymbol(library, "es2panda_GetImpl"); if (!getImpl.HasValue()) { - std::cout << "Error in load func get impl" << std::endl; + std::cout << "Error in load func get g_implPtr" << std::endl; return nullptr; } @@ -75,7 +76,7 @@ void AppendStatementToProgram(es2panda_Context *context, es2panda_AstNode *progr auto impl = GetImpl(); size_t sizeOfStatements = 0; auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); - es2panda_AstNode **newStatements = + auto **newStatements = static_cast(impl->AllocMemory(context, sizeOfStatements + 1, sizeof(es2panda_AstNode *))); for (size_t i = 0; i < sizeOfStatements; i++) { newStatements[i] = statements[i]; @@ -90,7 +91,7 @@ void PrependStatementToProgram(es2panda_Context *context, es2panda_AstNode *prog auto impl = GetImpl(); size_t sizeOfStatements = 0; auto *statements = impl->BlockStatementStatements(context, program, &sizeOfStatements); - es2panda_AstNode **newStatements = + auto **newStatements = static_cast(impl->AllocMemory(context, sizeOfStatements + 1, sizeof(es2panda_AstNode *))); for (size_t i = 0; i < sizeOfStatements; i++) { newStatements[i + 1] = statements[i]; @@ -100,13 +101,107 @@ void PrependStatementToProgram(es2panda_Context *context, es2panda_AstNode *prog impl->AstNodeSetParent(context, newStatement, program); } +static const char *GetPhaseName(es2panda_ContextState state) +{ + switch (state) { + case ES2PANDA_STATE_NEW: + return "NEW"; + case ES2PANDA_STATE_PARSED: + return "PARSE"; + case ES2PANDA_STATE_BOUND: + return "BOUND"; + case ES2PANDA_STATE_CHECKED: + return "CHECKED"; + case ES2PANDA_STATE_LOWERED: + return "LOWERED"; + case ES2PANDA_STATE_ASM_GENERATED: + return "ASM"; + case ES2PANDA_STATE_BIN_GENERATED: + return "BIN"; + case ES2PANDA_STATE_ERROR: + return "ERROR"; + default: + return "NON_VALID_STATE"; + } +} + +static bool IsAllowedStage(es2panda_ContextState state) +{ + switch (state) { + case ES2PANDA_STATE_NEW: + return false; + case ES2PANDA_STATE_ERROR: + return false; + default: + return true; + } +} + +static int DestroyTest(es2panda_Context *context, es2panda_Config *config, const int exitCode) +{ + g_implPtr->DestroyContext(context); + g_implPtr->DestroyConfig(config); + return exitCode; +} + +int RunAllStagesWithTestFunction(ProccedToStatePluginTestData &data) +{ + if (data.argc < MIN_ARGC) { + return INVALID_ARGC_ERROR_CODE; + } + + if (GetImpl() == nullptr) { + return NULLPTR_IMPL_ERROR_CODE; + } + *data.impl = GetImpl(); + std::cout << "LOAD SUCCESS" << std::endl; + const char **args = const_cast(&(data.argv[1])); + auto config = g_implPtr->CreateConfig(data.argc - 1, args); + es2panda_Context *context = nullptr; + if (data.fromSource) { + context = g_implPtr->CreateContextFromString(config, data.source.data(), data.argv[data.argc - 1]); + } else { + context = g_implPtr->CreateContextFromFile(config, data.argv[data.argc - 1]); + } + if (context == nullptr) { + std::cerr << "FAILED TO CREATE CONTEXT" << std::endl; + return NULLPTR_CONTEXT_ERROR_CODE; + } + + for (auto [testStage, _] : data.testFunctions) { + if (!IsAllowedStage(testStage)) { + return DestroyTest(context, config, TEST_ERROR_CODE); + } + } + + for (auto state = ES2PANDA_STATE_PARSED; state <= ES2PANDA_STATE_BIN_GENERATED; + state = static_cast(state + 1)) { + if (!IsAllowedStage(state)) { + continue; + } + g_implPtr->ProceedToState(context, state); + CheckForErrors(GetPhaseName(state), context); + for (const auto &testFunc : data.testFunctions[state]) { + if (!testFunc(context)) { + return DestroyTest(context, config, TEST_ERROR_CODE); + } + } + if (state == data.exitAfterState) { + break; + } + } + + int result = g_implPtr->ContextState(context) == ES2PANDA_STATE_ERROR ? PROCEED_ERROR_CODE : 0; + return DestroyTest(context, config, result); +} + int Test(es2panda_Context *context, es2panda_Impl *impl, int stage, - std::function handle) + const std::function &handle) { impl->ProceedToState(context, ES2PANDA_STATE_PARSED); CheckForErrors("PARSE", context); es2panda_AstNode *ast = impl->ProgramAst(context, impl->ContextProgram(context)); - if (!ast) { + if (ast == nullptr) { return TEST_ERROR_CODE; } switch (stage) { @@ -128,6 +223,9 @@ int Test(es2panda_Context *context, es2panda_Impl *impl, int stage, CheckForErrors("LOWERED", context); break; } + default: { + UNREACHABLE(); + } } if (impl->ContextState(context) == ES2PANDA_STATE_ERROR) { return PROCEED_ERROR_CODE; @@ -147,4 +245,4 @@ int Test(es2panda_Context *context, es2panda_Impl *impl, int stage, } impl->DestroyContext(context); return 0; -} \ No newline at end of file +} diff --git a/ets2panda/test/unit/plugin/util.h b/ets2panda/test/unit/plugin/util.h index 1fd7c0869a8b4a89572719a5cbc6fee97e6bade8..515f89b105bd02b3155f3658e172b7fd02788d7a 100644 --- a/ets2panda/test/unit/plugin/util.h +++ b/ets2panda/test/unit/plugin/util.h @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "os/library_loader.h" @@ -35,10 +37,21 @@ constexpr int NULLPTR_CONTEXT_ERROR_CODE = 6; es2panda_Impl *GetImpl(); +struct ProccedToStatePluginTestData { + int argc; + char **argv; + es2panda_Impl **impl; + std::map>> testFunctions; + bool fromSource; + std::string source; + es2panda_ContextState exitAfterState = ES2PANDA_STATE_ERROR; +}; + void CheckForErrors(const std::string &stateName, es2panda_Context *context); bool IsAssertCall(es2panda_AstNode *ast); es2panda_AstNode *CreateAssertStatement(es2panda_Context *context, es2panda_AstNode *test, es2panda_AstNode *second); es2panda_AstNode *AssertStatementTest(es2panda_Context *context, es2panda_AstNode *classInstance); +int RunAllStagesWithTestFunction(ProccedToStatePluginTestData &data); es2panda_AstNode *CreateIdentifierFromString(es2panda_Context *context, const std::string_view &name); @@ -47,6 +60,6 @@ void AppendStatementToProgram(es2panda_Context *context, es2panda_AstNode *progr void PrependStatementToProgram(es2panda_Context *context, es2panda_AstNode *program, es2panda_AstNode *newStatement); int Test(es2panda_Context *context, es2panda_Impl *impl, int stage, - std::function handle); + const std::function &handle); #endif diff --git a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp index d0dccca96004cb5e56d15a5c1ff122eac62db10a..7e88eff58069a34f01ac3ba0abc2ed237d37e9c3 100644 --- a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp +++ b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_i.cpp @@ -273,7 +273,7 @@ es2panda_RecordTable *classInstance/*return_args:*/, size_t *returnTypeLen) size_t i = 0; for (auto elem : resultSet) { auto toPush = reinterpret_cast< es2panda_AstNode *>(elem); - apiRes[i] = reinterpret_cast< es2panda_AstNode *>(toPush); + apiRes[i++] = reinterpret_cast< es2panda_AstNode *>(toPush); }; return apiRes; } @@ -343,7 +343,7 @@ TEST_F(PluginConversionRuleUnitTest, PairReturnValue) es2panda_Type *classInstance, [[maybe_unused]] es2panda_Type *sourceType/*return_args:*/, es2panda_Type **returnTypeSecond) { - auto *checkerE2p = reinterpret_cast(context)->checker->AsETSChecker(); + auto *checkerE2p = reinterpret_cast(context)->GetChecker()->AsETSChecker(); auto *sourceTypeE2p = reinterpret_cast(sourceType); auto *ctx = reinterpret_cast(context); [[maybe_unused]] auto *ctxAllocator = ctx->allocator; diff --git a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_ii.cpp b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_ii.cpp index d6f9e1b2820481ee809bf898384cd9ffa1f7d503..eee97381aa92785d2a7f9622fdb8c9bff839ce26 100644 --- a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_ii.cpp +++ b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_ii.cpp @@ -60,7 +60,7 @@ TEST_F(PluginConversionRuleUnitTest, CheckerTypeRelationConstructor) std::string targetCAPI {R"( extern "C" es2panda_TypeRelation *CreateTypeRelation([[maybe_unused]] es2panda_Context *context) { - auto *checkerE2p = reinterpret_cast(context)->checker; + auto *checkerE2p = reinterpret_cast(context)->GetChecker(); auto *ctx = reinterpret_cast(context); auto *ctxAllocator = ctx->allocator; return reinterpret_cast(ctxAllocator->New(checkerE2p)); 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 5678a362f547cf8c6575137c838f64f66eaf3f72..7c111a02bf1cb936eb920ec6ebace5d6144cae3d 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 @@ -198,7 +198,7 @@ TEST_F(PluginConversionRuleUnitTest, SourcePositionInputParameter) extern "C" void AstNodeSetStart([[maybe_unused]] es2panda_Context *context, es2panda_AstNode *classInstance, [[maybe_unused]] es2panda_SourcePosition *start/*return_args:*/) { - auto startE2p = *reinterpret_cast(start); + auto &startE2p = *reinterpret_cast(start); ((reinterpret_cast< ir::AstNode *>(classInstance))->SetStart(startE2p)); })"}; @@ -247,7 +247,7 @@ TEST_F(PluginConversionRuleUnitTest, VRegInputParameter) [[maybe_unused]] es2panda_VReg *objReg/*return_args:*/) { auto *pgE2p = reinterpret_cast(pg); - auto objRegE2p = *reinterpret_cast(objReg); + auto &objRegE2p = *reinterpret_cast(objReg); ((reinterpret_cast(classInstance))->CompileToReg(pgE2p, objRegE2p)); })"}; 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 8eb1282e8cd57206baca8071d10c9004b14e86fc..1b4c7be1d7115e28a79a197d3f1a15554b92e3df 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 @@ -62,7 +62,7 @@ TEST_F(PluginConversionRuleUnitTest, CheckerContextPtrReturnValue) extern "C" es2panda_CheckerContext *CreateCheckerContext([[maybe_unused]] es2panda_Context *context, [[maybe_unused]] Es2pandaCheckerStatus newStatus) { - auto *checkerE2p = reinterpret_cast(context)->checker; + auto *checkerE2p = reinterpret_cast(context)->GetChecker(); auto newStatusE2p = E2pToIrCheckerStatus(newStatus); auto *ctx = reinterpret_cast(context); auto *ctxAllocator = ctx->allocator; @@ -97,7 +97,7 @@ TEST_F(PluginConversionRuleUnitTest, CheckerContextPtrConstructor) extern "C" es2panda_CheckerContext *CreateCheckerContext([[maybe_unused]] es2panda_Context *context, [[maybe_unused]] Es2pandaCheckerStatus newStatus) { - auto *checkerE2p = reinterpret_cast(context)->checker; + auto *checkerE2p = reinterpret_cast(context)->GetChecker(); auto newStatusE2p = E2pToIrCheckerStatus(newStatus); auto *ctx = reinterpret_cast(context); auto *ctxAllocator = ctx->allocator; @@ -352,12 +352,11 @@ TEST_F(PluginConversionRuleUnitTest, PropertyProcessorInputParameter) extern "C" void ETSObjectTypeUpdateTypeProperties([[maybe_unused]] es2panda_Context *context, es2panda_Type *classInstance, [[maybe_unused]] PropertyProcessor func/*return_args:*/) { - auto *checkerE2p = reinterpret_cast(context)->checker->AsETSChecker(); std::function funcE2p = [func](varbinder::LocalVariable *propertyProcessorLambdaVariable, checker::Type *propertyProcessorLambdaType) { return reinterpret_cast(func(reinterpret_cast (propertyProcessorLambdaVariable), reinterpret_cast(propertyProcessorLambdaType)));}; - ((reinterpret_cast< checker::ETSObjectType *>(classInstance))->UpdateTypeProperties(checkerE2p, funcE2p)); + ((reinterpret_cast< checker::ETSObjectType *>(classInstance))->UpdateTypeProperties(funcE2p)); })"}; std::string targetAPIWithNoSpace = RemoveWhitespace(targetCAPI); diff --git a/ets2panda/test/unit/public/CMakeLists.txt b/ets2panda/test/unit/public/CMakeLists.txt index 1d3a5c064393e2a25bb2406aef8dfcda045b8481..ed6fd59ca481789c210c99263a404c0bc584ce31 100644 --- a/ets2panda/test/unit/public/CMakeLists.txt +++ b/ets2panda/test/unit/public/CMakeLists.txt @@ -38,13 +38,11 @@ ets2panda_add_gtest(ast_verifier_test_2 ast_verifier_variable_has_enclosing_scope_test.cpp ast_verifier_variable_has_scope_test.cpp ast_verifier_every_child_has_valid_parent_test.cpp - ast_verifier_check_infinite_loop_test.cpp TEST_GROUP qemu_excluded_gtests ) ets2panda_add_gtest(ast_verifier_test_3 CPP_SOURCES - ast_verifier_check_normal_loop_test.cpp ast_verifier_check_abstract_call_test.cpp ast_verifier_getter_setter_test.cpp ast_verifier_check_const_properties_test.cpp diff --git a/ets2panda/test/unit/public/ast_verifier_check_abstract_call_test.cpp b/ets2panda/test/unit/public/ast_verifier_check_abstract_call_test.cpp index 4564a46588737aec56e7d886b7c7bc1f7f81723a..7814d7f261bf2ede5137cefe7217592859b56161 100644 --- a/ets2panda/test/unit/public/ast_verifier_check_abstract_call_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_check_abstract_call_test.cpp @@ -33,7 +33,7 @@ namespace { TEST_F(ASTVerifierTest, LabelsHaveReferences) { ark::es2panda::util::DiagnosticEngine de; - ark::es2panda::checker::ETSChecker checker(de); + ark::es2panda::checker::ETSChecker checker {Allocator(), de}; char const *text = R"( abstract class A { diff --git a/ets2panda/test/unit/public/ast_verifier_check_const_properties_test.cpp b/ets2panda/test/unit/public/ast_verifier_check_const_properties_test.cpp index 51b3a9e2cfa67f1d3a5cfc22de33bcb5822e853e..2652cdfe6fe8bd1e178704da2bde225731af52f2 100644 --- a/ets2panda/test/unit/public/ast_verifier_check_const_properties_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_check_const_properties_test.cpp @@ -26,7 +26,7 @@ namespace { TEST_F(ASTVerifierTest, CheckConstProperties) { ark::es2panda::util::DiagnosticEngine de {}; - ark::es2panda::checker::ETSChecker checker {de}; + ark::es2panda::checker::ETSChecker checker {Allocator(), de}; char const *text = R"( class Test diff --git a/ets2panda/test/unit/public/ast_verifier_check_infinite_loop_test.cpp b/ets2panda/test/unit/public/ast_verifier_check_infinite_loop_test.cpp deleted file mode 100644 index 065f09d578141424723546ff9842470764503005..0000000000000000000000000000000000000000 --- a/ets2panda/test/unit/public/ast_verifier_check_infinite_loop_test.cpp +++ /dev/null @@ -1,94 +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. - */ - -#include "ast_verifier_test.h" -#include "ir/astNode.h" -#include "public/es2panda_lib.h" - -#include - -using ark::es2panda::compiler::ast_verifier::CheckInfiniteLoop; - -namespace { -struct TestData { - char const *program; -}; - -// NOLINTNEXTLINE(fuchsia-multiple-inheritance) -class InfiniteLoopTests : public ASTVerifierTest, public testing::WithParamInterface {}; - -// clang-format off -INSTANTIATE_TEST_SUITE_P(, - InfiniteLoopTests, - testing::Values( - TestData { - R"( - function main () { - while (true) {} - } - )", - }, - TestData { - R"( - function main () { - while (2 > 1) {} - } - )", - }, - TestData { - R"( - function main () { - do { - } while (true) - } - )", - }, - TestData { - R"( - function main () { - do { - } while (2 > 1) - } - )", - }, - TestData { - R"( - function main () { - for (;;) {} - } - )", - }, - TestData { - R"( - function main () { - for (; 2 > 1;) {} - } - )", - } -)); -// clang-format on - -TEST_P(InfiniteLoopTests, InfiniteLoop) -{ - TestData data = GetParam(); - - char const *text = data.program; - - CONTEXT(ES2PANDA_STATE_CHECKED, text) - { - EXPECT_TRUE(Verify(ExpectVerifierMessage {"INFINITE LOOP"})); - } -} -} // namespace diff --git a/ets2panda/test/unit/public/ast_verifier_check_normal_loop_test.cpp b/ets2panda/test/unit/public/ast_verifier_check_normal_loop_test.cpp deleted file mode 100644 index 255adba42ac5e8083ce356d195c09f11d59de258..0000000000000000000000000000000000000000 --- a/ets2panda/test/unit/public/ast_verifier_check_normal_loop_test.cpp +++ /dev/null @@ -1,75 +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. - */ - -#include "ast_verifier_test.h" -#include "ir/astNode.h" -#include "public/es2panda_lib.h" - -#include - -using ark::es2panda::compiler::ast_verifier::CheckInfiniteLoop; - -namespace { -struct TestData { - char const *program; -}; - -// NOLINTNEXTLINE(fuchsia-multiple-inheritance) -class NormalLoopTests : public ASTVerifierTest, public testing::WithParamInterface {}; - -// clang-format off -INSTANTIATE_TEST_SUITE_P(, - NormalLoopTests, - testing::Values( - TestData { - R"( - function main() { - let counter = 0; - while (counter < 10) { - counter = counter + 1; - } - } - )", - }, - TestData { - R"( - function main() { - let counter = 0; - do { - counter = counter + 1 - } while (counter < 10) - } - )", - }, - TestData { - R"( - function main() { - for (let i = 0; i < 10; ++i) {} - } - )", - })); -// clang-format on - -TEST_P(NormalLoopTests, NormalLoop) -{ - TestData data = GetParam(); - char const *text = data.program; - - CONTEXT(ES2PANDA_STATE_CHECKED, text) - { - EXPECT_TRUE(Verify()); - } -} -} // namespace diff --git a/ets2panda/test/unit/public/ast_verifier_check_struct_declaration_test.cpp b/ets2panda/test/unit/public/ast_verifier_check_struct_declaration_test.cpp index 5913d522d31282c3cd7f24186840e4266a59f3f6..dbdd1b433c20cd6034af0c1074360b797b1c39e2 100644 --- a/ets2panda/test/unit/public/ast_verifier_check_struct_declaration_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_check_struct_declaration_test.cpp @@ -163,7 +163,10 @@ TEST_F(ASTVerifierTest, StructInStruct) } )"; - CONTEXT(ES2PANDA_STATE_PARSED, ES2PANDA_STATE_ERROR, text) {} + CONTEXT(ES2PANDA_STATE_PARSED, ES2PANDA_STATE_ERROR, text) + { + ASSERT_TRUE(GetImpl()->IsAnyError(GetContext())); + } } } // namespace diff --git a/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp b/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp index b8d0e4960490b31aa08f7d9f85341080a4eeda5c..651b6ab840ed182055a63a6627d43f64c3f841db 100644 --- a/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_getter_setter_neg_test.cpp @@ -29,7 +29,7 @@ namespace { TEST_F(ASTVerifierTest, ValidateGetterReturnTypeAnnotation) { DiagnosticEngine de {}; - ETSChecker checker {de}; + ETSChecker checker {Allocator(), de}; char const *text = R"( @@ -87,7 +87,7 @@ TEST_F(ASTVerifierTest, ValidateGetterHasReturnStatement) auto *const method = child->AsMethodDefinition(); if (method->IsGetter() && method->Value()->IsFunctionExpression()) { auto *const function = method->Value()->AsFunctionExpression()->Function(); - auto &returns = function->ReturnStatements(); + auto &returns = function->ReturnStatementsForUpdate(); returns.clear(); } } @@ -104,7 +104,7 @@ TEST_F(ASTVerifierTest, ValidateGetterHasReturnStatement) TEST_F(ASTVerifierTest, ValidateGetterVoidReturnStatement) { DiagnosticEngine de {}; - ETSChecker checker {de}; + ETSChecker checker {Allocator(), de}; char const *text = R"( @@ -142,7 +142,7 @@ TEST_F(ASTVerifierTest, ValidateGetterVoidReturnStatement) TEST_F(ASTVerifierTest, ValidateGetterArguments) { DiagnosticEngine de {}; - ETSChecker checker {de}; + ETSChecker checker {Allocator(), de}; char const *text = R"( @@ -166,7 +166,7 @@ TEST_F(ASTVerifierTest, ValidateGetterArguments) auto *const method = child->AsMethodDefinition(); if (method->IsGetter() && method->Value()->IsFunctionExpression()) { auto *const function = method->Value()->AsFunctionExpression()->Function(); - auto ¶ms = function->Params(); + auto ¶ms = function->ParamsForUpdate(); ASSERT_EQ(params.size(), 0); params.push_back(param); } @@ -184,7 +184,7 @@ TEST_F(ASTVerifierTest, ValidateGetterArguments) TEST_F(ASTVerifierTest, ValidateSetterReturnType) { DiagnosticEngine de {}; - ETSChecker checker {de}; + ETSChecker checker {Allocator(), de}; char const *text = R"( @@ -225,7 +225,7 @@ TEST_F(ASTVerifierTest, ValidateSetterReturnType) TEST_F(ASTVerifierTest, ValidateSetterArguments) { DiagnosticEngine de {}; - ETSChecker checker {de}; + ETSChecker checker {Allocator(), de}; char const *text = R"( @@ -245,7 +245,7 @@ TEST_F(ASTVerifierTest, ValidateSetterArguments) auto *const method = child->AsMethodDefinition(); if (method->IsSetter() && method->Value()->IsFunctionExpression()) { auto *const function = method->Value()->AsFunctionExpression()->Function(); - auto ¶ms = function->Params(); + auto ¶ms = function->ParamsForUpdate(); ASSERT_EQ(params.size(), 1); params.clear(); } diff --git a/ets2panda/test/unit/public/ast_verifier_getter_setter_test.cpp b/ets2panda/test/unit/public/ast_verifier_getter_setter_test.cpp index 7ee4731ed7ff27114ecf4f2338e56762487f4851..542d91ddf755197429d7945a23a9a83e8faa5785 100644 --- a/ets2panda/test/unit/public/ast_verifier_getter_setter_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_getter_setter_test.cpp @@ -27,7 +27,7 @@ namespace { TEST_F(ASTVerifierTest, ValidateCorrectGetterSetter) { DiagnosticEngine de {}; - ETSChecker checker {de}; + ETSChecker checker {Allocator(), de}; char const *text = R"( @@ -52,7 +52,7 @@ TEST_F(ASTVerifierTest, ValidateCorrectGetterSetter) TEST_F(ASTVerifierTest, ValidateAbstractGettersSetters) { DiagnosticEngine de {}; - ETSChecker checker {de}; + ETSChecker checker {Allocator(), de}; char const *text = R"( @@ -72,7 +72,7 @@ TEST_F(ASTVerifierTest, ValidateAbstractGettersSetters) TEST_F(ASTVerifierTest, ValidateAmbientGettersSetters) { DiagnosticEngine de {}; - ETSChecker checker {de}; + ETSChecker checker {Allocator(), de}; char const *text = R"( diff --git a/ets2panda/test/unit/public/ast_verifier_private_access_negative_test.cpp b/ets2panda/test/unit/public/ast_verifier_private_access_negative_test.cpp index 917dc392710c873a58d775deddb6d41389a85438..4fbc212dba126534b2352772abe78d8a644b1d23 100644 --- a/ets2panda/test/unit/public/ast_verifier_private_access_negative_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_private_access_negative_test.cpp @@ -16,6 +16,8 @@ #include "ast_verifier_test.h" #include "checker/ETSchecker.h" +namespace { + using ark::es2panda::compiler::ast_verifier::ModifierAccessValid; TEST_F(ASTVerifierTest, PrivateAccessTestNegative1) @@ -40,8 +42,7 @@ TEST_F(ASTVerifierTest, PrivateAccessTestNegative1) ->AsClassProperty() ->AddModifier(ark::es2panda::ir::ModifierFlags::PRIVATE); - EXPECT_TRUE(Verify( - ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE(AstNodeType::MEMBER_EXPRESSION, line 6)"})); + EXPECT_TRUE(Verify(ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE"})); } } @@ -96,8 +97,7 @@ TEST_F(ASTVerifierTest, PrivateAccessTestNegative3) ->AsClassProperty() ->AddModifier(ark::es2panda::ir::ModifierFlags::PRIVATE); - EXPECT_TRUE(Verify( - ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE(AstNodeType::MEMBER_EXPRESSION, line 8)"})); + EXPECT_TRUE(Verify(ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE"})); } } @@ -253,3 +253,5 @@ TEST_F(ASTVerifierTest, PrivateAccessTestNegative7) EXPECT_TRUE(Verify(ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE"})); } } + +} // namespace diff --git a/ets2panda/test/unit/public/ast_verifier_protected_access_negative_test.cpp b/ets2panda/test/unit/public/ast_verifier_protected_access_negative_test.cpp index b605d4926eabb2d26170bc78596d75e6c3c6624e..2573cc1244f5604e63a9483ac5be715148b32388 100644 --- a/ets2panda/test/unit/public/ast_verifier_protected_access_negative_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_protected_access_negative_test.cpp @@ -16,6 +16,8 @@ #include "ast_verifier_test.h" #include "checker/ETSchecker.h" +namespace { + using ark::es2panda::compiler::ast_verifier::ModifierAccessValid; TEST_F(ASTVerifierTest, ProtectedAccessTestNegative1) @@ -41,8 +43,7 @@ TEST_F(ASTVerifierTest, ProtectedAccessTestNegative1) ->AsClassProperty() ->AddModifier(ark::es2panda::ir::ModifierFlags::PROTECTED); - EXPECT_TRUE(Verify( - ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE(AstNodeType::MEMBER_EXPRESSION, line 7)"})); + EXPECT_TRUE(Verify(ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE"})); } } @@ -98,8 +99,7 @@ TEST_F(ASTVerifierTest, ProtectedAccessTestNegative3) ->AsClassProperty() ->AddModifier(ark::es2panda::ir::ModifierFlags::PROTECTED); - EXPECT_TRUE(Verify( - ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE(AstNodeType::MEMBER_EXPRESSION, line 8)"})); + EXPECT_TRUE(Verify(ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE"})); } } @@ -227,3 +227,5 @@ TEST_F(ASTVerifierTest, ProtectedAccessTestNegative6) EXPECT_TRUE(Verify(ExpectVerifierMessage {"PROPERTY_NOT_VISIBLE_HERE"})); } } + +} // namespace diff --git a/ets2panda/test/unit/public/ast_verifier_short_test.cpp b/ets2panda/test/unit/public/ast_verifier_short_test.cpp index dec7ee7442e8c867961d7a8442851ab41ae20a05..4a20d2a0540dbc26ed29e1649e1400191036df99 100644 --- a/ets2panda/test/unit/public/ast_verifier_short_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_short_test.cpp @@ -24,6 +24,8 @@ #include "varbinder/ETSBinder.h" #include "util/diagnosticEngine.h" +namespace { + using ark::es2panda::ScriptExtension; using ark::es2panda::checker::ETSChecker; using ark::es2panda::compiler::ast_verifier::ArithmeticOperationValid; @@ -55,22 +57,20 @@ using ark::es2panda::varbinder::VariableFlags; TEST_F(ASTVerifierTest, NullParent) { StringLiteral emptyNode; - EXPECT_TRUE(VerifyNode(&emptyNode, - ExpectVerifierMessage {"NULL_PARENT(AstNodeType::STRING_LITERAL, line 1)"})); + EXPECT_TRUE(VerifyNode(&emptyNode, ExpectVerifierMessage {"NULL_PARENT"})); } TEST_F(ASTVerifierTest, NullRange) { StringLiteral emptyNode; - EXPECT_TRUE(VerifyNode( - &emptyNode, ExpectVerifierMessage {"NULL_RANGE(AstNodeType::STRING_LITERAL, line 1)"})); + EXPECT_TRUE(VerifyNode(&emptyNode, ExpectVerifierMessage {"NULL_RANGE"})); } -TEST_F(ASTVerifierTest, NullType) +// NOTE(dkofanov): #22355 'NodeHasType' is broken. +TEST_F(ASTVerifierTest, DISABLED_NullType) { StringLiteral emptyNode; - EXPECT_TRUE(VerifyNode(&emptyNode, - ExpectVerifierMessage {"NULL_TS_TYPE(AstNodeType::STRING_LITERAL, line 1)"})); + EXPECT_TRUE(VerifyNode(&emptyNode, ExpectVerifierMessage {"NULL_TS_TYPE"})); } TEST_F(ASTVerifierTest, WithoutScope) @@ -119,7 +119,7 @@ TEST_F(ASTVerifierTest, ScopeNodeTest) TEST_F(ASTVerifierTest, ArithmeticExpressionCorrect1) { DiagnosticEngine de {}; - ETSChecker etschecker {de}; + ETSChecker etschecker {Allocator(), de}; auto left = NumberLiteral(Number {1}); auto right = NumberLiteral(Number {6}); @@ -134,7 +134,7 @@ TEST_F(ASTVerifierTest, ArithmeticExpressionCorrect1) TEST_F(ASTVerifierTest, ArithmeticExpressionCorrect2) { DiagnosticEngine de {}; - ETSChecker etschecker {de}; + ETSChecker etschecker {Allocator(), de}; constexpr uint32_t LEFT1_PARAM = 1; constexpr uint32_t LEFT2_PARAM = 12; @@ -156,7 +156,7 @@ TEST_F(ASTVerifierTest, ArithmeticExpressionCorrect2) TEST_F(ASTVerifierTest, ArithmeticExpressionNegative1) { DiagnosticEngine de {}; - ETSChecker etschecker {de}; + ETSChecker etschecker {Allocator(), de}; const StringView leftParam("1"); constexpr uint32_t RIGHT_PARAM = 1; @@ -174,7 +174,7 @@ TEST_F(ASTVerifierTest, ArithmeticExpressionNegative1) TEST_F(ASTVerifierTest, ArithmeticExpressionNegative2) { DiagnosticEngine de {}; - ETSChecker etschecker {de}; + ETSChecker etschecker {Allocator(), de}; auto left = BooleanLiteral(true); auto right = NumberLiteral(Number {1}); @@ -183,29 +183,28 @@ TEST_F(ASTVerifierTest, ArithmeticExpressionNegative2) left.SetTsType(etschecker.GlobalETSStringLiteralType()); right.SetTsType(etschecker.GlobalIntType()); - EXPECT_TRUE(VerifyNode( - arithmeticExpression.AsBinaryExpression(), - ExpectVerifierMessage {"Not a numeric type(AstNodeType::BOOLEAN_LITERAL, line 1)"})); + EXPECT_TRUE(VerifyNode(arithmeticExpression.AsBinaryExpression(), + ExpectVerifierMessage {"Not a numeric type"})); } TEST_F(ASTVerifierTest, PrimitiveType) { DiagnosticEngine de {}; - ETSChecker etschecker {de}; + ETSChecker etschecker {Allocator(), de}; auto ast = BooleanLiteral(true); ast.SetTsType(etschecker.CreateETSBooleanType(true)); ASSERT_TRUE(VerifyNode(&ast, ExpectVerifierMessage {"PRIMITIVE_BEFORE_LOWERING"})); - std::get(invariants_).SetNumberLoweringOccured(); + Get()->SetNumberLoweringOccured(); ASSERT_TRUE(VerifyNode(&ast)); - std::get(invariants_).SetNumberLoweringOccured(false); + Get()->SetNumberLoweringOccured(false); } TEST_F(ASTVerifierTest, SequenceExpressionType) { auto de = DiagnosticEngine(); - auto checker = ETSChecker(de); + auto checker = ETSChecker(Allocator(), de); const auto literalsCount = 3; std::array literals {NumberLiteral {Number {1}}, NumberLiteral {Number {2}}, NumberLiteral {Number {3}}}; @@ -281,3 +280,5 @@ TEST_F(ASTVerifierTest, VariableNameIdentifierNameSame) EXPECT_TRUE(Verify()); } } + +} // namespace diff --git a/ets2panda/test/unit/public/ast_verifier_variable_has_scope_test.cpp b/ets2panda/test/unit/public/ast_verifier_variable_has_scope_test.cpp index ae5116fc669b18638773c68adc99bb12830bd857..76c9bb1724d69dd314c702f2d43273e255d6e4a9 100644 --- a/ets2panda/test/unit/public/ast_verifier_variable_has_scope_test.cpp +++ b/ets2panda/test/unit/public/ast_verifier_variable_has_scope_test.cpp @@ -90,8 +90,8 @@ TEST_F(ASTVerifierTest, LambdasHaveCorrectScope) TEST_F(ASTVerifierTest, AsyncLambda1) { char const *text = R"( - let fs: ((p: int) => int)[] - function foo(i: int): ((p: int) => int) { + let fs: ((p: int) => int)[] = []; + async function foo(i: int): Promise<((p: int) => int)> { return fs[i] } @@ -101,10 +101,10 @@ TEST_F(ASTVerifierTest, AsyncLambda1) ] let ps: Object = new Object() - ps = launch foo(0) + ps = foo(0) let cnt = 0 - cnt += (await ps as Promise<(p: int) => int>)(0) + cnt += (await (ps as Promise<(p: int) => int>))(0) } )"; diff --git a/ets2panda/test/unit/public/es2panda_public_test.cpp b/ets2panda/test/unit/public/es2panda_public_test.cpp index e32c4791a818f848d07b68a47e694e2e8e159815..8d1f457c6bb64897598a8d113b1beb95676c2fe6 100644 --- a/ets2panda/test/unit/public/es2panda_public_test.cpp +++ b/ets2panda/test/unit/public/es2panda_public_test.cpp @@ -20,6 +20,8 @@ #include "test/utils/ast_verifier_test.h" #include "util/diagnostic.h" +namespace { + using Es2PandaLibTest = test::utils::AstVerifierTest; TEST_F(Es2PandaLibTest, NoError) @@ -82,14 +84,16 @@ TEST_F(Es2PandaLibTest, LogDiagnostic) auto diagnosticStorage = reinterpret_cast(diagnostics); ASSERT_EQ(diagnosticStorage->size(), 0); - auto kind = GetImpl()->CreateDiagnosticKind(GetContext(), "Test {}"); + auto kind = GetImpl()->CreateDiagnosticKind(GetContext(), "Test {}", ES2PANDA_PLUGIN_ERROR); const char **args = new const char *[1]; // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) args[0] = "1"; GetImpl()->LogDiagnostic(GetContext(), kind, args, 1, pos); delete[] args; ASSERT_EQ(diagnosticStorage->size(), 1); - ASSERT_EQ((*diagnosticStorage)[0]->Type(), ark::es2panda::util::DiagnosticType::PLUGIN); + ASSERT_EQ((*diagnosticStorage)[0]->Type(), ark::es2panda::util::DiagnosticType::PLUGIN_ERROR); ASSERT_EQ((*diagnosticStorage)[0]->Message(), "Test 1"); } } + +} // namespace diff --git a/ets2panda/test/unit/relative_path/CMakeLists.txt b/ets2panda/test/unit/relative_path/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..928c34b3f60fd46f53b4be6c3c989efbef5492de --- /dev/null +++ b/ets2panda/test/unit/relative_path/CMakeLists.txt @@ -0,0 +1,43 @@ +# 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. + +add_custom_target(es2panda_relative_path_to_file) + +function(copy_to_workdir filename) + get_filename_component(filename_without_ext ${filename} NAME_WLE) + add_custom_target("copy_test_${filename_without_ext}" + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + ${CMAKE_CURRENT_BINARY_DIR}/${filename_without_ext}/${filename}) +endfunction() + +function(launch_with_reletaive_path_single_file filename) + copy_to_workdir(${filename}) + get_filename_component(filename_without_ext ${filename} NAME_WLE) + set(filename_abc "${filename_without_ext}.abc") + add_custom_command( + OUTPUT "${filename_abc}" + DEPENDS es2panda copy_test_${filename_without_ext} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${filename_without_ext} + COMMAND ${CMAKE_COMMAND} -E env + LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${PANDA_RUN_PREFIX} + $ --extension=ets --ets-unnamed --output=${filename_abc} + ${filename} + ) + add_custom_target(es2panda_relative_path_to_file_${filename_without_ext} DEPENDS ${filename_abc}) + add_dependencies(es2panda_relative_path_to_file es2panda_relative_path_to_file_${filename_without_ext}) +endfunction() + +add_dependencies(es2panda_tests es2panda_relative_path_to_file) + +launch_with_reletaive_path_single_file(package_a_file_1.ets) diff --git a/ets2panda/test/unit/relative_path/package_a_file_1.ets b/ets2panda/test/unit/relative_path/package_a_file_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..db6181aacafa2ee28c009568d618f901a97cfc8d --- /dev/null +++ b/ets2panda/test/unit/relative_path/package_a_file_1.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. + */ + +package A; + +export const num = 1; diff --git a/ets2panda/test/unit/rest_parameter_flag_test.cpp b/ets2panda/test/unit/rest_parameter_flag_test.cpp index 161825e88aed29542f46f65525aca2ef80efc27f..6a86bc31954191e0dd3d279ca74231b720e3f51e 100644 --- a/ets2panda/test/unit/rest_parameter_flag_test.cpp +++ b/ets2panda/test/unit/rest_parameter_flag_test.cpp @@ -70,7 +70,7 @@ TEST_F(RestParameterTest, function_without_rest_parameters_0) TEST_F(RestParameterTest, function_without_rest_parameters_1) { SetCurrentProgram(R"( - function fn(args: int[]): void { + function fn(args: FixedArray): void { } )"); CheckNoRestParameterFlag("dummy.ETSGLOBAL.fn:i32[];void;", true); @@ -79,7 +79,7 @@ TEST_F(RestParameterTest, function_without_rest_parameters_1) TEST_F(RestParameterTest, function_without_rest_parameters_2) { SetCurrentProgram(R"( - function fn(arg0: int, args: String[]): void { + function fn(arg0: int, args: FixedArray): void { } )"); CheckNoRestParameterFlag("dummy.ETSGLOBAL.fn:i32;std.core.String[];void;", true); @@ -88,7 +88,7 @@ TEST_F(RestParameterTest, function_without_rest_parameters_2) TEST_F(RestParameterTest, function_with_rest_parameter_0) { SetCurrentProgram(R"( - function fn(...args: String[]): void { + function fn(...args: FixedArray): void { } )"); CheckRestParameterFlag("dummy.ETSGLOBAL.fn:std.core.String[];void;", true); @@ -97,7 +97,7 @@ TEST_F(RestParameterTest, function_with_rest_parameter_0) TEST_F(RestParameterTest, function_with_rest_parameter_1) { SetCurrentProgram(R"( - function fn(o: Object, ...args: int[]): void { + function fn(o: Object, ...args: FixedArray): void { } )"); CheckRestParameterFlag("dummy.ETSGLOBAL.fn:std.core.Object;i32[];void;", true); @@ -128,7 +128,7 @@ TEST_F(RestParameterTest, class_method_with_rest_parameters_0) { SetCurrentProgram(R"( class A { - fn(...args: int[]) {}; + fn(...args: FixedArray) {}; } )"); CheckRestParameterFlag("dummy.A.fn:i32[];void;", false); @@ -159,7 +159,7 @@ TEST_F(RestParameterTest, static_class_method_with_rest_parameters_0) { SetCurrentProgram(R"( class A { - static fn(...args: int[]) {}; + static fn(...args: FixedArray) {}; } )"); CheckRestParameterFlag("dummy.A.fn:i32[];void;", true); @@ -169,7 +169,7 @@ TEST_F(RestParameterTest, static_class_method_with_rest_parameters_1) { SetCurrentProgram(R"( class A { - static fn(a: String[], ...args: int[]) {}; + static fn(a: FixedArray, ...args: FixedArray) {}; } )"); CheckRestParameterFlag("dummy.A.fn:std.core.String[];i32[];void;", true); @@ -190,7 +190,7 @@ TEST_F(RestParameterTest, class_constructor_without_rest_parameters_1) { SetCurrentProgram(R"( class A { - constructor(args: String[]) {}; + constructor(args: FixedArray) {}; } )"); CheckNoRestParameterFlag("dummy.A.:std.core.String[];void;", false); @@ -200,7 +200,7 @@ TEST_F(RestParameterTest, class_constructor_with_rest_parameters_0) { SetCurrentProgram(R"( class A { - constructor(...args: int[]) {}; + constructor(...args: FixedArray) {}; } )"); CheckRestParameterFlag("dummy.A.:i32[];void;", false); @@ -210,7 +210,7 @@ TEST_F(RestParameterTest, class_constructor_with_rest_parameters_1) { SetCurrentProgram(R"( class A { - constructor(v0: long, ...args: String[]) {}; + constructor(v0: long, ...args: FixedArray) {}; } )"); CheckRestParameterFlag("dummy.A.:i64;std.core.String[];void;", false); @@ -231,7 +231,7 @@ TEST_F(RestParameterTest, interface_without_rest_parameters_1) { SetCurrentProgram(R"( interface A { - fn(args: String[]) {}; + fn(args: FixedArray) {}; } )"); CheckNoRestParameterFlag("dummy.A.fn:std.core.String[];void;", false); @@ -241,7 +241,7 @@ TEST_F(RestParameterTest, interface_with_rest_parameters_0) { SetCurrentProgram(R"( interface A { - fn(...args: Object[]) {}; + fn(...args: FixedArray) {}; } )"); CheckRestParameterFlag("dummy.A.fn:std.core.Object[];void;", false); @@ -251,7 +251,7 @@ TEST_F(RestParameterTest, interface_with_rest_parameters_1) { SetCurrentProgram(R"( interface A { - fn(o: Object, ...args: String[]) {}; + fn(o: Object, ...args: FixedArray) {}; } )"); CheckRestParameterFlag("dummy.A.fn:std.core.Object;std.core.String[];void;", false); @@ -271,7 +271,7 @@ TEST_F(RestParameterTest, lambda_without_rest_parameters_0) TEST_F(RestParameterTest, lambda_without_rest_parameters_1) { SetCurrentProgram(R"( - let fn: (args: long[])=>int = (args: long[]): int => { + let fn: (args: FixedArray)=>int = (args: FixedArray): int => { return 1; } )"); @@ -293,7 +293,7 @@ TEST_F(RestParameterTest, abstract_function_without_rest_parameter_1) { SetCurrentProgram(R"( abstract class A { - abstract fn(args: String[]): void + abstract fn(args: FixedArray): void } )"); CheckNoRestParameterFlag("dummy.A.fn:std.core.String[];void;", false); @@ -303,7 +303,7 @@ TEST_F(RestParameterTest, abstract_function_with_rest_parameter_0) { SetCurrentProgram(R"( abstract class A { - abstract fn(...args: String[]): void + abstract fn(...args: FixedArray): void } )"); CheckRestParameterFlag("dummy.A.fn:std.core.String[];void;", false); @@ -313,7 +313,7 @@ TEST_F(RestParameterTest, abstract_function_with_rest_parameter_1) { SetCurrentProgram(R"( abstract class A { - abstract fn(v: int, ...args: String[]): void + abstract fn(v: int, ...args: FixedArray): void } )"); CheckRestParameterFlag("dummy.A.fn:i32;std.core.String[];void;", false); @@ -323,13 +323,13 @@ TEST_F(RestParameterTest, abstract_function_with_rest_parameter_1) TEST_F(RestParameterTest, external_function_with_rest_parameter_0) { SetCurrentProgram(""); - CheckRestParameterFlag("std.core.LambdaValue.invoke:std.core.Object[];std.core.Object;", false); + CheckRestParameterFlag("std.core.LambdaValue.invoke:escompat.Array;std.core.Object;", false); } TEST_F(RestParameterTest, external_function_with_rest_parameter_1) { SetCurrentProgram(""); - CheckRestParameterFlag("escompat.Math.max:f64[];f64;", true); + CheckRestParameterFlag("escompat.Math.max:escompat.Array;f64;", true); } } // namespace ark::es2panda::compiler::test diff --git a/ets2panda/test/unit/sizeof_node_test.cpp b/ets2panda/test/unit/sizeof_node_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3d964e211d995e0d0cf41aa5e7967d71b8bea03b --- /dev/null +++ b/ets2panda/test/unit/sizeof_node_test.cpp @@ -0,0 +1,723 @@ +/** + * 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 + +#include "ir/base/classDefinition.h" +#include "ir/base/classProperty.h" +#include "ir/base/methodDefinition.h" + +#include "ir/ets/etsModule.h" +#include "ir/ets/etsReExportDeclaration.h" +#include "ir/ets/etsStructDeclaration.h" +#include "ir/ets/etsTypeReference.h" +#include "ir/ets/etsTypeReferencePart.h" + +#include "ir/expressions/functionExpression.h" + +#include "ir/module/importDeclaration.h" + +#include "ir/statements/annotationDeclaration.h" +#include "ir/statements/classDeclaration.h" +#include "ir/statements/functionDeclaration.h" +#include "ir/statements/variableDeclaration.h" + +#include "ir/ts/tsEnumDeclaration.h" +#include "ir/ts/tsInterfaceDeclaration.h" +#include "ir/ts/tsTypeAliasDeclaration.h" +#include "ir/ts/tsTypeParameter.h" +#include "ir/ts/tsTypeParameterDeclaration.h" + +namespace ark::es2panda::ir { + +class SizeOfNodeTest : public testing::Test { +public: + template + size_t SizeOf(); + + static size_t Align(size_t value) + { + constexpr size_t FIELD_ALIGNMENT = 8; + return AlignUp(value, FIELD_ALIGNMENT); + } +}; + +// NOLINTBEGIN(bugprone-sizeof-container) + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + constexpr size_t SIZE_OF_VTABLE = sizeof(void *); + AstNode *node = nullptr; + + // clang-format off + return SIZE_OF_VTABLE + + sizeof(node->parent_) + + sizeof(node->range_) + + sizeof(node->type_) + + sizeof(node->flags_) + + sizeof(node->astNodeFlags_) + + sizeof(node->boxingUnboxingFlags_) + + sizeof(node->history_) + + sizeof(node->variable_) + + sizeof(node->originalNode_) + + sizeof(node->transformedNode_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + Typed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->tsType_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + return SizeOf>(); +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + AnnotationAllowed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->annotations_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>>() +{ + JsDocAllowed> *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->jsDocInformation_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ClassDefinition *node = nullptr; + + // clang-format off + return SizeOf>>() + + sizeof(node->scope_) + + sizeof(node->internalName_) + + sizeof(node->ident_) + + sizeof(node->typeParams_) + + sizeof(node->superTypeParams_) + + sizeof(node->implements_) + + sizeof(node->ctor_) + + sizeof(node->superClass_) + + sizeof(node->body_) + + sizeof(node->modifiers_) + + sizeof(node->lang_) + + sizeof(node->capturedVars_) + + sizeof(node->localVariableIsNeeded_) + + sizeof(node->origEnumDecl_) + + sizeof(node->anonClass_) + + Align(sizeof(node->localIndex_)) + + sizeof(node->localPrefix_) + + sizeof(node->functionalReferenceReferencedMethod_) + + sizeof(node->exportedClasses_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + return SizeOf(); +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ClassDeclaration *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->def_) + + sizeof(node->decorators_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + Typed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->tsType_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + return SizeOf>(); +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ClassElement *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->key_) + + sizeof(node->value_) + + sizeof(node->decorators_) + + Align(sizeof(node->isComputed_)) + + sizeof(node->enumMember_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + AnnotationAllowed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->annotations_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>>() +{ + JsDocAllowed> *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->jsDocInformation_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ClassProperty *node = nullptr; + + // clang-format off + return SizeOf>>() + + sizeof(node->typeAnnotation_) + + Align(sizeof(node->isDefault_) + + sizeof(node->needInitInStaticBlock_)); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + MethodDefinition *node = nullptr; + + // clang-format off + return SizeOf() + + Align(sizeof(node->isDefault_) + + sizeof(node->kind_)) + + sizeof(node->overloads_) + + sizeof(node->baseOverloadMethod_) + + sizeof(node->asyncPairMethod_) + + sizeof(node->overloadInfo_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + AnnotationAllowed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->annotations_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>>() +{ + JsDocAllowed> *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->jsDocInformation_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ScriptFunction *node = nullptr; + + // clang-format off + return SizeOf>>() + + sizeof(node->id_) + + Align(sizeof(node->irSignature_)) + + sizeof(node->body_) + + sizeof(node->scope_) + + Align(sizeof(node->funcFlags_)) + + sizeof(node->signature_) + + sizeof(node->preferredReturnType_) + + Align(sizeof(node->lang_)) + + sizeof(node->returnStatements_) + + sizeof(node->isolatedDeclGenInferType_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ImportDeclaration *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->source_) + + sizeof(node->specifiers_) + + Align(sizeof(node->importKinds_)); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + AnnotationAllowed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->annotations_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>>() +{ + JsDocAllowed> *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->jsDocInformation_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + FunctionDeclaration *node = nullptr; + + // clang-format off + return SizeOf>>() + + sizeof(node->decorators_) + + sizeof(node->func_) + + Align(sizeof(node->isAnonymous_)); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + TSEnumDeclaration *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->scope_) + + sizeof(node->decorators_) + + sizeof(node->key_) + + sizeof(node->members_) + + sizeof(node->internalName_) + + sizeof(node->boxedClass_) + + Align(sizeof(node->isConst_)); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + AnnotationAllowed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->annotations_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>>() +{ + JsDocAllowed> *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->jsDocInformation_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + TSInterfaceDeclaration *node = nullptr; + + // clang-format off + return SizeOf>>() + + sizeof(node->decorators_) + + sizeof(node->scope_) + + sizeof(node->id_) + + sizeof(node->typeParams_) + + sizeof(node->body_) + + sizeof(node->extends_) + + sizeof(node->internalName_) + + Align(sizeof(node->isStatic_) + + sizeof(node->isExternal_) + + sizeof(node->lang_)) + + sizeof(node->anonClass_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + Annotated *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->typeAnnotation_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + return SizeOf>(); +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + JsDocAllowed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->jsDocInformation_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + TSTypeAliasDeclaration *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->decorators_) + + sizeof(node->annotations_) + + sizeof(node->id_) + + sizeof(node->typeParams_) + + sizeof(node->typeParamTypes_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + Expression *node = nullptr; + + // clang-format off + return SizeOf() + + Align(sizeof(node->grouped_)); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + AnnotationAllowed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->annotations_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + VariableDeclaration *node = nullptr; + + // clang-format off + return SizeOf>>() + + Align(sizeof(node->kind_) + + sizeof(node->decorators_) + + sizeof(node->declarators_)); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ETSParameterExpression *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->ident_) + + sizeof(node->initializer_) + + sizeof(node->spread_) + + sizeof(node->savedLexer_) + + sizeof(node->extraValue_) + + Align(sizeof(node->isOptional_)); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + TSTypeParameter *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->name_) + + sizeof(node->constraint_) + + sizeof(node->defaultType_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + TSTypeParameterDeclaration *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->params_) + + sizeof(node->scope_) + + sizeof(node->requiredParams_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + return SizeOf>(); +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ETSTypeReference *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->part_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ETSTypeReferencePart *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->name_) + + sizeof(node->typeParams_) + + sizeof(node->prev_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + BlockStatement *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->scope_) + + sizeof(node->statements_) + + sizeof(node->trailingBlocks_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>() +{ + AnnotationAllowed *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->annotations_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf>>() +{ + JsDocAllowed> *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->jsDocInformation_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ETSModule *node = nullptr; + + // clang-format off + return SizeOf>>() + + sizeof(node->ident_) + + Align(sizeof(node->flag_)) + + sizeof(node->program_)+ + sizeof(node->globalClass_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + FunctionExpression *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->func_) + + sizeof(node->exprName_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + ETSReExportDeclaration *node = nullptr; + + // clang-format off + return SizeOf() + + sizeof(node->etsImportDeclarations_) + + sizeof(node->userPaths_) + + sizeof(node->programPath_); + // clang-format on +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + return SizeOf(); +} + +template <> +size_t SizeOfNodeTest::SizeOf() +{ + AnnotationDeclaration *node = nullptr; + + // clang-format off + return SizeOf>() + + sizeof(node->internalName_) + + sizeof(node->scope_) + + sizeof(node->expr_) + + sizeof(node->properties_) + + Align(sizeof(node->policy_)); + // clang-format on +} + +// NOLINTEND(bugprone-sizeof-container) + +TEST_F(SizeOfNodeTest, DeclNodesBase) +{ + // IMPORTANT NOTICE: This test purpose is to warn a developer who modified fields of specific node classes. + // Classes listed below implements CopyTo/Clone methods. + // When you add a new field to a class, make sure you updated corresponding method. + // Example: if you added new field to a ClassDefinition class, handle it in ClassDefinition::CopyTo/Clone. + + ASSERT_EQ(sizeof(AstNode), SizeOf()); + ASSERT_EQ(sizeof(Typed), SizeOf>()); + ASSERT_EQ(sizeof(TypedAstNode), SizeOf()); + ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); + ASSERT_EQ(sizeof(JsDocAllowed>), + SizeOf>>()); + ASSERT_EQ(sizeof(Statement), SizeOf()); + ASSERT_EQ(sizeof(Typed), SizeOf>()); + ASSERT_EQ(sizeof(TypedStatement), SizeOf()); + ASSERT_EQ(sizeof(ClassElement), SizeOf()); + ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); + ASSERT_EQ(sizeof(JsDocAllowed>), + SizeOf>>()); + ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); + ASSERT_EQ(sizeof(JsDocAllowed>), SizeOf>>()); + ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); + ASSERT_EQ(sizeof(JsDocAllowed>), SizeOf>>()); + ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); + ASSERT_EQ(sizeof(JsDocAllowed>), + SizeOf>>()); + + // IMPORTANT NOTICE: This test purpose is to warn a developer who modified fields of specific node classes. + // Classes listed below implements CopyTo/Clone methods. + // When you add a new field to a class, make sure you updated corresponding method. + // Example: if you added new field to a ClassDefinition class, handle it in ClassDefinition::CopyTo/Clone. + + ASSERT_EQ(sizeof(Annotated), SizeOf>()); + ASSERT_EQ(sizeof(AnnotatedStatement), SizeOf()); + ASSERT_EQ(sizeof(JsDocAllowed), SizeOf>()); + ASSERT_EQ(sizeof(Expression), SizeOf()); + ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); + ASSERT_EQ(sizeof(TypeNode), SizeOf()); + ASSERT_EQ(sizeof(BlockStatement), SizeOf()); + ASSERT_EQ(sizeof(AnnotationAllowed), SizeOf>()); +} + +TEST_F(SizeOfNodeTest, DeclNodesDerived) +{ + // IMPORTANT NOTICE: This test purpose is to warn a developer who modified fields of specific node classes. + // Classes listed below implements CopyTo/Clone methods. + // When you add a new field to a class, make sure you updated corresponding method. + // Example: if you added new field to a ClassDefinition class, handle it in ClassDefinition::CopyTo/Clone. + + ASSERT_EQ(sizeof(ClassDefinition), SizeOf()); + ASSERT_EQ(sizeof(ClassDeclaration), SizeOf()); + ASSERT_EQ(sizeof(ClassProperty), SizeOf()); + ASSERT_EQ(sizeof(MethodDefinition), SizeOf()); + ASSERT_EQ(sizeof(ScriptFunction), SizeOf()); + ASSERT_EQ(sizeof(ImportDeclaration), SizeOf()); + ASSERT_EQ(sizeof(FunctionDeclaration), SizeOf()); + ASSERT_EQ(sizeof(TSEnumDeclaration), SizeOf()); + ASSERT_EQ(sizeof(TSInterfaceDeclaration), SizeOf()); + ASSERT_EQ(sizeof(TSTypeAliasDeclaration), SizeOf()); + ASSERT_EQ(sizeof(VariableDeclaration), SizeOf()); + + // IMPORTANT NOTICE: This test purpose is to warn a developer who modified fields of specific node classes. + // Classes listed below implements CopyTo/Clone methods. + // When you add a new field to a class, make sure you updated corresponding method. + // Example: if you added new field to a ClassDefinition class, handle it in ClassDefinition::CopyTo/Clone. + + ASSERT_EQ(sizeof(ETSParameterExpression), SizeOf()); + ASSERT_EQ(sizeof(TSTypeParameter), SizeOf()); + ASSERT_EQ(sizeof(TSTypeParameterDeclaration), SizeOf()); + ASSERT_EQ(sizeof(ETSTypeReference), SizeOf()); + ASSERT_EQ(sizeof(ETSTypeReferencePart), SizeOf()); + ASSERT_EQ(sizeof(ETSModule), SizeOf()); + ASSERT_EQ(sizeof(FunctionExpression), SizeOf()); + ASSERT_EQ(sizeof(ETSReExportDeclaration), SizeOf()); + ASSERT_EQ(sizeof(ETSStructDeclaration), SizeOf()); + ASSERT_EQ(sizeof(AnnotationDeclaration), SizeOf()); +} +} // namespace ark::es2panda::ir diff --git a/ets2panda/test/unit/union_normalisation_test.h b/ets2panda/test/unit/union_normalisation_test.h index f5d9665d84da43501c6a47e937fcd835865738df..36b345f6c3940552772d8cb0cc84326e2ec7ed83 100644 --- a/ets2panda/test/unit/union_normalisation_test.h +++ b/ets2panda/test/unit/union_normalisation_test.h @@ -16,6 +16,7 @@ #ifndef PANDA_UNION_NORMALISATION_TEST_H #define PANDA_UNION_NORMALISATION_TEST_H +#include "ir/astNode.h" #include "util/options.h" namespace ark::es2panda::gtests { @@ -23,10 +24,11 @@ namespace ark::es2panda::gtests { class UnionNormalizationTest : public testing::Test { public: UnionNormalizationTest() - : allocator_(std::make_unique(SpaceType::SPACE_TYPE_COMPILER)), + : allocator_(std::make_unique(SpaceType::SPACE_TYPE_COMPILER, nullptr, true)), publicContext_ {std::make_unique()}, + phaseManager_ {ScriptExtension::ETS, Allocator()}, program_ {parser::Program::NewProgram(Allocator())}, - checker_ {diagnosticEngine_} + checker_ {Allocator(), diagnosticEngine_} { } @@ -38,7 +40,7 @@ public: PoolManager::Initialize(); } - ArenaAllocator *Allocator() + ark::ThreadSafeArenaAllocator *Allocator() { return allocator_.get(); } @@ -91,7 +93,6 @@ public: Compiler compiler(options->GetExtension(), options->GetThread()); SourceFile input(fileName, src, options->IsModule()); compiler::CompilationUnit unit {input, *options, 0, options->GetExtension(), diagnosticEngine_}; - auto getPhases = compiler::GetPhaseList(ScriptExtension::ETS); auto parser = Parser(program, unit.options, diagnosticEngine_, static_cast(unit.rawParserStatus)); @@ -104,6 +105,7 @@ public: varbinder->SetContext(publicContext_.get()); auto emitter = Emitter(publicContext_.get()); + auto phaseManager = new compiler::PhaseManager(publicContext_.get(), unit.ext, allocator_.get()); auto config = public_lib::ConfigImpl {}; publicContext_->config = &config; @@ -111,13 +113,16 @@ public: publicContext_->sourceFile = &unit.input; publicContext_->allocator = allocator_.get(); publicContext_->parser = &parser; - publicContext_->checker = checker; - publicContext_->analyzer = publicContext_->checker->GetAnalyzer(); - publicContext_->emitter = &emitter; + parser.SetContext(publicContext_.get()); publicContext_->parserProgram = program; + publicContext_->PushChecker(checker); + publicContext_->PushAnalyzer(publicContext_->GetChecker()->GetAnalyzer()); + publicContext_->emitter = &emitter; publicContext_->diagnosticEngine = &diagnosticEngine_; + publicContext_->phaseManager = phaseManager; + publicContext_->GetChecker()->Initialize(varbinder); parser.ParseScript(unit.input, unit.options.GetCompilationMode() == CompilationMode::GEN_STD_LIB); - for (auto *phase : getPhases) { + while (auto phase = publicContext_->phaseManager->NextPhase()) { if (!phase->Apply(publicContext_.get(), program)) { return; } @@ -157,8 +162,9 @@ protected: static constexpr uint8_t IDX2 = 2; private: - std::unique_ptr allocator_; + std::unique_ptr allocator_; std::unique_ptr publicContext_; + ark::es2panda::compiler::PhaseManager phaseManager_; parser::Program program_; util::DiagnosticEngine diagnosticEngine_; checker::ETSChecker checker_; diff --git a/ets2panda/test/utils/asm_test.cpp b/ets2panda/test/utils/asm_test.cpp index 9b51817a840f7df131df9fd593b79a83c0dd77b1..53fb2a8dcf1e4258b5c3b2826a3a882c931fe8df 100644 --- a/ets2panda/test/utils/asm_test.cpp +++ b/ets2panda/test/utils/asm_test.cpp @@ -137,6 +137,40 @@ void AsmTest::CheckRecordAnnotations(ark::pandasm::Program *program, const std:: } } +void AsmTest::CheckModuleAnnotation(ark::pandasm::Program *program, const std::string &recordName, bool isModule, + const std::vector &expectedAnnotations) +{ + const auto &recordTable = program->recordTable; + ASSERT_FALSE(recordTable.empty()) << "No records found in the program."; + auto found = recordTable.find(recordName); + ASSERT_NE(found, recordTable.end()); + + auto annotations = found->second.metadata->GetAnnotations(); + auto it = std::find_if(annotations.begin(), annotations.end(), [](const ark::pandasm::AnnotationData &annotation) { + return annotation.GetName() == std::string {ark::es2panda::compiler::Signatures::ETS_ANNOTATION_MODULE}; + }); + if (isModule) { + ASSERT_NE(it, annotations.end()) << recordName << " missing expected annotation: " + << ark::es2panda::compiler::Signatures::ETS_ANNOTATION_MODULE; + } else { + ASSERT_EQ(it, annotations.end()) << recordName << " has annotation: " + << ark::es2panda::compiler::Signatures::ETS_ANNOTATION_MODULE + << ", but shouldn't"; + return; + } + ASSERT_EQ(it->GetElements().size(), 1); + const auto &element = it->GetElements()[0]; + ASSERT_EQ(element.GetName(), std::string {ark::es2panda::compiler::Signatures::ANNOTATION_KEY_EXPORTED}) + << recordName << "module annotation missing element " + << ark::es2panda::compiler::Signatures::ANNOTATION_KEY_EXPORTED; + + for (const auto &val : element.GetValue()->GetAsArray()->GetValues()) { + auto name = val.GetValue().GetName(); + auto foundExpected = std::find(expectedAnnotations.begin(), expectedAnnotations.end(), name); + ASSERT_NE(foundExpected, expectedAnnotations.end()) << "Value mismatch for " + name; + } +} + void AsmTest::CheckRecordWithoutAnnotations(ark::pandasm::Program *program, const std::string &recordName, bool isModule) { @@ -191,7 +225,7 @@ void AsmTest::CheckFunctionParameterAnnotations(ark::pandasm::Program *program, ASSERT_LT(paramIndex, found->second.params.size()); for (const auto &expected : expectedAnnotations) { - auto annotations = found->second.params.at(paramIndex).metadata->GetAnnotations(); + auto annotations = found->second.params.at(paramIndex).GetOrCreateMetadata().GetAnnotations(); auto it = std::find_if(annotations.begin(), annotations.end(), [&expected](const ark::pandasm::AnnotationData &annotation) { return annotation.GetName() == expected.first; @@ -212,7 +246,7 @@ void AsmTest::CheckFunctionParameterWithoutAnnotations(ark::pandasm::Program *pr auto found = functionTable.find(functionName); ASSERT_NE(found, functionTable.end()); ASSERT_LT(paramIndex, found->second.params.size()); - ASSERT(found->second.params.at(paramIndex).metadata->GetAnnotations().empty()); + ASSERT(found->second.params.at(paramIndex).GetOrCreateMetadata().GetAnnotations().empty()); } void AsmTest::CheckClassFieldAnnotations(ark::pandasm::Program *program, const std::string &recordName, diff --git a/ets2panda/test/utils/asm_test.h b/ets2panda/test/utils/asm_test.h index 5dcef0c1e0276c5699dea7c20f253df9bf258c12..e58fde52fd5c68e6f7b3dff359a26101a31a28c0 100644 --- a/ets2panda/test/utils/asm_test.h +++ b/ets2panda/test/utils/asm_test.h @@ -71,6 +71,9 @@ public: void CheckRecordAnnotations(ark::pandasm::Program *program, const std::string &recordName, const AnnotationMap &expectedAnnotations); + void CheckModuleAnnotation(ark::pandasm::Program *program, const std::string &recordName, bool isModule, + const std::vector &expectedAnnotations = {}); + void CheckRecordWithoutAnnotations(ark::pandasm::Program *program, const std::string &recordName, bool isModule = false); diff --git a/ets2panda/test/utils/ast_verifier_test.cpp b/ets2panda/test/utils/ast_verifier_test.cpp index 96fc2c38f97a1d95cd8db36cf3b1828505333825..2175041ca7925aa23384e1a5f9cb1c3ddc7ac662 100644 --- a/ets2panda/test/utils/ast_verifier_test.cpp +++ b/ets2panda/test/utils/ast_verifier_test.cpp @@ -15,21 +15,25 @@ #include "ast_verifier_test.h" +#include + namespace test::utils { AstVerifierTest::AstVerifierTest() { impl_ = es2panda_GetImpl(ES2PANDA_LIB_VERSION); + impl_->MemInitialize(); auto es2pandaPath = test::utils::PandaExecutablePathGetter::Get()[0]; std::array argv = {es2pandaPath}; cfg_ = impl_->CreateConfig(argv.size(), argv.data()); - allocator_ = new ark::ArenaAllocator(ark::SpaceType::SPACE_TYPE_COMPILER); + allocator_ = new ark::ThreadSafeArenaAllocator(ark::SpaceType::SPACE_TYPE_COMPILER, nullptr, true); + phaseManager_ = new ark::es2panda::compiler::PhaseManager(nullptr, ark::es2panda::ScriptExtension::ETS, allocator_); } AstVerifierTest::~AstVerifierTest() { ASSERT(ctx_ == nullptr); - delete allocator_; + impl_->MemFinalize(); impl_->DestroyConfig(cfg_); } diff --git a/ets2panda/test/utils/ast_verifier_test.h b/ets2panda/test/utils/ast_verifier_test.h index 180afb419ffa7edc3f741fe490e397975570327d..0d4d9fd9550e911860cda8aa30cf36d617a12ced 100644 --- a/ets2panda/test/utils/ast_verifier_test.h +++ b/ets2panda/test/utils/ast_verifier_test.h @@ -18,6 +18,7 @@ #include "ast_verifier/ASTVerifier.h" #include "panda_executable_path_getter.h" +#include "compiler/lowering/phase.h" #include @@ -44,14 +45,14 @@ public: NO_MOVE_SEMANTIC(AstVerifierTest); ~AstVerifierTest() override; - ark::ArenaAllocator *Allocator() const + ark::ThreadSafeArenaAllocator *Allocator() const { return allocator_; } auto *GetChecker() { - return reinterpret_cast(ctx_)->checker->AsETSChecker(); + return reinterpret_cast(ctx_)->GetChecker()->AsETSChecker(); } auto *GetAst() @@ -173,18 +174,31 @@ public: [[nodiscard]] auto Verify(ExpectVerifierMessage expected = {}) { ASSERT(ctx_ != nullptr); - auto *inv = &std::get(invariants_); + auto *inv = Get(); inv->Init(); - inv->VerifyAst(GetAst()); + + std::function aux {}; + aux = [inv, &aux](const ir_alias::AstNode *child) -> void { + // Required invariants need to be manually called in tests: + std::apply([child](auto &...requiredInv) { (((void)(requiredInv)(child)), ...); }, inv->GetRequired()); + const auto [_, action] = (*inv)(child); + if (action == verifier_alias::CheckAction::SKIP_SUBTREE) { + return; + } + child->Iterate(aux); + }; + aux(GetAst()); return expected.CheckMessages(inv->ViewMessages()); } template [[nodiscard]] auto VerifyNode(const ir_alias::AstNode *ast, ExpectVerifierMessage expected = {}) { - auto *inv = &std::get(invariants_); + auto *inv = Get(); inv->Init(); - inv->VerifyNode(ast); + // Required invariants need to be manually called in tests: + std::apply([ast](auto &...requiredInv) { (((void)(requiredInv)(ast)), ...); }, inv->GetRequired()); + (void)(*inv)(ast); return expected.CheckMessages(inv->ViewMessages()); } @@ -192,7 +206,8 @@ private: es2panda_Impl const *impl_ {}; es2panda_Config *cfg_ {}; es2panda_Context *ctx_ {}; - ark::ArenaAllocator *allocator_ {}; + ark::ThreadSafeArenaAllocator *allocator_ {}; + ark::es2panda::compiler::PhaseManager *phaseManager_; friend class ::LSPAPITests; }; diff --git a/ets2panda/test/utils/checker_test.h b/ets2panda/test/utils/checker_test.h index 8d5a77f4ebfc969ef00730d818027d78e9033299..79259abbadaa30314635362e73d5b21792a83a71 100644 --- a/ets2panda/test/utils/checker_test.h +++ b/ets2panda/test/utils/checker_test.h @@ -22,6 +22,7 @@ #include "compiler/core/regSpiller.h" #include "compiler/core/ETSemitter.h" #include "checker/ETSAnalyzer.h" +#include "ir/astNode.h" #include "util/options.h" #include "util/diagnosticEngine.h" #include @@ -38,11 +39,13 @@ namespace test::utils { class CheckerTest : public testing::Test { public: CheckerTest() - : allocator_(std::make_unique(ark::SpaceType::SPACE_TYPE_COMPILER)), + : allocator_( + std::make_unique(ark::SpaceType::SPACE_TYPE_COMPILER, nullptr, true)), publicContext_ {std::make_unique()}, + phaseManager_ {ark::es2panda::ScriptExtension::ETS, Allocator()}, program_ {parser_alias::Program::NewProgram(allocator_.get())}, es2pandaPath_ {PandaExecutablePathGetter::Get()[0]}, - checker_(diagnosticEngine_) + checker_(allocator_.get(), diagnosticEngine_) { } ~CheckerTest() override = default; @@ -57,7 +60,7 @@ public: return &checker_; } - ark::ArenaAllocator *Allocator() + ark::ThreadSafeArenaAllocator *Allocator() { return allocator_.get(); } @@ -99,8 +102,6 @@ public: ark::es2panda::Compiler compiler(options->GetExtension(), options->GetThread()); ark::es2panda::SourceFile input(fileName, src, options->IsModule()); compiler_alias::CompilationUnit unit {input, *options, 0, options->GetExtension(), diagnosticEngine_}; - auto getPhases = compiler_alias::GetPhaseList(ark::es2panda::ScriptExtension::ETS); - auto parser = Parser(program, unit.options, diagnosticEngine_, static_cast(unit.rawParserStatus)); auto analyzer = Analyzer(checker); @@ -112,6 +113,7 @@ public: varbinder->SetContext(publicContext_.get()); auto emitter = Emitter(publicContext_.get()); + auto phaseManager = compiler_alias::PhaseManager(publicContext_.get(), unit.ext, allocator_.get()); auto config = plib_alias::ConfigImpl {}; publicContext_->config = &config; @@ -119,15 +121,17 @@ public: publicContext_->sourceFile = &unit.input; publicContext_->allocator = allocator_.get(); publicContext_->parser = &parser; - publicContext_->checker = checker; - publicContext_->analyzer = publicContext_->checker->GetAnalyzer(); - publicContext_->emitter = &emitter; + parser.SetContext(publicContext_.get()); publicContext_->parserProgram = program; + publicContext_->PushChecker(checker); + publicContext_->PushAnalyzer(publicContext_->GetChecker()->GetAnalyzer()); + publicContext_->emitter = &emitter; publicContext_->diagnosticEngine = &diagnosticEngine_; - + publicContext_->phaseManager = &phaseManager; + publicContext_->GetChecker()->Initialize(varbinder); parser.ParseScript(unit.input, unit.options.GetCompilationMode() == ark::es2panda::CompilationMode::GEN_STD_LIB); - for (auto *phase : getPhases) { + while (auto phase = publicContext_->phaseManager->NextPhase()) { if (!phase->Apply(publicContext_.get(), program)) { return; } @@ -137,8 +141,9 @@ public: NO_MOVE_SEMANTIC(CheckerTest); private: - std::unique_ptr allocator_; + std::unique_ptr allocator_; std::unique_ptr publicContext_; + ark::es2panda::compiler::PhaseManager phaseManager_; parser_alias::Program program_; std::string es2pandaPath_; util_alias::DiagnosticEngine diagnosticEngine_; diff --git a/ets2panda/test/utils/scope_init_test.h b/ets2panda/test/utils/scope_init_test.h index ce8df944bac418aedcb6a0ded16ce672310dec65..2529a908f57a0244d753db39bd5dbe91fcaa361b 100644 --- a/ets2panda/test/utils/scope_init_test.h +++ b/ets2panda/test/utils/scope_init_test.h @@ -21,6 +21,7 @@ #include "ir/statements/variableDeclarator.h" #include "ir/statements/variableDeclaration.h" #include "mem/pool_manager.h" +#include "compiler/lowering/phase.h" #include @@ -30,7 +31,14 @@ namespace test::utils { class ScopeInitTest : public testing::Test { public: - ScopeInitTest() : allocator_(std::make_unique(ark::SpaceType::SPACE_TYPE_COMPILER)) {} + ScopeInitTest() + : allocator_( + std::make_unique(ark::SpaceType::SPACE_TYPE_COMPILER, nullptr, true)) + { + phaseManager_ = std::make_unique(ark::es2panda::ScriptExtension::ETS, + allocator_.get()); + ark::es2panda::compiler::SetPhaseManager(phaseManager_.get()); + } /* * Shortcut to convert single elemnt block expression body to it's name @@ -44,13 +52,14 @@ public: ark::PoolManager::Initialize(); } - ark::ArenaAllocator *Allocator() + ark::ThreadSafeArenaAllocator *Allocator() { return allocator_.get(); } private: - std::unique_ptr allocator_; + std::unique_ptr allocator_; + std::unique_ptr phaseManager_; }; } // namespace test::utils diff --git a/ets2panda/util/arktsconfig.cpp b/ets2panda/util/arktsconfig.cpp index c541e534f741e089e0531a073d90b95bfd007264..d58d6220f2dbc5a84093c83c40a0112985db0cfb 100644 --- a/ets2panda/util/arktsconfig.cpp +++ b/ets2panda/util/arktsconfig.cpp @@ -64,6 +64,9 @@ fs::path NormalizePath(const fs::path &p) result /= part; } } + if (fs::exists(result)) { + return fs::canonical(result); + } return result; } #endif // ARKTSCONFIG_USE_FILESYSTEM @@ -229,7 +232,8 @@ static constexpr auto DECL_PATH = "declPath"; // CC-OFF(G.NAM.03-CPP) project c static constexpr auto OHM_URL = "ohmUrl"; // CC-OFF(G.NAM.03-CPP) project code style bool ArkTsConfig::ParseDynamicPaths(const JsonObject::JsonObjPointer *options, - std::map &dynamicPathsMap) + std::map &dynamicPathsMap, + const std::string &baseUrl) { if (options == nullptr) { return true; @@ -241,41 +245,52 @@ bool ArkTsConfig::ParseDynamicPaths(const JsonObject::JsonObjPointer *options, for (size_t keyIdx = 0; keyIdx < dynamicPaths->get()->GetSize(); ++keyIdx) { auto &key = dynamicPaths->get()->GetKeyByIndex(keyIdx); auto data = dynamicPaths->get()->GetValue(key); - if (IsAbsolute(key)) { - diagnosticEngine_.LogWarning("Don't use absolute path '" + key + "' as key in 'dynamicPaths'"); - } - if (!Check(data != nullptr, diagnostic::INVALID_VALUE, {"dynamic path", key})) { - return false; - } - auto langValue = data->get()->GetValue(LANGUAGE); - if (!Check(langValue != nullptr, diagnostic::INVALID_LANGUAGE, {LANGUAGE, key, ValidDynamicLanguages()})) { - return false; - } - auto lang = Language::FromString(*langValue); - if (!Check(lang && lang->IsDynamic(), diagnostic::INVALID_LANGUAGE, {LANGUAGE, key, ValidDynamicLanguages()})) { - return false; - } - auto isSupportLang = compiler::Signatures::Dynamic::IsSupported(*lang); - if (!Check(isSupportLang, diagnostic::UNSUPPORTED_LANGUAGE_FOR_INTEROP, {lang->ToString()})) { + if (!ParseSingleDynamicPath(key, data, dynamicPathsMap, baseUrl)) { return false; } - auto ohmUrl = data->get()->GetValue(OHM_URL); - if (ohmUrl == nullptr) { - diagnosticEngine_.LogWarning("\"ohmUrl\" for module '" + key + "' wasn't specified"); - } - std::string ohmUrlValue = (ohmUrl == nullptr) ? "" : *ohmUrl; - auto declPathValue = data->get()->GetValue(DECL_PATH); - std::string normalizedDeclPath {}; - if (declPathValue != nullptr) { - normalizedDeclPath = ark::os::GetAbsolutePath(*declPathValue); - } - auto res = dynamicPathsMap.insert( - {ark::os::NormalizePath(key), ArkTsConfig::DynamicImportData(*lang, normalizedDeclPath, ohmUrlValue)}); - if (!Check(res.second, diagnostic::DUPLICATED_DYNAMIC_PATH, {normalizedDeclPath, key})) { + } + return true; +} + +bool ArkTsConfig::ParseSingleDynamicPath(const std::string &key, const JsonObject::JsonObjPointer *data, + std::map &dynamicPathsMap, + const std::string &baseUrl) +{ + if (IsAbsolute(key)) { + diagnosticEngine_.LogDiagnostic(diagnostic::DYNAMIC_PATHS_ABSOLUTE, util::DiagnosticMessageParams {key}); + } + if (!Check(data != nullptr, diagnostic::INVALID_VALUE, {"dynamic path", key})) { + return false; + } + auto langValue = data->get()->GetValue(LANGUAGE); + if (!Check(langValue != nullptr, diagnostic::INVALID_LANGUAGE, {LANGUAGE, key, ValidDynamicLanguages()})) { + return false; + } + auto lang = Language::FromString(*langValue); + if (!Check(lang && lang->IsDynamic(), diagnostic::INVALID_LANGUAGE, {LANGUAGE, key, ValidDynamicLanguages()})) { + return false; + } + auto isSupportLang = compiler::Signatures::Dynamic::IsSupported(*lang); + if (!Check(isSupportLang, diagnostic::UNSUPPORTED_LANGUAGE_FOR_INTEROP, {lang->ToString()})) { + return false; + } + auto ohmUrl = data->get()->GetValue(OHM_URL); + if (ohmUrl == nullptr) { + diagnosticEngine_.LogDiagnostic(diagnostic::NO_OHMURL, util::DiagnosticMessageParams {key}); + } + std::string ohmUrlValue = (ohmUrl == nullptr) ? "" : *ohmUrl; + auto declPathValue = data->get()->GetValue(DECL_PATH); + std::string normalizedDeclPath {}; + if (declPathValue != nullptr) { + normalizedDeclPath = IsAbsolute(*declPathValue) ? ark::os::GetAbsolutePath(*declPathValue) + : MakeAbsolute(*declPathValue, baseUrl); + if (!Check(ark::os::IsFileExists(normalizedDeclPath), diagnostic::INVALID_DYNAMIC_PATH, {key})) { return false; } } - return true; + auto res = dynamicPathsMap.insert( + {ark::os::NormalizePath(key), ArkTsConfig::DynamicImportData(*lang, normalizedDeclPath, ohmUrlValue)}); + return Check(res.second, diagnostic::DUPLICATED_DYNAMIC_PATH, {normalizedDeclPath, key}); } template @@ -386,7 +401,7 @@ bool ArkTsConfig::ParseCompilerOptions(std::string &arktsConfigDir, std::unorder return false; } // Parse "dynamicPaths" - if (!ParseDynamicPaths(compilerOptions, dynamicPaths_)) { + if (!ParseDynamicPaths(compilerOptions, dynamicPaths_, baseUrl_)) { return false; } return true; @@ -482,31 +497,49 @@ static std::string TrimPath(const std::string &path) return trimmedPath; } -std::optional ArkTsConfig::ResolvePath(std::string_view path) const +std::optional ArkTsConfig::ResolvePath(std::string_view path, bool isDynamic) const { - for (const auto &[alias, paths] : paths_) { - auto trimmedAlias = TrimPath(alias); - size_t pos = path.rfind(trimmedAlias, 0); - if (pos == 0) { - auto resolved = std::string(path); - // NOTE(ivagin): arktsconfig contains array of paths for each prefix, for now just get first one - std::string newPrefix = TrimPath(paths[0]); - resolved.replace(pos, trimmedAlias.length(), newPrefix); - return resolved; + auto tryResolveWithPaths = [this, &path]() -> std::optional { + for (const auto &[alias, paths] : paths_) { + auto trimmedAlias = TrimPath(alias); + size_t pos = path.rfind(trimmedAlias, 0); + if (pos == 0) { + auto resolved = std::string(path); + // NOTE(ivagin): arktsconfig contains array of paths for each prefix, for now just get first one + std::string newPrefix = TrimPath(paths[0]); + resolved.replace(pos, trimmedAlias.length(), newPrefix); + return resolved; + } } - } + return std::nullopt; + }; + + auto tryResolveWithDynamicPaths = [this, &path]() -> std::optional { + auto normalizedPath = ark::os::NormalizePath(std::string(path)); + for (const auto &[dynPath, _] : dynamicPaths_) { + // NOTE(dkofanov): #23877. Fail, if there is no direct match of normalized dynamic module path. + // It may be worth to take an attempt to resolve 'path' as relative to some defined dynamicPath in order to + // keep 'arktsconfig.json's smaller. + if (normalizedPath == dynPath) { + return dynPath; + } + } + return std::nullopt; + }; - auto normalizedPath = ark::os::NormalizePath(std::string(path)); - for (const auto &[dynPath, _] : dynamicPaths_) { - // NOTE(dkofanov): #23877. Fail, if there is no direct match of normalized dynamic module path. - // It may be worth to take an attempt to resolve 'path' as relative to some defined dynamicPath in order to keep - // 'arktsconfig.json's smaller. - if (normalizedPath == dynPath) { - return dynPath; + if (isDynamic) { + auto result = tryResolveWithDynamicPaths(); + if (result != std::nullopt) { + return result; } + // NOTE: #26150. we fall to tryResolveWithPaths in this case 1.2->1.0->1.2 + return tryResolveWithPaths(); } - - return std::nullopt; + auto result = tryResolveWithPaths(); + if (result != std::nullopt) { + return result; + } + return tryResolveWithDynamicPaths(); } #ifdef ARKTSCONFIG_USE_FILESYSTEM @@ -532,7 +565,7 @@ std::vector GetSourceList(const std::shared_ptr &arktsCon includes = {ArkTsConfig::Pattern("**/*", configDir.string())}; } // If outDir in not default add it into exclude - if (!fs::equivalent(arktsConfig->OutDir(), configDir)) { + if (fs::exists(arktsConfig->OutDir()) && !fs::equivalent(arktsConfig->OutDir(), configDir)) { excludes.emplace_back("**/*", arktsConfig->OutDir()); } diff --git a/ets2panda/util/arktsconfig.h b/ets2panda/util/arktsconfig.h index e2d4c476e3942e65866244276c93a32ed976b84d..fec474785a06fc2237606dc25adce0ad5d7f9aff 100644 --- a/ets2panda/util/arktsconfig.h +++ b/ets2panda/util/arktsconfig.h @@ -39,7 +39,6 @@ #ifndef ARKTSCONFIG_USE_FILESYSTEM #include #include -#include #else #if __has_include() #include @@ -124,7 +123,7 @@ public: } bool Parse(std::unordered_set &parsedConfigPath); - std::optional ResolvePath(std::string_view path) const; + std::optional ResolvePath(std::string_view path, bool isDynamic = false) const; void ResolveAllDependenciesInArkTsConfig(); @@ -202,7 +201,11 @@ private: std::unordered_set &parsedConfigPath); bool ParsePaths(const JsonObject::JsonObjPointer *options, PathsMap &pathsMap, const std::string &baseUrl); bool ParseDynamicPaths(const JsonObject::JsonObjPointer *options, - std::map &dynamicPathsMap); + std::map &dynamicPathsMap, + const std::string &baseUrl); + bool ParseSingleDynamicPath(const std::string &key, const JsonObject::JsonObjPointer *data, + std::map &dynamicPathsMap, + const std::string &baseUrl); template bool ParseCollection(const JsonObject *config, Collection &out, const std::string &target, Function &&constructor); void ResolveConfigDependencies(std::unordered_map> &dependencies, diff --git a/ets2panda/util/diagnostic.cpp b/ets2panda/util/diagnostic.cpp index 93c3404439aa3b6fd86fbcd4b4074a39cfc18554..40b71f1e63297a59575f18ea5de1e2270d0cd09e 100644 --- a/ets2panda/util/diagnostic.cpp +++ b/ets2panda/util/diagnostic.cpp @@ -14,6 +14,8 @@ */ #include "diagnostic.h" +#include +#include #include "generated/diagnostic.h" #include "lexer/token/sourceLocation.h" #include "parser/program/program.h" @@ -156,7 +158,9 @@ const char *DiagnosticTypeToString(DiagnosticType type) return "TypeError"; case DiagnosticType::WARNING: return "Warning"; - case DiagnosticType::PLUGIN: + case DiagnosticType::PLUGIN_WARNING: + return "Plugin warning"; + case DiagnosticType::PLUGIN_ERROR: return "Plugin error"; case DiagnosticType::DECLGEN_ETS2TS_ERROR: return "Declgen ets2ts error"; @@ -164,6 +168,10 @@ const char *DiagnosticTypeToString(DiagnosticType type) return "Declgen ets2ts warning"; case DiagnosticType::ARKTS_CONFIG_ERROR: return "ArkTS config error"; + case DiagnosticType::SUGGESTION: + return "SUGGESTION"; + case DiagnosticType::ISOLATED_DECLGEN: + return "Isolated declgen error"; default: ES2PANDA_UNREACHABLE(); } @@ -213,15 +221,46 @@ ThrowableDiagnostic::ThrowableDiagnostic(const DiagnosticType type, const diagno { } +Suggestion::Suggestion(const diagnostic::DiagnosticKind *kind, std::vector ¶ms, + const char *substitutionCode, const lexer::SourceRange *range) + : kind_(kind), substitutionCode_(substitutionCode), message_(Format(kind->Message(), params)), range_(range) +{ +} + +DiagnosticType Suggestion::Type() const +{ + return kind_->Type(); +} + Diagnostic::Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind, - const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos) + const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos, + std::initializer_list suggestions) : DiagnosticBase(pos), diagnosticKind_(&diagnosticKind), diagnosticParams_(FormatParams(diagnosticParams)) { + if (suggestions.size() != 0) { + suggestions_ = std::make_unique>(); + for (auto suggestion : suggestions) { + suggestions_->emplace_back(suggestion); + } + } } Diagnostic::Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind, const util::DiagnosticMessageParams &diagnosticParams) - : Diagnostic(diagnosticKind, diagnosticParams, lexer::SourcePosition()) + : Diagnostic(diagnosticKind, diagnosticParams, lexer::SourcePosition(), {}) +{ +} + +Diagnostic::Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind, + const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos, + class Suggestion *suggestion) + : Diagnostic(diagnosticKind, diagnosticParams, pos, {suggestion}) +{ +} + +Diagnostic::Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind, + const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos) + : Diagnostic(diagnosticKind, diagnosticParams, pos, {}) { } diff --git a/ets2panda/util/diagnostic.h b/ets2panda/util/diagnostic.h index bc0be56c5a37d558e574ed6886b0549dac614278..cb4c70a25693c35fc347719755a49cd056f69ce6 100644 --- a/ets2panda/util/diagnostic.h +++ b/ets2panda/util/diagnostic.h @@ -16,6 +16,8 @@ #ifndef ES2PANDA_UTIL_DIAGNOSTIC_H #define ES2PANDA_UTIL_DIAGNOSTIC_H +#include +#include #include #include #include "util/es2pandaMacros.h" @@ -44,10 +46,13 @@ enum DiagnosticType { SYNTAX, SEMANTIC, WARNING, - PLUGIN, + PLUGIN_ERROR, + PLUGIN_WARNING, DECLGEN_ETS2TS_ERROR, DECLGEN_ETS2TS_WARNING, ARKTS_CONFIG_ERROR, + SUGGESTION, + ISOLATED_DECLGEN, COUNT, INVALID = COUNT }; @@ -118,6 +123,11 @@ using DiagnosticMessageElement = const checker::Type *const, const checker::Signature *const>; using DiagnosticMessageParams = std::vector; +struct DiagnosticWithParams { + const diagnostic::DiagnosticKind &kind; // NOLINT(readability-identifier-naming) + const DiagnosticMessageParams params = {}; // NOLINT(readability-identifier-naming) +}; + // NOLINTNEXTLINE(fuchsia-multiple-inheritance) class ThrowableDiagnostic : public DiagnosticBase, public std::exception { public: @@ -161,12 +171,47 @@ private: std::string message_ {}; }; +class Suggestion : public DiagnosticBase { +public: + explicit Suggestion(const diagnostic::DiagnosticKind *kind, std::vector ¶ms, + const char *substitutionCode, const lexer::SourceRange *range); + + const lexer::SourceRange *SourceRange() const + { + return range_; + } + + std::string SubstitutionCode() const + { + return substitutionCode_; + } + + std::string Message() const override + { + return message_; + } + + DiagnosticType Type() const override; + +private: + const diagnostic::DiagnosticKind *kind_; + const std::string substitutionCode_; + const std::string message_; + const lexer::SourceRange *range_; +}; + class Diagnostic : public DiagnosticBase { public: explicit Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind, const util::DiagnosticMessageParams &diagnosticParams); explicit Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind, const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos); + explicit Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind, + const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos, + Suggestion *suggestion); + explicit Diagnostic(const diagnostic::DiagnosticKind &diagnosticKind, + const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos, + std::initializer_list suggestions); NO_COPY_SEMANTIC(Diagnostic); DEFAULT_MOVE_SEMANTIC(Diagnostic); @@ -175,9 +220,15 @@ public: DiagnosticType Type() const override; std::string Message() const override; + const std::vector &Suggestion() const + { + return *suggestions_; + } + private: const diagnostic::DiagnosticKind *diagnosticKind_; std::vector diagnosticParams_ {}; + std::unique_ptr> suggestions_ {}; }; } // namespace ark::es2panda::util diff --git a/ets2panda/util/diagnostic/arktsconfig_error.yaml b/ets2panda/util/diagnostic/arktsconfig_error.yaml index 1f30a289bbce074d7f94aee9410bb0dfe5549422..2568bcd28449904e0a620df461f0554a248af0c4 100644 --- a/ets2panda/util/diagnostic/arktsconfig_error.yaml +++ b/ets2panda/util/diagnostic/arktsconfig_error.yaml @@ -75,3 +75,7 @@ arkts_config_error: - name: INVALID_DESTINATION_FILE id: 16 message: Invalid destination file + +- name: INVALID_DYNAMIC_PATH + id: 17 + message: Invalid dynamic path '{}' diff --git a/ets2panda/util/diagnostic/isolated_declgen.yaml b/ets2panda/util/diagnostic/isolated_declgen.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fb9d9d2c3246f2352e92f6b34b5a4f3ae43f42ea --- /dev/null +++ b/ets2panda/util/diagnostic/isolated_declgen.yaml @@ -0,0 +1,48 @@ +# 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. +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: OBJECTS_THAT_CONTAIN_SPREAD_ASSIGNMENTS_CANNOT_BE_INFERRED_WITH_ISOLATED_DECL + id: 4 + message: Objects that contain spread assignments cannot be inferred with isolated declaration. + +- name: ONLY_CONST_ARRAYS_CAN_BE_INFERRED_WITH_ISOLATED_DECL + id: 5 + 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: 6 + 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: 7 + message: Cannot use array creation expression with type parameter. + +- name: FUNCTION_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL + id: 8 + message: Function must have an explicit return type annotation when using isolated declaration. + +- name: METHOD_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL + id: 9 + message: Method must have an explicit return type annotation when using isolated declaration. \ No newline at end of file diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 1ce3c79fce67dd10ce2a5743b446f63e905b6e5f..e61143986bcf695abdb9aa0c4020ed3b1e3d0d43 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -192,7 +192,7 @@ semantic: id: 45 message: "The parameter '{}' does not match any declared property in the annotation '{}'." -- name: LAMBDA_TYPE_MISMATCH +- name: TYPE_MISMATCH_AT_IDX id: 46 message: "Type '{}' is not compatible with type '{}' at index {}" @@ -260,7 +260,7 @@ semantic: id: 62 message: "need to specify target type for class composite" -- name: CKASS_COMPOSITE_INVALID_TARGET +- name: CLASS_COMPOSITE_INVALID_TARGET id: 63 message: "Target type for class composite needs to be an object type, found '{}'" @@ -415,9 +415,9 @@ semantic: id: 101 message: "Initializer must be able to complete normally." -- name: UNREACHABLE_STMT +- name: EXTEND_DYNAMIC id: 102 - message: "Unreachable statement." + message: "Class {} shouldn't extend dynamic class." - name: MISSING_RETURN_STMT id: 103 @@ -549,7 +549,7 @@ semantic: - name: MAIN_PARAM_NOT_ARR_OF_STRING id: 135 - message: "Only 'string[]' type argument is allowed." + message: "Only 'FixedArray' type argument is allowed." - name: OVERRIDE_DOESNT_OVERRIDE id: 136 @@ -927,7 +927,7 @@ semantic: id: 230 message: "Annotation missing '@' symbol before annotation name." -- name: TUPLE_TOO_FEW_ELEMS +- name: TUPLE_WRONG_NUMBER_OF_ELEMS id: 231 message: "Initializer has {} elements, but tuple requires {}" @@ -1106,3 +1106,379 @@ semantic: - name: LOCAL_CLASS_NATIVE_METHOD id: 278 message: "Local class '{}' shouldn't have native methods/constructors" + +- name: TUPLEN_NOT_IMPLEMENTED + id: 279 + message: "Tuple types with arity >16 are not yet implemented" + +- name: PROPERTY_MAYBE_MISSING_INIT + id: 280 + message: "Property '{}' might not have been initialized." + +- name: NOT_ALLOWED_THIS_IN_UNION_TYPE + id: 281 + message: "A 'this' cannot be used as a part of union type." + +- name: NOT_ALLOWED_THIS_IN_TUPLE_TYPE + id: 282 + message: "A 'this' cannot be used as a part of tuple type." + +- name: NOT_ALLOWED_THIS_IN_ARRAY_TYPE + id: 283 + message: "A 'this' cannot be used as type of array." + +- name: TYPE_FROM_UNION_TYPE_UNSUPPORTED + id: 284 + message: "Acquiring types for union types is not supported." + +- name: TYPE_FROM_UNRESOLVABLE_TYPE + id: 285 + message: "Unable to resolve type." + +- name: TYPE_FROM_TUPLE_TYPE_UNSUPPORTED + id: 286 + message: "Acquiring types for tuple types is not supported." + +- name: TYPE_FROM_STRING_LITERAL_TYPE_UNSUPPORTED + id: 287 + message: "Acquiring types for string literal types is not supported." + +- name: STATIC_REF_TO_NONSTATIC + id: 288 + message: "Cannot make a static reference to the non-static type {}" + +- name: EXPR_NOT_CALLABLE + id: 289 + message: "This expression is not callable." + +- name: CALLEE_NONCONSTRUCTIBLE + id: 290 + message: "Type '{}' is not constructible." + +- 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: EXPR_NONCONSTRUCTIBLE + id: 292 + message: "This expression is not constructible." + +- 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: AWAITED_NOT_PROMISE + id: 303 + message: "'await' expressions require Promise object as argument." + +- name: NULLISH_CAST_TO_NONNULLISH + id: 304 + message: "Cannot cast 'null' or 'undefined' to non-nullish type." + +- name: CAST_TO_NEVER + id: 305 + message: "Cast to 'never' is prohibited" + +- name: PRIVATE_METHOD_AS_VALUE + id: 306 + message: "Private method is used as value" + +- name: OVERLOADED_METHOD_AS_VALUE + id: 307 + message: "Overloaded method is used as value" + +- name: CIRCULAR_DEPENDENCY + id: 308 + message: "Circular dependency detected for identifier: {}" + +- 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: CYCLIC_VAR_REF + id: 314 + message: "'{}' is referenced directly or indirectly in its own initializer ot type annotation." + +- name: IFACE_MULTIPLE_EXTENSION + id: 315 + message: "Interface '{}' cannot simultaneously extend types '{}' and '{}'." + +- 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: 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_ASSIGNMNENT + id: 318 + message: "Type '{}' cannot be assigned to type '{}'" + +- name: PROP_INCOMPAT + id: 319 + message: "Type '{}' is not compatible with type '{}' at property '{}'" + +- name: IFACE_INVALID_EXTENDS + id: 320 + message: "Interface '{}' incorrectly extends interface '{}'" + +- name: INVALID_ASSIGNMNENT_2 + id: 321 + message: "Type '{}' is not assignable to type '{}'." + +- 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: REST_PARAM_INCOMPAT_AT + id: 323 + message: "Type '{}' is not compatible with rest parameter type '{}' at index {}" + +- name: PROP_ASSIGN_TO_NUMERIC_INDEX + id: 324 + message: "Property '{}' of type '{}' is not assignable to numeric index type '{}'." + +- name: TUPLE_CONVERSION_FAILURE + id: 325 + message: "Tuple type couldn't be converted " + +- name: INVALID_CAST + id: 326 + message: "Cannot cast type '{}' to '{}'" + +- name: PROP_ASSIGN_TO_STRING_INDEX + id: 327 + message: "Property '{}' of type '{}' is not assignable to string index type '{}'." + +- name: UNIMPLEMENTED_REST_TUPLE + id: 328 + message: "Tuple types for rest arguments are not yet implemented" + +- name: REF_INVALID + id: 329 + message: "Invalid reference '{}'." + +- name: ID_WRONG_CTX + id: 330 + message: "Identifier '{}' is used in wrong context." + +- name: VARIANT_PARAM_INVARIAN_USE + id: 331 + message: "Type Parameter '{}' is declared as{} but occurs in 'invariant' position." + +- name: VARIANCE_TPARAM_IN_OUT + id: 332 + message: "Type Parameter '{}' is declared as 'in' but occurs in 'out' position." + +- name: VARIANCE_TPARAM_OUT_IN + id: 333 + message: "Type Parameter '{}' is declared as 'out' but occurs in 'in' position." + +- name: SWITCH_ENUM_NOT_UNQUALIFIED_ENUM_CONST + id: 334 + message: "Enum switch case must be unqualified name of an enum constant" + +- 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: INTERFACE_PROPERTY_REQUIRES_SETTER + id: 337 + message: "Cannot implement interface {}: property '{}' must have a setter, but the implementation is readonly" + +- name: READONLY_PROPERTY_REASSIGN + id: 338 + message: "The 'Readonly' property cannot be reassigned." + +- name: ILLEGAL_NON_NULLISH_TYPE + id: 339 + message: "Only type parameters can be used as a nonnullish 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_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_PROPERTIES_BY_INDEX + id: 343 + message: "Indexed signatures are not allowed. Use arrays instead!" + +- name: USE_BEFORE_INIT + id: 344 + message: "{} '{}' is used before being assigned." + +- name: TYPE_NOT_FOUND + id: 345 + message: "Cannot find type '{}'." + +- name: INTERFACE_REDECLARED + id: 346 + message: "Interface redeclaration is not allowed" + +- name: OVERLOADED_MAIN + id: 347 + message: "Main overload is not enabled" + +- name: MULTIPLE_DEFAULT_EXPORTS + id: 348 + message: "Only one default export is allowed in a module" + +- name: REDEFINITION + id: 349 + message: "{} '{}' is already defined." + +- name: REDEFINITION_DIFF_TYPE + id: 350 + message: "{} '{}' is already defined with different type." + +- name: VARIABLE_REDECLARED + id: 351 + message: "Variable '{}' has already been declared." + +- name: DEFAULT_DYNAMIC_IMPORT + id: 352 + message: "Default import is currently not implemented in dynamic import" + +- name: DEFAULT_EXPORT_DIRECT_IMPORTED + id: 353 + message: "Use the default import syntax to import a default exported element" + +- name: IMPORTING_NONEXPORTED_TYPE + id: 354 + message: "Cannot import '{}', imported type imports only exported types." + +- name: IMPORTED_NOT_EXPORTED + id: 355 + message: "Imported element not exported '{}'" + +- name: IMPORT_NOT_FOUND + id: 356 + message: "Cannot find imported element '{}'" + +- name: IMPORT_RENAMES_ANNOTATION + id: 357 + message: "Can not rename annotation '{}' in export or import statements." + +- name: DEFAULT_IMPORT_NOT_FOUND + id: 358 + message: "Cannot find default imported element in the target" + +- name: MODULE_INDEX_MISSING + id: 359 + message: "Cannot find index.[ets|ts] or package module in folder: {}" + +- name: IMPORT_NOT_FOUND_2 + id: 360 + message: "Cannot find import: {}" + +- name: EXPORT_INCORRECT + id: 361 + message: "Incorrect export '{}'" + +- name: AMBIGUOUS_EXPORT + id: 362 + message: "Ambiguous export '{}'" + +- name: CONST_WITHOUT_INIT + id: 363 + message: "Missing initializer in const declaration" + +- 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: INVALID_EXPORT + id: 367 + message: "Invalid exported binding" + +- name: NOT_IMPLEMENTED + id: 368 + message: "not implemented" + +- name: ID_REDECLARED + id: 369 + message: "Identifier '{}' has already been declared." + +- 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: LATE_INITIALIZATION_FIELD_HAS_INVALID_TYPE + id: 371 + message: "Late-initialized field cannot be nullish types or possibly nullish types." + +- name: SUPER_NOT_ACCESSIBLE + id: 372 + message: "Class field '{}' defined by the parent class is not accessible in the child class via super." diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index c66b45870b47b2867d30e2b9e878278936cf4abd..a412c35ab549ada14459b3f41c431bdf0075ed09 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -146,7 +146,7 @@ syntax: - name: MULTIPLE_STATIC_BLOCK id: 34 - message: "Only one static block is allowed." + message: "Only one static block is allowed in one namespace or class." - name: INVALID_ENUM_TYPE id: 35 @@ -516,9 +516,9 @@ syntax: id: 126 message: "Variable declaration expected." -- name: ENUM_MUST_HAVE_ONE_CONST +- name: CONFLICTING_FIELD_MODIFIERS id: 127 - message: "An enum must have at least one enum constant." + message: "Conflicting modifiers '!' and '?' on field." - name: VALUE_IS_NOT_SET id: 128 @@ -780,9 +780,9 @@ syntax: id: 192 message: "Rest parameter cannot have the default value." -- name: ONLY_ARRAY_FOR_REST +- name: ONLY_ARRAY_OR_TUPLE_FOR_REST id: 193 - message: "Rest parameter should be of an array type." + message: "Rest parameter should be either array or tuple type." - name: EXPLICIT_PARAM_TYPE id: 194 @@ -1155,7 +1155,79 @@ syntax: - name: INVALID_SHORTHAND_PROPERTY_INITIALIZER id: 286 message: "Invalid shorthand property initializer." - + - name: RETURN_WITH_VALUE id: 287 message: "Unexpected return value." + +- name: INVALID_INIT_IN_PACKAGE + id: 288 + message: "Non-constant initializer of Package should be apply in Initializer Block." + +- name: PACKAGE_MULTIPLE_STATIC_BLOCK + id: 289 + message: "static block cannot apply to multi-files for one package" + +- name: CONSTANT_MULTI_INITIALIZED_IN_STATIC_BLOCK + id: 290 + message: "package constant property initialization can only be applied once in static block" + +- name: INVALID_PACKAGE_TOP_LEVEL_STMT + id: 291 + message: "Invalid package toplevel statement" + +- name: ONLY_CONSTANT_ALLOWED + id: 292 + message: "Only constant expression is expected in the field" + +- name: ENUM_OR_ANNOTATION_DIVIDE_BY_ZERO + id: 293 + message: "Division by zero are not allowed in Enum or Annotation" + +- name: MISSING_INIT_FOR_CONST_PACKAGE_PROP + id: 294 + message: "Missing initialization for const package property" + +- name: PREDEFINED_TYPE_AS_IDENTIFIER + id: 295 + message: "{} is a predefined type, cannot be used as an identifier" + +- name: EXPORT_WITHOUT_DECLARE_IN_DECL_MODULE + id: 296 + message: "Export keyword without declare shouldn't be used in declaration module." + +- name: ERROR_ARKTS_NO_VAR + id: 297 + message: "'var' keyword is not supported. Use 'let' instead." + +- name: ERROR_ARKTS_NO_PRIVATE_IDENTIFIERS + id: 298 + message: "Use 'private' keyword to declare an identifier as private." + +- name: ERROR_ARKTS_NO_DEBUGGER_STATEMENT + id: 299 + message: "Debugger statement is not supported!" + +- name: MISSING_LOOP_BODY + id: 300 + message: "Missing body in {} statement" + +- name: MISSING_LOOP_CONDITION + id: 301 + message: "Missing condition in {} statement" + +- name: PRIVATE_FIELD_MISMATCH + id: 302 + message: "Private field '{}' must be declared in an enclosing class" + +- name: STATIC_LATE_INITIALIZATION_FIELD_INVALID_MODIFIER + id: 303 + message: "Late-initialized field cannot be defined as static." + +- name: LATE_INITIALIZATION_FIELD_HAS_DEFAULT_VALUE + id: 304 + message: "Late-initialized field cannot have default value." + +- name: DEEP_NESTING + id: 305 + message: "Maximum allowed nesting level exceeded." \ No newline at end of file diff --git a/ets2panda/util/diagnostic/warning.yaml b/ets2panda/util/diagnostic/warning.yaml index 7c5314fafb15559d73b5bb1a4182698f1e210e0f..264a442c2df3de7ad09236d4d6ac5c921f14b0d2 100644 --- a/ets2panda/util/diagnostic/warning.yaml +++ b/ets2panda/util/diagnostic/warning.yaml @@ -47,3 +47,67 @@ warning: - name : ANNOTATION_UNUSED_GENERIC_ALIAS_WARN id: 9 message: "Type alias generic parameter '{}' is not used in type annotation" + +- name: DYNAMIC_PATHS_ABSOLUTE + id: 10 + message: "Don't use absolute path '{}' as key in 'dynamicPaths'" + +- 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: 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_REASSIGNED + id: 17 + message: "{} '{}' might already have been assigned." + +- name: PROP_MAYBE_UNINITIALIZED + id: 18 + message: "Property '{}' might not have been initialized." + +- name: MAYBE_FALLTHROUGH + id: 20 + message: "Possible fall-through into case" + +- 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: 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: UNREACHABLE_STMT + id: 26 + message: "Unreachable statement." \ No newline at end of file diff --git a/ets2panda/util/diagnosticEngine.cpp b/ets2panda/util/diagnosticEngine.cpp index 69e1f1ad0ac9e1f96d07d581f395e7fccf20c3f3..9660f1f160f0261e55eee8caa904972c4c70247f 100644 --- a/ets2panda/util/diagnosticEngine.cpp +++ b/ets2panda/util/diagnosticEngine.cpp @@ -52,8 +52,8 @@ DiagnosticStorage DiagnosticEngine::GetAllDiagnostic() DiagnosticStorage merged; merged.reserve(totalSize); for (auto &vec : diagnostics_) { - for (auto &&diag : vec) { - merged.emplace_back(std::move(diag)); + for (auto &diag : vec) { + merged.emplace_back(diag); } } return merged; @@ -61,12 +61,17 @@ DiagnosticStorage DiagnosticEngine::GetAllDiagnostic() void DiagnosticEngine::FlushDiagnostic() { + if (isFlushed_) { + return; + } auto log = GetAllDiagnostic(); std::sort(log.begin(), log.end(), [](const auto &lhs, const auto &rhs) { return *lhs < *rhs; }); - auto last = std::unique(log.begin(), log.end()); + auto last = + std::unique(log.begin(), log.end(), [&](const auto &rhs, const auto &lhs) -> bool { return *rhs == *lhs; }); for (auto it = log.begin(); it != last; it++) { printer_->Print(**it); } + isFlushed_ = true; } #ifndef FUZZING_EXIT_ON_FAILED_ASSERT static void SigSegvHandler([[maybe_unused]] int sig) @@ -111,13 +116,17 @@ bool DiagnosticEngine::IsError(DiagnosticType type) const case DiagnosticType::FATAL: case DiagnosticType::SYNTAX: case DiagnosticType::SEMANTIC: - case DiagnosticType::PLUGIN: + case DiagnosticType::PLUGIN_ERROR: case DiagnosticType::DECLGEN_ETS2TS_ERROR: case DiagnosticType::ARKTS_CONFIG_ERROR: + case DiagnosticType::ISOLATED_DECLGEN: return true; case DiagnosticType::WARNING: case DiagnosticType::DECLGEN_ETS2TS_WARNING: + case DiagnosticType::PLUGIN_WARNING: return wError_; + case DiagnosticType::SUGGESTION: + return false; default: ES2PANDA_UNREACHABLE(); } diff --git a/ets2panda/util/diagnosticEngine.h b/ets2panda/util/diagnosticEngine.h index 6ad7156132bdb2d005e3f438fc81f33c51337af3..a013fc7a71296a28d869b92a28d67a00afe02e86 100644 --- a/ets2panda/util/diagnosticEngine.h +++ b/ets2panda/util/diagnosticEngine.h @@ -46,7 +46,7 @@ public: void Print(const DiagnosticBase &diagnostic) const override; }; -using DiagnosticStorage = std::vector>; +using DiagnosticStorage = std::vector>; class DiagnosticEngine { public: @@ -67,12 +67,25 @@ public: [[nodiscard]] bool IsAnyError() const noexcept; + template + Suggestion *CreateSuggestion(T &&...args) + { + return CreateDiagnostic(std::forward(args)...); + } + template void LogDiagnostic(T &&...args) { LogDiagnostic(std::forward(args)...); } + void ClearDiagnostics() + { + for (auto &it : diagnostics_) { + it.clear(); + } + } + // NOTE(schernykh): should be removed void Log([[maybe_unused]] const ThrowableDiagnostic &error) { @@ -94,11 +107,6 @@ public: { LogThrowableDiagnostic(DiagnosticType::FATAL, std::forward(args)...); } - template - void LogWarning(T &&...args) - { - LogThrowableDiagnostic(DiagnosticType::WARNING, std::forward(args)...); - } // NOTE(schernykh): should not be able from ETS template @@ -129,11 +137,18 @@ public: private: template - void LogDiagnostic(T &&...args) + DIAGNOSTIC *CreateDiagnostic(T &&...args) { auto diag = std::make_unique(std::forward(args)...); auto type = diag->Type(); diagnostics_[type].push_back(std::move(diag)); + return reinterpret_cast(diagnostics_[type].back().get()); + } + + template + void LogDiagnostic(T &&...args) + { + CreateDiagnostic(std::forward(args)...); } template @@ -157,6 +172,7 @@ private: std::array(DiagnosticType::COUNT)> diagnostics_; std::unique_ptr printer_; bool wError_ {false}; + bool isFlushed_ {false}; }; } // namespace ark::es2panda::util diff --git a/ets2panda/util/doubleLinkedList.h b/ets2panda/util/doubleLinkedList.h new file mode 100644 index 0000000000000000000000000000000000000000..a4d5a5a9197a794011563ddf8f266196f9bd6b98 --- /dev/null +++ b/ets2panda/util/doubleLinkedList.h @@ -0,0 +1,168 @@ +/** + * 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 ES2PANDA_UTIL_DOUBLE_LINKED_LIST_H +#define ES2PANDA_UTIL_DOUBLE_LINKED_LIST_H + +#include "mem/arena_allocator.h" + +namespace ark::es2panda::util { + +template +class ArenaDoubleLinkedList { +public: + explicit ArenaDoubleLinkedList(ArenaAllocator *allocator) : allocator_ {allocator} {} + + struct Item { + T data {}; + Item *next {nullptr}; + Item *prev {nullptr}; + }; + + Item *Head() + { + return head_; + } + + Item *Tail() + { + return tail_; + } + + bool Empty() + { + return head_ == nullptr; + }; + + ArenaAllocator *Allocator() + { + return allocator_; + } + + Item *Append(const T &data) + { + auto item = allocator_->New(); + item->data = data; + Append(item); + return item; + } + + void Append(Item *item) + { + item->next = nullptr; + item->prev = nullptr; + + if (Empty()) { + head_ = item; + tail_ = item; + } else { + tail_->next = item; + item->prev = tail_; + tail_ = item; + } + } + + Item *Prepend(const T &data) + { + auto item = allocator_->New(); + item->data = data; + Prepend(item); + return item; + } + + void Prepend(Item *item) + { + item->next = nullptr; + item->prev = nullptr; + + if (Empty()) { + head_ = item; + tail_ = item; + } else { + head_->prev = item; + item->next = head_; + head_ = item; + } + } + + Item *Insert(Item *after, const T &data) + { + auto item = allocator_->New(); + item->data = data; + Insert(after, item); + return item; + } + + void Insert(Item *after, Item *item) + { + ES2PANDA_ASSERT(!Empty()); + ES2PANDA_ASSERT(after != nullptr); + ES2PANDA_ASSERT(item != nullptr); + + auto afterNext = after->next; + + after->next = item; + item->prev = after; + + item->next = afterNext; + if (afterNext != nullptr) { + afterNext->prev = item; + } + + if (after == tail_) { + tail_ = item; + } + } + + void Erase(Item *item) + { + ES2PANDA_ASSERT(!Empty()); + ES2PANDA_ASSERT(item != nullptr); + + if (item == head_ && item == tail_) { + // Item is the only element in list + head_ = nullptr; + tail_ = nullptr; + } else if (item == head_) { + head_ = head_->next; + if (head_ != nullptr) { + head_->prev = nullptr; + } + } else if (item == tail_) { + tail_ = tail_->prev; + if (tail_ != nullptr) { + tail_->next = nullptr; + } + } else { + // Item is not a head or tail element of list + auto prev = item->prev; + auto next = item->next; + + ES2PANDA_ASSERT(prev != nullptr && next != nullptr); + prev->next = next; + next->prev = prev; + } + + item->next = nullptr; + item->prev = nullptr; + } + +private: + Item *head_ {nullptr}; + Item *tail_ {nullptr}; + ArenaAllocator *allocator_; +}; +} // namespace ark::es2panda::util +#endif diff --git a/ets2panda/util/enumbitops.h b/ets2panda/util/enumbitops.h index 46a95feeb13deec32a36e70db739689d02203b04..b22f3325b19332835b92a5e03e3faea22018be79 100644 --- a/ets2panda/util/enumbitops.h +++ b/ets2panda/util/enumbitops.h @@ -27,7 +27,9 @@ enumbitops::operator^, \ enumbitops::operator|=, \ enumbitops::operator&=, \ - enumbitops::operator^= + enumbitops::operator^=, \ + enumbitops::All, \ + enumbitops::Any // clang-format on namespace enumbitops { @@ -98,6 +100,20 @@ inline constexpr T &operator^=(T &a, T b) return a = a ^ b; } +template ::value, bool> = true> +inline constexpr bool All(T flags, T test) +{ + using Utype = std::underlying_type_t; + return (flags & test) == static_cast(test); +} + +template ::value, bool> = true> +inline constexpr bool Any(T flags, T test) +{ + using Utype = std::underlying_type_t; + return (flags & test) != static_cast(0); +} + } // namespace enumbitops #endif diff --git a/ets2panda/util/es2pandaMacros.h b/ets2panda/util/es2pandaMacros.h index cc0990c7b5768973d1159ca7af31193b5bcfa31d..6764fadf6a481d4e5a58a42b249cceed57169ad3 100644 --- a/ets2panda/util/es2pandaMacros.h +++ b/ets2panda/util/es2pandaMacros.h @@ -18,6 +18,7 @@ #include "macros.h" #include "lexer/token/sourceLocation.h" + namespace ark::es2panda::parser { class Program; } // namespace ark::es2panda::parser diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index e7204d2d33947ee031a17c5dbb38e781159adecb..41e971809ed09181714b401412afbf453d490b37 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -402,11 +402,11 @@ bool Helpers::IsPattern(const ir::AstNode *node) return node->IsArrayPattern() || node->IsObjectPattern() || node->IsAssignmentPattern(); } -static void CollectBindingName(ir::AstNode *node, std::vector *bindings) +static void CollectBindingName(varbinder::VarBinder *vb, ir::AstNode *node, std::vector *bindings) { switch (node->Type()) { case ir::AstNodeType::IDENTIFIER: { - if (!Helpers::IsGlobalIdentifier(node->AsIdentifier()->Name())) { + if (!vb->IsGlobalIdentifier(node->AsIdentifier()->Name())) { bindings->push_back(node->AsIdentifier()); } @@ -414,26 +414,26 @@ static void CollectBindingName(ir::AstNode *node, std::vector } case ir::AstNodeType::OBJECT_PATTERN: { for (auto *prop : node->AsObjectPattern()->Properties()) { - CollectBindingName(prop, bindings); + CollectBindingName(vb, prop, bindings); } break; } case ir::AstNodeType::ARRAY_PATTERN: { for (auto *element : node->AsArrayPattern()->Elements()) { - CollectBindingName(element, bindings); + CollectBindingName(vb, element, bindings); } break; } case ir::AstNodeType::ASSIGNMENT_PATTERN: { - CollectBindingName(node->AsAssignmentPattern()->Left(), bindings); + CollectBindingName(vb, node->AsAssignmentPattern()->Left(), bindings); break; } case ir::AstNodeType::PROPERTY: { - CollectBindingName(node->AsProperty()->Value(), bindings); + CollectBindingName(vb, node->AsProperty()->Value(), bindings); break; } case ir::AstNodeType::REST_ELEMENT: { - CollectBindingName(node->AsRestElement()->Argument(), bindings); + CollectBindingName(vb, node->AsRestElement()->Argument(), bindings); break; } default: @@ -441,10 +441,10 @@ static void CollectBindingName(ir::AstNode *node, std::vector } } -std::vector Helpers::CollectBindingNames(ir::Expression *node) +std::vector Helpers::CollectBindingNames(varbinder::VarBinder *vb, ir::Expression *node) { std::vector bindings; - CollectBindingName(node, &bindings); + CollectBindingName(vb, node, &bindings); return bindings; } @@ -700,9 +700,9 @@ std::pair Helpers::SplitSignature(std::strin std::vector const &Helpers::StdLib() { - static std::vector stdlib {"std/core", "std/math", "std/containers", "std/time", - "std/interop/js", "std/debug", "std/debug/concurrency", "std/testing", - "escompat", "std/concurrency", "std/annotations"}; + static std::vector stdlib {"std/core", "std/math", "std/containers", "std/interop/js", + "std/time", "std/debug", "std/debug/concurrency", "std/testing", + "escompat", "std/concurrency", "std/annotations", "std/interop"}; return stdlib; } @@ -769,4 +769,10 @@ bool Helpers::IsAsyncMethod(ir::AstNode const *node) return method->Function()->IsAsyncFunc() && !method->Function()->IsProxy(); } +bool Helpers::IsGlobalVar(const ark::es2panda::varbinder::Variable *var) +{ + return var->Declaration()->Node()->IsClassDeclaration() && + var->Declaration()->Node()->AsClassDeclaration()->Definition()->IsGlobal(); +} + } // namespace ark::es2panda::util diff --git a/ets2panda/util/helpers.h b/ets2panda/util/helpers.h index 3ac27791612128135fbd33bb94c53a6fb131e477..a861a59a42c4503ea57e85770b0bd372d297e3ac 100644 --- a/ets2panda/util/helpers.h +++ b/ets2panda/util/helpers.h @@ -149,7 +149,7 @@ public: static compiler::Literal ToConstantLiteral(const ir::Expression *expr); static bool IsBindingPattern(const ir::AstNode *node); static bool IsPattern(const ir::AstNode *node); - static std::vector CollectBindingNames(ir::Expression *node); + static std::vector CollectBindingNames(varbinder::VarBinder *vb, ir::Expression *node); static util::StringView FunctionName(ArenaAllocator *allocator, const ir::ScriptFunction *func); static void CheckImportedName(const ArenaVector &specifiers, const ir::ImportSpecifier *specifier, const std::string &fileName); @@ -160,6 +160,8 @@ public: std::uint32_t index); static bool IsAsyncMethod(ir::AstNode const *node); + static bool IsGlobalVar(const ark::es2panda::varbinder::Variable *var); + template static ArenaVector ConvertVector(const ArenaVector &src) { diff --git a/ets2panda/util/importPathManager.cpp b/ets2panda/util/importPathManager.cpp index 872a21887a1ba10dc73bc6eabb12c99f1241c9d5..7cf04669276b7b647c1a6d4a086c986641ad2d86 100644 --- a/ets2panda/util/importPathManager.cpp +++ b/ets2panda/util/importPathManager.cpp @@ -58,24 +58,23 @@ static bool IsAbsolute(const std::string &path) #endif // ARKTSCONFIG_USE_FILESYSTEM } -ImportPathManager::ImportMetadata ImportPathManager::GatherImportMetadata(const parser::ParserContext &context, +ImportPathManager::ImportMetadata ImportPathManager::GatherImportMetadata(parser::Program *program, + ImportFlags importFlags, ir::StringLiteral *importPath) { srcPos_ = &importPath->Start(); // NOTE(dkofanov): The code below expresses the idea of 'dynamicPaths' defining separated, virtual file system. // Probably, paths of common imports should be isolated from the host fs as well, being resolved by 'ModuleInfo' // instead of 'AbsoluteName'. - auto curModulePath = context.GetProgram()->ModuleInfo().isDeclForDynamicStaticInterop - ? context.GetProgram()->ModuleInfo().moduleName - : context.GetProgram()->AbsoluteName(); + isDynamic_ = program->ModuleInfo().isDeclForDynamicStaticInterop; + auto curModulePath = isDynamic_ ? program->ModuleInfo().moduleName : program->AbsoluteName(); auto [resolvedImportPath, resolvedIsDynamic] = ResolvePath(curModulePath.Utf8(), importPath); if (resolvedImportPath.empty()) { ES2PANDA_ASSERT(diagnosticEngine_.IsAnyError()); return ImportMetadata {util::ImportFlags::NONE, Language::Id::COUNT, ERROR_LITERAL}; } - auto importFlags = (context.Status() & parser::ParserStatus::IN_DEFAULT_IMPORTS) != 0U - ? util::ImportFlags::DEFAULT_IMPORT - : util::ImportFlags::NONE; + + globalProgram_->AddFileDependencies(std::string(curModulePath), std::string(resolvedImportPath)); ImportMetadata importData {importFlags}; importData.resolvedSource = resolvedImportPath; @@ -89,7 +88,7 @@ ImportPathManager::ImportMetadata ImportPathManager::GatherImportMetadata(const importData.ohmUrl = dynImportData.OhmUrl(); } else { ES2PANDA_ASSERT(IsAbsolute(std::string(importData.resolvedSource))); - importData.lang = ToLanguage(context.GetProgram()->Extension()).GetId(); + importData.lang = ToLanguage(program->Extension()).GetId(); importData.declPath = util::ImportPathManager::DUMMY_PATH; importData.ohmUrl = util::ImportPathManager::DUMMY_PATH; } @@ -173,7 +172,7 @@ ImportPathManager::ResolvedPathRes ImportPathManager::ResolveAbsolutePath(const } ES2PANDA_ASSERT(arktsConfig_ != nullptr); - auto resolvedPath = arktsConfig_->ResolvePath(importPath); + auto resolvedPath = arktsConfig_->ResolvePath(importPath, isDynamic_); if (!resolvedPath) { diagnosticEngine_.LogDiagnostic( diagnostic::IMPORT_CANT_FIND_PREFIX, diff --git a/ets2panda/util/importPathManager.h b/ets2panda/util/importPathManager.h index 11bb355d53efbf223e4357663e03a45e410e47a3..9e011a215919850377801f2c805284ab4e50a03d 100644 --- a/ets2panda/util/importPathManager.h +++ b/ets2panda/util/importPathManager.h @@ -125,8 +125,19 @@ public: return parseList_; } + [[nodiscard]] ArenaVector &ParseList() + { + return parseList_; + } + + void ClearParseList() + { + parseList_.clear(); + } + util::StringView FormModuleName(const util::Path &path, const lexer::SourcePosition &srcPos); - ImportMetadata GatherImportMetadata(const parser::ParserContext &context, ir::StringLiteral *importPath); + ImportMetadata GatherImportMetadata(parser::Program *program, ImportFlags importFlags, + ir::StringLiteral *importPath); void AddImplicitPackageImportToParseList(StringView packageDir, const lexer::SourcePosition &srcPos); // API version for resolving paths. Kept only for API compatibility. Doesn't support 'dynamicPath'. @@ -149,12 +160,13 @@ private: // NOLINTEND(misc-non-private-member-variables-in-classes) }; ResolvedPathRes ResolvePath(std::string_view curModulePath, ir::StringLiteral *importPath) const; - ResolvedPathRes ResolveAbsolutePath(const ir::StringLiteral &importPath) const; + ResolvedPathRes ResolveAbsolutePath(const ir::StringLiteral &importPathNode) const; std::string_view DirOrDirWithIndexFile(StringView dir) const; ResolvedPathRes AppendExtensionOrIndexFileIfOmitted(StringView basePath) const; std::string TryMatchDynamicPath(std::string_view fixedPath) const; StringView GetRealPath(StringView path) const; +public: void AddToParseList(ImportMetadata importMetadata); #ifdef USE_UNIX_SYSCALL void UnixWalkThroughDirectoryAndAddToParseList(ImportMetadata importMetadata); @@ -170,6 +182,7 @@ private: util::DiagnosticEngine &diagnosticEngine_; std::string_view pathDelimiter_ {ark::os::file::File::GetPathDelim()}; mutable const lexer::SourcePosition *srcPos_ {}; + bool isDynamic_ = false; }; } // namespace ark::es2panda::util diff --git a/ets2panda/util/options.cpp b/ets2panda/util/options.cpp index 82bc0cee609ff70e585a550bee9206795fda275b..9f42bc27ab6b00253434bd595348cb5f457bbad6 100644 --- a/ets2panda/util/options.cpp +++ b/ets2panda/util/options.cpp @@ -242,6 +242,8 @@ bool Options::Parse(Span args) logLevel_ = Logger::LevelFromString(GetLogLevel()); } + parseJsdoc_ = WasSetParseJsdoc(); + InitCompilerOptions(); return ProcessEtsSpecificOptions(); @@ -338,8 +340,9 @@ bool Options::DetermineExtension() #ifdef ENABLE_AFTER_21192 // NOTE(mkaskov): Enable after #21192 if (!SourceFileName().empty() && WasSetExtension() && gen::Options::GetExtension() != sourceFileExtension) { - diagnosticEngine_.LogWarning({"Not matching extensions! Sourcefile: ", std::string_view(sourceFileExtension), - ", Manual(used): ", std::string_view(gen::Options::GetExtension())}); + diagnosticEngine_.LogDiagnostic( + diagnostic::EXTENSION_MISMATCH, + {std::string_view(sourceFileExtension), std::string_view(gen::Options::GetExtension())}); } #endif // ENABLE_AFTER_21192 // Note: the file suffix `.ets` is a valid suffix for compiler, which is equivalent to `.ets` diff --git a/ets2panda/util/options.h b/ets2panda/util/options.h index c9ac36f9951077eef682db783c51dfca00fb7e5d..47e693e74c59a76784698f42e4c9e90f833dedcd 100644 --- a/ets2panda/util/options.h +++ b/ets2panda/util/options.h @@ -59,17 +59,17 @@ public: // NOTE(dkofanov): Replace this getter with something that does 'std::move(parserInputContents_)' as currently it // encourages copying of 'parserInputContents_' data. - auto CStrParserInputContents() const + std::pair CStrParserInputContents() const { return std::pair {parserInputContents_.c_str(), parserInputContents_.size()}; } - const auto &ArkTSConfig() const + const std::shared_ptr &ArkTSConfig() const { return arktsConfig_; } - auto LogLevel() const + Logger::Level LogLevel() const { return logLevel_; } @@ -81,7 +81,7 @@ public: : CompilationMode::PROJECT; } - auto GetCompilationMode() const + CompilationMode GetCompilationMode() const { return compilationMode_; } @@ -105,7 +105,7 @@ public: return evalMode_ == eval_mode::FUNCTION; } - auto SourceFileName() const + std::string SourceFileName() const { return inputFile_.GetValue(); } @@ -115,36 +115,36 @@ public: return extension_ != ScriptExtension::ETS; } - const auto &GetAstVerifierWarnings() const + const std::array &GetAstVerifierWarnings() const { return verifierWarnings_; } - const auto &GetAstVerifierErrors() const + const std::array &GetAstVerifierErrors() const { return verifierErrors_; } - const auto &GetSkipPhases() const + const std::set &GetSkipPhases() const { return skipPhases_; } - const auto &GetDumpBeforePhases() const + const std::set &GetDumpBeforePhases() const { return dumpBeforePhases_; } - const auto &GetDumpEtsSrcBeforePhases() const + const std::set &GetDumpEtsSrcBeforePhases() const { return dumpEtsSrcBeforePhases_; } - const auto &GetDumpAfterPhases() const + const std::set &GetDumpAfterPhases() const { return dumpAfterPhases_; } - const auto &GetDumpEtsSrcAfterPhases() const + const std::set &GetDumpEtsSrcAfterPhases() const { return dumpEtsSrcAfterPhases_; } - const auto &GetEtsWarningCollection() const + const std::vector &GetEtsWarningCollection() const { return etsWarningCollection_; } @@ -169,6 +169,11 @@ public: return astVerifierEachPhase_ || astVerifierPhases_.find(std::string(phase)) != astVerifierPhases_.end(); } + bool IsEnableJsdocParse() const + { + return parseJsdoc_; + } + private: template static bool CallPandArgParser(const std::vector &args, T &options, @@ -203,6 +208,7 @@ private: Logger::Level logLevel_ {Logger::Level::ERROR}; EvalMode evalMode_ = {EvalMode::NONE}; util::DiagnosticEngine &diagnosticEngine_; + bool parseJsdoc_ {}; }; } // namespace ark::es2panda::util diff --git a/ets2panda/util/options.yaml b/ets2panda/util/options.yaml index 5277544a04434f5174814ee08b1853233cb91af1..3dab3459f66048e31eae1d9ee80131919daaecf3 100644 --- a/ets2panda/util/options.yaml +++ b/ets2panda/util/options.yaml @@ -63,7 +63,7 @@ options: type: bool default: false description: Dump AST with synthetic nodes for dynamic languages - + - name: dump-ast-only-silent type: bool default: false @@ -73,7 +73,12 @@ options: type: bool default: false description: Print names of files that are part of compilation - + +- name: parse-jsdoc + type: bool + default: false + description: Enable the ability to parse jsdoc + # Compiler - name: dump-assembly type: bool @@ -166,6 +171,22 @@ options: description: Paths to evaluation mode (.abc) files, must be accessible delimiter: ":" +- name: generate-decl + description: Input static file and generate static declaration files + sub_options: + - name: enabled + type: bool + default: false + description: Whether to enable static declaration file generation + - name: path + type: std::string + default: "" + description: Output path for generated static declaration files + - name: enable-isolated + type: bool + default: false + description: Whether to enable isolated declaration file generation + - name: thread type: int default: 0 @@ -233,7 +254,6 @@ options: - ReferenceTypeAnnotationIsNull - ArithmeticOperationValid - SequenceExpressionHasLastType - - CheckInfiniteLoop - ForLoopCorrectlyInitialized - VariableHasEnclosingScope - ModifierAccessValid @@ -247,7 +267,7 @@ options: - name: warnings type: arg_list_t description: Print warnings and continue compilation even if AST tree is incorrect. - default: [ CheckInfiniteLoop ] + default: [ ] possible_values: *VerifierInvariants delimiter: ':' - name: errors @@ -257,7 +277,6 @@ options: - ArithmeticOperationValid - CheckAbstractMethod # - CheckConstProperties - # - CheckInfiniteLoop # - CheckScopeDeclaration - CheckStructDeclaration - EveryChildHasValidParent @@ -279,7 +298,7 @@ options: delimiter: ':' - name: phases type: arg_list_t - default: [ "each" ] + default: [ "after" ] description: > Specify phases to finalize with ASTVerifier. Shortcuts: "before", "each", "after". delimiter: ':' @@ -354,3 +373,8 @@ options: type: arg_list_t default: [] description: Bytecode optimizer's compiler arguments + +- name: perm-arena + type: bool + default: true + description: Place AST trees in permanent arena diff --git a/ets2panda/util/path.cpp b/ets2panda/util/path.cpp index 5c5e54c443f4c0dd3b2bd0baf97385b28db37ad6..995424b52469d9bf82322cad60fed00adc5568df 100644 --- a/ets2panda/util/path.cpp +++ b/ets2panda/util/path.cpp @@ -116,9 +116,7 @@ void Path::InitializeAbsoluteParentFolder() int position = absolutePath_.Mutf8().find_last_of(PATH_DELIMITER); - if (!absolutePath_.Empty() && isRelative_) { - absoluteParentFolder_ = absolutePath_.Substr(0, position); - } + absoluteParentFolder_ = absolutePath_.Substr(0, position); } void Path::InitializeParentFolder() diff --git a/ets2panda/util/ast-builders/etsLaunchExpressionBuilder.h b/ets2panda/util/recursiveGuard.h similarity index 39% rename from ets2panda/util/ast-builders/etsLaunchExpressionBuilder.h rename to ets2panda/util/recursiveGuard.h index dc43d9322bff3f9f720a9eb870927ffea10634c9..34b57989b1ec5ec1c1ec112c1a01ccb641901e54 100644 --- a/ets2panda/util/ast-builders/etsLaunchExpressionBuilder.h +++ b/ets2panda/util/recursiveGuard.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 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 @@ -13,34 +13,45 @@ * limitations under the License. */ -#ifndef ES2PANDA_UTIL_INCLUDE_ETS_LAUNCH_EXPRESSION_BUILDER -#define ES2PANDA_UTIL_INCLUDE_ETS_LAUNCH_EXPRESSION_BUILDER +#ifndef RECURSIVE_GUARD_H +#define RECURSIVE_GUARD_H -#include "ir/ets/etsLaunchExpression.h" -#include "mem/arena_allocator.h" -#include "astBuilder.h" +namespace ark::es2panda::parser { -namespace ark::es2panda::ir { +constexpr unsigned int MAX_RECURSION_DEPTH = 1024; -class ETSLaunchExpressionBuilder : public AstBuilder { +struct RecursiveContext { + unsigned depth = 0; +}; + +class TrackRecursive { public: - explicit ETSLaunchExpressionBuilder(ark::ArenaAllocator *allocator) : AstBuilder(allocator) {} + explicit TrackRecursive(RecursiveContext &recursivecontext) : recursivecontext_(recursivecontext) + { + ++recursivecontext_.depth; + valid_ = recursivecontext_.depth <= MAX_RECURSION_DEPTH; + }; - ETSLaunchExpressionBuilder &SetExpression(CallExpression *expr) + ~TrackRecursive() { - expr_ = expr; - return *this; + --recursivecontext_.depth; } - ETSLaunchExpression *Build() + TrackRecursive(const TrackRecursive &) = delete; + TrackRecursive(TrackRecursive &&) = delete; + TrackRecursive &operator=(const TrackRecursive &) = delete; + TrackRecursive &operator=(TrackRecursive &&) = delete; + + explicit operator bool() const { - auto node = AllocNode(expr_); - return node; + return valid_; } private: - CallExpression *expr_ {}; + RecursiveContext &recursivecontext_; + bool valid_ = true; }; -} // namespace ark::es2panda::ir -#endif // ES2PANDA_UTIL_INCLUDE_ETS_LAUNCH_EXPRESSION_BUILDER \ No newline at end of file +} // namespace ark::es2panda::parser + +#endif // UTIL_GUARD_H diff --git a/ets2panda/util/ustring.cpp b/ets2panda/util/ustring.cpp index 7a8d1ace6d23afd00f7bcc4c95c9e673a2dcbb88..90cf82ad7718209eebd29408a5b6421bb2617765 100644 --- a/ets2panda/util/ustring.cpp +++ b/ets2panda/util/ustring.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 @@ -80,14 +80,6 @@ void StringView::Iterator::SkipCp() } } -bool StringView::IsConvertibleToChar() const -{ - Iterator it(*this); - size_t size = 0; - char32_t ch = it.PeekCp(&size); - return size == Length() && ch != Iterator::INVALID_CP; -} - } // namespace ark::es2panda::util // NOLINTNEXTLINE(cert-dcl58-cpp) diff --git a/ets2panda/util/ustring.h b/ets2panda/util/ustring.h index a1fc97e97df2f68fcbe2b002a74f5aa043fced25..be6a745d60eeb58ac60b8e767f1bb344cc9cf59f 100644 --- a/ets2panda/util/ustring.h +++ b/ets2panda/util/ustring.h @@ -156,8 +156,6 @@ public: template static void Mutf8Encode(T *str, char32_t cu); - bool IsConvertibleToChar() const; - class Iterator { public: static char32_t constexpr INVALID_CP = std::numeric_limits::max(); @@ -234,6 +232,10 @@ public: class Constants { public: + static constexpr uint16_t UTF8_2BYTE_REQUIRED = 2; + static constexpr uint16_t UTF8_3BYTE_REQUIRED = 3; + static constexpr uint16_t UTF8_4BYTE_REQUIRED = 4; + static constexpr uint16_t UTF8_1BYTE_LIMIT = 0x80; static constexpr uint16_t UTF8_2BYTE_LIMIT = 0x800; static constexpr uint32_t UTF8_3BYTE_LIMIT = 0x10000; @@ -375,22 +377,25 @@ char32_t StringView::Iterator::DecodeCP([[maybe_unused]] size_t *cpSize) const } const auto *iterNext = iter_; + const auto remain = static_cast(sv_.end() - iterNext); char32_t cu0 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) char32_t res {}; if (cu0 < Constants::UTF8_1BYTE_LIMIT) { res = cu0; - } else if ((cu0 & Constants::UTF8_3BYTE_HEADER) == Constants::UTF8_2BYTE_HEADER) { + } else if ((cu0 & Constants::UTF8_3BYTE_HEADER) == Constants::UTF8_2BYTE_HEADER && + remain >= Constants::UTF8_2BYTE_REQUIRED) { char32_t cu1 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) res = ((cu0 & Constants::UTF8_2BYTE_MASK) << Constants::UTF8_2BYTE_SHIFT) | (cu1 & Constants::UTF8_CONT_MASK); - } else if ((cu0 & Constants::UTF8_4BYTE_HEADER) == Constants::UTF8_3BYTE_HEADER) { + } else if ((cu0 & Constants::UTF8_4BYTE_HEADER) == Constants::UTF8_3BYTE_HEADER && + remain >= Constants::UTF8_3BYTE_REQUIRED) { char32_t cu1 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) char32_t cu2 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) res = ((cu0 & Constants::UTF8_3BYTE_MASK) << Constants::UTF8_3BYTE_SHIFT) | ((cu1 & Constants::UTF8_CONT_MASK) << Constants::UTF8_2BYTE_SHIFT) | (cu2 & Constants::UTF8_CONT_MASK); } else if (((cu0 & Constants::UTF8_DECODE_4BYTE_MASK) == Constants::UTF8_4BYTE_HEADER) && - (cu0 <= Constants::UTF8_DECODE_4BYTE_LIMIT)) { + cu0 <= Constants::UTF8_DECODE_4BYTE_LIMIT && remain >= Constants::UTF8_4BYTE_REQUIRED) { char32_t cu1 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) char32_t cu2 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) char32_t cu3 = static_cast(*iterNext++); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index 23cd6c7c9f401cb451e3a7ef6c09b87994e386c3..3c1b368ce7d2fe7a0da0d81285a47f1c0bd200fd 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -18,6 +18,7 @@ #include "evaluate/scopedDebugInfoPlugin.h" #include "public/public.h" #include "compiler/lowering/util.h" +#include "util/helpers.h" namespace ark::es2panda::varbinder { @@ -29,6 +30,7 @@ void ETSBinder::IdentifierAnalysis() recordTable_->SetProgram(Program()); globalRecordTable_.SetClassDefinition(Program()->GlobalClass()); + BuildProgram(); ES2PANDA_ASSERT(globalRecordTable_.ClassDefinition() == Program()->GlobalClass()); @@ -75,7 +77,7 @@ bool ETSBinder::HandleDynamicVariables(ir::Identifier *ident, Variable *variable bool ETSBinder::LookupInDebugInfoPlugin(ir::Identifier *ident) { - auto *checker = GetContext()->checker->AsETSChecker(); + auto *checker = GetContext()->GetChecker()->AsETSChecker(); auto *debugInfoPlugin = checker->GetDebugInfoPlugin(); if (UNLIKELY(debugInfoPlugin)) { auto *var = debugInfoPlugin->FindClass(ident); @@ -96,7 +98,7 @@ static void CreateDummyVariable(ETSBinder *varBinder, ir::Identifier *ident) varBinder->NewVarDecl(ident->Start(), compiler::GenName(varBinder->Allocator()).View()); var->SetScope(varBinder->GetScope()); ident->SetVariable(var); - ident->SetTsType(var->SetTsType(varBinder->GetContext()->checker->AsETSChecker()->GlobalTypeError())); + ident->SetTsType(var->SetTsType(varBinder->GetContext()->GetChecker()->AsETSChecker()->GlobalTypeError())); decl->BindNode(ident); } @@ -152,7 +154,10 @@ void ETSBinder::LookupTypeReference(ir::Identifier *ident, bool allowDynamicName return; } - ThrowUnresolvableType(ident->Start(), name); + if (!GetContext()->config->options->IsGenerateDeclEnableIsolated()) { + ThrowUnresolvableType(ident->Start(), name); + } + CreateDummyVariable(this, ident); } @@ -265,7 +270,8 @@ void ETSBinder::LookupIdentReference(ir::Identifier *ident) } if (ident->IsReference(Extension()) && res.variable->Declaration()->IsLetOrConstDecl() && - !res.variable->HasFlag(VariableFlags::INITIALIZED)) { + !res.variable->HasFlag(VariableFlags::INITIALIZED) && + !res.variable->HasFlag(VariableFlags::INIT_IN_STATIC_BLOCK)) { ThrowTDZ(ident->Start(), name); } } @@ -501,14 +507,20 @@ void ETSBinder::BuildClassDefinitionImpl(ir::ClassDefinition *classDef) auto fieldName = prop->Id()->Name(); if (auto fieldVar = fieldScope->FindLocal(fieldName, varbinder::ResolveBindingOptions::BINDINGS); fieldVar != nullptr) { - fieldVar->AddFlag(VariableFlags::INITIALIZED); + if (fieldVar->Declaration()->Node()->IsClassProperty() && + fieldVar->Declaration()->Node()->AsClassProperty()->NeedInitInStaticBlock()) { + fieldVar->AddFlag(VariableFlags::INIT_IN_STATIC_BLOCK); + } else if (!fieldVar->Declaration()->Node()->IsDefinite()) { + fieldVar->AddFlag(VariableFlags::INITIALIZED); + } + if ((fieldVar->Declaration()->IsConstDecl() || fieldVar->Declaration()->IsReadonlyDecl()) && prop->Value() == nullptr) { fieldVar->AddFlag(VariableFlags::EXPLICIT_INIT_REQUIRED); } } else { ES2PANDA_ASSERT(GetContext()->diagnosticEngine->IsAnyError()); - auto *checker = GetContext()->checker->AsETSChecker(); + auto *checker = GetContext()->GetChecker()->AsETSChecker(); prop->SetTsType(checker->GlobalTypeError()); prop->Id()->SetTsType(checker->GlobalTypeError()); } @@ -550,7 +562,7 @@ void ETSBinder::AddDynamicSpecifiersToTopBindings(ir::AstNode *const specifier, { // NOTE issue #23214: enable it after fix default import in dynamic import if (specifier->IsImportDefaultSpecifier()) { - ThrowError(specifier->Start(), "Default import is currently not implemented in dynamic import"); + ThrowError(specifier->Start(), diagnostic::DEFAULT_DYNAMIC_IMPORT); return; } const auto name = [specifier]() { @@ -592,20 +604,21 @@ void ETSBinder::InsertOrAssignForeignBinding(ir::AstNode *const specifier, const TopScope()->InsertOrAssignForeignBinding(name, var); } -std::string RedeclarationErrorMessageAssembler(const Variable *const var, const Variable *const variable, - util::StringView localName) +void ETSBinder::ThrowRedeclarationError(const lexer::SourcePosition &pos, const Variable *const var, + const Variable *const variable, util::StringView localName) { - bool isNamespace = var->Declaration()->Node()->IsClassDefinition() && - var->Declaration()->Node()->AsClassDefinition()->IsNamespaceTransformed(); - auto type = isNamespace ? "Namespace '" - : var->Declaration()->Node()->IsClassDefinition() ? "Class '" - : var->Declaration()->IsFunctionDecl() ? "Function '" - : "Variable '"; - auto str = util::Helpers::AppendAll(type, localName.Utf8(), "'"); - str += variable->Declaration()->Type() == var->Declaration()->Type() ? " is already defined." - : " is already defined with different type."; + const bool isNamespace = var->Declaration()->Node()->IsClassDefinition() && + var->Declaration()->Node()->AsClassDefinition()->IsNamespaceTransformed(); + const auto type = isNamespace ? "Namespace" + : var->Declaration()->Node()->IsClassDefinition() ? "Class" + : var->Declaration()->IsFunctionDecl() ? "Function" + : "Variable"; - return str; + if (variable->Declaration()->Type() == var->Declaration()->Type()) { + ThrowError(pos, diagnostic::REDEFINITION, {type, localName}); + } else { + ThrowError(pos, diagnostic::REDEFINITION_DIFF_TYPE, {type, localName}); + } } void AddOverloadFlag(ArenaAllocator *allocator, bool isStdLib, varbinder::Variable *importedVar, @@ -634,11 +647,13 @@ void AddOverloadFlag(ArenaAllocator *allocator, bool isStdLib, varbinder::Variab if (!currentNode->HasOverload(method)) { currentNode->AddOverload(method); - method->Function()->Id()->SetVariable(variable); - method->Function()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD); - method->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD); - util::UString newInternalName(method->Function()->Scope()->Name(), allocator); - method->Function()->Scope()->BindInternalName(newInternalName.View()); + if (method->Function()->Scope()->InternalName() == "") { + method->Function()->Id()->SetVariable(variable); + method->Function()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD); + method->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL_OVERLOAD); + util::UString newInternalName(method->Function()->Scope()->Name(), allocator); + method->Function()->Scope()->BindInternalName(newInternalName.View()); + } } } @@ -651,16 +666,16 @@ void ETSBinder::ImportAllForeignBindings(ir::AstNode *const specifier, bool const isStdLib = util::Helpers::IsStdLib(Program()); for (const auto [bindingName, var] : globalBindings) { - if (bindingName.Is(compiler::Signatures::ETS_GLOBAL)) { + if (!var->Declaration()->Node()->IsValidInCurrentPhase()) { + continue; + } + if (util::Helpers::IsGlobalVar(var)) { const auto *const classDef = var->Declaration()->Node()->AsClassDeclaration()->Definition(); ImportGlobalProperties(classDef); continue; } - ES2PANDA_ASSERT(bindingName.Utf8().find(compiler::Signatures::ETS_GLOBAL) == std::string::npos); - if (!importGlobalScope->IsForeignBinding(bindingName) && !var->Declaration()->Node()->IsDefaultExported() && - (var->AsLocalVariable()->Declaration()->Node()->IsExported() || - var->AsLocalVariable()->Declaration()->Node()->IsExportedType())) { + (var->AsLocalVariable()->Declaration()->Node()->IsExported())) { auto variable = Program()->GlobalClassScope()->FindLocal(bindingName, ResolveBindingOptions::ALL); if (variable == nullptr || var == variable) { InsertForeignBinding(specifier, import, bindingName, var); @@ -677,7 +692,7 @@ void ETSBinder::ImportAllForeignBindings(ir::AstNode *const specifier, InsertForeignBinding(specifier, import, bindingName, var); } - ThrowError(import->Source()->Start(), RedeclarationErrorMessageAssembler(var, variable, bindingName)); + ThrowRedeclarationError(import->Source()->Start(), var, variable, bindingName); } } @@ -772,8 +787,7 @@ Variable *ETSBinder::FindImportSpecifiersVariable(const util::StringView &import static bool IsExportedVariable(varbinder::Variable *const var) { return var != nullptr && - (var->Declaration()->Node()->IsExported() || var->Declaration()->Node()->IsExportedType() || - var->Declaration()->Node()->IsDefaultExported()); + (var->Declaration()->Node()->IsExported() || var->Declaration()->Node()->IsDefaultExported()); } ir::ETSImportDeclaration *ETSBinder::FindImportDeclInReExports(const ir::ETSImportDeclaration *const import, @@ -816,27 +830,24 @@ ir::ETSImportDeclaration *ETSBinder::FindImportDeclInReExports(const ir::ETSImpo return implDecl; } -void ETSBinder::ValidateImportVariable(const ir::AstNode *node, const ir::ETSImportDeclaration *const import, - const util::StringView &imported, const ir::StringLiteral *const importPath) +void ETSBinder::ValidateImportVariable(const ir::AstNode *node, const util::StringView &imported, + const ir::StringLiteral *const importPath) { if (node->IsDefaultExported()) { - ThrowError(importPath->Start(), "Use the default import syntax to import a default exported element"); - } else if (import->IsTypeKind() && !node->IsExportedType()) { - ThrowError(importPath->Start(), - "Cannot import '" + imported.Mutf8() + "', imported type imports only exported types."); - } else if (!node->IsExported() && !node->IsExportedType() && !node->IsDefaultExported()) { - ThrowError(importPath->Start(), "Imported element not exported '" + imported.Mutf8() + "'"); + ThrowError(importPath->Start(), diagnostic::DEFAULT_EXPORT_DIRECT_IMPORTED); + } else if (!node->IsExported() && !node->IsDefaultExported()) { + ThrowError(importPath->Start(), diagnostic::IMPORTED_NOT_EXPORTED, {imported}); } } bool ETSBinder::DetectNameConflict(const util::StringView localName, Variable *const var, Variable *const otherVar, - const ir::StringLiteral *const importPath, bool overloadAllowed) + const ir::StringLiteral *const importPath) { if (otherVar == nullptr || var == otherVar) { return false; } - if (overloadAllowed && var->Declaration()->IsFunctionDecl() && otherVar->Declaration()->IsFunctionDecl()) { + if (var->Declaration()->IsFunctionDecl() && otherVar->Declaration()->IsFunctionDecl()) { AddOverloadFlag(Allocator(), util::Helpers::IsStdLib(Program()), var, otherVar); return true; } @@ -846,7 +857,7 @@ bool ETSBinder::DetectNameConflict(const util::StringView localName, Variable *c return false; } - ThrowError(importPath->Start(), RedeclarationErrorMessageAssembler(var, otherVar, localName)); + ThrowRedeclarationError(importPath->Start(), var, otherVar, localName); return true; } @@ -887,33 +898,32 @@ bool ETSBinder::AddImportSpecifiersToTopBindings(Span re return true; } - ThrowError(importPath->Start(), "Cannot find imported element '" + imported.Mutf8() + "'"); + ThrowError(importPath->Start(), diagnostic::IMPORT_NOT_FOUND, {imported}); return false; } auto *node = FindNodeInAliasMap(import->ResolvedSource(), imported); - ValidateImportVariable(node != nullptr ? node : var->Declaration()->Node(), import, imported, importPath); + ValidateImportVariable(node != nullptr ? node : var->Declaration()->Node(), imported, importPath); const auto localName = importSpecifier->Local()->Name(); auto varInGlobalClassScope = Program()->GlobalClassScope()->FindLocal(localName, ResolveBindingOptions::ALL); auto previouslyImportedVariable = TopScope()->FindLocal(localName, ResolveBindingOptions::ALL); - if (DetectNameConflict(localName, var, varInGlobalClassScope, importPath, true) || - DetectNameConflict(localName, var, previouslyImportedVariable, importPath, false)) { + if (DetectNameConflict(localName, var, varInGlobalClassScope, importPath) || + DetectNameConflict(localName, var, previouslyImportedVariable, importPath)) { return true; } if (var->Declaration()->Node()->IsAnnotationDeclaration() && var->Declaration()->Node()->AsAnnotationDeclaration()->GetBaseName()->Name() != localName) { - ThrowError(importPath->Start(), "Can not rename annotation '" + var->Declaration()->Name().Mutf8() + - "' in export or import statements."); + ThrowError(importPath->Start(), diagnostic::IMPORT_RENAMES_ANNOTATION, {var->Declaration()->Name()}); return false; } // The first part of the condition will be true, if something was given an alias when exported, but we try // to import it using its original name. if (nameToSearchFor == imported && var->Declaration()->Node()->HasExportAlias()) { - ThrowError(importSpecifier->Start(), "Cannot find imported element '" + imported.Mutf8() + "'"); + ThrowError(importSpecifier->Start(), diagnostic::IMPORT_NOT_FOUND, {imported}); return false; } @@ -968,7 +978,10 @@ static Variable *FindInStatic(parser::Program *program) static Variable *FindInInstance(parser::Program *program) { - auto predicateFunc = [](const auto &item) { return item.second->Declaration()->Node()->IsDefaultExported(); }; + auto predicateFunc = [](const auto &item) { + return item.second->Declaration()->Node()->IsValidInCurrentPhase() && + item.second->Declaration()->Node()->IsDefaultExported(); + }; const auto &instanceMethodBindings = program->GlobalClassScope()->InstanceMethodScope()->Bindings(); auto result = std::find_if(instanceMethodBindings.begin(), instanceMethodBindings.end(), predicateFunc); if (result == instanceMethodBindings.end()) { @@ -996,7 +1009,10 @@ varbinder::Variable *ETSBinder::FindStaticBinding(Span r if (result != nullptr) { return result; } - ThrowError(importPath->Start(), "Cannot find default imported element in the target"); + if (!GetContext()->config->options->IsGenerateDeclEnableIsolated()) { + ThrowError(importPath->Start(), diagnostic::DEFAULT_IMPORT_NOT_FOUND); + } + return nullptr; } @@ -1018,10 +1034,9 @@ ArenaVector ETSBinder::GetExternalProgram(util::StringView so auto programList = GetProgramList(sourceName); if (programList.empty()) { if (ark::os::file::File::IsDirectory(sourceName.Mutf8())) { - ThrowError(importPath->Start(), - "Cannot find index.[ets|ts] or package module in folder: " + importPath->Str().Mutf8()); + ThrowError(importPath->Start(), diagnostic::MODULE_INDEX_MISSING, {importPath->Str()}); } else { - ThrowError(importPath->Start(), "Cannot find import: " + importPath->Str().Mutf8()); + ThrowError(importPath->Start(), diagnostic::IMPORT_NOT_FOUND_2, {importPath->Str()}); } } @@ -1110,7 +1125,7 @@ bool ETSBinder::BuildInternalName(ir::ScriptFunction *scriptFunc) bool compilable = scriptFunc->Body() != nullptr && !isExternal; if (!compilable) { - recordTable_->Signatures().push_back(funcScope); + recordTable_->EmplaceSignatures(funcScope, scriptFunc); } return compilable; @@ -1133,7 +1148,7 @@ bool ETSBinder::BuildInternalNameWithCustomRecordTable(ir::ScriptFunction *const const bool compilable = scriptFunc->Body() != nullptr && !isExternal; if (!compilable) { - recordTable->Signatures().push_back(funcScope); + recordTable->EmplaceSignatures(funcScope, scriptFunc); } return compilable; @@ -1198,16 +1213,9 @@ void ETSBinder::BuildProgram() ValidateReexports(); - auto &stmts = Program()->Ast()->Statements(); + auto &stmts = Program()->Ast()->StatementsForUpdates(); const auto etsGlobal = std::find_if(stmts.begin(), stmts.end(), [](const ir::Statement *stmt) { - if (stmt->IsClassDeclaration() && - !stmt->AsClassDeclaration()->Definition()->Ident()->Name().Is(compiler::Signatures::ETS_GLOBAL)) { - ES2PANDA_ASSERT(stmt->AsClassDeclaration()->Definition()->Ident()->Name().Utf8().find( - // CC-OFFNXT(G.FMT.06-CPP,G.FMT.05-CPP) project code style - compiler::Signatures::ETS_GLOBAL) == std::string::npos); - } - return stmt->IsClassDeclaration() && - stmt->AsClassDeclaration()->Definition()->Ident()->Name().Is(compiler::Signatures::ETS_GLOBAL); + return stmt->IsClassDeclaration() && stmt->AsClassDeclaration()->Definition()->IsGlobal(); }); if (etsGlobal != stmts.end()) { const auto begin = std::find_if(stmts.rbegin(), stmts.rend(), [](const ir::Statement *stmt) { @@ -1231,13 +1239,19 @@ void ETSBinder::BuildExternalProgram(parser::Program *extProgram) auto flags = Program()->VarBinder()->IsGenStdLib() ? RecordTableFlags::NONE : RecordTableFlags::EXTERNAL; auto *extRecordTable = Allocator()->New(Allocator(), extProgram, flags); + extRecordTable->SetClassDefinition(extProgram->GlobalClass()); + externalRecordTable_.insert({extProgram, extRecordTable}); ResetTopScope(extProgram->GlobalScope()); recordTable_ = extRecordTable; SetProgram(extProgram); - BuildProgram(); + if (!extProgram->IsASTLowered()) { + BuildProgram(); + } else { + extRecordTable->Merge(extProgram->VarBinder()->AsETSBinder()->GetExternalRecordTable().at(extProgram)); + } SetProgram(savedProgram); recordTable_ = savedRecordTable; @@ -1329,14 +1343,14 @@ void ETSBinder::ValidateReexportDeclaration(ir::ETSReExportDeclaration *decl) const auto *const import = decl->GetETSImportDeclarations(); const auto &specifiers = import->Specifiers(); - for (auto specifier : specifiers) { + for (auto const specifier : specifiers) { // Example: export {foo} from "./A" if (specifier->IsImportSpecifier()) { auto importSpecifier = specifier->AsImportSpecifier(); const auto reexported = importSpecifier->Imported()->Name(); auto *const var = ValidateImportSpecifier(importSpecifier, import); if (var == nullptr) { - ThrowError(import->Start(), "Incorrect export \"" + reexported.Mutf8() + "\""); + ThrowError(import->Start(), diagnostic::EXPORT_INCORRECT, {reexported}); continue; } @@ -1345,7 +1359,7 @@ void ETSBinder::ValidateReexportDeclaration(ir::ETSReExportDeclaration *decl) // Remember reexported name to check for ambiguous reexports if (!reexportedNames_.insert(reexported).second) { - ThrowError(import->Start(), "Ambiguous export \"" + reexported.Mutf8() + "\""); + ThrowError(import->Start(), diagnostic::AMBIGUOUS_EXPORT, {reexported}); continue; } } @@ -1376,7 +1390,7 @@ bool ETSBinder::ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable return true; } - ThrowError(classElement->Id()->Start(), RedeclarationErrorMessageAssembler(var, variable, name.Utf8())); + ThrowRedeclarationError(classElement->Id()->Start(), var, variable, name.Utf8()); } const auto insRes = TopScope()->InsertForeignBinding(name, var); @@ -1388,7 +1402,7 @@ bool ETSBinder::ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable return true; } - ThrowError(classElement->Id()->Start(), RedeclarationErrorMessageAssembler(var, insRes.first->second, name.Utf8())); + ThrowRedeclarationError(classElement->Id()->Start(), var, insRes.first->second, name.Utf8()); return false; } @@ -1468,9 +1482,15 @@ bool ETSBinder::IsDynamicNamespaceVariable(const Variable *var) const noexcept return data->specifier->IsImportNamespaceSpecifier(); } -void ETSBinder::ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const +void ETSBinder::ThrowError(const lexer::SourcePosition &pos, const diagnostic::DiagnosticKind &kind, + const util::DiagnosticMessageParams ¶ms) const +{ + GetContext()->diagnosticEngine->LogDiagnostic(kind, params, pos); +} + +bool ETSBinder::IsGlobalIdentifier([[maybe_unused]] const util::StringView &str) const { - GetContext()->diagnosticEngine->LogSemanticError(msg, pos); + return false; } } // namespace ark::es2panda::varbinder diff --git a/ets2panda/varbinder/ETSBinder.h b/ets2panda/varbinder/ETSBinder.h index 81f7705bcb7c9688b03d560b4aad7af55c79d8fe..140596eccdc48348626616e97dcf9b436d0b61b9 100644 --- a/ets2panda/varbinder/ETSBinder.h +++ b/ets2panda/varbinder/ETSBinder.h @@ -150,8 +150,7 @@ public: const ir::ETSImportDeclaration *const import); void BuildETSNewClassInstanceExpression(ir::ETSNewClassInstanceExpression *classInstance); [[nodiscard]] bool DetectNameConflict(const util::StringView localName, Variable *const var, - Variable *const otherVar, const ir::StringLiteral *const importPath, - bool overloadAllowed); + Variable *const otherVar, const ir::StringLiteral *const importPath); [[nodiscard]] ArenaVector GetExternalProgram(util::StringView sourceName, const ir::StringLiteral *importPath); @@ -166,14 +165,14 @@ public: void AddImportDefaultSpecifiersToTopBindings(Span records, ir::ImportDefaultSpecifier *importDefaultSpecifier, const ir::ETSImportDeclaration *import); - void ValidateImportVariable(const ir::AstNode *node, const ir::ETSImportDeclaration *const import, - const util::StringView &imported, const ir::StringLiteral *const importPath); + void ValidateImportVariable(const ir::AstNode *node, const util::StringView &imported, + const ir::StringLiteral *const importPath); Variable *FindImportSpecifiersVariable(const util::StringView &imported, const varbinder::Scope::VariableMap &globalBindings, Span record); Variable *FindStaticBinding(Span records, const ir::StringLiteral *importPath); - void AddSpecifiersToTopBindings(ir::AstNode *specifier, const ir::ETSImportDeclaration *import); - void AddDynamicSpecifiersToTopBindings(ir::AstNode *specifier, const ir::ETSImportDeclaration *import); + void AddSpecifiersToTopBindings(ir::AstNode *const specifier, const ir::ETSImportDeclaration *const import); + void AddDynamicSpecifiersToTopBindings(ir::AstNode *const specifier, const ir::ETSImportDeclaration *const import); void ResolveInterfaceDeclaration(ir::TSInterfaceDeclaration *decl); void ResolveMethodDefinition(ir::MethodDefinition *methodDef); @@ -188,7 +187,13 @@ public: void BuildProxyMethod(ir::ScriptFunction *func, const util::StringView &containingClassName, bool isExternal); void AddFunctionThisParam(ir::ScriptFunction *func); - void ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const override; + void ThrowError(const lexer::SourcePosition &pos, const diagnostic::DiagnosticKind &kind) const + { + ThrowError(pos, kind, util::DiagnosticMessageParams {}); + } + void ThrowError(const lexer::SourcePosition &pos, const diagnostic::DiagnosticKind &kind, + const util::DiagnosticMessageParams ¶ms) const override; + bool IsGlobalIdentifier(const util::StringView &str) const override; void SetDefaultImports(ArenaVector defaultImports) noexcept { @@ -204,10 +209,15 @@ public: void AddReExportImport(ir::ETSReExportDeclaration *reExport) noexcept { - reExportImports_.push_back(reExport); + reExportImports_.insert(reExport); + } + + [[nodiscard]] const ArenaUnorderedSet &ReExportImports() const noexcept + { + return reExportImports_; } - [[nodiscard]] const ArenaVector &ReExportImports() const noexcept + [[nodiscard]] ArenaUnorderedSet &ReExportImports() noexcept { return reExportImports_; } @@ -268,6 +278,18 @@ public: globalRecordTable_.CleanUp(); } + void CopyTo(VarBinder *target) override + { + auto targetImpl = reinterpret_cast(target); + + targetImpl->defaultImports_ = defaultImports_; + InitImplicitThisParam(); + targetImpl->selectiveExportAliasMultimap_ = selectiveExportAliasMultimap_; + ; + + VarBinder::CopyTo(target); + } + private: void BuildClassDefinitionImpl(ir::ClassDefinition *classDef); void InitImplicitThisParam(); @@ -282,18 +304,20 @@ private: void ImportAllForeignBindings(ir::AstNode *specifier, const varbinder::Scope::VariableMap &globalBindings, const parser::Program *importProgram, const varbinder::GlobalScope *importGlobalScope, const ir::ETSImportDeclaration *import); + void ThrowRedeclarationError(const lexer::SourcePosition &pos, const Variable *const var, + const Variable *const variable, util::StringView localName); RecordTable globalRecordTable_; RecordTable *recordTable_; ArenaMap externalRecordTable_; - ArenaVector defaultImports_; + ArenaVector defaultImports_; // 1 ArenaVector dynamicImports_; - ArenaVector reExportImports_; + ArenaUnorderedSet reExportImports_; ArenaSet reexportedNames_; DynamicImportVariables dynamicImportVars_; - ir::Identifier *thisParam_ {}; + ir::Identifier *thisParam_ {}; // 2 ir::AstNode *defaultExport_ {}; - ModulesToExportedNamesWithAliases selectiveExportAliasMultimap_; + ModulesToExportedNamesWithAliases selectiveExportAliasMultimap_; // 3 friend class RecordTableContext; }; @@ -303,7 +327,8 @@ public: RecordTableContext(ETSBinder *varBinder, parser::Program *extProgram) : varBinder_(varBinder), savedRecordTable_(varBinder->recordTable_) { - if (extProgram != nullptr) { + if (extProgram != nullptr && + varBinder->externalRecordTable_.find(extProgram) != varBinder->externalRecordTable_.end()) { varBinder->recordTable_ = varBinder->externalRecordTable_[extProgram]; } } diff --git a/ets2panda/varbinder/recordTable.h b/ets2panda/varbinder/recordTable.h index 1b3c9bd10c98555613327fa05b3ac7b8e8f766a3..437a2ffb79dd259f21257e6901141194fc991930 100644 --- a/ets2panda/varbinder/recordTable.h +++ b/ets2panda/varbinder/recordTable.h @@ -21,6 +21,8 @@ #include "util/ustring.h" #include "util/enumbitops.h" +#include + namespace ark::es2panda::parser { class Program; } // namespace ark::es2panda::parser @@ -72,6 +74,25 @@ public: ~RecordTable() = default; + void Merge(RecordTable *other) + { + for (auto classDef : other->classDefinitions_) { + classDefinitions_.insert(classDef); + } + + for (auto interfaceDecl : other->InterfaceDeclarations()) { + interfaceDeclarations_.insert(interfaceDecl); + } + + for (auto annoDecl : other->AnnotationDeclarations()) { + annotationDeclarations_.insert(annoDecl); + } + + for (auto sig : other->signatures_) { + signatures_.insert(sig); + } + } + bool IsExternal() const { return (flags_ & RecordTableFlags::EXTERNAL) != 0; @@ -107,16 +128,22 @@ public: return annotationDeclarations_; } - ArenaVector &Signatures() + ArenaSet &Signatures() { return signatures_; } - const ArenaVector &Signatures() const + const ArenaSet &Signatures() const { return signatures_; } + void EmplaceSignatures(varbinder::FunctionScope *signature, ir::ScriptFunction *func) + { + func->AddFlag(ir::ScriptFunctionFlags::IN_RECORD); + signatures_.insert(signature); + } + void SetClassDefinition(ir::ClassDefinition *classDefinition) { record_ = classDefinition; @@ -208,7 +235,7 @@ private: ArenaSet classDefinitions_; ArenaSet interfaceDeclarations_; ArenaSet annotationDeclarations_; - ArenaVector signatures_; + ArenaSet signatures_; RecordHolder record_ {nullptr}; parser::Program *program_ {}; BoundContext *boundCtx_ {}; diff --git a/ets2panda/varbinder/scope.cpp b/ets2panda/varbinder/scope.cpp index 7e0673b21016d39cba19118155888208cb148554..ed4d78ebdb9c7b700213a05f7896d1a84a6ed96f 100644 --- a/ets2panda/varbinder/scope.cpp +++ b/ets2panda/varbinder/scope.cpp @@ -437,7 +437,8 @@ Variable *ParamScope::AddParameter(ArenaAllocator *allocator, Decl *newDecl, Var return param; } -std::tuple ParamScope::AddParamDecl(ArenaAllocator *allocator, ir::Expression *parameter) +std::tuple ParamScope::AddParamDecl(ArenaAllocator *allocator, varbinder::VarBinder *vb, + ir::Expression *parameter) { auto [name, pattern] = util::Helpers::ParamName(allocator, parameter, params_.size()); if (name.Is(ERROR_LITERAL)) { @@ -450,7 +451,7 @@ std::tuple ParamScope::AddParamDecl(ArenaAllocator } if (pattern) { - std::vector bindings = util::Helpers::CollectBindingNames(parameter); + std::vector bindings = util::Helpers::CollectBindingNames(vb, parameter); for (auto *binding : bindings) { auto *varDecl = NewDecl(allocator, binding->Name()); @@ -640,7 +641,7 @@ Scope::InsertResult GlobalScope::InsertImpl(const util::StringView &name, Variab ES2PANDA_ASSERT(var->Declaration()->Name().Utf8().find(compiler::Signatures::ETS_GLOBAL) == std::string::npos); const auto *const node = var->Declaration()->Node(); - if (!(node->IsExported() || node->IsDefaultExported() || node->IsExportedType())) { + if (!(node->IsExported() || node->IsDefaultExported())) { return Scope::InsertResult {Bindings().end(), false}; } } @@ -959,11 +960,15 @@ Variable *ClassScope::AddBinding(ArenaAllocator *allocator, [[maybe_unused]] Var return nullptr; } - if (auto node = newDecl->Node(); - node->IsStatement() && - (node->AsStatement()->IsMethodDefinition() || node->IsClassProperty() || node->IsClassStaticBlock()) && - node->AsStatement()->AsClassElement()->Value() != nullptr) { - props.SetFlagsType(VariableFlags::INITIALIZED); + if (auto node = newDecl->Node(); node->IsStatement() && (node->AsStatement()->IsMethodDefinition() || + node->IsClassProperty() || node->IsClassStaticBlock())) { + if (node->AsStatement()->AsClassElement()->Value() != nullptr) { + props.SetFlagsType(VariableFlags::INITIALIZED); + } + + if (node->IsClassProperty() && node->AsClassProperty()->NeedInitInStaticBlock()) { + props.SetFlagsType(VariableFlags::INIT_IN_STATIC_BLOCK); + } } var->SetScope(this); diff --git a/ets2panda/varbinder/scope.h b/ets2panda/varbinder/scope.h index 5ef35b88d0fefcc3c04486f5bc85f9269938f8cd..d8701598bd2d46f1fa646fed8afaa85f2968d76a 100644 --- a/ets2panda/varbinder/scope.h +++ b/ets2panda/varbinder/scope.h @@ -441,7 +441,8 @@ public: return params_; } - std::tuple AddParamDecl(ArenaAllocator *allocator, ir::Expression *parameter); + std::tuple AddParamDecl(ArenaAllocator *allocator, varbinder::VarBinder *vb, + ir::Expression *parameter); protected: explicit ParamScope(ArenaAllocator *allocator, Scope *parent) @@ -572,6 +573,16 @@ public: return internalName_; } + void SetEmitted() + { + emitted_ = true; + } + + bool IsEmitted() const + { + return emitted_; + } + Variable *AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, [[maybe_unused]] ScriptExtension extension) override; Variable *InsertBindingIfAbsentInScope(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, @@ -580,6 +591,7 @@ public: private: util::StringView name_ {}; util::StringView internalName_ {}; + bool emitted_ {false}; }; class ClassScope : public LocalScope { diff --git a/ets2panda/varbinder/varbinder.cpp b/ets2panda/varbinder/varbinder.cpp index 7d668b5de24eca46040b9fff9cfe3b07c09cc012..83750a64247d1fa390960df5d42edf312e0cb6d4 100644 --- a/ets2panda/varbinder/varbinder.cpp +++ b/ets2panda/varbinder/varbinder.cpp @@ -24,7 +24,6 @@ void VarBinder::InitTopScope() } else { topScope_ = Allocator()->New(Allocator()); } - scope_ = topScope_; varScope_ = topScope_; } @@ -33,53 +32,66 @@ Variable *VarBinder::AddParamDecl(ir::Expression *param) { ES2PANDA_ASSERT(scope_->IsFunctionParamScope() || scope_->IsCatchParamScope()); - auto [var, node] = static_cast(scope_)->AddParamDecl(Allocator(), param); + auto [var, node] = static_cast(scope_)->AddParamDecl(Allocator(), this, param); ES2PANDA_ASSERT(var != nullptr); if (node != nullptr) { - ThrowRedeclaration(node->Start(), var->Name()); + ThrowRedeclaration(node->Start(), var->Name(), var->Declaration()->Type()); } return var; } -void VarBinder::ThrowRedeclaration(const lexer::SourcePosition &pos, const util::StringView &name) const +void VarBinder::ThrowRedeclaration(const lexer::SourcePosition &pos, const util::StringView &name, + DeclType declType) const +{ + ThrowError(pos, diagnostic::VARIABLE_REDECLARED, {name}); + + switch (declType) { + case DeclType::CLASS: + case DeclType::INTERFACE: + case DeclType::ENUM: + ThrowError(pos, diagnostic::MERGED_DECLS); + break; + default: + break; + } +} + +void VarBinder::ThrowLocalRedeclaration(const lexer::SourcePosition &pos, const util::StringView &className) const { - auto const str = std::string {"Variable '"}.append(name.Utf8()).append("' has already been declared."); - ThrowError(pos, str); + ThrowError(pos, diagnostic::ID_REDECLARED, {className}); } void VarBinder::ThrowUnresolvableType(const lexer::SourcePosition &pos, const util::StringView &name) const { - auto const str = std::string {"Cannot find type '"}.append(name.Utf8()).append("'."); - ThrowError(pos, str); + ThrowError(pos, diagnostic::TYPE_NOT_FOUND, {name}); } void VarBinder::ThrowTDZ(const lexer::SourcePosition &pos, const util::StringView &name) const { - auto const str = std::string {"Variable '"}.append(name.Utf8()).append("' is accessed before it's initialization."); - ThrowError(pos, str); + ThrowError(pos, diagnostic::TEMPORAL_DEADZONE, {name}); } void VarBinder::ThrowInvalidCapture(const lexer::SourcePosition &pos, const util::StringView &name) const { - auto const str = std::string {"Cannot capture variable '"}.append(name.Utf8()).append("'."); - ThrowError(pos, str); + ThrowError(pos, diagnostic::INVALID_CAPTURE, {name}); } void VarBinder::ThrowPrivateFieldMismatch(const lexer::SourcePosition &pos, const util::StringView &name) const { - auto const str = - std::string {"Private field '"}.append(name.Utf8()).append("' must be declared in an enclosing class"); - ThrowError(pos, str); + ThrowError(pos, diagnostic::PRIVATE_FIELD_MISMATCH, {name}); } -void VarBinder::ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const +void VarBinder::ThrowError(const lexer::SourcePosition &pos, const diagnostic::DiagnosticKind &kind, + const util::DiagnosticMessageParams ¶ms) const { - lexer::LineIndex index(program_->SourceCode()); - lexer::SourceLocation loc = index.GetLocation(pos); + context_->diagnosticEngine->ThrowSyntaxError(kind, params, pos); +} - context_->diagnosticEngine->ThrowSyntaxError(msg, program_->SourceFilePath().Utf8(), loc.line, loc.col); +bool VarBinder::IsGlobalIdentifier(const util::StringView &str) const +{ + return util::Helpers::IsGlobalIdentifier(str); } void VarBinder::IdentifierAnalysis() @@ -118,7 +130,7 @@ bool VarBinder::InstantiateArgumentsImpl(Scope **scope, Scope *iter, const ir::A auto [argumentsVariable, exists] = (*scope)->AddDecl(Allocator(), FUNCTION_ARGUMENTS, VariableFlags::INITIALIZED); if (exists && Extension() != ScriptExtension::JS) { - ThrowRedeclaration(node->Start(), FUNCTION_ARGUMENTS); + ThrowRedeclaration(node->Start(), FUNCTION_ARGUMENTS, argumentsVariable->Declaration()->Type()); } else if (iter->IsFunctionParamScope()) { *scope = iter->AsFunctionParamScope()->GetFunctionScope(); (*scope)->InsertBinding(argumentsVariable->Name(), argumentsVariable); @@ -249,7 +261,7 @@ void VarBinder::BuildVarDeclaratorId(ir::AstNode *childNode) auto *ident = childNode->AsIdentifier(); const auto &name = ident->Name(); - if (util::Helpers::IsGlobalIdentifier(name) || name.Is(ERROR_LITERAL)) { + if (IsGlobalIdentifier(name) || name.Is(ERROR_LITERAL)) { break; } @@ -458,6 +470,19 @@ void VarBinder::VisitScriptFunction(ir::ScriptFunction *func) } if (!BuildInternalName(func)) { + if (func->Body() == nullptr) { + return; + } + auto stmt = func->Body()->AsBlockStatement()->Statements(); + auto scopeCtx = LexicalScope::Enter(this, funcScope); + std::function doNode = [&](ir::AstNode *node) { + if (node->IsTSInterfaceDeclaration() || node->IsClassDeclaration() || node->IsTSEnumDeclaration() || + node->IsAnnotationDeclaration()) { + ResolveReference(node); + } + node->Iterate([&](ir::AstNode *child) { doNode(child); }); + }; + doNode(func->Body()); return; } @@ -503,6 +528,7 @@ void VarBinder::ResolveReferenceWhileHelper(ir::AstNode *childNode) return ResolveReference(whileStatement->Body()); } +// CC-OFFNXT(huge_method,huge_cyclomatic_complexity,G.FUN.01-CPP) big switch-case, solid logic void VarBinder::ResolveReference(ir::AstNode *childNode) { switch (childNode->Type()) { @@ -512,8 +538,9 @@ void VarBinder::ResolveReference(ir::AstNode *childNode) case ir::AstNodeType::SUPER_EXPRESSION: scope_->EnclosingVariableScope()->AddFlag(ScopeFlags::USE_SUPER); return ResolveReferences(childNode); - case ir::AstNodeType::SCRIPT_FUNCTION: + case ir::AstNodeType::SCRIPT_FUNCTION: { return VisitScriptFunctionWithPotentialTypeParams(childNode->AsScriptFunction()); + } case ir::AstNodeType::VARIABLE_DECLARATOR: return BuildVarDeclarator(childNode->AsVariableDeclarator()); case ir::AstNodeType::CLASS_DEFINITION: @@ -522,17 +549,14 @@ void VarBinder::ResolveReference(ir::AstNode *childNode) return BuildClassProperty(childNode->AsClassProperty()); case ir::AstNodeType::BLOCK_STATEMENT: { auto scopeCtx = LexicalScope::Enter(this, childNode->AsBlockStatement()->Scope()); - return ResolveReferences(childNode); } case ir::AstNodeType::BLOCK_EXPRESSION: { auto scopeCtx = LexicalScope::Enter(this, childNode->AsBlockExpression()->Scope()); - return ResolveReferences(childNode); } case ir::AstNodeType::SWITCH_STATEMENT: { auto scopeCtx = LexicalScope::Enter(this, childNode->AsSwitchStatement()->Scope()); - return ResolveReferences(childNode); } case ir::AstNodeType::DO_WHILE_STATEMENT: diff --git a/ets2panda/varbinder/varbinder.h b/ets2panda/varbinder/varbinder.h index a7649724f59fbc9025c2368e469342db695d8f17..ff674f639bedec5df0df93fdecf5d21aab8b3379 100644 --- a/ets2panda/varbinder/varbinder.h +++ b/ets2panda/varbinder/varbinder.h @@ -92,7 +92,6 @@ public: void SetContext(public_lib::Context *context) { - ES2PANDA_ASSERT(!context_); context_ = context; } @@ -160,11 +159,18 @@ public: } void ThrowPrivateFieldMismatch(const lexer::SourcePosition &pos, const util::StringView &name) const; - void ThrowRedeclaration(const lexer::SourcePosition &pos, const util::StringView &name) const; + void ThrowRedeclaration(const lexer::SourcePosition &pos, const util::StringView &name, DeclType declType) const; + void ThrowLocalRedeclaration(const lexer::SourcePosition &pos, const util::StringView &name) const; void ThrowUnresolvableType(const lexer::SourcePosition &pos, const util::StringView &name) const; void ThrowTDZ(const lexer::SourcePosition &pos, const util::StringView &name) const; void ThrowInvalidCapture(const lexer::SourcePosition &pos, const util::StringView &name) const; - virtual void ThrowError(const lexer::SourcePosition &pos, const std::string_view msg) const; + void ThrowError(const lexer::SourcePosition &pos, const diagnostic::DiagnosticKind &kind) const + { + ThrowError(pos, kind, util::DiagnosticMessageParams {}); + } + virtual void ThrowError(const lexer::SourcePosition &pos, const diagnostic::DiagnosticKind &kind, + const util::DiagnosticMessageParams ¶ms) const; + virtual bool IsGlobalIdentifier(const util::StringView &str) const; void PropagateDirectEval() const; @@ -249,7 +255,7 @@ protected: void BuildForInOfLoop(varbinder::LoopScope *loopScope, ir::AstNode *left, ir::Expression *right, ir::Statement *body); void BuildCatchClause(ir::CatchClause *catchClauseStmt); - void BuildTypeAliasDeclaration(ir::TSTypeAliasDeclaration *typeAliasDecl); + void BuildTypeAliasDeclaration(ir::TSTypeAliasDeclaration *const typeAliasDecl); void ResolveReferences(const ir::AstNode *parent); void VisitScriptFunctionWithPotentialTypeParams(ir::ScriptFunction *func); void VisitScriptFunction(ir::ScriptFunction *func); @@ -279,6 +285,15 @@ protected: functionScopes_.clear(); } + virtual void CopyTo(VarBinder *target) + { + target->program_ = program_; + target->allocator_ = allocator_; + target->context_ = context_; + target->bindingOptions_ = bindingOptions_; + target->genStdLib_ = genStdLib_; + } + private: parser::Program *program_ {}; ArenaAllocator *allocator_ {}; @@ -381,7 +396,7 @@ T *VarBinder::AddTsDecl(const lexer::SourcePosition &pos, Args &&...args) T *decl = Allocator()->New(std::forward(args)...); if (scope_->AddTsDecl(Allocator(), decl, Extension()) == nullptr) { - ThrowRedeclaration(pos, decl->Name()); + ThrowRedeclaration(pos, decl->Name(), decl->Type()); } return decl; @@ -393,7 +408,7 @@ T *VarBinder::AddDecl(const lexer::SourcePosition &pos, Args &&...args) T *decl = Allocator()->New(std::forward(args)...); if (scope_->AddDecl(Allocator(), decl, Extension()) == nullptr) { - ThrowRedeclaration(pos, decl->Name()); + ThrowRedeclaration(pos, decl->Name(), decl->Type()); } return decl; @@ -403,10 +418,12 @@ template std::tuple VarBinder::NewVarDecl(const lexer::SourcePosition &pos, Args &&...args) { T *decl = Allocator()->New(std::forward(args)...); - varbinder::Variable *var = scope_->AddDecl(Allocator(), decl, Extension()); + auto *allocator = Allocator(); + auto extension = Extension(); + varbinder::Variable *var = scope_->AddDecl(allocator, decl, extension); if (var == nullptr) { - ThrowRedeclaration(pos, decl->Name()); + ThrowRedeclaration(pos, decl->Name(), decl->Type()); var = scope_->FindLocal(decl->Name(), ResolveBindingOptions::BINDINGS); } diff --git a/ets2panda/varbinder/variable.h b/ets2panda/varbinder/variable.h index ba937f6b0135da8607f155b9bdd9cb9a045fae43..be95eb82d3fd27bc765b38cb42380c925f96502d 100644 --- a/ets2panda/varbinder/variable.h +++ b/ets2panda/varbinder/variable.h @@ -152,7 +152,7 @@ private: class LocalVariable : public Variable { public: explicit LocalVariable(Decl *decl, VariableFlags flags); - explicit LocalVariable(VariableFlags flags); + explicit LocalVariable(const VariableFlags flags); VariableType Type() const override { diff --git a/ets2panda/varbinder/variableFlags.h b/ets2panda/varbinder/variableFlags.h index 683c4326a8221cac7b6bb3c966dfdf97a836fe8a..1177e71a3099a354ea472b0b41beac43ee24fe73 100644 --- a/ets2panda/varbinder/variableFlags.h +++ b/ets2panda/varbinder/variableFlags.h @@ -164,6 +164,7 @@ enum class VariableFlags : uint64_t { ANNOTATIONDECL = 1ULL << 33ULL, ANNOTATIONUSAGE = 1ULL << 34ULL, NAMESPACE = 1ULL << 35ULL, + INIT_IN_STATIC_BLOCK = 1ULL << 36ULL, HOIST_VAR = HOIST | VAR, CLASS_OR_INTERFACE = CLASS | INTERFACE, diff --git a/test262/ignored-test262-fastverify-qemu-int.txt b/test262/ignored-test262-fastverify-qemu-int.txt index fd9fb1bf1b5fcf78dec983a2de976fb5ebf13d7f..b1ba6cf9a7d39c21110534b5716d2d999de42b33 100644 --- a/test262/ignored-test262-fastverify-qemu-int.txt +++ b/test262/ignored-test262-fastverify-qemu-int.txt @@ -162,3 +162,6 @@ test262/data/test_es2021/built-ins/encodeURI/S15.1.3.3_A2.2_T1.js test262/data/test_es2021/intl402/default-locale-is-supported.js test262/data/test_es2021/intl402/supportedLocalesOf-duplicate-elements-removed.js test262/data/test_es2021/intl402/DisplayNames/options-style-toString-abrupt-throws.js + +#25907 +test262/data/test_es2021/built-ins/Object/create/15.2.3.5-4-194.js diff --git a/test262/ignored-test262-fastverify-x64-aot-pgo-litecg.txt b/test262/ignored-test262-fastverify-x64-aot-pgo-litecg.txt index 8b137891791fe96927ad78e64b0aad7bded08bdc..a9b564117521913ace0cd6d0dd67b43e7e2a3c57 100644 --- a/test262/ignored-test262-fastverify-x64-aot-pgo-litecg.txt +++ b/test262/ignored-test262-fastverify-x64-aot-pgo-litecg.txt @@ -1 +1,3 @@ +#19208 +test262/data/test_es2021/language/module-code/instn-iee-err-circular-as.js